diff --git a/msd/.gitignore b/msd/.gitignore
new file mode 100644
index 00000000..c5be9858
--- /dev/null
+++ b/msd/.gitignore
@@ -0,0 +1,16 @@
+/.php-cs-fixer.cache
+/work/config/myoosdumper.conf.php
+/work/config/myoosdumper.php
+/work/config/sql_statements
+/work/log/*.gz
+*.bak
+/work/config/*.php
+/work/backup/*.gz
+/work/structure/*.gz
+/.project
+/.buildpath
+/.settings
+/work/cache
+/work/temp
+/work/log/update.log
+/nbproject
diff --git a/msd/.htaccess b/msd/.htaccess
index b7c87f6f..ec3ec769 100644
--- a/msd/.htaccess
+++ b/msd/.htaccess
@@ -3,5 +3,5 @@ RewriteEngine off
 </IfModule>
 AuthName "MyOOS-Dumper"
 AuthType Basic
-AuthUserFile "/var/www/web360/htdocs/leitgedanken_utf8/msd/.htpasswd"
+AuthUserFile "/var/www/web360/htdocs/leitgedanken_php8/msd/.htpasswd"
 require valid-user
\ No newline at end of file
diff --git a/msd/README.md b/msd/README.md
new file mode 100644
index 00000000..5befd68a
--- /dev/null
+++ b/msd/README.md
@@ -0,0 +1,76 @@
+# [MyOOS [Dumper]](https://www.oos-shop.de) 
+===============
+
+MyOOS [Dumper] is an open source community project. MyOOS [Dumper] is a backup program for MySQL databases. With it, backup copies of the data (forum, store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access MyOOS [Dumper] is a useful alternative. 
+
+Requirements
+------------
+
+- PHP version 7.4 or higher.
+- MySQL version 5.6 or higher.
+- Apache version 2.4 or higher.
+
+
+Installation
+------------
+
+1. [Download MyOOS [Dumper]](https://github.com/r23/MyOOS-Dumper/releases)
+2. Unzip the downloaded zip file 
+3. Extract the file into an empty directory and upload everything from the directory Myoos-Dumper to the server.
+4. Go to install.php with your browser. The installation routine guides you through the individual steps and helps you to create the access data and database. 
+
+
+Documentation
+-------------
+
+### MyOOS [Dumper]
+Use your browser to open the [doku.oos-shop.de](https://doku.oos-shop.de/myoos-benutzerhandbuch/ueber-myoos/eine-einfuehrung-in-das-myoos-shopsystem/ueber-mysqldumper/) page for links to documentation.
+
+
+Support
+-------------
+For free support, visit our support site: (https://foren.myoos.de/viewforum.php?f=40)
+
+
+
+Wish list / Future attractions
+-------------
+Do you have any suggestions for improvement? Feel free to contact the development team via the forum: (https://foren.myoos.de/viewforum.php?f=40)
+
+
+
+
+Contribute
+-------------
+If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.
+https://github.com/r23/MyOOS-Dumper
+
+
+License
+-------------
+MyOOS [Dumper] Copyright (c) 2013 - by the MyOOS Development Team.
+
+based on MySQLDumper 1.24.4
+MySqlDumper Copyright (C)2004-2009 Daniel Schlichtholz (admin@mysqldumper.de)
+
+This program is free software; you can redistribute it and/or modify it under 
+the terms of the GNU General Public License as published by the Free Software 
+Foundation; either version 2 of the License, or (at your option) any later 
+version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT 
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
+FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
+details.
+
+You should have received a copy of the GNU General Public License along with 
+this program; if not, write to the Free Software Foundation, Inc., 675 Mass 
+Ave, Cambridge, MA 02139, USA.
+
+Released under the GNU General Public License. You can find the whole license text in the `license.txt` file.
+
+
+## Further reading
+
+* [MyOOS](https://www.oos-shop.de) - Homepage of MyOOS 
+* [MyOOS Forum](https://foren.myoos.de/viewforum.php?f=40) - Community forum
diff --git a/msd/ReadMe/ReadMe.txt b/msd/ReadMe/ReadMe.txt
index 920489b3..4cfd19cf 100644
--- a/msd/ReadMe/ReadMe.txt
+++ b/msd/ReadMe/ReadMe.txt
@@ -1,4 +1,4 @@
-MyOOS [Dumper] Copyright (c) 2016 - by the MyOOS Development Team.
+MyOOS [Dumper] Copyright (c) 2013 - by the MyOOS Development Team.
 
 based on MySQLDumper 1.24.4
 MySqlDumper Copyright (C)2004-2009 Daniel Schlichtholz (admin@mysqldumper.de)
diff --git a/msd/ReadMe/changelog_deutsch.txt b/msd/ReadMe/changelog_deutsch.txt
deleted file mode 100644
index 369e9358..00000000
--- a/msd/ReadMe/changelog_deutsch.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-MyOOS [Dumper] Version 4.2.0
-
-Folgende Dinge wurden geändert:
-- Funktion 'ereg' ist veraltet, wir verwenden 'preg_match'
-- Funktion 'split' ist veraltet, wir verweden 'explode' oder 'preg_split' 
-- Funktion 'mysql_list_tables' is veraltet
-- PHP mysql Erweiterung ist seit PHP 5.5.0 veraltet und wurde in PHP 7.0.0 entfernt. Wir verwenden mysqli
-
-
-
-MyOOS [Dumper] based on MySQLDumper 1.24.4
-
-Wer Du es ganz genau wissen möchtest, dann schaue Dir das changelog auf GitHub an. Hier ist akribisch 
-jede Änderung am Code dokumentiert:
-
-https://github.com/r23/MyOOS/tree/master/msd
diff --git a/msd/ReadMe/changelog_english.txt b/msd/ReadMe/changelog_english.txt
deleted file mode 100644
index c4197e5a..00000000
--- a/msd/ReadMe/changelog_english.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-MyOOS Version 4.2.0
-
-We addressed the following issues:
-- Function 'ereg' is deprecated, we use 'preg_match'
-- Function 'split' is deprecated, we use 'explode' or 'preg_split' 
-- Function 'mysql_list_tables' is deprecated
-- PHP 'mysql' extension is deprecated as of PHP 5.5.0, and has been removed as of PHP 7.0.0. Instead. 
-
-
-MyOOS [Dumper] based on MySQLDumper 1.24.4
-
-
-When you want to know more, just take a look at the changelog of my code changes at GitHub . Each change
-of the code is documented here:
-
-https://github.com/r23/MyOOS/tree/master/msd
diff --git a/msd/ReadMe/install_deutsch.txt b/msd/ReadMe/install_deutsch.txt
deleted file mode 100644
index 963134da..00000000
--- a/msd/ReadMe/install_deutsch.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Installation:
-
-- lade den Ordner mysqldumper in einen beliebeigen Ordner auf Deinen Webspace hoch
-- Starte das Script im Browser (http://example.org/mysqldumper/)
-- Folge den Installationsanweisungen
diff --git a/msd/ReadMe/install_english.txt b/msd/ReadMe/install_english.txt
deleted file mode 100644
index b50efff0..00000000
--- a/msd/ReadMe/install_english.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Installation:
-
-- upload the folder mysqldumper to any folder on your webspace
-- start the script in your browser (http://example.org/mysqldumper/)
-- Follow the Installatio assistent
\ No newline at end of file
diff --git a/msd/ReadMe/install_francais.txt b/msd/ReadMe/install_francais.txt
deleted file mode 100644
index c3443240..00000000
--- a/msd/ReadMe/install_francais.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Installation: 
-
-- Envoyer le r�pertoire "mysqldumper" sur votre serveur 
-- D�buter le script en saisissant l'adresse suivante dans votre navigateur (http://example.org/mysqldumper/)
-- Suivez les instructions d'installation du script 
diff --git a/msd/ReadMe/install_italiano.txt b/msd/ReadMe/install_italiano.txt
deleted file mode 100644
index 14a6ea81..00000000
--- a/msd/ReadMe/install_italiano.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-Installazione:
-
-- carica la cartella mysqldumper sul tuo spazio web
-- metti i diritti del file config.php a 777
-- fai partire lo script nel tuo Browser (http://example.org/mysqldumper/)
-- segui la installazione
\ No newline at end of file
diff --git a/msd/ReadMe/license_deutsch.txt b/msd/ReadMe/license_deutsch.txt
deleted file mode 100644
index 629c6a8b..00000000
--- a/msd/ReadMe/license_deutsch.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-GNU General Public License
-Deutsche Übersetzung der Version 2, Juni 1991
-
-Copyright © 1989, 1991 Free Software Foundation, Inc. 
-
-59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
-
-
-Diese Übersetzung ist kein rechtskräftiger Ersatz für die englischsprachige Originalversion! 
-
-
-Vorwort 
-Die meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die Freiheit zu nehmen, die Software weiterzugeben und zu verändern. Im Gegensatz dazu soll Ihnen die GNU General Public License , die Allgemeine Öffentliche GNU-Lizenz, ebendiese Freiheit garantieren. Sie soll sicherstellen, daß die Software für alle Benutzer frei ist. Diese Lizenz gilt für den Großteil der von der Free Software Foundation herausgegebenen Software und für alle anderen Programme, deren Autoren ihr Datenwerk dieser Lizenz unterstellt haben. Auch Sie können diese Möglichkeit der Lizenzierung für Ihre Programme anwenden. (Ein anderer Teil der Software der Free Software Foundation unterliegt stattdessen der GNU Library General Public License , der Allgemeinen Öffentlichen GNU-Lizenz für Bibliotheken.) [Mittlerweile wurde die GNU Library Public License von der GNU Lesser Public License abgelöst - Anmerkung des Übersetzers.] 
-
-Die Bezeichnung ,,freie`` Software bezieht sich auf Freiheit, nicht auf den Preis. Unsere Lizenzen sollen Ihnen die Freiheit garantieren, Kopien freier Software zu verbreiten (und etwas für diesen Service zu berechnen, wenn Sie möchten), die Möglichkeit, die Software im Quelltext zu erhalten oder den Quelltext auf Wunsch zu bekommen. Die Lizenzen sollen garantieren, daß Sie die Software ändern oder Teile davon in neuen freien Programmen verwenden dürfen - und daß Sie wissen, daß Sie dies alles tun dürfen. 
-
-Um Ihre Rechte zu schützen, müssen wir Einschränkungen machen, die es jedem verbieten, Ihnen diese Rechte zu verweigern oder Sie aufzufordern, auf diese Rechte zu verzichten. Aus diesen Einschränkungen folgen bestimmte Verantwortlichkeiten für Sie, wenn Sie Kopien der Software verbreiten oder sie verändern. 
-
-Beispielsweise müssen Sie den Empfängern alle Rechte gewähren, die Sie selbst haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien eines solchen Programms verbreiten. Sie müssen sicherstellen, daß auch die Empfänger den Quelltext erhalten bzw. erhalten können. Und Sie müssen ihnen diese Bedingungen zeigen, damit sie ihre Rechte kennen. 
-
-Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen die Software unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz an, die Ihnen das Recht gibt, die Software zu vervielfältigen, zu verbreiten und/oder zu verändern. 
-
-Um die Autoren und uns zu schützen, wollen wir darüberhinaus sicherstellen, daß jeder erfährt, daß für diese freie Software keinerlei Garantie besteht. Wenn die Software von jemand anderem modifiziert und weitergegeben wird, möchten wir, daß die Empfänger wissen, daß sie nicht das Original erhalten haben, damit irgendwelche von anderen verursachte Probleme nicht den Ruf des ursprünglichen Autors schädigen. 
-
-Schließlich und endlich ist jedes freie Programm permanent durch Software-Patente bedroht. Wir möchten die Gefahr ausschließen, daß Distributoren eines freien Programms individuell Patente lizensieren - mit dem Ergebnis, daß das Programm proprietär würde. Um dies zu verhindern, haben wir klargestellt, daß jedes Patent entweder für freie Benutzung durch jedermann lizenziert werden muß oder überhaupt nicht lizenziert werden darf. 
-
-Es folgen die genauen Bedingungen für die Vervielfältigung, Verbreitung und Bearbeitung: 
-
-
-Allgemeine Öffentliche GNU-Lizenz 
-Bedingungen für die Vervielfältigung, 
-Verbreitung und Bearbeitung 
-§0. Diese Lizenz gilt für jedes Programm und jedes andere Datenwerk, in dem ein entsprechender Vermerk des Copyright-Inhabers darauf hinweist, daß das Datenwerk unter den Bestimmungen dieser General Public License verbreitet werden darf. Im folgenden wird jedes derartige Programm oder Datenwerk als ,,das Programm`` bezeichnet; die Formulierung ,,auf dem Programm basierendes Datenwerk`` bezeichnet das Programm sowie jegliche Bearbeitung des Programms im urheberrechtlichen Sinne, also ein Datenwerk, welches das Programm, auch auszugsweise, sei es unverändert oder verändert und/oder in eine andere Sprache übersetzt, enthält. (Im folgenden wird die Übersetzung ohne Einschränkung als ,,Bearbeitung`` eingestuft.) Jeder Lizenznehmer wird im folgenden als ,,Sie`` angesprochen. 
-
-Andere Handlungen als Vervielfältigung, Verbreitung und Bearbeitung werden von dieser Lizenz nicht berührt; sie fallen nicht in ihren Anwendungsbereich. Der Vorgang der Ausführung des Programms wird nicht eingeschränkt, und die Ausgaben des Programms unterliegen dieser Lizenz nur, wenn der Inhalt ein auf dem Programm basierendes Datenwerk darstellt (unabhängig davon, daß die Ausgabe durch die Ausführung des Programmes erfolgte). Ob dies zutrifft, hängt von den Funktionen des Programms ab. 
-
-§1. Sie dürfen auf beliebigen Medien unveränderte Kopien des Quelltextes des Programms, wie sie ihn erhalten haben, anfertigen und verbreiten. Voraussetzung hierfür ist, daß Sie mit jeder Kopie einen entsprechenden Copyright-Vermerk sowie einen Haftungsausschluß veröffentlichen, alle Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie beziehen, unverändert lassen und desweiteren allen anderen Empfängern des Programms zusammen mit dem Programm eine Kopie dieser Lizenz zukommen lassen. 
-
-Sie dürfen für den eigentlichen Kopiervorgang eine Gebühr verlangen. Wenn Sie es wünschen, dürfen Sie auch gegen Entgeld eine Garantie für das Programm anbieten. 
-
-§2. Sie dürfen Ihre Kopie(n) des Programms oder eines Teils davon verändern, wodurch ein auf dem Programm basierendes Datenwerk entsteht; Sie dürfen derartige Bearbeitungen unter den Bestimmungen von Paragraph 1 vervielfältigen und verbreiten, vorausgesetzt, daß zusätzlich alle im folgenden genannten Bedingungen erfüllt werden: 
-
-
-1. 
-Sie müssen die veränderten Dateien mit einem auffälligen Vermerk versehen, der auf die von Ihnen vorgenommene Modifizierung und das Datum jeder Änderung hinweist. 
-
-2. 
-Sie müssen dafür sorgen, daß jede von Ihnen verbreitete oder veröffentlichte Arbeit, die ganz oder teilweise von dem Programm oder Teilen davon abgeleitet ist, Dritten gegenüber als Ganzes unter den Bedingungen dieser Lizenz ohne Lizenzgebühren zur Verfügung gestellt wird. 
-
-3. 
-Wenn das veränderte Programm normalerweise bei der Ausführung interaktiv Kommandos einliest, müssen Sie dafür sorgen, daß es, wenn es auf dem üblichsten Wege für solche interaktive Nutzung gestartet wird, eine Meldung ausgibt oder ausdruckt, die einen geeigneten Copyright-Vermerk enthält sowie einen Hinweis, daß es keine Gewährleistung gibt (oder anderenfalls, daß Sie Garantie leisten), und daß die Benutzer das Programm unter diesen Bedingungen weiter verbreiten dürfen. Auch muß der Benutzer darauf hingewiesen werden, wie er eine Kopie dieser Lizenz ansehen kann. (Ausnahme: Wenn das Programm selbst interaktiv arbeitet, aber normalerweise keine derartige Meldung ausgibt, muß Ihr auf dem Programm basierendes Datenwerk auch keine solche Meldung ausgeben). 
-
-Diese Anforderungen gelten für das bearbeitete Datenwerk als Ganzes. Wenn identifizierbare Teile des Datenwerkes nicht von dem Programm abgeleitet sind und vernünftigerweise als unabhängige und eigenständige Datenwerke für sich selbst zu betrachten sind, dann gelten diese Lizenz und ihre Bedingungen nicht für die betroffenen Teile, wenn Sie diese als eigenständige Datenwerke weitergeben. Wenn Sie jedoch dieselben Abschnitte als Teil eines Ganzen weitergeben, das ein auf dem Programm basierendes Datenwerk darstellt, dann muß die Weitergabe des Ganzen nach den Bedingungen dieser Lizenz erfolgen, deren Bedingungen für weitere Lizenznehmer somit auf das gesamte Ganze ausgedehnt werden - und somit auf jeden einzelnen Teil, unabhängig vom jeweiligen Autor. 
-
-Somit ist es nicht die Absicht dieses Abschnittes, Rechte für Datenwerke in Anspruch zu nehmen oder Ihnen die Rechte für Datenwerke streitig zu machen, die komplett von Ihnen geschrieben wurden; vielmehr ist es die Absicht, die Rechte zur Kontrolle der Verbreitung von Datenwerken, die auf dem Programm basieren oder unter seiner auszugsweisen Verwendung zusammengestellt worden sind, auszuüben. 
-
-Ferner bringt auch das einfache Zusammenlegen eines anderen Datenwerkes, das nicht auf dem Programm basiert, mit dem Programm oder einem auf dem Programm basierenden Datenwerk auf ein- und demselben Speicher- oder Vertriebsmedium dieses andere Datenwerk nicht in den Anwendungsbereich dieser Lizenz. 
-
-§3. Sie dürfen das Programm (oder ein darauf basierendes Datenwerk gemäß Paragraph 2) als Objectcode oder in ausführbarer Form unter den Bedingungen der Paragraphen 1 und 2 kopieren und weitergeben - vorausgesetzt, daß Sie außerdem eine der folgenden Leistungen erbringen: 
-
-
-1. 
-Liefern Sie das Programm zusammen mit dem vollständigen zugehörigen maschinenlesbaren Quelltext auf einem für den Datenaustausch üblichen Medium aus, wobei die Verteilung unter den Bedingungen der Paragraphen 1 und 2 erfolgen muß. Oder: 
-
-2. 
-Liefern Sie das Programm zusammen mit einem mindestens drei Jahre lang gültigen schriftlichen Angebot aus, jedem Dritten eine vollständige maschinenlesbare Kopie des Quelltextes zur Verfügung zu stellen - zu nicht höheren Kosten als denen, die durch den physikalischen Kopiervorgang anfallen -, wobei der Quelltext unter den Bedingungen der Paragraphen 1 und 2 auf einem für den Datenaustausch üblichen Medium weitergegeben wird. Oder: 
-
-3. 
-Liefern Sie das Programm zusammen mit dem schriftlichen Angebot der Zurverfügungstellung des Quelltextes aus, das Sie selbst erhalten haben. (Diese Alternative ist nur für nicht-kommerzielle Verbreitung zulässig und nur, wenn Sie das Programm als Objectcode oder in ausführbarer Form mit einem entsprechenden Angebot gemäß Absatz b erhalten haben.) 
-
-Unter dem Quelltext eines Datenwerkes wird diejenige Form des Datenwerkes verstanden, die für Bearbeitungen vorzugsweise verwendet wird. Für ein ausführbares Programm bedeutet ,,der komplette Quelltext``: Der Quelltext aller im Programm enthaltenen Module einschließlich aller zugehörigen Modulschnittstellen-Definitionsdateien sowie der zur Compilation und Installation verwendeten Skripte. Als besondere Ausnahme jedoch braucht der verteilte Quelltext nichts von dem zu enthalten, was üblicherweise (entweder als Quelltext oder in binärer Form) zusammen mit den Hauptkomponenten des Betriebssystems (Kernel, Compiler usw.) geliefert wird, unter dem das Programm läuft - es sei denn, diese Komponente selbst gehört zum ausführbaren Programm. 
-
-Wenn die Verbreitung eines ausführbaren Programms oder von Objectcode dadurch erfolgt, daß der Kopierzugriff auf eine dafür vorgesehene Stelle gewährt wird, so gilt die Gewährung eines gleichwertigen Zugriffs auf den Quelltext als Verbreitung des Quelltextes, auch wenn Dritte nicht dazu gezwungen sind, den Quelltext zusammen mit dem Objectcode zu kopieren. 
-
-§4. Sie dürfen das Programm nicht vervielfältigen, verändern, weiter lizenzieren oder verbreiten, sofern es nicht durch diese Lizenz ausdrücklich gestattet ist. Jeder anderweitige Versuch der Vervielfältigung, Modifizierung, Weiterlizenzierung und Verbreitung ist nichtig und beendet automatisch Ihre Rechte unter dieser Lizenz. Jedoch werden die Lizenzen Dritter, die von Ihnen Kopien oder Rechte unter dieser Lizenz erhalten haben, nicht beendet, solange diese die Lizenz voll anerkennen und befolgen. 
-
-§5. Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie sie nicht unterzeichnet haben. Jedoch gibt Ihnen nichts anderes die Erlaubnis, das Programm oder von ihm abgeleitete Datenwerke zu verändern oder zu verbreiten. Diese Handlungen sind gesetzlich verboten, wenn Sie diese Lizenz nicht anerkennen. Indem Sie das Programm (oder ein darauf basierendes Datenwerk) verändern oder verbreiten, erklären Sie Ihr Einverständnis mit dieser Lizenz und mit allen ihren Bedingungen bezüglich der Vervielfältigung, Verbreitung und Veränderung des Programms oder eines darauf basierenden Datenwerks. 
-
-§6. Jedesmal, wenn Sie das Programm (oder ein auf dem Programm basierendes Datenwerk) weitergeben, erhält der Empfänger automatisch vom ursprünglichen Lizenzgeber die Lizenz, das Programm entsprechend den hier festgelegten Bestimmungen zu vervielfältigen, zu verbreiten und zu verändern. Sie dürfen keine weiteren Einschränkungen der Durchsetzung der hierin zugestandenen Rechte des Empfängers vornehmen. Sie sind nicht dafür verantwortlich, die Einhaltung dieser Lizenz durch Dritte durchzusetzen. 
-
-§7. Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer Patentverletzung oder aus einem anderen Grunde (nicht auf Patentfragen begrenzt) Bedingungen (durch Gerichtsbeschluß, Vergleich oder anderweitig) auferlegt werden, die den Bedingungen dieser Lizenz widersprechen, so befreien Sie diese Umstände nicht von den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht möglich ist, das Programm unter gleichzeitiger Beachtung der Bedingungen in dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu verbreiten, dann dürfen Sie als Folge das Programm überhaupt nicht verbreiten. Wenn zum Beispiel ein Patent nicht die gebührenfreie Weiterverbreitung des Programms durch diejenigen erlaubt, die das Programm direkt oder indirekt von Ihnen erhalten haben, dann besteht der einzige Weg, sowohl das Patentrecht als auch diese Lizenz zu befolgen, darin, ganz auf die Verbreitung des Programms zu verzichten. 
-
-Sollte sich ein Teil dieses Paragraphen als ungültig oder unter bestimmten Umständen nicht durchsetzbar erweisen, so soll dieser Paragraph seinem Sinne nach angewandt werden; im übrigen soll dieser Paragraph als Ganzes gelten. 
-
-Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen, irgendwelche Patente oder andere Eigentumsansprüche zu verletzen oder die Gültigkeit solcher Ansprüche zu bestreiten; dieser Paragraph hat einzig den Zweck, die Integrität des Verbreitungssystems der freien Software zu schützen, das durch die Praxis öffentlicher Lizenzen verwirklicht wird. Viele Leute haben großzügige Beiträge zu dem großen Angebot der mit diesem System verbreiteten Software im Vertrauen auf die konsistente Anwendung dieses Systems geleistet; es liegt am Autor/Geber, zu entscheiden, ob er die Software mittels irgendeines anderen Systems verbreiten will; ein Lizenznehmer hat auf diese Entscheidung keinen Einfluß. 
-
-Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als Konsequenz aus dem Rest dieser Lizenz betrachtet wird. 
-
-§8. Wenn die Verbreitung und/oder die Benutzung des Programms in bestimmten Staaten entweder durch Patente oder durch urheberrechtlich geschützte Schnittstellen eingeschränkt ist, kann der Urheberrechtsinhaber, der das Programm unter diese Lizenz gestellt hat, eine explizite geographische Begrenzung der Verbreitung angeben, in der diese Staaten ausgeschlossen werden, so daß die Verbreitung nur innerhalb und zwischen den Staaten erlaubt ist, die nicht ausgeschlossen sind. In einem solchen Fall beinhaltet diese Lizenz die Beschränkung, als wäre sie in diesem Text niedergeschrieben. 
-
-§9. Die Free Software Foundation kann von Zeit zu Zeit überarbeitete und/oder neue Versionen der General Public License veröffentlichen. Solche neuen Versionen werden vom Grundprinzip her der gegenwärtigen entsprechen, können aber im Detail abweichen, um neuen Problemen und Anforderungen gerecht zu werden. 
-
-Jede Version dieser Lizenz hat eine eindeutige Versionsnummer. Wenn in einem Programm angegeben wird, daß es dieser Lizenz in einer bestimmten Versionsnummer oder ,,jeder späteren Version`` (``any later version'') unterliegt, so haben Sie die Wahl, entweder den Bestimmungen der genannten Version zu folgen oder denen jeder beliebigen späteren Version, die von der Free Software Foundation veröffentlicht wurde. Wenn das Programm keine Versionsnummer angibt, können Sie eine beliebige Version wählen, die je von der Free Software Foundation veröffentlicht wurde. 
-
-§10. Wenn Sie den Wunsch haben, Teile des Programms in anderen freien Programmen zu verwenden, deren Bedingungen für die Verbreitung anders sind, schreiben Sie an den Autor, um ihn um die Erlaubnis zu bitten. Für Software, die unter dem Copyright der Free Software Foundation steht, schreiben Sie an die Free Software Foundation ; wir machen zu diesem Zweck gelegentlich Ausnahmen. Unsere Entscheidung wird von den beiden Zielen geleitet werden, zum einen den freien Status aller von unserer freien Software abgeleiteten Datenwerke zu erhalten und zum anderen das gemeinschaftliche Nutzen und Wiederverwenden von Software im allgemeinen zu fördern. 
-
-
-Keine Gewährleistung 
-
-§11. Da das Programm ohne jegliche Kosten lizenziert wird, besteht keinerlei Gewährleistung für das Programm, soweit dies gesetzlich zulässig ist. Sofern nicht anderweitig schriftlich bestätigt, stellen die Copyright-Inhaber und/oder Dritte das Programm so zur Verfügung, ,,wie es ist``, ohne irgendeine Gewährleistung, weder ausdrücklich noch implizit, einschließlich - aber nicht begrenzt auf - Marktreife oder Verwendbarkeit für einen bestimmten Zweck. Das volle Risiko bezüglich Qualität und Leistungsfähigkeit des Programms liegt bei Ihnen. Sollte sich das Programm als fehlerhaft herausstellen, liegen die Kosten für notwendigen Service, Reparatur oder Korrektur bei Ihnen. 
-
-§12. In keinem Fall, außer wenn durch geltendes Recht gefordert oder schriftlich zugesichert, ist irgendein Copyright-Inhaber oder irgendein Dritter, der das Programm wie oben erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber für irgendwelche Schäden haftbar, einschließlich jeglicher allgemeiner oder spezieller Schäden, Schäden durch Seiteneffekte (Nebenwirkungen) oder Folgeschäden, die aus der Benutzung des Programms oder der Unbenutzbarkeit des Programms folgen (einschließlich - aber nicht beschränkt auf - Datenverluste, fehlerhafte Verarbeitung von Daten, Verluste, die von Ihnen oder anderen getragen werden müssen, oder dem Unvermögen des Programms, mit irgendeinem anderen Programm zusammenzuarbeiten), selbst wenn ein Copyright-Inhaber oder Dritter über die Möglichkeit solcher Schäden unterrichtet worden war. 
-
-
-Ende der Bedingungen 
diff --git a/msd/composer.json b/msd/composer.json
new file mode 100644
index 00000000..b894f827
--- /dev/null
+++ b/msd/composer.json
@@ -0,0 +1,14 @@
+{
+    "require": {
+		"php": "^7.4 || ^8.0",
+		"ext-ftp": "*",	
+		"ext-mysqli": "*",
+		"ext-openssl": "*",
+		"ext-curl": "*",
+		"ext-json": "*",
+		"ext-zip": "*",
+		"ext-zlib": "*",		
+        "league/flysystem-sftp": "^2.0",
+		"visualappeal/php-auto-update": "^1.0.2"
+    }
+}
diff --git a/msd/composer.lock b/msd/composer.lock
new file mode 100644
index 00000000..5df68cc0
--- /dev/null
+++ b/msd/composer.lock
@@ -0,0 +1,755 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "531d14fef9748689e0b5fca816d3f8f1",
+    "packages": [
+        {
+            "name": "composer/semver",
+            "version": "3.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/semver.git",
+                "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
+                "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^1.4",
+                "symfony/phpunit-bridge": "^4.2 || ^5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Semver\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "Semver library that offers utilities, version constraint parsing and validation.",
+            "keywords": [
+                "semantic",
+                "semver",
+                "validation",
+                "versioning"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/semver/issues",
+                "source": "https://github.com/composer/semver/tree/3.3.2"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-04-01T19:23:25+00:00"
+        },
+        {
+            "name": "desarrolla2/cache",
+            "version": "v3.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/desarrolla2/Cache.git",
+                "reference": "0b8f985d09abfc04a2c1535943f6f07b7206161a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/desarrolla2/Cache/zipball/0b8f985d09abfc04a2c1535943f6f07b7206161a",
+                "reference": "0b8f985d09abfc04a2c1535943f6f07b7206161a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.0",
+                "psr/simple-cache": "^1.0"
+            },
+            "provide": {
+                "psr/simple-cache-implementation": "1.0"
+            },
+            "require-dev": {
+                "cache/integration-tests": "dev-master",
+                "ext-apcu": "*",
+                "ext-json": "*",
+                "ext-memcached": "*",
+                "ext-mysqli": "*",
+                "mikey179/vfsstream": "v1.6.8",
+                "mongodb/mongodb": "^1.3",
+                "phpstan/phpstan": "^0.12.29",
+                "phpunit/phpunit": "^8.3 || ^9.0",
+                "predis/predis": "~1.0.0",
+                "symfony/phpunit-bridge": "^5.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Desarrolla2\\Cache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Daniel González",
+                    "homepage": "http://desarrolla2.com/"
+                },
+                {
+                    "name": "Arnold Daniels",
+                    "homepage": "https://jasny.net/"
+                }
+            ],
+            "description": "Provides an cache interface for several adapters Apc, Apcu, File, Mongo, Memcache, Memcached, Mysql, Mongo, Redis is supported.",
+            "homepage": "https://github.com/desarrolla2/Cache/",
+            "keywords": [
+                "apc",
+                "apcu",
+                "cache",
+                "file",
+                "memcache",
+                "memcached",
+                "mongo",
+                "mysql",
+                "psr-16",
+                "redis",
+                "simple-cache"
+            ],
+            "support": {
+                "issues": "https://github.com/desarrolla2/Cache/issues",
+                "source": "https://github.com/desarrolla2/Cache/tree/v3.0.2"
+            },
+            "time": "2022-03-27T23:04:06+00:00"
+        },
+        {
+            "name": "league/flysystem",
+            "version": "2.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem.git",
+                "reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8aaffb653c5777781b0f7f69a5d937baf7ab6cdb",
+                "reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "league/mime-type-detection": "^1.0.0",
+                "php": "^7.2 || ^8.0"
+            },
+            "conflict": {
+                "guzzlehttp/ringphp": "<1.1.1"
+            },
+            "require-dev": {
+                "async-aws/s3": "^1.5",
+                "async-aws/simple-s3": "^1.0",
+                "aws/aws-sdk-php": "^3.132.4",
+                "composer/semver": "^3.0",
+                "ext-fileinfo": "*",
+                "ext-ftp": "*",
+                "friendsofphp/php-cs-fixer": "^3.2",
+                "google/cloud-storage": "^1.23",
+                "phpseclib/phpseclib": "^2.0",
+                "phpstan/phpstan": "^0.12.26",
+                "phpunit/phpunit": "^8.5 || ^9.4",
+                "sabre/dav": "^4.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "League\\Flysystem\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
+                }
+            ],
+            "description": "File storage abstraction for PHP",
+            "keywords": [
+                "WebDAV",
+                "aws",
+                "cloud",
+                "file",
+                "files",
+                "filesystem",
+                "filesystems",
+                "ftp",
+                "s3",
+                "sftp",
+                "storage"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/flysystem/issues",
+                "source": "https://github.com/thephpleague/flysystem/tree/2.5.0"
+            },
+            "funding": [
+                {
+                    "url": "https://ecologi.com/frankdejonge",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/frankdejonge",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-09-17T21:02:32+00:00"
+        },
+        {
+            "name": "league/flysystem-sftp",
+            "version": "2.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem-sftp.git",
+                "reference": "e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7",
+                "reference": "e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7",
+                "shasum": ""
+            },
+            "require": {
+                "league/flysystem": "^2.0.0",
+                "league/mime-type-detection": "^1.0.0",
+                "php": "^7.2 || ^8.0",
+                "phpseclib/phpseclib": "^2.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "League\\Flysystem\\PhpseclibV2\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
+                }
+            ],
+            "description": "SFTP filesystem adapter for Flysystem.",
+            "keywords": [
+                "Flysystem",
+                "file",
+                "files",
+                "filesystem",
+                "sftp"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/flysystem-sftp/issues",
+                "source": "https://github.com/thephpleague/flysystem-sftp/tree/2.5.0"
+            },
+            "funding": [
+                {
+                    "url": "https://ecologi.com/frankdejonge",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/frankdejonge",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+                    "type": "tidelift"
+                }
+            ],
+            "abandoned": "league/flysystem-sftp-v3",
+            "time": "2022-04-27T17:27:27+00:00"
+        },
+        {
+            "name": "league/mime-type-detection",
+            "version": "1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/mime-type-detection.git",
+                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+                "shasum": ""
+            },
+            "require": {
+                "ext-fileinfo": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^3.2",
+                "phpstan/phpstan": "^0.12.68",
+                "phpunit/phpunit": "^8.5.8 || ^9.3"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "League\\MimeTypeDetection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
+                }
+            ],
+            "description": "Mime-type detection for Flysystem",
+            "support": {
+                "issues": "https://github.com/thephpleague/mime-type-detection/issues",
+                "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/frankdejonge",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-04-17T13:12:02+00:00"
+        },
+        {
+            "name": "monolog/monolog",
+            "version": "2.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/monolog.git",
+                "reference": "720488632c590286b88b80e62aa3d3d551ad4a50"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50",
+                "reference": "720488632c590286b88b80e62aa3d3d551ad4a50",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2",
+                "psr/log": "^1.0.1 || ^2.0 || ^3.0"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
+            },
+            "require-dev": {
+                "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+                "doctrine/couchdb": "~1.0@dev",
+                "elasticsearch/elasticsearch": "^7 || ^8",
+                "ext-json": "*",
+                "graylog2/gelf-php": "^1.4.2",
+                "guzzlehttp/guzzle": "^7.4",
+                "guzzlehttp/psr7": "^2.2",
+                "mongodb/mongodb": "^1.8",
+                "php-amqplib/php-amqplib": "~2.4 || ^3",
+                "phpspec/prophecy": "^1.15",
+                "phpstan/phpstan": "^0.12.91",
+                "phpunit/phpunit": "^8.5.14",
+                "predis/predis": "^1.1 || ^2.0",
+                "rollbar/rollbar": "^1.3 || ^2 || ^3",
+                "ruflin/elastica": "^7",
+                "swiftmailer/swiftmailer": "^5.3|^6.0",
+                "symfony/mailer": "^5.4 || ^6",
+                "symfony/mime": "^5.4 || ^6"
+            },
+            "suggest": {
+                "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+                "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+                "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+                "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+                "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+                "ext-mbstring": "Allow to work properly with unicode symbols",
+                "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+                "ext-openssl": "Required to send log messages using SSL",
+                "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+                "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+                "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+                "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+                "rollbar/rollbar": "Allow sending log messages to Rollbar",
+                "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Monolog\\": "src/Monolog"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "https://seld.be"
+                }
+            ],
+            "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+            "homepage": "https://github.com/Seldaek/monolog",
+            "keywords": [
+                "log",
+                "logging",
+                "psr-3"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/monolog/issues",
+                "source": "https://github.com/Seldaek/monolog/tree/2.8.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Seldaek",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-07-24T11:55:47+00:00"
+        },
+        {
+            "name": "phpseclib/phpseclib",
+            "version": "2.0.41",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpseclib/phpseclib.git",
+                "reference": "7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b",
+                "reference": "7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phing/phing": "~2.7",
+                "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
+                "squizlabs/php_codesniffer": "~2.0"
+            },
+            "suggest": {
+                "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+                "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+                "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+                "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
+                "ext-xml": "Install the XML extension to load XML formatted public keys."
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "phpseclib/bootstrap.php"
+                ],
+                "psr-4": {
+                    "phpseclib\\": "phpseclib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jim Wigginton",
+                    "email": "terrafrost@php.net",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Patrick Monnerat",
+                    "email": "pm@datasphere.ch",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Andreas Fischer",
+                    "email": "bantu@phpbb.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Hans-Jürgen Petrich",
+                    "email": "petrich@tronic-media.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+            "homepage": "http://phpseclib.sourceforge.net",
+            "keywords": [
+                "BigInteger",
+                "aes",
+                "asn.1",
+                "asn1",
+                "blowfish",
+                "crypto",
+                "cryptography",
+                "encryption",
+                "rsa",
+                "security",
+                "sftp",
+                "signature",
+                "signing",
+                "ssh",
+                "twofish",
+                "x.509",
+                "x509"
+            ],
+            "support": {
+                "issues": "https://github.com/phpseclib/phpseclib/issues",
+                "source": "https://github.com/phpseclib/phpseclib/tree/2.0.41"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/terrafrost",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/phpseclib",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-12-23T16:44:18+00:00"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/log/tree/1.1.4"
+            },
+            "time": "2021-05-03T11:20:27+00:00"
+        },
+        {
+            "name": "psr/simple-cache",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/simple-cache.git",
+                "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+                "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\SimpleCache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interfaces for simple caching",
+            "keywords": [
+                "cache",
+                "caching",
+                "psr",
+                "psr-16",
+                "simple-cache"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/simple-cache/tree/master"
+            },
+            "time": "2017-10-23T01:57:42+00:00"
+        },
+        {
+            "name": "visualappeal/php-auto-update",
+            "version": "1.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/VisualAppeal/PHP-Auto-Update.git",
+                "reference": "4454361a0fa346c7fb179deef11585c79715b645"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/VisualAppeal/PHP-Auto-Update/zipball/4454361a0fa346c7fb179deef11585c79715b645",
+                "reference": "4454361a0fa346c7fb179deef11585c79715b645",
+                "shasum": ""
+            },
+            "require": {
+                "composer/semver": "^3.0",
+                "desarrolla2/cache": "^3.0",
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-zip": "*",
+                "monolog/monolog": "^2.1",
+                "php": ">=7.2.0",
+                "psr/log": "1.1.4"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5",
+                "roave/security-advisories": "dev-master"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "VisualAppeal\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Tim Helfensdörfer",
+                    "email": "tim@visualappeal.de"
+                }
+            ],
+            "description": "Autoupdater for PHP",
+            "support": {
+                "issues": "https://github.com/VisualAppeal/PHP-Auto-Update/issues",
+                "source": "https://github.com/VisualAppeal/PHP-Auto-Update/tree/1.0.2"
+            },
+            "time": "2021-11-27T22:39:05+00:00"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": {
+        "php": "^7.4 || ^8.0",
+        "ext-ftp": "*",
+        "ext-mysqli": "*",
+        "ext-openssl": "*",
+        "ext-curl": "*",
+        "ext-json": "*",
+        "ext-zip": "*",
+        "ext-zlib": "*"
+    },
+    "platform-dev": [],
+    "plugin-api-version": "2.3.0"
+}
diff --git a/msd/config.php b/msd/config.php
index 866bae6f..465dd9bd 100644
--- a/msd/config.php
+++ b/msd/config.php
@@ -1,22 +1,6 @@
 <?php
-/* ----------------------------------------------------------------------
 
-   MyOOS [Dumper]
-   http://www.oos-shop.de/
-
-   Copyright (c) 2016 by the MyOOS Development Team.
-   ----------------------------------------------------------------------
-   Based on:
-
-   MySqlDumper
-   http://www.mysqldumper.de
-
-   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
-   ----------------------------------------------------------------------
-   Released under the GNU General Public License
-   ---------------------------------------------------------------------- */
-
-// MySQL Dumper Configuration
+// MyOOS [Dumper] Configuration
 
 // Host-Adress, default 'localhost'
 $config['dbhost'] = 'localhost';
@@ -32,112 +16,148 @@ $config['dbpass'] = '!S1ge1nA';
 
 //Speed Values between 50 and 1000000
 //use low values if you have bad connection or slow machines
-$config['minspeed']=100;
-$config['maxspeed']=50000;
+$config['minspeed'] = 100;
+$config['maxspeed'] = 50000;
 
 // Interface language and style
-$config['language']='en';
-$config['theme']='msd';
+$config['language'] = 'en';
+$config['theme'] = 'mod';
 
 //Shows the Serveradress if 1
-$config['interface_server_caption']=1;
-$config['interface_server_captioncolor']='#ff9966';
+$config['interface_server_caption'] = 1;
+$config['interface_server_captioncolor'] = '#ff9966';
 //Position of the Serveradress 0=left, 1=right
-$config['interface_server_caption_position']=0;
+$config['interface_server_caption_position'] = 0;
 
 //Height of the SQL-Box in Mini-SQL in pixel
-$config['interface_sqlboxsize']=70;
-$config['interface_table_compact']=0;
+$config['interface_sqlboxsize'] = 70;
+$config['interface_table_compact'] = 0;
 
 // Determine the maximum Amount for Memory Use in Bytes, 0 for no limit
-$config['memory_limit']=100000;
+$config['memory_limit'] = 100000;
 
 // For gz-Compression set to 1, without compression set to 0
-$config['compression']=1;
+$config['compression'] = 1;
 
 //Refreshtime for MySQL processlist in msec, use any value >1000
-$config['processlist_refresh']=3000;
+$config['processlist_refresh'] = 3000;
 
-$config['empty_db_before_restore']=0;
-$config['optimize_tables_beforedump']=0;
-$config['stop_with_error']=1;
+$config['empty_db_before_restore'] = 0;
+$config['optimize_tables_beforedump'] = 0;
+$config['use_binary_container'] = 0;
+$config['stop_with_error'] = 1;
+$config['ignore_enable_keys'] = 0;
 
 // For sending a mail after backup set send_mail to 1, otherless set to 0
-$config['send_mail']=0;
+$config['send_mail'] = 0;
 // Attach the backup 0=no  1=yes
-$config['send_mail_dump']=0;
+$config['send_mail_dump'] = 0;
 // set the recieve adress for the mail
-$config['email_recipient']='';
-$config['email_recipient_cc']='';
+$config['email_recipient'] = '';
+$config['email_recipient_cc'] = '';
 // set the sender adress (the script)
-$config['email_sender']='';
+$config['email_sender'] = '';
 
 //max. Size of Email-Attach, here 3 MB
-$config['email_maxsize1']=3;
-$config['email_maxsize2']=2;
+$config['email_maxsize1'] = 3;
+$config['email_maxsize2'] = 2;
 
 // FTP Server Configuration for Transfer
-$config['ftp_transfer'][0]=0;
-$config['ftp_timeout'][0]=30;
-$config['ftp_useSSL'][0]=0;
-$config['ftp_mode'][0]=0;
-$config['ftp_server'][0]=''; // Adress of FTP-Server
-$config['ftp_port'][0]='21'; // Port
-$config['ftp_user'][0]=''; // Username
-$config['ftp_pass'][0]=''; // Password
-$config['ftp_dir'][0]=''; // Upload-Directory
+$config['ftp_transfer'][0] = 0;
+$config['ftp_timeout'][0] = 30;
+$config['ftp_useSSL'][0] = 0;
+$config['ftp_mode'][0] = 0;
+$config['ftp_server'][0] = ''; // Adress of FTP-Server
+$config['ftp_port'][0] = '21'; // Port
+$config['ftp_user'][0] = ''; // Username
+$config['ftp_pass'][0] = ''; // Password
+$config['ftp_dir'][0] = ''; // Upload-Directory
 
-$config['ftp_transfer'][1]=0;
-$config['ftp_timeout'][1]=30;
-$config['ftp_useSSL'][1]=0;
-$config['ftp_mode'][1]=0;
-$config['ftp_server'][1]='';
-$config['ftp_port'][1]='21';
-$config['ftp_user'][1]='';
-$config['ftp_pass'][1]='';
-$config['ftp_dir'][1]='';
+$config['ftp_transfer'][1] = 0;
+$config['ftp_timeout'][1] = 30;
+$config['ftp_useSSL'][1] = 0;
+$config['ftp_mode'][1] = 0;
+$config['ftp_server'][1] = '';
+$config['ftp_port'][1] = '21';
+$config['ftp_user'][1] = '';
+$config['ftp_pass'][1] = '';
+$config['ftp_dir'][1] = '';
 
-$config['ftp_transfer'][2]=0;
-$config['ftp_timeout'][2]=30;
-$config['ftp_useSSL'][2]=0;
-$config['ftp_mode'][2]=0;
-$config['ftp_server'][2]='';
-$config['ftp_port'][2]='21';
-$config['ftp_user'][2]='';
-$config['ftp_pass'][2]='';
-$config['ftp_dir'][2]='';
+$config['ftp_transfer'][2] = 0;
+$config['ftp_timeout'][2] = 30;
+$config['ftp_useSSL'][2] = 0;
+$config['ftp_mode'][2] = 0;
+$config['ftp_server'][2] = '';
+$config['ftp_port'][2] = '21';
+$config['ftp_user'][2] = '';
+$config['ftp_pass'][2] = '';
+$config['ftp_dir'][2] = '';
+
+// SFTP Server Configuration for Transfer
+$config['sftp_transfer'][0] = 0;
+$config['sftp_timeout'][0] = 30;
+$config['sftp_server'][0] = ''; // Adress of SFTP-Server
+$config['sftp_port'][0] = '22'; // Port
+$config['sftp_user'][0] = ''; // Username
+$config['sftp_pass'][0] = ''; // Password
+$config['sftp_dir'][0] = ''; // Upload-Directory
+$config['sftp_path_to_private_key'][0] = null; // private key (optional, default: null) can be used instead of password, set to null if password is set
+$config['sftp_secret_passphrase_for_private_key'][0] = null;  // passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
+$config['sftp_fingerprint'][0] = null; // host fingerprint (optional, default: null),
+
+$config['sftp_transfer'][1] = 0;
+$config['sftp_timeout'][1] = 30;
+$config['sftp_server'][1] = '';
+$config['sftp_port'][1] = '22';
+$config['sftp_user'][1] = '';
+$config['sftp_pass'][1] = '';
+$config['sftp_dir'][1] = '';
+$config['sftp_path_to_private_key'][1] = null;
+$config['sftp_secret_passphrase_for_private_key'][1] = null;
+$config['sftp_fingerprint'][1] = null;
+
+$config['sftp_transfer'][2] = 0;
+$config['sftp_timeout'][2] = 30;
+$config['sftp_server'][2] = '';
+$config['sftp_port'][2] = '22';
+$config['sftp_user'][2] = '';
+$config['sftp_pass'][2] = '';
+$config['sftp_dir'][2] = '';
+$config['sftp_path_to_private_key'][2] = null;
+$config['sftp_secret_passphrase_for_private_key'][2] = null;
+$config['sftp_fingerprint'][2] = null;
 
 //Multipart 0=off 1=on
-$config['multi_part']=0;
-$config['multipartgroesse1']=1;
-$config['multipartgroesse2']=2;
-$config['multipart_groesse']=0;
+$config['multi_part'] = 0;
+$config['multipartgroesse1'] = 1;
+$config['multipartgroesse2'] = 2;
+$config['multipart_groesse'] = 0;
 
 //Auto-Delete 0=off 1=on
-$config['auto_delete']=0;
-$config['max_backup_files']=3;
+$config['auto_delete'] = 0;
+$config['max_backup_files'] = 3;
 
 //configuration file
-$config['cron_configurationfile']='myoosdumper.conf.php';
+$config['cron_configurationfile'] = 'myoosdumper.conf.php';
 //path to perl, for windows use e.g. C:perlbinperl.exe
-$config['cron_perlpath']='/usr/bin/perl';
+$config['cron_perlpath'] = '/usr/bin/perl';
 //mailer use sendmail(1) or SMTP(0)
-$config['cron_use_sendmail']=1;
+$config['cron_use_sendmail'] = 1;
 //path to sendmail
-$sendmail_path=ini_get('sendmail_path');
-$config['cron_sendmail']=$sendmail_path>'' ? $sendmail_path: '/usr/lib/sendmail -t -oi -oem';
+$sendmail_path = ini_get('sendmail_path');
+$config['cron_sendmail'] = $sendmail_path > '' ? $sendmail_path : '/usr/lib/sendmail -t -oi -oem';
 
 //adress of smtp-server
-$config['cron_smtp']='localhost';
+$config['cron_smtp'] = 'localhost';
 //smtp-port
-$config['cron_smtp_port']=25;
-$config['cron_extender']=0;
-$config['cron_compression']=1;
-$config['cron_printout']=1;
-$config['cron_completelog']=1;
-$config['cron_comment']='';
-$config['multi_dump']=0;
-$config['logcompression']=1;
-$config['log_maxsize1']=1;
-$config['log_maxsize2']=2;
-$config['log_maxsize']=1048576;
+$config['cron_smtp_port'] = 25;
+$config['cron_extender'] = 0;
+$config['cron_compression'] = 1;
+$config['cron_printout'] = 1;
+$config['cron_completelog'] = 1;
+$config['cron_comment'] = '';
+$config['multi_dump'] = 0;
+$config['logcompression'] = 1;
+$config['log_maxsize1'] = 1;
+$config['log_maxsize2'] = 2;
+$config['log_maxsize'] = 1048576;
diff --git a/msd/config_overview.php b/msd/config_overview.php
index b53fc862..84b1efca 100644
--- a/msd/config_overview.php
+++ b/msd/config_overview.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,988 +18,1232 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
 function print_save_button()
 {
-	global $lang;
-	$t='<span style="float:right;padding-right:6px;"><input class="Formbutton" type="submit" name="save" value="' . $lang['L_SAVE'] . '"></span>';
-	return $t;
+    global $lang;
+    $t = '<span style="float:right;padding-right:6px;"><input class="Formbutton" type="submit" name="save" value="'.$lang['L_SAVE'].'"></span>';
+
+    return $t;
 }
 
-// wenn neue Sprache angewählt wurde schon vor dem includen übernehmen
-if (isset($_POST['save']) && $_POST['language'] != $_POST['lang_old'])
-{
-	$config['language']=$_POST['language'];
-	$temp_lang=$config['language'];
-	include_once ( './inc/header.php' ); // Normal prodecure (resets config[language])
-	$config['language']=$temp_lang; // re-set language
-	include ( './language/lang_list.php' ); // This re-initializes $lang[] and loads appropiate language files
+// if new language was selected already before include
+if (isset($_POST['save']) && $_POST['language'] != $_POST['lang_old']) {
+    $config['language'] = $_POST['language'];
+    $temp_lang = $config['language'];
+    include_once './inc/header.php'; // Normal prodecure (resets config[language])
+    $config['language'] = $temp_lang; // re-set language
+    include './language/lang_list.php'; // This re-initializes $lang[] and loads appropiate language files
+} else {
+    include_once './inc/header.php'; // language not changed, go on as usual
 }
-else
-	include_once ( './inc/header.php' ); // language not changed, go on as usual
-include_once ( './inc/runtime.php' );
-include_once ( './inc/functions_sql.php' );
-include_once ( './language/' . $config['language'] . '/lang_help.php' );
-include_once ( './language/' . $config['language'] . '/lang_config_overview.php' );
-include_once ( './language/' . $config['language'] . '/lang_sql.php' );
+include_once './inc/runtime.php';
+include_once './inc/functions_sql.php';
+include_once './language/'.$config['language'].'/lang_help.php';
+include_once './language/'.$config['language'].'/lang_config_overview.php';
+include_once './language/'.$config['language'].'/lang_sql.php';
 
-$msg='';
-$sel=( isset($_POST['sel']) ) ? $_POST['sel'] : 'db';
-if (isset($_GET['sel'])) $sel=$_GET['sel'];
+$msg = '';
+$sel = (isset($_POST['sel'])) ? $_POST['sel'] : 'db';
 
-$old_config_file=$config['config_file'];
-if (isset($_GET['config']))
-{
-	unset($databases);
-	$databases=array();
-	if (isset($_POST['save'])) unset($_POST['save']);
-	if (read_config($_GET['config']))
-	{
-		$config['config_file']=$_GET['config'];
-		$_SESSION['config_file']=$config['config_file'];
-		$msg="<strong>" . sprintf($lang['L_CONFIG_LOADED'],$config['config_file']) . "</strong>";
-		$msg.='<script type="text/javascript" language="javascript">parent.MyOOS_Dumper_menu.location.href="menu.php?config=' . $config['config_file'] . '";</script>';
-	}
-	else
-	{
-		read_config($old_config_file);
-		$msg='<p class="error">' . sprintf($lang['L_ERROR_LOADING_CONFIGFILE'],$config['config_file']) . '</p>';
-	}
+if (isset($_GET['sel'])) {
+    $sel = $_GET['sel'];
 }
 
-if (isset($_GET['config_delete']))
-{
-	$del_config=urldecode($_GET['config_delete']);
-	if ($del_config == $config['config_file'])
-	{
-		//aktuell gewaehlte Konfiguration wurde geloescht
-		$config['config_file']='myoosdumper';
-		$_SESSION['config_file']=$config['config_file'];
-		read_config($config['config_file']); // Standard laden
-	}
-
-	$del=@unlink($config['paths']['config'] . $del_config . '.php');
-	if ($del) $del=@unlink($config['paths']['config'] . $del_config . '.conf.php');
-	if ($del === false) $msg='<p class="error">' . sprintf($lang['L_ERROR_DELETING_CONFIGFILE'],$del_config) . '</p>';
-	else $msg='<p class="success">' . sprintf($lang['L_SUCCESS_DELETING_CONFIGFILE'],$del_config) . '</p>' . '<script type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php?config=' . $config['config_file'] . '";</script>'; //refresh menu-frame
-	$sel='configs';
+$old_config_file = $config['config_file'];
+if (isset($_GET['config'])) {
+    unset($databases);
+    $databases = [];
+    if (isset($_POST['save'])) {
+        unset($_POST['save']);
+    }
+    if (read_config($_GET['config'])) {
+        $config['config_file'] = $_GET['config'];
+        $_SESSION['config_file'] = $config['config_file'];
+        $msg = '<strong>'.sprintf($lang['L_CONFIG_LOADED'], $config['config_file']).'</strong>';
+        $msg .= '<script>parent.MyOOS_Dumper_menu.location.href="menu.php?config='.$config['config_file'].'";</script>';
+    } else {
+        read_config($old_config_file);
+        $msg = '<p class="error">'.sprintf($lang['L_ERROR_LOADING_CONFIGFILE'], $config['config_file']).'</p>';
+    }
 }
 
-include_once ( './inc/define_icons.php' );
+if (isset($_GET['config_delete'])) {
+    $del_config = urldecode($_GET['config_delete']);
+    if ($del_config == $config['config_file']) {
+        // currently selected configuration was deleted
+        $config['config_file'] = 'myoosdumper';
+        $_SESSION['config_file'] = $config['config_file'];
+        read_config($config['config_file']); // Load standard
+    }
 
-$config['files']['parameter']=$config['paths']['config'] . $config['config_file'] . '.php';
-$config['theme']=( !isset($config['theme']) ) ? 'msd' : $config['theme'];
-$config['cron_smtp_port']=( !isset($config['cron_smtp_port']) ) ? 25 : $config['cron_smtp_port'];
-
-if (!isset($command)) $command=0;
-
-$checkFTP=Array(
-
-				"&nbsp;<br><br>&nbsp;<br>&nbsp;",
-				"&nbsp;<br><br>&nbsp;<br>&nbsp;",
-				"&nbsp;<br><br>&nbsp;<br>&nbsp;"
-);
-$checkFTP[$i]="";
-$ftptested=-1;
-if (( isset($_POST['testFTP0']) ) || ( isset($_POST['testFTP1']) ) || ( isset($_POST['testFTP2']) ))
-{
-	$config['ftp_transfer']=array();
-	$config['ftp_timeout']=array();
-	$config['ftp_mode']=array();
-	$config['ftp_useSSL']=array();
-
-	for ($i=0; $i < 3; $i++)
-	{
-		$config['ftp_transfer'][$i]=( isset($_POST['ftp_transfer'][$i]) ) ? $_POST['ftp_transfer'][$i] : 0;
-		$config['ftp_timeout'][$i]=( isset($_POST['ftp_timeout'][$i]) ) ? $_POST['ftp_timeout'][$i] : 30;
-		$config['ftp_useSSL'][$i]=( isset($_POST['ftp_useSSL'][$i]) ) ? $_POST['ftp_useSSL'][$i] : 0;
-		$config['ftp_mode'][$i]=( isset($_POST['ftp_mode'][$i]) ) ? 1 : 0;
-		$config['ftp_server'][$i]=( isset($_POST['ftp_server'][$i]) ) ? $_POST['ftp_server'][$i] : '';
-		$config['ftp_port'][$i]=( isset($_POST['ftp_port'][$i]) ) ? $_POST['ftp_port'][$i] : 21;
-		$config['ftp_user'][$i]=( isset($_POST['ftp_user'][$i]) ) ? $_POST['ftp_user'][$i] : '';
-		$config['ftp_pass'][$i]=( isset($_POST['ftp_pass'][$i]) ) ? $_POST['ftp_pass'][$i] : '';
-		$config['ftp_dir'][$i]=( isset($_POST['ftp_dir'][$i]) ) ? stripslashes($_POST['ftp_dir'][$i]) : '/';
-		if ($config['ftp_dir'][$i] == "" || ( strlen($config['ftp_dir'][$i]) > 1 && substr($config['ftp_dir'][$i],-1) != "/" )) $config['ftp_dir'][$i].="/";
-		if (isset($_POST['testFTP' . $i]))
-		{
-			$checkFTP[$i]='<div class="ssmall">' . $lang['L_TESTCONNECTION'] . ' FTP-Connection ' . ( $i + 1 ) . '<br><br>' . TesteFTP($i) . '</div>';
-			$ftptested=$i;
-		}
-	}
+    $del = @unlink($config['paths']['config'].$del_config.'.php');
+    if ($del) {
+        $del = @unlink($config['paths']['config'].$del_config.'.conf.php');
+    }
+    if (false === $del) {
+        $msg = '<p class="error">'.sprintf($lang['L_ERROR_DELETING_CONFIGFILE'], $del_config).'</p>';
+    } else {
+        $msg = '<p class="success">'.sprintf($lang['L_SUCCESS_DELETING_CONFIGFILE'], $del_config).'</p>'.'<script>parent.MyOOS_Dumper_menu.location.href="menu.php?config='.$config['config_file'].'";</script>'; //refresh menu-frame
+    }
+    $sel = 'configs';
 }
 
-$showVP=false;
-$oldtheme=$config['theme'];
-$oldscposition=$config['interface_server_caption_position'];
+include_once './inc/define_icons.php';
 
-if ($ftptested > -1)
-{
-	$ftp_server[$ftptested]=$_POST['ftp_server'][$ftptested];
-	$ftp_port[$ftptested]=$_POST['ftp_port'][$ftptested];
-	$ftp_user[$ftptested]=$_POST['ftp_user'][$ftptested];
-	$ftp_pass[$ftptested]=$_POST['ftp_pass'][$ftptested];
-	$ftp_dir_s='ftp_dir[' . $ftptested . ']';
-	$f=$_POST['ftp_dir'];
-	$ftp_dir[$ftptested]=stripslashes($f[$ftptested]);
-	// Eingaben merken
-	$config['ftp_transfer'][$ftptested]=( isset($_POST['ftp_transfer'][$ftptested]) ) ? $_POST['ftp_transfer'][$ftptested] : 0;
-	$config['ftp_timeout'][$ftptested]=( isset($_POST['ftp_timeout'][$ftptested]) ) ? $_POST['ftp_timeout'][$ftptested] : 30;
-	$config['ftp_useSSL'][$ftptested]=( isset($_POST['ftp_useSSL'][$ftptested]) ) ? $_POST['ftp_useSSL'][$ftptested] : 0;
-	$config['ftp_mode'][$ftptested]=( isset($_POST['ftp_mode'][$ftptested]) ) ? 1 : 0;
-	$config['ftp_server'][$ftptested]=$ftp_server[$ftptested];
-	$config['ftp_port'][$ftptested]=$ftp_port[$ftptested];
-	$config['ftp_user'][$ftptested]=$ftp_user[$ftptested];
-	$config['ftp_pass'][$ftptested]=$ftp_pass[$ftptested];
-	$config['ftp_dir'][$ftptested]=$ftp_dir[$ftptested];
+$config['files']['parameter'] = $config['paths']['config'].$config['config_file'].'.php';
+$config['theme'] = (!isset($config['theme'])) ? 'mod' : $config['theme'];
+$config['cron_smtp_port'] = (!isset($config['cron_smtp_port'])) ? 25 : $config['cron_smtp_port'];
 
-	if ($ftp_dir[$ftptested] == "" || ( strlen($ftp_dir[$ftptested]) > 1 && substr($ftp_dir[$ftptested],-1) != "/" )) $ftp_dir[$ftptested].="/";
-	WriteParams();
+if (!isset($command)) {
+    $command = 0;
 }
 
-echo MSDHeader();
+$checkFTP = [
+                '&nbsp;<br><br>&nbsp;<br>&nbsp;',
+                '&nbsp;<br><br>&nbsp;<br>&nbsp;',
+                '&nbsp;<br><br>&nbsp;<br>&nbsp;',
+];
+$checkFTP[$i] = '';
+$ftptested = -1;
 
-if (isset($_POST['load']))
-{
-	$msg=SetDefault(true);
-	$msg=nl2br($msg) . "<br>" . $lang['L_LOAD_SUCCESS'] . "<br>";
-	echo '<script type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php";</script>';
+if ((isset($_POST['testFTP0'])) || (isset($_POST['testFTP1'])) || (isset($_POST['testFTP2']))) {
+    $config['ftp_transfer'] = [];
+    $config['ftp_timeout'] = [];
+    $config['ftp_mode'] = [];
+    $config['ftp_useSSL'] = [];
+
+    for ($i = 0; $i < 3; ++$i) {
+        $config['ftp_transfer'][$i] = (isset($_POST['ftp_transfer'][$i])) ? $_POST['ftp_transfer'][$i] : 0;
+        $config['ftp_timeout'][$i] = (isset($_POST['ftp_timeout'][$i])) ? $_POST['ftp_timeout'][$i] : 30;
+        $config['ftp_useSSL'][$i] = (isset($_POST['ftp_useSSL'][$i])) ? $_POST['ftp_useSSL'][$i] : 0;
+        $config['ftp_mode'][$i] = (isset($_POST['ftp_mode'][$i])) ? 1 : 0;
+        $config['ftp_server'][$i] = (isset($_POST['ftp_server'][$i])) ? $_POST['ftp_server'][$i] : '';
+        $config['ftp_port'][$i] = (isset($_POST['ftp_port'][$i])) ? $_POST['ftp_port'][$i] : 21;
+        $config['ftp_user'][$i] = (isset($_POST['ftp_user'][$i])) ? $_POST['ftp_user'][$i] : '';
+        $config['ftp_pass'][$i] = (isset($_POST['ftp_pass'][$i])) ? $_POST['ftp_pass'][$i] : '';
+        $config['ftp_dir'][$i] = (isset($_POST['ftp_dir'][$i])) ? stripslashes($_POST['ftp_dir'][$i]) : '/';
+        if ('' == $config['ftp_dir'][$i] || (strlen($config['ftp_dir'][$i]) > 1 && '/' != substr($config['ftp_dir'][$i], -1))) {
+            $config['ftp_dir'][$i] .= '/';
+        }
+        if (isset($_POST['testFTP'.$i])) {
+            $checkFTP[$i] = '<div class="ssmall">'.$lang['L_TESTCONNECTION'].' FTP-Connection '.($i + 1).'<br><br>'.TesteFTP($i).'</div>';
+            $ftptested = $i;
+        }
+    }
 }
 
-if (isset($_POST['save']))
-{
-	$save_config=true;
-	//Parameter auslesen
-	$config['multi_dump']=( isset($_POST['MultiDBDump']) ) ? $_POST['MultiDBDump'] : 0;
-	$config['compression']=$_POST['compression'];
-	$config['language']=$_POST['language'];
-	if (!isset($_POST['server_caption'])) $config['interface_server_caption']=0;
-	else $config['interface_server_caption']=$_POST['server_caption'];
-	$config['interface_server_caption_position']=isset($_POST['server_caption_position']) ? $_POST['server_caption_position'] : 0;
-	$config['interface_sqlboxsize']=$_POST['sqlboxsize'];
-	$config['theme']=$_POST['theme'];
-	$config['interface_table_compact']=( isset($_POST['interface_table_compact']) ) ? $_POST['interface_table_compact'] : 1;
+// SFTP
+$checkSFTP = [
+                '&nbsp;<br><br>&nbsp;<br>&nbsp;',
+                '&nbsp;<br><br>&nbsp;<br>&nbsp;',
+                '&nbsp;<br><br>&nbsp;<br>&nbsp;',
+];
+$checkSFTP[$i] = '';
+$sftptested = -1;
+if ((isset($_POST['testSFTP0'])) || (isset($_POST['testSFTP1'])) || (isset($_POST['testSFTP2']))) {
+    $config['sftp_transfer'] = [];
 
-	$config['email_recipient']=$_POST['email0'];
-	$config['email_recipient_cc']=$_POST['email_recipient_cc'];
-	$config['email_sender']=$_POST['email1'];
-	$config['send_mail']=$_POST['send_mail'];
-	$config['send_mail_dump']=$_POST['send_mail_dump'];
+    $config['sftp_timeout'] = [];
 
-	$config['email_maxsize1']=$_POST['email_maxsize1'];
-	if ($config['email_maxsize1'] == "") $config['email_maxsize1']=0;
-	$config['email_maxsize2']=$_POST['email_maxsize2'];
-	$config['email_maxsize']=$config['email_maxsize1'] * ( ( $config['email_maxsize2'] == 1 ) ? 1024 : 1024 * 1024 );
+    for ($i = 0; $i < 3; ++$i) {
+        $config['sftp_transfer'][$i] = (isset($_POST['sftp_transfer'][$i])) ? $_POST['sftp_transfer'][$i] : 0;
+        $config['sftp_timeout'][$i] = (isset($_POST['sftp_timeout'][$i])) ? $_POST['sftp_timeout'][$i] : 30;
+        $config['sftp_server'][$i] = (isset($_POST['sftp_server'][$i])) ? $_POST['sftp_server'][$i] : '';
+        $config['sftp_port'][$i] = (isset($_POST['sftp_port'][$i])) ? $_POST['sftp_port'][$i] : 22;
+        $config['sftp_user'][$i] = (isset($_POST['sftp_user'][$i])) ? $_POST['sftp_user'][$i] : '';
+        $config['sftp_pass'][$i] = (isset($_POST['sftp_pass'][$i])) ? $_POST['sftp_pass'][$i] : '';
+        $config['sftp_dir'][$i] = (isset($_POST['sftp_dir'][$i])) ? stripslashes($_POST['sftp_dir'][$i]) : '/';
 
-	$config['memory_limit']=$_POST['memory_limit'];
-	if ($config['memory_limit'] == "") $config['memory_limit']=0;
-	$config['minspeed']=$_POST['minspeed'];
-	if ($config['minspeed'] < 50) $config['minspeed']=50;
-	$config['maxspeed']=$_POST['maxspeed'];
-	if ($config['maxspeed'] < $config['minspeed']) $config['maxspeed']=$config['minspeed'] * 2;
-    $config['stop_with_error']=$_POST['stop_with_error'];
-    $config['ignore_enable_keys']=isset($_POST['ignore_enable_keys']) ? (int) $_POST['ignore_enable_keys']:0;
+        $config['sftp_path_to_private_key'][$i] = (isset($_POST['sftp_path_to_private_key'][$i])) ? stripslashes($_POST['sftp_path_to_private_key'][$i]) : null;
+        $config['sftp_secret_passphrase_for_private_key'][$i] = (isset($_POST['sftp_secret_passphrase_for_private_key'][$i])) ? stripslashes($_POST['sftp_secret_passphrase_for_private_key'][$i]) : null;
+        $config['sftp_fingerprint'][$i] = (isset($_POST['sftp_fingerprint'][$i])) ? stripslashes($_POST['sftp_fingerprint'][$i]) : null;
 
-	$config['multi_part']=$_POST['multi_part'];
-	$config['multipartgroesse1']=isset($_POST['multipartgroesse1']) ? floatval(str_replace(',','.',$_POST['multipartgroesse1'])) : 0;
-	$config['multipartgroesse2']=isset($_POST['multipartgroesse2']) ? intval($_POST['multipartgroesse2']) : 0;
-	if ($config['multipartgroesse1'] < 100 && $config['multipartgroesse2'] == 1) $config['multipartgroesse1']=100;
-	if ($config['multipartgroesse1'] < 1 && $config['multipartgroesse2'] == 2) $config['multipartgroesse1']=1;
+        if ('' == $config['sftp_dir'][$i] || (strlen($config['sftp_dir'][$i]) > 1 && '/' != substr($config['sftp_dir'][$i], -1))) {
+            $config['sftp_dir'][$i] .= '/';
+        }
 
-	$oldlogcompression=$config['logcompression'];
-	$config['logcompression']=( isset($_POST['logcompression']) && $_POST['logcompression'] == 1 ) ? 1 : 0;
-	$config['log_maxsize1']=$_POST['log_maxsize1'];
-	if ($config['log_maxsize1'] == "") $config['log_maxsize1']=0;
-	$config['log_maxsize2']=$_POST['log_maxsize2'];
-	$config['log_maxsize']=$config['log_maxsize1'] * ( ( $config['log_maxsize2'] == 1 ) ? 1024 : 1024 * 1024 );
+        if (isset($_POST['testSFTP'.$i])) {
+            $checkSFTP[$i] = '<div class="ssmall">'.$lang['L_TESTCONNECTION'].' SFTP-Connection '.($i + 1).'<br><br>'.TesteSFTP($i).'</div>';
+            $sftptested = $i;
+        }
+    }
+}
 
-	$config['auto_delete']=$_POST['auto_delete'];
-	$config['max_backup_files']=$_POST['max_backup_files'];
+$showVP = false;
+$oldtheme = $config['theme'] ?? 'mod';
+$oldscposition = $config['interface_server_caption_position'] ?? '';
 
-	$config['empty_db_before_restore']=$_POST['empty_db_before_restore'];
-	$config['optimize_tables_beforedump']=$_POST['optimize_tables'];
-	$config['cron_dbindex']=$_POST['cron_dbindex'];
-	$config['cron_comment']=$_POST['cron_comment'];
+if ($ftptested > -1) {
+    $ftp_server[$ftptested] = $_POST['ftp_server'][$ftptested];
+    $ftp_port[$ftptested] = $_POST['ftp_port'][$ftptested];
+    $ftp_user[$ftptested] = $_POST['ftp_user'][$ftptested];
+    $ftp_pass[$ftptested] = $_POST['ftp_pass'][$ftptested];
+    $ftp_dir_s = 'ftp_dir['.$ftptested.']';
+    $f = $_POST['ftp_dir'];
+    $ftp_dir[$ftptested] = stripslashes($f[$ftptested]);
+    // Remember inputs
+    $config['ftp_transfer'][$ftptested] = (isset($_POST['ftp_transfer'][$ftptested])) ? $_POST['ftp_transfer'][$ftptested] : 0;
+    $config['sftp'][$ftptested] = (isset($_POST['sftp'][$ftptested])) ? $_POST['sftp'][$ftptested] : 0;
+    $config['ftp_timeout'][$ftptested] = (isset($_POST['ftp_timeout'][$ftptested])) ? $_POST['ftp_timeout'][$ftptested] : 30;
+    $config['ftp_useSSL'][$ftptested] = (isset($_POST['ftp_useSSL'][$ftptested])) ? $_POST['ftp_useSSL'][$ftptested] : 0;
+    $config['ftp_mode'][$ftptested] = (isset($_POST['ftp_mode'][$ftptested])) ? 1 : 0;
+    $config['ftp_server'][$ftptested] = $ftp_server[$ftptested];
+    $config['ftp_port'][$ftptested] = $ftp_port[$ftptested];
+    $config['ftp_user'][$ftptested] = $ftp_user[$ftptested];
+    $config['ftp_pass'][$ftptested] = $ftp_pass[$ftptested];
+    $config['ftp_dir'][$ftptested] = $ftp_dir[$ftptested];
 
-	$config['cron_extender']=$_POST['cron_extender'];
-	// cron_select_savepath/
-	if (!isset($_POST['cron_select_savepath'])) $_POST['cron_select_savepath']=$config['config_file'];
-	if (isset($_POST['cron_savepath_new']) && !empty($_POST['cron_savepath_new']))
-	{
-		$tmp_configfilename=utf8_decode(trim($_POST['cron_savepath_new']));
-		if (!preg_match("/^[a-z.-_]+$/i",$tmp_configfilename,$matches))
-		{
-			$save_config=false;
-			$msg.='<p class="error">' . sprintf($lang['L_ERROR_CONFIGFILE_NAME'],$_POST['cron_savepath_new']) . '</p>';
-		}
-		else
-		{
-			$config['config_file']=$_POST['cron_savepath_new'];
-			$config['cron_configurationfile']=$_POST['cron_savepath_new'] . ".conf.php";
-		}
-	}
+    if ('' == $ftp_dir[$ftptested] || (strlen($ftp_dir[$ftptested]) > 1 && '/' != substr($ftp_dir[$ftptested], -1))) {
+        $ftp_dir[$ftptested] .= '/';
+    }
+    WriteParams();
+}
 
-	$config['cron_execution_path']=$_POST['cron_execution_path'];
-	if ($config['cron_execution_path'] == "") $config['cron_execution_path']="msd_cron/";
-	if (strlen($config['cron_execution_path']) > 1 && substr($config['cron_execution_path'],-1) != "/") $config['cron_execution_path'].="/";
+if ($sftptested > -1) {
+    $sftp_server[$sftptested] = $_POST['sftp_server'][$sftptested];
+    $sftp_port[$sftptested] = $_POST['sftp_port'][$sftptested];
+    $sftp_user[$sftptested] = $_POST['sftp_user'][$sftptested];
+    $sftp_pass[$sftptested] = $_POST['sftp_pass'][$sftptested];
+    $sftp_dir_s = 'sftp_dir['.$sftptested.']';
+    $f = $_POST['sftp_dir'];
+    $sftp_dir[$sftptested] = stripslashes($f[$sftptested]);
+    if ('' == $sftp_dir[$sftptested] || (strlen($sftp_dir[$sftptested]) > 1 && '/' != substr($sftp_dir[$sftptested], -1))) {
+        $sftp_dir[$sftptested] .= '/';
+    }
 
-	$config['cron_use_sendmail']=$_POST['cron_use_sendmail'];
-	$config['cron_sendmail']=$_POST['cron_sendmail'];
-	$config['cron_smtp']=isset($_POST['cron_smtp']) ? $_POST['cron_smtp'] : 'localhost';
+    $sftp_path_to_private_key[$sftptested] = stripslashes($_POST['sftp_path_to_private_key'][$sftptested]);
+    $sftp_secret_passphrase_for_private_key[$sftptested] = stripslashes($_POST['sftp_secret_passphrase_for_private_key'][$sftptested]);
+    $sftp_fingerprint[$sftptested] = stripslashes($_POST['sftp_fingerprint'][$sftptested]);
 
-	$config['cron_printout']=$_POST['cron_printout'];
-	$config['cron_completelog']=$_POST['cron_completelog'];
-	$config['cron_compression']=$_POST['compression'];
-	$config['cron_completelog']=$_POST['cron_completelog'];
+    // Remember inputs
+    $config['sftp_transfer'][$sftptested] = (isset($_POST['sftp_transfer'][$sftptested])) ? $_POST['sftp_transfer'][$sftptested] : 0;
+    $config['sftp_timeout'][$sftptested] = (isset($_POST['sftp_timeout'][$sftptested])) ? $_POST['sftp_timeout'][$sftptested] : 30;
+    $config['sftp_server'][$sftptested] = $sftp_server[$sftptested];
+    $config['sftp_port'][$sftptested] = $sftp_port[$sftptested];
+    $config['sftp_user'][$sftptested] = $sftp_user[$sftptested];
+    $config['sftp_pass'][$sftptested] = $sftp_pass[$sftptested];
+    $config['sftp_dir'][$sftptested] = $sftp_dir[$sftptested];
+    $config['sftp_path_to_private_key'][$sftptested] = $sftp_path_to_private_key[$sftptested];
+    $config['sftp_secret_passphrase_for_private_key'][$sftptested] = $sftp_secret_passphrase_for_private_key[$sftptested];
+    $config['sftp_fingerprint'][$sftptested] = $sftp_fingerprint[$sftptested];
 
-	$databases['multi']=Array();
-	$databases['multi_praefix']=Array();
-	$databases['multi_commandbeforedump']=Array();
-	$databases['multi_commandafterdump']=Array();
+    WriteParams();
+}
 
-	if (isset($databases['Name'][0]) && $databases['Name'][0] > '')
-	{
-		for ($i=0; $i < count($databases['Name']); $i++)
-		{
-			$databases['praefix'][$i]=isset($_POST['dbpraefix_' . $i]) ? $_POST['dbpraefix_' . $i] : '';
-			$databases['command_before_dump'][$i]=( !isset($_POST['command_before_' . $i]) ) ? "" : $_POST['command_before_' . $i];
-			$databases['command_after_dump'][$i]=( !isset($_POST['command_after_' . $i]) ) ? "" : $_POST['command_after_' . $i];
-			if (isset($_POST['db_multidump_' . $i]) && $_POST['db_multidump_' . $i] == "db_multidump_$i")
-			{
-				$databases['multi'][]=$databases['Name'][$i];
-				$databases['multi_praefix'][]=$databases['praefix'][$i];
-				$databases['multi_commandbeforedump'][]=$databases['command_before_dump'][$i];
-				$databases['multi_commandafterdump'][]=$databases['command_after_dump'][$i];
-			}
-		}
-	}
-	$databases['multisetting']=( count($databases['multi']) > 0 ) ? implode(";",$databases['multi']) : "";
-	$databases['multisetting_praefix']=( count($databases['multi']) > 0 ) ? implode(";",$databases['multi_praefix']) : "";
-	$databases['multisetting_commandbeforedump']=( count($databases['multi']) > 0 ) ? implode(";",$databases['multi_commandbeforedump']) : "";
-	$databases['multisetting_commandafterdump']=( count($databases['multi']) > 0 ) ? implode(";",$databases['multi_commandafterdump']) : "";
+echo MODHeader();
 
-	if ($config['cron_dbindex'] == -2)
-	{
-		$datenbanken=count($databases['Name']);
-		$cron_db_array=str_replace(";","|",$databases['multisetting']);
-		$cron_dbpraefix_array=str_replace(";","|",$databases['multisetting_praefix']);
-		$cron_db_cbd_array=str_replace(";","|",$databases['multisetting_commandbeforedump']);
-		$cron_db_cad_array=str_replace(";","|",$databases['multisetting_commandafterdump']);
+if (isset($_POST['load'])) {
+    $msg = SetDefault(true);
+    $msg = nl2br($msg).'<br>'.$lang['L_LOAD_SUCCESS'].'<br>';
+    echo '<script>parent.MyOOS_Dumper_menu.location.href="menu.php";</script>';
+}
 
-	}
-	elseif ($config['cron_dbindex'] == -3)
-	{
-		$cron_db_array=implode("|",$databases['Name']);
-		$cron_dbpraefix_array=implode("|",$databases['praefix']);
-		$cron_db_cbd_array = isset($databases['command_before_dump']) && !empty($databases['command_before_dump']) ? implode("|",$databases['command_before_dump']) : "";
-		$cron_db_cad_array = isset($databases['command_after_dump']) && !empty($databases['command_after_dump']) ? implode("|",$databases['command_after_dump']) : "";
-	}
+if (isset($_POST['save'])) {
+    $save_config = true;
+    //Read parameters
+    $config['multi_dump'] = $_POST['MultiDBDump'] ?? 0;
+    $config['compression'] = $_POST['compression'] ?? 0;
+    $config['language'] = $_POST['language'];
+    $config['interface_server_caption'] = $_POST['server_caption'] ?? 0;
+    $config['interface_server_caption_position'] = isset($_POST['server_caption_position']) ? $_POST['server_caption_position'] : 0;
+    $config['interface_sqlboxsize'] = $_POST['sqlboxsize'];
+    $config['theme'] = $_POST['theme'];
+    $config['interface_table_compact'] = (isset($_POST['interface_table_compact'])) ? $_POST['interface_table_compact'] : 1;
 
-	$config['ftp_transfer']=array();
-	$config['ftp_timeout']=array();
-	$config['ftp_mode']=array();
-	$config['ftp_useSSL']=array();
+    // if (isset($_POST['selected_config'])) $new_config = $_POST['selected_config'];
 
-	for ($i=0; $i < 3; $i++)
-	{
-		$checkFTP[$i]="";
-		$config['ftp_transfer'][$i]=isset($_POST['ftp_transfer'][$i]) ? $_POST['ftp_transfer'][$i] : $config['ftp_transfer'][$i];
-		$config['ftp_timeout'][$i]=isset($_POST['ftp_timeout'][$i]) ? $_POST['ftp_timeout'][$i] : 30;
-		$config['ftp_useSSL'][$i]=isset($_POST['ftp_useSSL'][$i]) ? 1 : 0;
+    if (isset($_POST['email0'])) {
+        $config['email_recipient'] = $_POST['email0'];
+    }
+    if (isset($_POST['email_recipient_cc'])) {
+        $config['email_recipient_cc'] = $_POST['email_recipient_cc'];
+    }
+    if (isset($_POST['email1'])) {
+        $config['email_sender'] = $_POST['email1'];
+    }
+    $config['send_mail'] = isset($_POST['send_mail']) ? $_POST['send_mail'] : 0;
+    $config['send_mail_dump'] = isset($_POST['send_mail_dump']) ? $_POST['send_mail_dump'] : 0;
 
-		$config['ftp_mode'][$i]=isset($_POST['ftp_mode'][$i]) ? 1 : 0;
-		$config['ftp_server'][$i]=$_POST['ftp_server'][$i];
-		$config['ftp_port'][$i]=$_POST['ftp_port'][$i];
-		$config['ftp_user'][$i]=$_POST['ftp_user'][$i];
-		$config['ftp_pass'][$i]=$_POST['ftp_pass'][$i];
-		$config['ftp_dir'][$i]=stripslashes($_POST['ftp_dir'][$i]);
-		if ($config['ftp_port'][$i] == 0) $config['ftp_port'][$i]=21;
-		if ($config['ftp_dir'][$i] == "" || ( strlen($config['ftp_dir'][$i]) > 1 && substr($config['ftp_dir'][$i],-1) != "/" )) $config['ftp_dir'][$i].="/";
-	}
+    if (isset($_POST['email_maxsize1'])) {
+        $config['email_maxsize1'] = $_POST['email_maxsize1'];
+    }
+    if ('' == $config['email_maxsize1']) {
+        $config['email_maxsize1'] = 0;
+    }
+    if (isset($_POST['email_maxsize2'])) {
+        $config['email_maxsize2'] = $_POST['email_maxsize2'];
+    }
+    $config['email_maxsize'] = $config['email_maxsize1'] * ((1 == $config['email_maxsize2']) ? 1024 : 1024 * 1024);
 
-	$config['bb_width']=$_POST['bb_width'];
-	$config['bb_textcolor']=$_POST['bb_textcolor'];
-	$config['sql_limit']=$_POST['sql_limit'];
+    if (isset($_POST['memory_limit'])) {
+        $config['memory_limit'] = $_POST['memory_limit'];
+    }
+    if ('' == $config['memory_limit']) {
+        $config['memory_limit'] = 0;
+    }
+    if (isset($_POST['minspeed'])) {
+        $config['minspeed'] = $_POST['minspeed'];
+    }
+    if ($config['minspeed'] < 5) {
+        $config['minspeed'] = 5;
+    }
+    if (isset($_POST['maxspeed'])) {
+        $config['maxspeed'] = $_POST['maxspeed'];
+    }
+    if ($config['maxspeed'] < $config['minspeed']) {
+        $config['maxspeed'] = $config['minspeed'] * 2;
+    }
+    if (isset($_POST['stop_with_error'])) {
+        $config['stop_with_error'] = $_POST['stop_with_error'];
+    }
+    $config['ignore_enable_keys'] = isset($_POST['ignore_enable_keys']) ? (int) $_POST['ignore_enable_keys'] : 0;
 
-	if ($config['dbhost'] != $_POST['dbhost'] || $config['dbuser'] != $_POST['dbuser'] || $config['dbpass'] != $_POST['dbpass'] || $config['dbport'] != $_POST['dbport'] || $config['dbsocket'] != $_POST['dbsocket'])
-	{
-		//neue Verbindungsparameter
-		$show_VP=true;
+    $config['multi_part'] = isset($_POST['multi_part']) ? $_POST['multi_part'] : 0;
+    if (1 == $config['multi_part']) {
+        $config['multipartgroesse1'] = isset($_POST['multipartgroesse1']) ? floatval(str_replace(',', '.', $_POST['multipartgroesse1'])) : 0;
+        $config['multipartgroesse2'] = isset($_POST['multipartgroesse2']) ? intval($_POST['multipartgroesse2']) : 0;
+    }
+    if ($config['multipartgroesse1'] < 100 && 1 == $config['multipartgroesse2']) {
+        $config['multipartgroesse1'] = 100;
+    }
+    if ($config['multipartgroesse1'] < 1 && 2 == $config['multipartgroesse2']) {
+        $config['multipartgroesse1'] = 1;
+    }
 
-		//alte Parameter sichern
-		$old['dbhost']=$config['dbhost'];
-		$old['dbuser']=$config['dbuser'];
-		$old['dbpass']=$config['dbpass'];
-		$old['dbport']=$config['dbport'];
-		$old['dbsocket']=$config['dbsocket'];
+    $config['logcompression'] = isset($config['logcompression']) ? $config['logcompression'] : 0;
+    $oldlogcompression = $config['logcompression'];
+    $config['logcompression'] = (isset($_POST['logcompression']) && 1 == $_POST['logcompression']) ? 1 : 0;
+    if (isset($_POST['log_maxsize1'])) {
+        $config['log_maxsize1'] = $_POST['log_maxsize1'];
+    }
+    if ('' == $config['log_maxsize1']) {
+        $config['log_maxsize1'] = 0;
+    }
+    if (isset($_POST['log_maxsize2'])) {
+        $config['log_maxsize2'] = $_POST['log_maxsize2'];
+    }
+    $config['log_maxsize'] = $config['log_maxsize1'] * ((1 == $config['log_maxsize2']) ? 1024 : 1024 * 1024);
 
-		//neu setzen
-		$config['dbhost']=$_POST['dbhost'];
-		$config['dbuser']=$_POST['dbuser'];
-		$config['dbpass']=$_POST['dbpass'];
-		$config['dbport']=$_POST['dbport'];
-		$config['dbsocket']=$_POST['dbsocket'];
-		if (MSD_mysql_connect())
-		{
-			// neue Verbindungsdaten wurden akzeptiert -> manuelle DB-Liste von anderem User löschen
-			SetDefault();
-			$msg.='<script type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php";</script>';
-		}
-		else
-		{
-			//alte Werte holen
-			$config['dbhost']=$old['dbhost'];
-			$config['dbuser']=$old['dbuser'];
-			$config['dbpass']=$old['dbpass'];
-			$config['dbport']=$old['dbport'];
-			$config['dbsocket']=$old['dbsocket'];
-			$msg.='<p class="error">' . $lang['L_WRONG_CONNECTIONPARS'] . '</p>';
-		}
-	}
+    $config['auto_delete'] = isset($_POST['auto_delete']) ? $_POST['auto_delete'] : 0;
+    if (isset($_POST['max_backup_files'])) {
+        $config['max_backup_files'] = $_POST['max_backup_files'];
+    }
 
-	// Manuelles hinzufügen einer Datenbank
-	if ($_POST['add_db_manual'] > '')
-	{
-		$to_add=trim($_POST['add_db_manual']);
-		$found=false;
-		// Prüfen, ob die DB bereits in der Liste vorhanden ist
-		if (isset($databases['Name'][0]))
-		{
-			foreach ($databases['Name'] as $existing_db)
-			{
-				if ($existing_db == $to_add) $found=true;
-			}
-		}
-		if ($found) $add_db_message=sprintf($lang['L_DB_IN_LIST'],$to_add);
-		else
-		{
-			if (MSD_mysql_connect())
-			{
-				$res=@mysqli_select_db($config['dbconnection'], $to_add);
-				if (!$res === false)
-				{
-					$databases['Name'][] = $to_add;
-					//Menü aktualisieren, damit die DB in der Selectliste erscheint
-					echo '<script type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php";</script>';
-				}
-				else
-					$add_db_message=sprintf($lang['L_DB_MANUAL_ERROR'],$to_add);
-				$showVP=true;
-			}
-		}
-	}
+    $config['empty_db_before_restore'] = isset($_POST['empty_db_before_restore']) ? $_POST['empty_db_before_restore'] : 0;
+    $config['optimize_tables_beforedump'] = isset($_POST['optimize_tables']) ? $_POST['optimize_tables'] : 0;
+    $config['use_binary_container'] = isset($_POST['binary_container']) ? $_POST['binary_container'] : 0;
+    if (isset($_POST['cron_dbindex'])) {
+        $config['cron_dbindex'] = $_POST['cron_dbindex'];
+    }
+    if (isset($_POST['cron_comment'])) {
+        $config['cron_comment'] = $_POST['cron_comment'];
+    }
 
-	//Nach einer Uebernahme einer neuen Configuration vor dem Schreiben ueberfluessige Indexe entfernen
-	$anzahl_datenbanken=sizeof($databases['Name']);
-	if (sizeof($databases['praefix']) > $anzahl_datenbanken)
-	{
-		for ($i=sizeof($databases['praefix']); $i >= $anzahl_datenbanken; $i--)
-		{
-			unset($databases['praefix'][$i]);
-			unset($databases['command_before_dump'][$i]);
-			unset($databases['command_after_dump'][$i]);
-		}
-		if ($databases['db_selected_index'] >= $anzahl_datenbanken) $databases['db_selected_index']=0;
-	}
+    if (isset($_POST['cron_extender'])) {
+        $config['cron_extender'] = $_POST['cron_extender'];
+    }
+    // cron_select_savepath/
+    if (!isset($_POST['cron_select_savepath'])) {
+        $_POST['cron_select_savepath'] = $config['config_file'];
+    }
+    if (isset($_POST['cron_savepath_new']) && !empty($_POST['cron_savepath_new'])) {
+        $tmp_configfilename = utf8_decode(trim($_POST['cron_savepath_new']));
+        if (!preg_match('/^[a-z.-_]+$/i', $tmp_configfilename, $matches)) {
+            $save_config = false;
+            $msg .= '<p class="error">'.sprintf($lang['L_ERROR_CONFIGFILE_NAME'], $_POST['cron_savepath_new']).'</p>';
+        } else {
+            $config['config_file'] = $_POST['cron_savepath_new'];
+            $config['cron_configurationfile'] = $_POST['cron_savepath_new'].'.conf.php';
+        }
+    }
 
-	// und wegschreiben
-	if ($save_config)
-	{
-		if (WriteParams(false) == true)
-		{
-			//neue Sprache? Dann Menue links auch aktualisieren
-			if ($_SESSION['config']['language'] != $config['language'] || $_POST['scaption_old'] != $config['interface_server_caption'] || $oldtheme != $config['theme'] || $oldscposition != $config['interface_server_caption_position'])
-			{
-				$msg.='<script type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php?config=' . urlencode($config['config_file']) . '";</script>';
-				if (isset($_POST['cron_savepath_new']) && $_POST['cron_savepath_new'] > '') $msg.='<p class="success">' . $lang['L_SUCCESS_CONFIGFILE_CREATED'] . '</p>';
-			}
-			//Parameter laden
-			read_config($config['config_file']);
-			if ($config['logcompression'] != $oldlogcompression) DeleteLog();
-			$msg.='<p class="success">' . sprintf($lang['L_SAVE_SUCCESS'],$config['config_file']) . '</p>';
-			$msg.='<script type="text/javascript" language="javascript">parent.MyOOS_Dumper_menu.location.href="menu.php?config=' . $config['config_file'] . '";</script>';
-		}
-		else
-			$msg.='<p class="error">' . $lang['L_SAVE_ERROR'] . '</p>';
-	}
+    if (isset($_POST['cron_execution_path'])) {
+        $config['cron_execution_path'] = $_POST['cron_execution_path'];
+    }
+    if ('' == $config['cron_execution_path']) {
+        $config['cron_execution_path'] = 'mod_cron/';
+    }
+    if (strlen($config['cron_execution_path']) > 1 && '/' != substr($config['cron_execution_path'], -1)) {
+        $config['cron_execution_path'] .= '/';
+    }
 
+    if (isset($_POST['cron_use_sendmail'])) {
+        $config['cron_use_sendmail'] = $_POST['cron_use_sendmail'];
+    }
+    if (isset($_POST['cron_sendmail'])) {
+        $config['cron_sendmail'] = $_POST['cron_sendmail'];
+    }
+    $config['cron_smtp'] = isset($_POST['cron_smtp']) ? $_POST['cron_smtp'] : 'localhost';
+
+    $config['cron_printout'] = isset($_POST['cron_printout']) ? $_POST['cron_printout'] : 0;
+    $config['cron_completelog'] = isset($_POST['cron_completelog']) ? $_POST['cron_completelog'] : 0;
+    $config['cron_compression'] = isset($_POST['compression']) ? $_POST['compression'] : 0;
+    if (isset($_POST['cron_completelog'])) {
+        $config['cron_completelog'] = $_POST['cron_completelog'];
+    }
+
+    $databases['multi'] = [];
+    $databases['multi_praefix'] = [];
+    $databases['multi_commandbeforedump'] = [];
+    $databases['multi_commandafterdump'] = [];
+
+    if (isset($databases['Name'][0]) && $databases['Name'][0] > '') {
+        for ($i = 0; $i < count($databases['Name']); ++$i) {
+            $databases['praefix'][$i] = isset($_POST['dbpraefix_'.$i]) ? $_POST['dbpraefix_'.$i] : '';
+            $databases['command_before_dump'][$i] = (!isset($_POST['command_before_'.$i])) ? '' : $_POST['command_before_'.$i];
+            $databases['command_after_dump'][$i] = (!isset($_POST['command_after_'.$i])) ? '' : $_POST['command_after_'.$i];
+            if (isset($_POST['db_multidump_'.$i]) && $_POST['db_multidump_'.$i] == "db_multidump_$i") {
+                $databases['multi'][] = $databases['Name'][$i];
+                $databases['multi_praefix'][] = $databases['praefix'][$i];
+                $databases['multi_commandbeforedump'][] = $databases['command_before_dump'][$i];
+                $databases['multi_commandafterdump'][] = $databases['command_after_dump'][$i];
+            }
+        }
+    }
+    $databases['multisetting'] = (count($databases['multi']) > 0) ? implode(';', $databases['multi']) : '';
+    $databases['multisetting_praefix'] = (count($databases['multi']) > 0) ? implode(';', $databases['multi_praefix']) : '';
+    $databases['multisetting_commandbeforedump'] = (count($databases['multi']) > 0) ? implode(';', $databases['multi_commandbeforedump']) : '';
+    $databases['multisetting_commandafterdump'] = (count($databases['multi']) > 0) ? implode(';', $databases['multi_commandafterdump']) : '';
+
+
+    if (-2 == $config['cron_dbindex']) {
+        $datenbanken = count($databases['Name']);
+        $cron_db_array = str_replace(';', '|', $databases['multisetting']);
+        $cron_dbpraefix_array = str_replace(';', '|', $databases['multisetting_praefix']);
+        $cron_db_cbd_array = str_replace(';', '|', $databases['multisetting_commandbeforedump']);
+        $cron_db_cad_array = str_replace(';', '|', $databases['multisetting_commandafterdump']);
+    } elseif (-3 == $config['cron_dbindex']) {
+        $cron_db_array = implode('|', $databases['Name']);
+        $cron_dbpraefix_array = implode('|', $databases['praefix']);
+        $cron_db_cbd_array = isset($databases['command_before_dump']) && !empty($databases['command_before_dump']) ? implode('|', $databases['command_before_dump']) : '';
+        $cron_db_cad_array = isset($databases['command_after_dump']) && !empty($databases['command_after_dump']) ? implode('|', $databases['command_after_dump']) : '';
+    }
+
+    $config['ftp_transfer'] = [];
+    $config['ftp_timeout'] = [];
+    $config['ftp_mode'] = [];
+    $config['ftp_useSSL'] = [];
+
+    $config['ftp_server'] = [];
+    $config['ftp_port'] = [];
+    $config['ftp_user'] = [];
+    $config['ftp_pass'] = [];
+    $config['ftp_dir'] = [];
+
+    for ($i = 0; $i < 3; ++$i) {
+        $checkFTP[$i] = '';
+        $config['ftp_transfer'][$i] = isset($_POST['ftp_transfer'][$i]) ? $_POST['ftp_transfer'][$i] : 0;
+        $config['ftp_timeout'][$i] = isset($_POST['ftp_timeout'][$i]) ? $_POST['ftp_timeout'][$i] : 30;
+        $config['ftp_useSSL'][$i] = isset($_POST['ftp_useSSL'][$i]) ? 1 : 0;
+
+        $config['ftp_mode'][$i] = isset($_POST['ftp_mode'][$i]) ? 1 : 0;
+        $config['ftp_server'][$i] = isset($_POST['ftp_server'][$i]) ? $_POST['ftp_server'][$i] : '';
+        $config['ftp_port'][$i] = isset($_POST['ftp_port'][$i]) ? $_POST['ftp_port'][$i] : 0;
+        $config['ftp_user'][$i] = isset($_POST['ftp_user'][$i]) ? $_POST['ftp_user'][$i] : '';
+        $config['ftp_pass'][$i] = isset($_POST['ftp_pass'][$i]) ? $_POST['ftp_pass'][$i] : '';
+        $config['ftp_dir'][$i] = isset($_POST['ftp_dir'][$i]) ? stripslashes($_POST['ftp_dir'][$i]) : '';
+        if (0 == $config['ftp_port'][$i]) {
+            $config['ftp_port'][$i] = 21;
+        }
+        if ('' == $config['ftp_dir'][$i] || (strlen($config['ftp_dir'][$i]) > 1 && '/' != substr($config['ftp_dir'][$i], -1))) {
+            $config['ftp_dir'][$i] .= '/';
+        }
+    }
+
+    $config['sftp_transfer'] = [];
+    $config['sftp_timeout'] = [];
+
+    $config['sftp_server'] = [];
+    $config['sftp_port'] = [];
+    $config['sftp_user'] = [];
+    $config['sftp_pass'] = [];
+    $config['sftp_dir'] = [];
+
+    $config['sftp_path_to_private_key'] = [];
+    $config['sftp_secret_passphrase_for_private_key'] = [];
+    $config['sftp_fingerprint'] = [];
+
+    for ($i = 0; $i < 3; ++$i) {
+        $checkFTP[$i] = '';
+        $config['sftp_transfer'][$i] = isset($_POST['sftp_transfer'][$i]) ? $_POST['sftp_transfer'][$i] : 0;
+        $config['sftp_timeout'][$i] = isset($_POST['sftp_timeout'][$i]) ? $_POST['sftp_timeout'][$i] : 30;
+
+        $config['sftp_server'][$i] = isset($_POST['sftp_server'][$i]) ? $_POST['sftp_server'][$i] : '';
+        $config['sftp_port'][$i] = isset($_POST['sftp_port'][$i]) ? $_POST['sftp_port'][$i] : 0;
+        $config['sftp_user'][$i] = isset($_POST['sftp_user'][$i]) ? $_POST['sftp_user'][$i] : '';
+        $config['sftp_pass'][$i] = isset($_POST['sftp_pass'][$i]) ? $_POST['sftp_pass'][$i] : '';
+        $config['sftp_dir'][$i] = isset($_POST['sftp_dir'][$i]) ? stripslashes($_POST['sftp_dir'][$i]) : '';
+
+        $config['sftp_path_to_private_key'][$i] = (isset($_POST['sftp_path_to_private_key'][$i])) ? stripslashes($_POST['sftp_path_to_private_key'][$i]) : null;
+        $config['sftp_secret_passphrase_for_private_key'][$i] = (isset($_POST['sftp_secret_passphrase_for_private_key'][$i])) ? stripslashes($_POST['sftp_secret_passphrase_for_private_key'][$i]) : null;
+        $config['sftp_fingerprint'][$i] = (isset($_POST['sftp_fingerprint'][$i])) ? stripslashes($_POST['sftp_fingerprint'][$i]) : null;
+
+        if (0 == $config['sftp_port'][$i]) {
+            $config['sftp_port'][$i] = 22;
+        }
+        if ('' == $config['sftp_dir'][$i] || (strlen($config['sftp_dir'][$i]) > 1 && '/' != substr($config['sftp_dir'][$i], -1))) {
+            $config['sftp_dir'][$i] .= '/';
+        }
+    }
+
+    $config['bb_width'] = $_POST['bb_width'];
+    $config['bb_textcolor'] = $_POST['bb_textcolor'];
+    $config['sql_limit'] = $_POST['sql_limit'];
+
+    if ($config['dbhost'] != $_POST['dbhost'] || $config['dbuser'] != $_POST['dbuser'] || $config['dbpass'] != $_POST['dbpass'] || $config['dbport'] != $_POST['dbport'] || $config['dbsocket'] != $_POST['dbsocket']) {
+        // new connection parameters
+        $show_VP = true;
+
+        // Save old parameters
+        $old['dbhost'] = $config['dbhost'];
+        $old['dbuser'] = $config['dbuser'];
+        $old['dbpass'] = $config['dbpass'];
+        $old['dbport'] = $config['dbport'];
+        $old['dbsocket'] = $config['dbsocket'];
+
+        //set new
+        $config['dbhost'] = $_POST['dbhost'];
+        $config['dbuser'] = $_POST['dbuser'];
+        $config['dbpass'] = $_POST['dbpass'];
+        $config['dbport'] = $_POST['dbport'];
+        $config['dbsocket'] = $_POST['dbsocket'];
+        if (mod_mysqli_connect()) {
+            // new connection data was accepted -> manually delete DB list from other user
+            SetDefault();
+            $msg .= '<script>parent.MyOOS_Dumper_menu.location.href="menu.php";</script>';
+        } else {
+            // Get old values
+            $config['dbhost'] = $old['dbhost'];
+            $config['dbuser'] = $old['dbuser'];
+            $config['dbpass'] = $old['dbpass'];
+            $config['dbport'] = $old['dbport'];
+            $config['dbsocket'] = $old['dbsocket'];
+            $msg .= '<p class="error">'.$lang['L_WRONG_CONNECTIONPARS'].'</p>';
+        }
+    }
+
+    // Manuelles hinzufügen einer Datenbank
+    if ($_POST['add_db_manual'] > '') {
+        $to_add = trim($_POST['add_db_manual']);
+        $found = false;
+        // Check if the DB already exists in the list
+        if (isset($databases['Name'][0])) {
+            foreach ($databases['Name'] as $existing_db) {
+                if ($existing_db == $to_add) {
+                    $found = true;
+                }
+            }
+        }
+        if ($found) {
+            $add_db_message = sprintf($lang['L_DB_IN_LIST'], $to_add);
+        } else {
+            if (mod_mysqli_connect()) {
+                $res = mysqli_select_db($config['dbconnection'], $to_add);
+                if (false === !$res) {
+                    $databases['Name'][] = $to_add;
+                    // Refresh menu so that the DB appears in the select list
+                    echo '<script>parent.MyOOS_Dumper_menu.location.href="menu.php";</script>';
+                } else {
+                    $add_db_message = sprintf($lang['L_DB_MANUAL_ERROR'], $to_add);
+                }
+                $showVP = true;
+            }
+        }
+    }
+
+    // After a transfer of a new configuration remove superfluous indexes before writing
+    $number_databases = sizeof($databases['Name']);
+    if (sizeof($databases['praefix']) > $number_databases) {
+        for ($i = sizeof($databases['praefix']); $i >= $number_databases; --$i) {
+            unset($databases['praefix'][$i]);
+            unset($databases['command_before_dump'][$i]);
+            unset($databases['command_after_dump'][$i]);
+        }
+        if ($databases['db_selected_index'] >= $number_databases) {
+            $databases['db_selected_index'] = 0;
+        }
+    }
+
+    // and write away
+    if ($save_config) {
+        if (true == WriteParams(false)) {
+            // new language? Then also update menu on the left
+            if ($_SESSION['config']['language'] != $config['language'] || $_POST['scaption_old'] != $config['interface_server_caption'] || $oldtheme != $config['theme'] || $oldscposition != $config['interface_server_caption_position']) {
+                $msg .= '<script>parent.MyOOS_Dumper_menu.location.href="menu.php?config='.urlencode($config['config_file']).'";</script>';
+                if (isset($_POST['cron_savepath_new']) && $_POST['cron_savepath_new'] > '') {
+                    $msg .= '<p class="success">'.$lang['L_SUCCESS_CONFIGFILE_CREATED'].'</p>';
+                }
+            }
+            // Load parameters
+            read_config($config['config_file']);
+            if ($config['logcompression'] != $oldlogcompression) {
+                DeleteLog();
+            }
+            $msg .= '<p class="success">'.sprintf($lang['L_SAVE_SUCCESS'], $config['config_file']).'</p>';
+            $msg .= '<script>parent.MyOOS_Dumper_menu.location.href="menu.php?config='.$config['config_file'].'";</script>';
+        } else {
+            $msg .= '<p class="error">'.$lang['L_SAVE_ERROR'].'</p>';
+        }
+    }
 }
 
 ReadSQL();
 ?>
-<script type="text/javascript">
-function hide_pardivs() {
-	document.getElementById("db").style.display = 'none';
-	document.getElementById("global1").style.display = 'none';
-	document.getElementById("global2").style.display = 'none';
-	document.getElementById("global3").style.display = 'none';
-	document.getElementById("transfer1").style.display = 'none';
-	document.getElementById("transfer2").style.display = 'none';
-	document.getElementById("cron").style.display = 'none';
-	document.getElementById("configs").style.display = 'none';
-	for(i=0;i<8;i++) {
-		document.getElementById("command"+i).className  ='ConfigButton';
+<script>
+	function hide_pardivs() {
+		document.getElementById("db").style.display = 'none';
+		document.getElementById("global1").style.display = 'none';
+		document.getElementById("global2").style.display = 'none';
+		document.getElementById("global3").style.display = 'none';
+		document.getElementById("transfer1").style.display = 'none';
+		document.getElementById("transfer2").style.display = 'none';
+		document.getElementById("transfer3").style.display = 'none';
+		document.getElementById("cron").style.display = 'none';
+		document.getElementById("configs").style.display = 'none';
+		for(i = 0; i < 8; i++) {
+			document.getElementById("command"+i).className  ='ConfigButton';
+		}
 	}
-}
-function SwitchVP(objid) {
-	if (!document.getElementById(objid)) objid='VP';
-	if(document.getElementById(objid).style.display=='none')
-		document.getElementById(objid).style.display='block';
-	else
-		document.getElementById(objid).style.display='none'
-}
 
-function show_pardivs(lab) {
-	hide_pardivs();
-	switch(lab) {
-		case "db":
-			document.getElementById("db").style.display = 'block';
-			document.getElementById("command1").className ='ConfigButtonSelected';
-			break;
-		case "global1":
-			document.getElementById("global1").style.display = 'block';
-			document.getElementById("command2").className ='ConfigButtonSelected';
-			break;
-		case "global2":
-			document.getElementById("global3").style.display = 'block';
-			document.getElementById("command3").className ='ConfigButtonSelected';
-			break;
-		case "global3":
-			document.getElementById("global2").style.display = 'block';
-			document.getElementById("command4").className ='ConfigButtonSelected';
-			break;
-		case "transfer1":
-			document.getElementById("transfer1").style.display = 'block';
-			document.getElementById("command5").className ='ConfigButtonSelected';
-			break;
-		case "transfer2":
-			document.getElementById("transfer2").style.display = 'block';
-			document.getElementById("command6").className ='ConfigButtonSelected';
-			break;
-		case "cron":
-			document.getElementById("cron").style.display = 'block';
-			document.getElementById("command7").className ='ConfigButtonSelected';
-			break;
-		case "configs":
-			document.getElementById("configs").style.display = 'block';
-			document.getElementById("command0").className ='ConfigButtonSelected';
-			break;
-		case "all":
-			document.getElementById("db").style.display = 'block';
-			document.getElementById("global1").style.display = 'block';
-			document.getElementById("global2").style.display = 'block';
-			document.getElementById("global3").style.display = 'block';
-			document.getElementById("transfer1").style.display = 'block';
-			document.getElementById("transfer2").style.display = 'block';
-			document.getElementById("cron").style.display = 'block';
-			document.getElementById("configs").style.display = 'block';
-			document.getElementById("command8").className ='ConfigButtonSelected';
-			break;
-		default:
-			document.getElementById("db").style.display = 'block';
-			document.getElementById("command1").className ='ConfigButtonSelected';
-			break;
+	function SwitchVP(objid) {
+		if (!document.getElementById(objid)) objid = 'VP';
+		if(document.getElementById(objid).style.display == 'none')
+			document.getElementById(objid).style.display = 'block';
+		else
+			document.getElementById(objid).style.display = 'none'
+	}
+
+	function show_pardivs(lab) {
+		hide_pardivs();
+		switch(lab) {
+				case "db":
+						document.getElementById("db").style.display = 'block';
+						document.getElementById("command1").className ='ConfigButtonSelected';
+						break;
+				case "global1":
+						document.getElementById("global1").style.display = 'block';
+						document.getElementById("command2").className ='ConfigButtonSelected';
+						break;
+				case "global2":
+						document.getElementById("global3").style.display = 'block';
+						document.getElementById("command3").className ='ConfigButtonSelected';
+						break;
+				case "global3":
+						document.getElementById("global2").style.display = 'block';
+						document.getElementById("command4").className ='ConfigButtonSelected';
+						break;
+				case "transfer1":
+						document.getElementById("transfer1").style.display = 'block';
+						document.getElementById("command5").className ='ConfigButtonSelected';
+						break;
+				case "transfer2":
+						document.getElementById("transfer2").style.display = 'block';
+						document.getElementById("command6").className ='ConfigButtonSelected';
+						break;
+				case "transfer3":
+						document.getElementById("transfer3").style.display = 'block';
+						document.getElementById("command11").className ='ConfigButtonSelected';
+						break;			
+			
+			
+				case "cron":
+						document.getElementById("cron").style.display = 'block';
+						document.getElementById("command7").className ='ConfigButtonSelected';
+						break;
+				case "configs":
+						document.getElementById("configs").style.display = 'block';
+						document.getElementById("command0").className ='ConfigButtonSelected';
+						break;
+				case "all":
+						document.getElementById("db").style.display = 'block';
+						document.getElementById("global1").style.display = 'block';
+						document.getElementById("global2").style.display = 'block';
+						document.getElementById("global3").style.display = 'block';
+						document.getElementById("transfer1").style.display = 'block';
+						document.getElementById("transfer2").style.display = 'block';
+						document.getElementById("transfer3").style.display = 'block';
+						document.getElementById("cron").style.display = 'block';
+						document.getElementById("configs").style.display = 'block';
+						document.getElementById("command8").className ='ConfigButtonSelected';
+						break;
+				default:
+						document.getElementById("db").style.display = 'block';
+						document.getElementById("command1").className ='ConfigButtonSelected';
+						break;
+			}
+			document.getElementById("sel").value=lab;
+	}
+
+	function WriteMem() {
+		document.getElementById("mlimit").value=<?php
+        echo round($config['php_ram'] * 1024 * 1024 * 0.9, 0);
+        ?>;
 	}
-	document.getElementById("sel").value=lab;
-}
-function WriteMem()
-{
-	document.getElementById("mlimit").value=<?php
-	echo round($config['php_ram'] * 1024 * 1024 * 0.9,0);
-	?>;
-}
 </script>
 <?php
-if (!isset($config['email_maxsize1'])) $config['email_maxsize1']=0;
-if (!isset($config['email_maxsize2'])) $config['email_maxsize2']=1;
-if (!isset($databases['multisetting'])) $databases['multisetting']="";
-$databases['multi']=explode(";",$databases['multisetting']);
+if (!isset($config['email_maxsize1'])) {
+            $config['email_maxsize1'] = 0;
+        }
+if (!isset($config['email_maxsize2'])) {
+    $config['email_maxsize2'] = 1;
+}
+if (!isset($databases['multisetting'])) {
+    $databases['multisetting'] = '';
+}
+$databases['multi'] = explode(';', $databases['multisetting']);
 
-//Ausgabe-Teile
-$aus['formstart']=headline($lang['L_CONFIG_HEADLINE'] . ': ' . $config['config_file']);
-$aus['formstart'].='<form name="frm_config" method="POST" action="config_overview.php"><input type="hidden" name="sel" id="sel" value="db">' . $nl;
-$aus['formstart'].='<div id="configleft">';
-$aus['formstart'].='<input type="Button" id="command1" onclick="show_pardivs(\'db\');" value="' . $lang['L_DBS'] . '" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command2" onclick="show_pardivs(\'global1\');" value="' . $lang['L_GENERAL'] . '" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command3" onclick="show_pardivs(\'global2\');" value="' . $lang['L_CONFIG_INTERFACE'] . '" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command4" onclick="show_pardivs(\'global3\');" value="' . $lang['L_CONFIG_AUTODELETE'] . '" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command5" onclick="show_pardivs(\'transfer1\');" value="Email" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command6" onclick="show_pardivs(\'transfer2\');" value="FTP" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command7" onclick="show_pardivs(\'cron\');" value="Cronscript" class="ConfigButton"><br>' . $nl;
-$aus['formstart'].='<input type="Button" id="command0" onclick="show_pardivs(\'configs\');" value="' . $lang['L_CONFIGFILES'] . '" class="ConfigButton"><br>' . $nl;
-//$aus['formstart'].='<input type="Button" id="command8" onclick="show_pardivs(\'all\');" value="' . $lang['L_ALLPARS'] . '" class="ConfigButton"><br>' . $nl;
+// Output parts
+$aus['formstart'] = headline($lang['L_CONFIG_HEADLINE'].': '.$config['config_file']);
+$aus['formstart'] .= '<form name="frm_config" method="POST" action="config_overview.php"><input type="hidden" name="sel" id="sel" value="db">'.$nl;
+$aus['formstart'] .= '<div id="configleft">';
+$aus['formstart'] .= '<input type="Button" id="command1" onclick="show_pardivs(\'db\');" value="'.$lang['L_DBS'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command2" onclick="show_pardivs(\'global1\');" value="'.$lang['L_GENERAL'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command3" onclick="show_pardivs(\'global2\');" value="'.$lang['L_CONFIG_INTERFACE'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command4" onclick="show_pardivs(\'global3\');" value="'.$lang['L_CONFIG_AUTODELETE'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command5" onclick="show_pardivs(\'transfer1\');" value="'.$lang['L_CONFIG_EMAIL'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command6" onclick="show_pardivs(\'transfer2\');" value="'.$lang['L_FTP'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command11" onclick="show_pardivs(\'transfer3\');" value="'.$lang['L_SFTP'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command7" onclick="show_pardivs(\'cron\');" value="'.$lang['L_CONFIG_CRONSCRIPT'].'" class="ConfigButton"><br>'.$nl;
+$aus['formstart'] .= '<input type="Button" id="command0" onclick="show_pardivs(\'configs\');" value="'.$lang['L_CONFIGFILES'].'" class="ConfigButton"><br>'.$nl;
+//$aus['formstart'] .= '<input type="Button" id="command8" onclick="show_pardivs(\'all\');" value="'.$lang['L_ALLPARS'].'" class="ConfigButton"><br>'.$nl;
 
+//$aus['formstart'] .= '<input class="Formbutton" type="reset" name="reset" value="'.$lang['L_RESET'].'">';
+$aus['formstart'] .= '<br><input class="Formbutton" type="submit" name="save" value="'.$lang['L_SAVE'].'"><br><br>'.$nl;
+$aus['formstart'] .= '<input class="Formbutton" type="Submit" name="load" value="'.$lang['L_LOAD'].'" onclick="if (!confirm(\''.$lang['L_CONFIG_ASKLOAD'].'\')) return false;">'.$nl;
+//$aus['formstart'] .= '<input class="Formbutton" type="button" value="'.$lang['L_INSTALL'].'" onclick="parent.location.href=\'install.php\'">'.$nl;
+$aus['formstart'] .= '</div><div id="configright">'.$msg.$nl;
 
-//$aus['formstart'].='<input class="Formbutton" type="reset" name="reset" value="' . $lang['L_RESET'] . '">';
-$aus['formstart'].='<br><input class="Formbutton" type="submit" name="save" value="' . $lang['L_SAVE'] . '"><br><br>' . $nl;
-$aus['formstart'].='<input class="Formbutton" type="Submit" name="load" value="' . $lang['L_LOAD'] . '" onclick="if (!confirm(\'' . $lang['L_CONFIG_ASKLOAD'] . '\')) return false;">' . $nl;
-//$aus['formstart'].='<input class="Formbutton" type="button" value="' . $lang['L_INSTALL'] . '" onclick="parent.location.href=\'install.php\'">' . $nl;
-$aus['formstart'].='</div><div id="configright">' . $msg . $nl;
+// Configuration files
+$aus['conf'] = '<div id="configs"><fieldset><legend>'.$lang['L_CONFIGFILES'].'</legend>'.$nl.$nl;
 
-// Konfigurationsdateien
-$aus['conf']='<div id="configs"><fieldset><legend>' . $lang['L_CONFIGFILES'] . '</legend>' . $nl . $nl;
+$aus['conf'] .= '<table><tr class="dbrow">';
+$aus['conf'] .= '<td style="vertical-align:middle">'.$lang['L_CREATE_CONFIGFILE'].':</td>';
+$aus['conf'] .= '<td style="vertical-align:middle"><input type="text" class="text" style="width:300px;" name="cron_savepath_new" value=""></td>';
+$aus['conf'] .= '<td colspan="2">'.print_save_button().'</td>';
+$aus['conf'] .= '</tr></table>';
 
-$aus['conf'].='<table><tr class="dbrow">';
-$aus['conf'].='<td style="vertical-align:middle">' . $lang['L_CREATE_CONFIGFILE'] . ':</td>';
-$aus['conf'].='<td style="vertical-align:middle"><input type="text" class="text" style="width:300px;" name="cron_savepath_new" value=""></td>';
-$aus['conf'].='<td colspan="2">' . print_save_button() . '</td>';
-$aus['conf'].='</tr></table>';
+$aus['conf'] .= '<br><table class="bdr"><tr class="thead"><th>#</th><th>'.$lang['L_CONFIGFILE'].' / '.$lang['L_MYSQL_DATA'].'</th>';
+$aus['conf'] .= '<th>'.$lang['L_CONFIGURATIONS'].'</th><th>'.$lang['L_ACTION'].'</th></tr>';
 
-$aus['conf'].='<br><table class="bdr"><tr class="thead"><th>#</th><th>' . $lang['L_CONFIGFILE'] . ' / ' . $lang['L_MYSQL_DATA'] . '</th>';
-$aus['conf'].='<th>' . $lang['L_CONFIGURATIONS'] . '</th><th>' . $lang['L_ACTION'] . '</th></tr>';
+$i = 0;
+$old_config = $config;
+$configs = get_config_filenames();
 
-$i=0;
-$old_config=$config;
-$configs=get_config_filenames();
-if (sizeof($configs) > 0)
-{
-	foreach ($configs as $c)
-	{
-		$i++;
-		unset($databases);
-		read_config($c);
-		$aus['conf'].='<tr class="';
-		if ($old_config['config_file'] == $c) $aus['conf'].='dbrowsel';
-		else $aus['conf'].=( $i % 2 ) ? 'dbrow' : 'dbrow1';
-		$aus['conf'].='">';
+if (sizeof($configs) > 0) {
+    foreach ($configs as $c) {
+        ++$i;
+        unset($databases);
+        read_config($c);
+        $aus['conf'] .= '<tr class="';
+        if ($old_config['config_file'] == $c) {
+            $aus['conf'] .= 'dbrowsel';
+        } else {
+            $aus['conf'] .= ($i % 2) ? 'dbrow' : 'dbrow1';
+        }
+        $aus['conf'] .= '">';
 
-		$aus['conf'].='<td><a name="config' . sprintf("%03d",$i) . '" style="text-decoration:none;">' . $i . '.</a></td>';
+        $aus['conf'] .= '<td><a name="config'.sprintf('%03d', $i).'" style="text-decoration:none;">'.$i.'.</a></td>';
 
-		// Einstellungen
-		$aus['conf'].='<td>';
+        // Settings
+        $aus['conf'] .= '<td>';
 
-		$aus['conf'].='<table>';
-		$aus['conf'].='<tr><td>' . $lang['L_NAME'] . ':</td><td><strong>' . $c . '</strong></td></tr>'; // filename
+        $aus['conf'] .= '<table>';
+        $aus['conf'] .= '<tr><td>'.$lang['L_NAME'].':</td><td><strong>'.$c.'</strong></td></tr>'; // filename
 
+        $aus['conf'] .= '<tr><td>'.$lang['L_DB_HOST'].':</td><td><strong>'.$config['dbhost'].'</strong></td></tr>';
+        $aus['conf'] .= '<tr><td>'.$lang['L_DB_USER'].':</td><td><strong>'.$config['dbuser'].'</strong></td></tr>';
+        $aus['conf'] .= '<tr><td>';
 
-		$aus['conf'].='<tr><td>' . $lang['L_DB_HOST'] . ':</td><td><strong>' . $config['dbhost'] . '</strong></td></tr>';
-		$aus['conf'].='<tr><td>' . $lang['L_DB_USER'] . ':</td><td><strong>' . $config['dbuser'] . '</strong></td></tr>';
-		$aus['conf'].='<tr><td>';
+        $aus['conf'] .= $lang['L_DBS'].':</td><td>';
+        $aus['conf'] .= '<a href="#config'.sprintf('%03d', $i).'" onclick="SwitchVP(\'show_db'.sprintf('%03d', $i).'\');">';
+        $aus['conf'] .= $icon['search'].'<strong>'.sizeof($databases['Name']).'</strong></a>';
+        $aus['conf'] .= '</td></tr>';
 
-		$aus['conf'].=$lang['L_DBS'] . ':</td><td>';
-		$aus['conf'].='<a href="#config' . sprintf("%03d",$i) . '" onclick="SwitchVP(\'show_db' . sprintf("%03d",$i) . '\');">';
-		$aus['conf'].=$icon['search'] . '<strong>' . sizeof($databases['Name']) . '</strong></a>';
-		$aus['conf'].='</td></tr>';
+        // Show database list
+        $aus['conf'] .= '<tr><td colspan="2">';
+        $aus['conf'] .= '<div id="show_db'.sprintf('%03d', $i).'" style="padding:0;margin:0;display:none;">';
+        $a = 1;
+        $aus['conf'] .= '<table  class="bdr">';
+        if (isset($databases['Name'])) {
+            foreach ($databases['Name'] as $d) {
+                $aus['conf'] .= '<tr class="'.(($a % 2) ? 'dbrow' : 'dbrow1').'"><td style="text-align:right;">';
+                $aus['conf'] .= $a.'.&nbsp;</td><td>';
+                $aus['conf'] .= '<a href="sql.php?db='.urlencode($d).'">';
+                $aus['conf'] .= $d.'</a></td></tr>';
+                ++$a;
+            }
+        }
+        $aus['conf'] .= '</table></div></td></tr>';
 
-		// Datenbankliste anzeigen
-		$aus['conf'].='<tr><td colspan="2">';
-		$aus['conf'].='<div id="show_db' . sprintf("%03d",$i) . '" style="padding:0;margin:0;display:none;">';
-		$a=1;
-		$aus['conf'].='<table  class="bdr">';
-		if (isset($databases['Name']))
-		{
-			foreach ($databases['Name'] as $d)
-			{
-				$aus['conf'].='<tr class="' . ( ( $a % 2 ) ? 'dbrow' : 'dbrow1' ) . '"><td style="text-align:right;">';
-				$aus['conf'].=$a . '.&nbsp;</td><td>';
-				$aus['conf'].='<a href="sql.php?db=' . urlencode($d) . '">';
-				$aus['conf'].=$d . '</a></td></tr>';
-				$a++;
-			}
-		}
-		$aus['conf'].='</table></div></td></tr>';
+        $aus['conf'] .= '</table></td>';
 
-		$aus['conf'].='</table></td>';
+        $aus['conf'] .= '<td><table>';
 
-		$aus['conf'].='<td><table>';
+        // Build string from multidump DBs
+        $toolboxstring = '';
+        $databases['multi'] = [];
+        if (isset($databases['multisetting'])) {
+            $databases['multi'] = explode(';', $databases['multisetting']);
+        }
+        $multi_praefixe = [];
+        if (isset($databases['multisetting_praefix'])) {
+            $multi_praefixe = explode(';', $databases['multisetting_praefix']);
+        }
+        if (is_array($databases['multi'])) {
+            for ($x = 0; $x < sizeof($databases['multi']); ++$x) {
+                if ($x > 0) {
+                    $toolboxstring .= ', ';
+                }
+                $toolboxstring .= $databases['multi'][$x];
+                if (isset($multi_praefixe[$x]) && $multi_praefixe[$x] > '') {
+                    $toolboxstring .= ' (<i>\''.$multi_praefixe[$x].'\'</i>)';
+                }
+            }
+        }
 
-		// String aus Multidump-DBs aufbauen
-		$toolboxstring='';
-		$databases['multi']=array();
-		if (isset($databases['multisetting'])) $databases['multi']=explode(";",$databases['multisetting']);
-		$multi_praefixe=array();
-		if (isset($databases['multisetting_praefix'])) $multi_praefixe=explode(";",$databases['multisetting_praefix']);
-		if (is_array($databases['multi']))
-		{
-			for ($x=0; $x < sizeof($databases['multi']); $x++)
-			{
-				if ($x > 0) $toolboxstring.=', ';
-				$toolboxstring.=$databases['multi'][$x];
-				if (isset($multi_praefixe[$x]) && $multi_praefixe[$x] > '') $toolboxstring.=' (<i>\'' . $multi_praefixe[$x] . '\'</i>)';
-			}
-		}
+        // DB list for PHP
+        if (isset($config['multi_dump']) && (1 == $config['multi_dump'])) { // Multidump
+            $aus['conf'] .= table_output($lang['L_BACKUP_DBS_PHP'], $toolboxstring);
+        } else {
+            // Current DB
+            $text = isset($databases['db_actual']) ? $databases['db_actual'] : '';
+            if (isset($databases['db_selected_index']) && isset($databases['praefix'][$databases['db_selected_index']]) && $databases['praefix'][$databases['db_selected_index']] > '') {
+                $text .= " ('<i>".$databases['praefix'][$databases['db_selected_index']]."</i>')";
+            }
+            $aus['conf'] .= table_output($lang['L_BACKUP_DBS_PHP'], $text);
+        }
 
-		// DB-Liste fuer PHP
-		if ($config['multi_dump'] == 1) // Multidump
-		{
-			$aus['conf'].=table_output($lang['L_BACKUP_DBS_PHP'],$toolboxstring);
-		}
-		else
-		{
-			// aktuelle DB
-			$text=isset($databases['db_actual']) ? $databases['db_actual'] : '';
-			if (isset($databases['db_selected_index']) && isset($databases['praefix'][$databases['db_selected_index']]) && $databases['praefix'][$databases['db_selected_index']] > '') $text.=" ('<i>" . $databases['praefix'][$databases['db_selected_index']] . "</i>')";
-			$aus['conf'].=table_output($lang['L_BACKUP_DBS_PHP'],$text);
-		}
+        // DB list for Perl
+        // Fallback if index is not yet set from old configuration files -> save all DBs
+        if (!isset($config['cron_dbindex'])) {
+            $config['cron_dbindex'] = -3;
+        }
+        if (-2 == $config['cron_dbindex']) {
+            $aus['conf'] .= table_output($lang['L_BACKUP_DBS_PERL'], $toolboxstring);
+        } elseif (-3 == $config['cron_dbindex']) {
+            $text = $lang['L_ALL'];
+            $aus['conf'] .= table_output($lang['L_BACKUP_DBS_PERL'], $text);
+        } else {
+            $text = isset($databases['Name'][$config['cron_dbindex']]) ? $databases['Name'][$config['cron_dbindex']] : '';
+            if (isset($databases['praefix'][$config['cron_dbindex']]) && $databases['praefix'][$config['cron_dbindex']] > '') {
+                $text .= " ('<i>".$databases['praefix'][$config['cron_dbindex']]."</i>')";
+            }
+            $aus['conf'] .= table_output($lang['L_BACKUP_DBS_PERL'], $text);
+        }
 
-		// DB-Liste fuer Perl
-		// Fallback falls aus alten Konfigurationsdateien der Index noch nicht gesetzt ist -> alle DBs sichern
-		if (!isset($config['cron_dbindex'])) $config['cron_dbindex']=-3;
-		if ($config['cron_dbindex'] == -2)
-		{
-			$aus['conf'].=table_output($lang['L_BACKUP_DBS_PERL'],$toolboxstring);
-		}
-		elseif ($config['cron_dbindex'] == -3)
-		{
-			$text=$lang['L_ALL'];
-			$aus['conf'].=table_output($lang['L_BACKUP_DBS_PERL'],$text);
-		}
-		else
-		{
-			$text=isset($databases['Name'][$config['cron_dbindex']]) ? $databases['Name'][$config['cron_dbindex']] : '';
-			if (isset($databases['praefix'][$config['cron_dbindex']]) && $databases['praefix'][$config['cron_dbindex']] > '') $text.=" ('<i>" . $databases['praefix'][$config['cron_dbindex']] . "</i>')";
-			$aus['conf'].=table_output($lang['L_BACKUP_DBS_PERL'],$text);
-		}
+        if (isset($config['multi_part']) && (1 == $config['multi_part'])) { // Multipart
+            $aus['conf'] .= table_output($lang['L_MULTI_PART'], $lang['L_YES'].', '.$lang['L_FILESIZE'].' '.byte_output($config['multipart_groesse']));
+        }
 
-		if ($config['multi_part'] == 1) // Multipart
-		{
-			$aus['conf'].=table_output($lang['L_MULTI_PART'],$lang['L_YES'] . ", " . $lang['L_FILESIZE'] . " " . byte_output($config['multipart_groesse']));
-		}
+        if (isset($config['send_mail']) && (1 == $config['send_mail'])) { // Email
+            $aus['conf'] .= table_output($lang['L_SEND_MAIL_FORM'], $lang['L_YES'].', '.$lang['L_EMAIL_ADRESS'].': '.$config['email_recipient']);
+            if ($config['email_recipient_cc'] > '') {
+                $aus['conf'] .= table_output($lang['L_EMAIL_CC'], $config['email_recipient_cc']);
+            }
+            $text = $lang['L_YES'].', '.$lang['L_MAX_UPLOAD_SIZE'].': ';
+            $bytes = $config['email_maxsize1'] * 1024;
+            if (2 == $config['email_maxsize2']) {
+                $bytes = $bytes * 1024;
+            }
+            $text .= byte_output($bytes);
+            if (1 == $config['send_mail_dump']) {
+                $aus['conf'] .= table_output($lang['L_SEND_MAIL_DUMP'], $text);
+            }
+        }
 
-		if ($config['send_mail'] == 1) //Email
-		{
-			$aus['conf'].=table_output($lang['L_SEND_MAIL_FORM'],$lang['L_YES'] . ", " . $lang['L_EMAIL_ADRESS'] . ": " . $config['email_recipient']);
-			if ($config['email_recipient_cc'] > '') $aus['conf'].=table_output($lang['L_EMAIL_CC'],$config['email_recipient_cc']);
-			$text=$lang['L_YES'] . ", " . $lang['L_MAX_UPLOAD_SIZE'] . ": ";
-			$bytes=$config['email_maxsize1'] * 1024;
-			if ($config['email_maxsize2'] == 2) $bytes=$bytes * 1024;
-			$text.=byte_output($bytes);
-			if ($config['send_mail_dump'] == 1) $aus['conf'].=table_output($lang['L_SEND_MAIL_DUMP'],$text);
+        for ($x = 0; $x < 3; ++$x) {
+            // FTP
+            if (isset($config['ftp_transfer'][$x]) && $config['ftp_transfer'][$x] > 0) {
+                $aus['conf'] .= table_output($lang['L_FTP'], sprintf($lang['L_FTP_SEND_TO'], $config['ftp_server'][$x], $config['ftp_dir'][$x]));
+            }
+            // SFTP
+            if (isset($config['sftp_transfer'][$x]) && $config['sftp_transfer'][$x] > 0) {
+                $aus['conf'] .= table_output($lang['L_SFTP'], sprintf($lang['L_SFTP_SEND_TO'], $config['sftp_server'][$x], $config['sftp_dir'][$x]));
+            }
+        }
+        $aus['conf'] .= '</table></td><td>';
+        $aus['conf'] .= '<a href="config_overview.php?config='.urlencode($c).'">'.$icon['edit'].'</a>';
 
-		}
+        if ('myoosdumper' != $c) { // && $old_config['config_file']!= $c)
+            $aus['conf'] .= '<a href="config_overview.php?config_delete='.urlencode($c).'" onclick="if(!confirm(\''.sprintf($lang['L_CONFIRM_CONFIGFILE_DELETE'], $c).'\')) return false;">'.$icon['delete'].'</a>';
+        } else {
+            $aus['conf'] .= '&nbsp;';
+        }
 
-		for ($x=0; $x < 3; $x++)
-		{
-			if (isset($config['ftp_transfer'][$x]) && $config['ftp_transfer'][$x] > 0)
-			{
-				//$aus['conf'].=table_output($lang['L_FTP'],sprintf($lang['L_FTP_SEND_TO'],$config['ftp_server'][$x],$config['ftp_dir'][$x]),1,2);
-				$aus['conf'].=table_output($lang['L_FTP'],sprintf($lang['L_FTP_SEND_TO'],$config['ftp_server'][$x],$config['ftp_dir'][$x]));
-			}
-		}
-		$aus['conf'].='</table></td><td>';
-		$aus['conf'].='<a href="config_overview.php?config=' . urlencode($c) . '">' . $icon['edit'] . '</a>';
-
-		if ($c != 'myoosdumper') // && $old_config['config_file']!=$c)
-$aus['conf'].='<a href="config_overview.php?config_delete=' . urlencode($c) . '" onclick="if(!confirm(\'' . sprintf($lang['L_CONFIRM_CONFIGFILE_DELETE'],$c) . '\')) return false;">' . $icon['delete'] . '</a>';
-		else $aus['conf'].='&nbsp;';
-
-		$aus['conf'].='</td></tr>';
-	}
+        $aus['conf'] .= '</td></tr>';
+    }
 }
 
-$configfile=$old_config['config_file'];
-$config=$old_config;
+$configfile = $old_config['config_file'];
+$config = $old_config;
 unset($databases);
-$databases=array();
+$databases = [];
 read_config($configfile);
 
-$aus['conf'].='</table>';
-$aus['conf'].='</fieldset></div>' . $nl . $nl;
+$aus['conf'] .= '</table>';
+$aus['conf'] .= '</fieldset></div>'.$nl.$nl;
 
-// Zugangsdaten
-$aus['db']='<div id="db"><fieldset><legend>' . $lang['L_CONNECTIONPARS'] . '</legend>' . $nl . $nl;
-$aus['db'].='<div id="VP" style="display:none;"';
-$aus['db'].='><table><tr><td>Host / User / Passwort:</td>';
-$aus['db'].='<td><input class="text" type="text" name="dbhost" value="' . $config['dbhost'] . '">&nbsp;&nbsp;/&nbsp;&nbsp;';
-$aus['db'].='<input class="text" type="text" name="dbuser" value="' . $config['dbuser'] . '" size="20">&nbsp;&nbsp;/&nbsp;&nbsp;';
-$aus['db'].='<input class="text" type="password" name="dbpass" value="' . $config['dbpass'] . '" size="20"></td></tr>';
-$aus['db'].='<tr><td colspan="2"><strong>' . $lang['L_EXTENDEDPARS'] . '</strong></td></tr>';
-$aus['db'].='<tr><td>Port / Socket:</td><td><input class="text" type="text" name="dbport" value="' . $config['dbport'] . '">&nbsp;&nbsp;/&nbsp;&nbsp;';
-$aus['db'].='<input class="text" type="text" name="dbsocket" value="' . $config['dbsocket'] . '"></td></tr>';
+// Access data
+$aus['db'] = '<div id="db"><fieldset><legend>'.$lang['L_CONNECTIONPARS'].'</legend>'.$nl.$nl;
+$aus['db'] .= '<div id="VP" style="display:none;"';
+$aus['db'] .= '><table><tr><td>Host / User / Passwort:</td>';
+$aus['db'] .= '<td><input class="text" type="text" name="dbhost" value="'.$config['dbhost'].'">&nbsp;&nbsp;/&nbsp;&nbsp;';
+$aus['db'] .= '<input class="text" type="text" name="dbuser" value="'.$config['dbuser'].'" size="20">&nbsp;&nbsp;/&nbsp;&nbsp;';
+$aus['db'] .= '<input class="text" type="password" name="dbpass" value="'.$config['dbpass'].'" size="20"></td></tr>';
+$aus['db'] .= '<tr><td colspan="2"><strong>'.$lang['L_EXTENDEDPARS'].'</strong></td></tr>';
+$aus['db'] .= '<tr><td>Port / Socket:</td><td><input class="text" type="text" name="dbport" value="'.$config['dbport'].'">&nbsp;&nbsp;/&nbsp;&nbsp;';
+$aus['db'] .= '<input class="text" type="text" name="dbsocket" value="'.$config['dbsocket'].'"></td></tr>';
 
-$aus['db'].='<tr><td>' . $lang['L_ADD_DB_MANUALLY'] . ':</td>';
-$aus['db'].='<td><input class="text" type="text" name="add_db_manual" value=""></td></tr>';
+$aus['db'] .= '<tr><td>'.$lang['L_ADD_DB_MANUALLY'].':</td>';
+$aus['db'] .= '<td><input class="text" type="text" name="add_db_manual" value=""></td></tr>';
 
-if (isset($add_db_message))
-{
-	$aus['db'].='<tr><td colspan="2" class="error">' . $add_db_message;
-	$aus['db'].='</td></tr>';
+if (isset($add_db_message)) {
+    $aus['db'] .= '<tr><td colspan="2" class="error">'.$add_db_message;
+    $aus['db'] .= '</td></tr>';
 }
-$aus['db'].='<tr><td colspan="2">' . print_save_button() . '</td></tr>';
+$aus['db'] .= '<tr><td colspan="2">'.print_save_button().'</td></tr>';
 
-$aus['db'].='</table></div><div><a class="small" href="#" onclick="SwitchVP();">' . $lang['L_FADE_IN_OUT'] . '</a></div></fieldset><fieldset><legend>' . $lang['L_DB_BACKUPPARS'] . '</legend>';
+$aus['db'] .= '</table></div><div><a class="small" href="#" onclick="SwitchVP();">'.$lang['L_FADE_IN_OUT'].'</a></div></fieldset><fieldset><legend>'.$lang['L_DB_BACKUPPARS'].'</legend>';
 
-$aus['db'].='<table>';
+$aus['db'] .= '<table>';
 
-//Wenn Datenbanken vorhanden sind
-if (isset($databases['Name'][0]) && $databases['Name'][0] > '')
-{
-	if (!isset($databases['multi']) || ( !is_array($databases['multi']) )) $databases['multi']=array();
-	if (count($databases['Name']) == 1)
-	{
-		$databases['db_actual']=$databases['Name'][0];
-		$databases['db_selected_index']=0;
-		$aus['db'].='<tr><td>' . Help($lang['L_HELP_DB'],"conf1") . $lang['L_LIST_DB'] . '</td>';
-		$aus['db'].='<td><strong>' . $databases['db_actual'] . '</strong></td></tr>';
-		$aus['db'].='<tr><td>' . Help($lang['L_HELP_PRAEFIX'],"conf2") . $lang['L_PRAEFIX'] . '</td><td><input type="text" class="text" name="dbpraefix_' . $databases['db_selected_index'] . '" size="10" value="' . $databases['praefix'][$databases['db_selected_index']] . '"></td></tr>';
-		$aus['db'].='<tr><td>' . Help($lang['L_HELP_COMMANDS'],"") . 'Command before Dump</td><td>' . ComboCommandDump(0,$databases['db_selected_index']) . '</td></tr>';
-		$aus['db'].='<tr><td>' . Help($lang['L_HELP_COMMANDS'],"") . 'Command after Dump</td><td>' . ComboCommandDump(1,$databases['db_selected_index']) . '</td>';
-		$aus['db'].='<td><a href="sql.php?context=1">' . $lang['L_SQL_BEFEHLE'] . '</a></td>';
-		$aus['db'].='</tr>';
-	}
-	else
-	{
+// If databases are available
+if (isset($databases['Name'][0]) && $databases['Name'][0] > '') {
+    if (!isset($databases['multi']) || (!is_array($databases['multi']))) {
+        $databases['multi'] = [];
+    }
+    if (1 == count($databases['Name'])) {
+        $databases['db_actual'] = $databases['Name'][0];
+        $databases['db_selected_index'] = 0;
+        $aus['db'] .= '<tr><td>'.Help($lang['L_HELP_DB'], 'conf1').$lang['L_LIST_DB'].'</td>';
+        $aus['db'] .= '<td><strong>'.$databases['db_actual'].'</strong></td></tr>';
+        $aus['db'] .= '<tr><td>'.Help($lang['L_HELP_PRAEFIX'], 'conf2').$lang['L_PRAEFIX'].'</td><td><input type="text" class="text" name="dbpraefix_'.$databases['db_selected_index'].'" size="10" value="'.$databases['praefix'][$databases['db_selected_index']].'"></td></tr>';
+        $aus['db'] .= '<tr><td>'.Help($lang['L_HELP_COMMANDS'], '').'Command before Dump</td><td>'.ComboCommandDump(0, $databases['db_selected_index']).'</td></tr>';
+        $aus['db'] .= '<tr><td>'.Help($lang['L_HELP_COMMANDS'], '').'Command after Dump</td><td>'.ComboCommandDump(1, $databases['db_selected_index']).'</td>';
+        $aus['db'] .= '<td><a href="sql.php?context=1">'.$lang['L_SQL_BEFEHLE'].'</a></td>';
+        $aus['db'] .= '</tr>';
+    } else {
         $disabled = '';
-        if (in_array($databases['db_actual'], $dontBackupDatabases)) $disabled = ' disabled="disabled"';
+        if (in_array($databases['db_actual'], $dontBackupDatabases)) {
+            $disabled = ' disabled="disabled"';
+        }
 
-		$aus['db'].='<tr><td>' . Help($lang['L_HELP_DB'],"conf1") . $lang['L_LIST_DB'] . '</td><td><input type="checkbox" class="checkbox" name="MultiDBDump" value="1" ' . ( ( $config['multi_dump'] == 1 ) ? "CHECKED" : "" ) . '>&nbsp;' . $lang['L_ACTIVATE_MULTIDUMP'] . '</td>';
-		$aus['db'].='<tr><td colspan="2"><table class="bdr">';
-		$aus['db'].='<tr class="thead"><th>' . $lang['L_DB'] . '</th><th>Multidump<br><span class="ssmall">(<a href="javascript:SelectMD(true,' . count($databases['Name']) . ')" class="small">' . $lang['L_ALL'] . '</a>&nbsp;<a href="javascript:SelectMD(false,' . count($databases['Name']) . ')" class="small">' . $lang['L_NONE'] . '</a>)</span></th>';
-		$aus['db'].='<th>' . Help($lang['L_HELP_PRAEFIX'],"conf2") . $lang['L_PRAEFIX'] . '</th><th>' . Help($lang['L_HELP_COMMANDS'],"",11) . 'Command before Dump</th><th>' . Help($lang['L_HELP_COMMANDS'],"",11) . 'Command after Dump</th><th>' . $lang['L_SQL_BEFEHLE'] . '</th></tr>';
+        $aus['db'] .= '<tr><td>'.Help($lang['L_HELP_DB'], 'conf1').$lang['L_LIST_DB'].'</td><td><input type="checkbox" class="checkbox" name="MultiDBDump" value="1" '.((isset($config['multi_dump']) && (1 == $config['multi_dump'])) ? 'CHECKED' : '').'>&nbsp;'.$lang['L_ACTIVATE_MULTIDUMP'].'</td>';
+        $aus['db'] .= '<tr><td colspan="2"><table class="bdr">';
+        $aus['db'] .= '<tr class="thead"><th>'.$lang['L_DB'].'</th><th>Multidump<br><span class="ssmall">(<a href="javascript:SelectMD(true,'.count($databases['Name']).')" class="small">'.$lang['L_ALL'].'</a>&nbsp;<a href="javascript:SelectMD(false,'.count($databases['Name']).')" class="small">'.$lang['L_NONE'].'</a>)</span></th>';
+        $aus['db'] .= '<th>'.Help($lang['L_HELP_PRAEFIX'], 'conf2').$lang['L_PRAEFIX'].'</th><th>'.Help($lang['L_HELP_COMMANDS'], '', 11).'Command before Dump</th><th>'.Help($lang['L_HELP_COMMANDS'], '', 11).'Command after Dump</th><th>'.$lang['L_SQL_BEFEHLE'].'</th></tr>';
 
-		//erst die aktuelle DB
-		$aus['db'].='<tr class="dbrowsel"><td><strong>' . $databases['db_actual'] . '</strong></td>';
-		$aus['db'].='<td align="center"><input type="checkbox" class="checkbox" name="db_multidump_' . $databases['db_selected_index'] . '" value="db_multidump_' . $databases['db_selected_index'] . '" ' . ( ( in_array($databases['db_actual'],$databases['multi']) ) ? "CHECKED" : "" );
-		$aus['db'].= $disabled . '></td>';
-		$aus['db'].='<td><img src="' . $icon['blank'] . '" width="40" height="1" alt=""><input type="text" class="text" name="dbpraefix_' . $databases['db_selected_index'] . '" size="10" value="'
-		  . $databases['praefix'][$databases['db_selected_index']] . '"' . $disabled . '></td>';
-		$aus['db'].='<td>' . ComboCommandDump(0,$databases['db_selected_index'], $disabled)
-		  . '</td><td>' . ComboCommandDump(1,$databases['db_selected_index'], $disabled) . '</td>';
-		$aus['db'].='<td><a href="sql.php?context=1">' . $lang['L_SQL_BEFEHLE'] . '</a></td>';
-		$aus['db'].='</tr>';
+        //erst die aktuelle DB
+        $aus['db'] .= '<tr class="dbrowsel"><td><strong>'.$databases['db_actual'].'</strong></td>';
+        $aus['db'] .= '<td align="center"><input type="checkbox" class="checkbox" name="db_multidump_'.$databases['db_selected_index'].'" value="db_multidump_'.$databases['db_selected_index'].'" '.((in_array($databases['db_actual'], $databases['multi'])) ? 'CHECKED' : '');
+        $aus['db'] .= $disabled.'></td>';
+        $aus['db'] .= '<td><input type="text" class="text" name="dbpraefix_'.$databases['db_selected_index'].'" size="10" value="'
+                .$databases['praefix'][$databases['db_selected_index']].'"'.$disabled.'></td>';
+        $aus['db'] .= '<td>'.ComboCommandDump(0, $databases['db_selected_index'], $disabled)
+               .'</td><td>'.ComboCommandDump(1, $databases['db_selected_index'], $disabled).'</td>';
+        $aus['db'] .= '<td><a href="sql.php?context=1">'.$lang['L_SQL_BEFEHLE'].'</a></td>';
+        $aus['db'] .= '</tr>';
 
-		$dbacombo=$dbbcombo="";
-		$j=0;
-		for ($i=0; $i < count($databases['Name']); $i++)
-		{
-			if ($i != $databases['db_selected_index'])
-			{
-				$j++;
-				$disabled = '';
-                if (in_array($databases['Name'][$i], $dontBackupDatabases)) $disabled = ' disabled="disabled"';
-				if (!isset($databases['praefix'][$i])) $databases['praefix'][$i] = '';
-				$aus['db'].='<tr class="' . ( ( $i % 2 ) ? 'dbrow' : 'dbrow1' ) . '"><td>' . $databases['Name'][$i] . '</td>';
-				$aus['db'].='<td align="center"><input type="checkbox" class="checkbox" name="db_multidump_' . $i . '" value="db_multidump_' . $i . '" ' . ( ( in_array($databases['Name'][$i],$databases['multi']) ) ? "CHECKED" : "" );
-				$aus['db'] .= $disabled.'></td>';
-				$aus['db'].='<td><img src="' . $icon['blank'] . '" width="40" height="1" alt=""><input type="text" class="text" name="dbpraefix_' . $i . '" size="10" value="'
-				    . $databases['praefix'][$i] . '"';
+        $dbacombo = $dbbcombo = '';
+        $j = 0;
+        for ($i = 0; $i < count($databases['Name']); ++$i) {
+            if ($i != $databases['db_selected_index']) {
+                ++$j;
+                $disabled = '';
+                if (in_array($databases['Name'][$i], $dontBackupDatabases)) {
+                    $disabled = ' disabled="disabled"';
+                }
+                if (!isset($databases['praefix'][$i])) {
+                    $databases['praefix'][$i] = '';
+                }
+                $aus['db'] .= '<tr class="'.(($i % 2) ? 'dbrow' : 'dbrow1').'"><td>'.$databases['Name'][$i].'</td>';
+                $aus['db'] .= '<td align="center"><input type="checkbox" class="checkbox" name="db_multidump_'.$i.'" value="db_multidump_'.$i.'" '.((in_array($databases['Name'][$i], $databases['multi'])) ? 'CHECKED' : '');
+                $aus['db'] .= $disabled.'></td>';
+                $aus['db'] .= '<td><input type="text" class="text" name="dbpraefix_'.$i.'" size="10" value="'
+                        .$databases['praefix'][$i].'"';
 
-				$aus['db'] .= $disabled . '></td><td>' . ComboCommandDump(0,$i, $disabled) . '</td><td>'
-				    . ComboCommandDump(1,$i, $disabled) . '</td>';
-				$aus['db'].='<td><a href="sql.php?context=1">' . $lang['L_SQL_BEFEHLE'] . '</a></td>';
-				$aus['db'].='</tr>';
-			}
-		}
-	}
+                $aus['db'] .= $disabled.'></td><td>'.ComboCommandDump(0, $i, $disabled).'</td><td>'
+                        .ComboCommandDump(1, $i, $disabled).'</td>';
+                $aus['db'] .= '<td><a href="sql.php?context=1">'.$lang['L_SQL_BEFEHLE'].'</a></td>';
+                $aus['db'] .= '</tr>';
+            }
+        }
+    }
+} else {
+    $aus['db'] .= '<tr><td>'.$lang['L_NO_DB_FOUND'].'</td></tr>';
 }
-else
-	$aus['db'].='<tr><td>' . $lang['L_NO_DB_FOUND'] . '</td></tr>';
-$aus['db'].='</table></td></tr>';
-$aus['db'].='</table></fieldset></div>';
+$aus['db'] .= '</table></td></tr>';
+$aus['db'] .= '</table></fieldset></div>';
 
 // sonstige Einstellungen
-$aus['global1']='<div id="global1"><fieldset><legend>' . $lang['L_GENERAL'] . '</legend><table>';
+$aus['global1'] = '<div id="global1"><fieldset><legend>'.$lang['L_GENERAL'].'</legend><table>';
 
-$aus['global1'].='<tr><td>' . Help("","") . 'Logfiles:&nbsp;</td>';
-$aus['global1'].='<td><input type="checkbox" class="checkbox" value="1" name="logcompression" ' . ( ( $config['zlib'] ) ? '' : 'disabled' ) . ( ( $config['logcompression'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_COMPRESSED'] . '<br>';
-$aus['global1'].='' . $lang['L_MAXSIZE'] . ':&nbsp;&nbsp;<input type="text" class="text" name="log_maxsize1" size="3" maxlength="3" value="' . $config['log_maxsize1'] . '">&nbsp;&nbsp;';
-$aus['global1'].='<select name="log_maxsize2"><option value="1" ' . ( ( $config['log_maxsize2'] == 1 ) ? ' SELECTED' : '' ) . '>Kilobytes</option>';
-$aus['global1'].='<option value="2" ' . ( ( $config['log_maxsize2'] == 2 ) ? ' SELECTED' : '' ) . '>Megabytes</option></select></td></tr>';
+$aus['global1'] .= '<tr><td>'.Help('', '').'Logfiles:&nbsp;</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="logcompression" '.(($config['zlib']) ? '' : 'disabled').((isset($config['logcompression']) && (1 == $config['logcompression'])) ? ' checked' : '').'>&nbsp;'.$lang['L_COMPRESSED'].'<br>';
+$aus['global1'] .= ''.$lang['L_MAXSIZE'].':&nbsp;&nbsp;<input type="text" class="text" name="log_maxsize1" size="3" maxlength="3" style="text-align:right;" value="'.((isset($config['log_maxsize1'])) ? $config['log_maxsize1'] : '').'">&nbsp;&nbsp;';
+$aus['global1'] .= '<select name="log_maxsize2"><option value="1" '.((isset($config['log_maxsize2']) && (1 == $config['log_maxsize2'])) ? ' SELECTED' : '').'>Kilobytes</option>';
+$aus['global1'] .= '<option value="2" '.((isset($config['log_maxsize2']) && (2 == $config['log_maxsize2'])) ? ' SELECTED' : '').'>Megabytes</option></select>';
+$aus['global1'] .= '</td></tr>';
 
-$aus['global1'].='<tr><td>' . Help($lang['L_HELP_MEMORYLIMIT'],"") . $lang['L_MEMORY_LIMIT'] . ':&nbsp;&nbsp;</td>';
-$aus['global1'].='<td>';
-$aus['global1'].='<input type="text" class="text" size="10" id="mlimit" name="memory_limit" maxlength="10" style="text-align:right;font-size:11px;" value="' . $config['memory_limit'] . '"> Bytes&nbsp;&nbsp;&nbsp;<a href="#" onclick="WriteMem();" class="small">' . $lang['L_AUTODETECT'] . '</a>';
-$aus['global1'].='</td></tr>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_MEMORYLIMIT'], '').$lang['L_MEMORY_LIMIT'].':&nbsp;&nbsp;</td>';
+$aus['global1'] .= '<td><input type="text" class="text" size="10" id="mlimit" name="memory_limit" maxlength="10" style="text-align:right;font-size:11px;" value="'.((isset($config['memory_limit'])) ? $config['memory_limit'] : '').'"> Bytes&nbsp;&nbsp;&nbsp;<a href="#" onclick="WriteMem();" class="small">'.$lang['L_AUTODETECT'].'</a>';
+$aus['global1'] .= '</td></tr>';
 
-$aus['global1'].='<tr><td>' . Help($lang['L_HELP_SPEED'],"") . $lang['L_SPEED'] . ':&nbsp;</td>';
-$aus['global1'].='<td><input type="text" class="text" size="6" name="minspeed" maxlength="6" style="text-align:right;" value="' . $config['minspeed'] . '">&nbsp;' . $lang['L_TO'] . '&nbsp;<input type="text" class="text" size="6" name="maxspeed" maxlength="9" style="text-align:right;" value="' . $config['maxspeed'] . '"></td></tr>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_SPEED'], '').$lang['L_SPEED'].':&nbsp;</td>';
+$aus['global1'] .= '<td><input type="text" class="text" size="6" name="minspeed" maxlength="6" style="text-align:right;" value="'.((isset($config['minspeed'])) ? $config['minspeed'] : '').'">&nbsp;'.$lang['L_TO'].'&nbsp;<input type="text" class="text" size="6" name="maxspeed" maxlength="9" style="text-align:right;" value="'.((isset($config['maxspeed'])) ? $config['maxspeed'] : '').'"></td></tr>';
 
-$aus['global1'].='</table></fieldset><fieldset><legend>' . $lang['L_DUMP'] . '</legend><table>';
+$aus['global1'] .= '</table></fieldset><fieldset><legend>'.$lang['L_DUMP'].'</legend><table>';
 
-$aus['global1'].='<tr><td>' . Help($lang['L_HELP_ZIP'],"conf3") . $lang['L_GZIP'] . ':&nbsp;</td>';
-$aus['global1'].='<td><input type="radio" class="radio" value="1" name="compression" ' . ( ( $config['zlib'] ) ? '' : 'disabled' ) . ( ( $config['compression'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_ACTIVATED'];
-$aus['global1'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="compression" ' . ( ( $config['compression'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NOT_ACTIVATED'] . '</td></tr>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_ZIP'], 'conf3').$lang['L_GZIP'].':&nbsp;</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="compression" '.(($config['zlib']) ? '' : 'disabled').((isset($config['compression']) && (1 == $config['compression'])) ? ' checked' : '').'>';
+$aus['global1'] .= '</td></tr>';
 //Multipart-Backup -->
-$aus['global1'].='<tr><td>' . Help($lang['L_HELP_MULTIPART'],"") . $lang['L_MULTI_PART'] . ':&nbsp;</td><td>';
-$aus['global1'].='<input type="radio" class="radio" value="1" name="multi_part" onclick="obj_enable(\'multipartgroesse1\');obj_enable(\'multipartgroesse2\');" ' . ( ( $config['multi_part'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['global1'].='&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="multi_part" onclick="obj_disable(\'multipartgroesse1\');obj_disable(\'multipartgroesse2\');" ' . ( ( $config['multi_part'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'];
-$aus['global1'].='</td></tr><tr><td>' . Help($lang['L_HELP_MULTIPARTGROESSE'],"") . $lang['L_MULTI_PART_GROESSE'] . ':&nbsp;</td>';
-$aus['global1'].='<td>&nbsp;';
 
-$aus['global1'].='<input type="text" class="text" id="multipartgroesse1" name="multipartgroesse1" size="3" maxlength="8" value="' . $config['multipartgroesse1'] . '"';
-if ($config['multi_part'] == 0) $aus['global1'].=' disabled';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_MULTIPART'], '').$lang['L_MULTI_PART'].':&nbsp;</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="multi_part" onclick="obj_disable(\'multipartgroesse1\', this.checked);obj_disable(\'multipartgroesse2\', this.checked);" '.((isset($config['multi_part']) && (1 == $config['multi_part'])) ? ' checked' : '').'>';
+$aus['global1'] .= '</td></tr>';
 
-$aus['global1'].='>&nbsp;&nbsp;';
-$aus['global1'].='<select id="multipartgroesse2" name="multipartgroesse2"';
-if ($config['multi_part'] == 0) $aus['global1'].=' disabled';
-$aus['global1'].='><option value="1" ' . ( ( $config['multipartgroesse2'] == 1 ) ? 'SELECTED' : '' ) . '>Kilobytes</option><option value="2" ' . ( ( $config['multipartgroesse2'] == 2 ) ? 'SELECTED' : '' ) . '>Megabytes</option></select></td></tr>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_MULTIPARTGROESSE'], '').$lang['L_MULTI_PART_GROESSE'].':&nbsp;</td>';
+$aus['global1'] .= '<td><input type="text" class="text" id="multipartgroesse1" name="multipartgroesse1" size="3" maxlength="8" style="text-align:right;" value="'.((isset($config['multipartgroesse1'])) ? $config['multipartgroesse1'] : '').'"';
+if (isset($config['multi_part']) && (0 == $config['multi_part'])) {
+    $aus['global1'] .= ' disabled';
+}
 
-$aus['global1'].='<tr><td>' . Help($lang['L_HELP_OPTIMIZE'],"") . $lang['L_OPTIMIZE'] . ':</td>';
-$aus['global1'].='<td><input type="radio" class="radio" value="1" name="optimize_tables" ' . ( ( $config['optimize_tables_beforedump'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_ACTIVATED'];
-$aus['global1'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="optimize_tables" ' . ( ( $config['optimize_tables_beforedump'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NOT_ACTIVATED'] . '</td></tr>';
+$aus['global1'] .= '>&nbsp;&nbsp;';
+$aus['global1'] .= '<select id="multipartgroesse2" name="multipartgroesse2"';
+if (isset($config['multi_part']) && (0 == $config['multi_part'])) {
+    $aus['global1'] .= ' disabled';
+}
+$aus['global1'] .= '><option value="1" '.((1 == $config['multipartgroesse2']) ? 'SELECTED' : '').'>Kilobytes</option><option value="2" '.((2 == $config['multipartgroesse2']) ? 'SELECTED' : '').'>Megabytes</option></select>';
+$aus['global1'] .= '</td></tr>';
 
-$aus['global1'].='</table></fieldset><fieldset><legend>' . $lang['L_RESTORE'] . '</legend><table>';
-$aus['global1'].='<tr><td>' . Help($lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'],"conf4") . $lang['L_EMPTY_DB_BEFORE_RESTORE'] . ':&nbsp;</td><td>';
-$aus['global1'].='<input type="radio" class="radio" value="1" name="empty_db_before_restore" ' . ( ( $config['empty_db_before_restore'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['global1'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="empty_db_before_restore" ' . ( ( $config['empty_db_before_restore'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'];
-$aus['global1'].='</td></tr>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_OPTIMIZE'], '').$lang['L_OPTIMIZE'].':</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="optimize_tables" '.((isset($config['optimize_tables_beforedump']) && (1 == $config['optimize_tables_beforedump'])) ? ' checked' : '').'>';
+$aus['global1'] .= '</td></tr>';
 
-$aus['global1'].='<tr><td>' . Help("","") . $lang['L_ERRORHANDLING_RESTORE'] . ':</td><td>';
-$aus['global1'].='<input type="radio" class="radio" name="stop_with_error" value="0" ' . ( ( $config['stop_with_error'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_EHRESTORE_CONTINUE'] . '<br>';
-$aus['global1'].='<input type="radio" class="radio" name="stop_with_error" value="1" ' . ( ( $config['stop_with_error'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_EHRESTORE_STOP'];
-$aus['global1'].='</td></tr>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_BINARY'], '').$lang['L_BINARY'].':</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="binary_container" '.((isset($config['use_binary_container']) && (1 == $config['use_binary_container'])) ? ' checked' : '').'>';
+$aus['global1'] .= '</td></tr>';
+
+$aus['global1'] .= '</table></fieldset><fieldset><legend>'.$lang['L_RESTORE'].'</legend><table>';
+$aus['global1'] .= '<tr><td>'.Help($lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'], 'conf4').$lang['L_EMPTY_DB_BEFORE_RESTORE'].':&nbsp;</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="empty_db_before_restore" '.((isset($config['empty_db_before_restore']) && (1 == $config['empty_db_before_restore'])) ? ' checked' : '').'>';
+$aus['global1'] .= '</td></tr>';
+
+$aus['global1'] .= '<tr><td>'.Help('', '').$lang['L_ERRORHANDLING_RESTORE'].':</td>';
+$aus['global1'] .= '<td><input type="radio" class="radio" name="stop_with_error" value="0" '.((isset($config['stop_with_error']) && (0 == $config['stop_with_error'])) ? ' checked' : '').'>&nbsp;'.$lang['L_EHRESTORE_CONTINUE'];
+$aus['global1'] .= '&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" name="stop_with_error" value="1" '.((isset($config['stop_with_error']) && (1 == $config['stop_with_error'])) ? ' checked' : '').'>&nbsp;'.$lang['L_EHRESTORE_STOP'];
+$aus['global1'] .= '</td></tr>';
 
 if (!isset($config['ignore_enable_keys'])) {
     $config['ignore_enable_keys'] = 0;
 }
-$aus['global1'].='<tr><td>Ignore "ENABLE KEYS":</td><td>';
-$aus['global1'].='<input type="radio" class="radio" name="ignore_enable_keys" value="1" ' . ( ( $config['ignore_enable_keys'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['global1'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" name="ignore_enable_keys" value="0" ' . ( ( $config['ignore_enable_keys'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'];
-$aus['global1'].='</td></tr>';
+$aus['global1'] .= '<tr><td>Ignore "ENABLE KEYS":</td>';
+$aus['global1'] .= '<td><input type="checkbox" class="checkbox" name="ignore_enable_keys" value="1" '.((isset($config['ignore_enable_keys']) && (1 == $config['ignore_enable_keys'])) ? ' checked' : '').'>';
+$aus['global1'] .= '</td></tr>';
 
-$aus['global1'].='</table></fieldset>';
-$aus['global1'].=print_save_button();
-$aus['global1'].='</div>';
+$aus['global1'] .= '</table></fieldset>';
+$aus['global1'] .= print_save_button();
+$aus['global1'] .= '</div>';
 
 //Interface -->
-$aus['global3']='<div id="global3"><fieldset><legend>' . $lang['L_CONFIG_INTERFACE'] . '</legend><table>';
-$aus['global3'].='<tr><td>' . Help($lang['L_HELP_LANG'],"conf11") . $lang['L_LANGUAGE'] . ':&nbsp;</td>';
-$aus['global3'].='<td><select name="language">' . GetLanguageCombo("op");
-$aus['global3'].='</select><input type="hidden" name="lang_old" value="' . $config['language'] . '"><input type="hidden" name="scaption_old" value="' . $config['interface_server_caption'] . '"></td></tr>';
+$aus['global3'] = '<div id="global3"><fieldset><legend>'.$lang['L_CONFIG_INTERFACE'].'</legend><table>';
+$aus['global3'] .= '<tr><td>'.Help($lang['L_HELP_LANG'], 'conf11').$lang['L_LANGUAGE'].':&nbsp;</td>';
+$aus['global3'] .= '<td><select name="language">'.GetLanguageCombo('op');
 
-$aus['global3'].='<tr><td>' . Help($lang['L_HELP_SERVERCAPTION'],"") . $lang['L_SERVERCAPTION'] . ':</td>';
-$aus['global3'].='<td><input type="checkbox" class="checkbox" value="1" name="server_caption" ' . ( ( $config['interface_server_caption'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_ACTIVATED'] . '&nbsp;&nbsp;&nbsp;';
-$aus['global3'].='<input type="radio" class="radio" name="server_caption_position" value="1" ' . ( ( $config['interface_server_caption_position'] == 1 ) ? "checked" : "" ) . '>&nbsp;' . $lang['L_IN_MAINFRAME'] . '&nbsp;&nbsp;<input type="radio" class="radio" name="server_caption_position" value="0" ' . ( ( $config['interface_server_caption_position'] == 0 ) ? "checked" : "" ) . '>&nbsp;' . $lang['L_IN_LEFTFRAME'] . '';
-$aus['global3'].='</td></tr>';
-$aus['global3'].='<tr><td>' . Help("","") . 'Theme:</td><td><select name="theme">' . GetThemes() . '</select></td></tr>';
+$config['interface_server_caption'] = isset($config['interface_server_caption']) ? $config['interface_server_caption'] : '';
+$aus['global3'] .= '</select><input type="hidden" name="lang_old" value="'.$config['language'].'"><input type="hidden" name="scaption_old" value="'.$config['interface_server_caption'].'"></td></tr>';
 
-$aus['global3'].='</table></fieldset><fieldset><legend>' . $lang['L_SQL_BROWSER'] . '</legend><table>';
-$aus['global3'].='<tr><td>' . Help("","") . $lang['L_SQLBOXHEIGHT'] . ':&nbsp;</td>';
-$aus['global3'].='<td><input type="text" class="text" name="sqlboxsize" value="' . $config['interface_sqlboxsize'] . '" size="3" maxlength="3">&nbsp;Pixel</td></tr>';
-$aus['global3'].='<tr><td>' . Help("","") . $lang['L_SQLLIMIT'] . ':&nbsp;</td>';
-$aus['global3'].='<td><input type="text" class="text" name="sql_limit" value="' . $config['sql_limit'] . '" size="3" maxlength="6">&nbsp;</td></tr>';
-$aus['global3'].='<tr><td>' . Help("","") . $lang['L_BBPARAMS'] . ':&nbsp;</td>';
-$aus['global3'].='<td>';
-$aus['global3'].='<table><tr><td>' . $lang['L_WIDTH'] . ':</td><td><input type="text" class="text" name="bb_width" value="' . $config['bb_width'] . '" size="3" maxlength="3">&nbsp;pixel</td></tr>';
-$aus['global3'].='<tr><td>' . $lang['L_BBTEXTCOLOR'] . ':&nbsp;</td>';
-$aus['global3'].='<td><select name="bb_textcolor">
-<option value="#000000" style="color :#000000;" ' . ( ( $config['bb_textcolor'] == "#000000" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
-<option value="#000066" style="color :#000066;" ' . ( ( $config['bb_textcolor'] == "#000066" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
-<option value="#800000" style="color :#800000;" ' . ( ( $config['bb_textcolor'] == "#800000" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
-<option value="#990000" style="color :#990000;" ' . ( ( $config['bb_textcolor'] == "#990000" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
-<option value="#006600" style="color :#006600;" ' . ( ( $config['bb_textcolor'] == "#006600" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
-<option value="#996600" style="color :#996600;" ' . ( ( $config['bb_textcolor'] == "#996600" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
-<option value="#999999" style="color :#999999;" ' . ( ( $config['bb_textcolor'] == "#999999" ? ' selected="selected"' : "" ) ) . '>&nbsp;Textcolor&nbsp;</option>
+$aus['global3'] .= '<tr><td>'.Help($lang['L_HELP_SERVERCAPTION'], '').$lang['L_SERVERCAPTION'].':</td>';
+$aus['global3'] .= '<td><input type="checkbox" class="checkbox" value="1" name="server_caption" '.((isset($config['interface_server_caption']) && (1 == $config['interface_server_caption'])) ? ' checked' : '').'><br>';
+$aus['global3'] .= '<input type="radio" class="radio" name="server_caption_position" value="1" '.((isset($config['interface_server_caption_position']) && (1 == $config['interface_server_caption_position'])) ? 'checked' : '').'>&nbsp;'.$lang['L_IN_MAINFRAME'].'&nbsp;&nbsp;<input type="radio" class="radio" name="server_caption_position" value="0" '.((isset($config['interface_server_caption_position']) && (0 == $config['interface_server_caption_position'])) ? 'checked' : '').'>&nbsp;'.$lang['L_IN_LEFTFRAME'].'';
+$aus['global3'] .= '</td></tr>';
+
+$aus['global3'] .= '<tr><td>'.Help('', '').'Theme:</td><td><select name="theme">'.GetThemes().'</select></td></tr>';
+
+$aus['global3'] .= '</table></fieldset><fieldset><legend>'.$lang['L_SQL_BROWSER'].'</legend><table>';
+$aus['global3'] .= '<tr><td>'.Help('', '').$lang['L_SQLBOXHEIGHT'].':&nbsp;</td>';
+
+$config['interface_sqlboxsize'] = isset($config['interface_sqlboxsize']) ? $config['interface_sqlboxsize'] : '';
+$aus['global3'] .= '<td><input type="text" class="text" name="sqlboxsize" style="text-align:right;" value="'.$config['interface_sqlboxsize'].'" size="3" maxlength="3">&nbsp;Pixel</td></tr>';
+
+$aus['global3'] .= '<tr><td>'.Help('', '').$lang['L_SQLLIMIT'].':&nbsp;</td>';
+$aus['global3'] .= '<td><input type="text" class="text" name="sql_limit" style="text-align:right;" value="'.$config['sql_limit'].'" size="3" maxlength="6">&nbsp;</td></tr>';
+$aus['global3'] .= '<tr><td>'.Help('', '').$lang['L_BBPARAMS'].':&nbsp;</td>';
+$aus['global3'] .= '<td>';
+$aus['global3'] .= '<table><tr><td>'.$lang['L_WIDTH'].':</td><td><input type="text" class="text" name="bb_width" style="text-align:right;" value="'.$config['bb_width'].'" size="3" maxlength="3">&nbsp;pixel</td></tr>';
+$aus['global3'] .= '<tr><td>'.$lang['L_BBTEXTCOLOR'].':&nbsp;</td>';
+$aus['global3'] .= '<td><select name="bb_textcolor">
+<option value="#000000" style="color :#000000;" '.(('#000000' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
+<option value="#000066" style="color :#000066;" '.(('#000066' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
+<option value="#800000" style="color :#800000;" '.(('#800000' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
+<option value="#990000" style="color :#990000;" '.(('#990000' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
+<option value="#006600" style="color :#006600;" '.(('#006600' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
+<option value="#996600" style="color :#996600;" '.(('#996600' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
+<option value="#999999" style="color :#999999;" '.(('#999999' == $config['bb_textcolor'] ? ' selected="selected"' : '')).'>&nbsp;Textcolor&nbsp;</option>
 </select></td></tr></table>';
-$aus['global3'].='</td></tr><tr><td>' . Help("","") . 'SQL-Grid:&nbsp;</td>';
-$aus['global3'].='<td><input type="radio" class="radio" name="interface_table_compact" value="0" ' . ( ( $config['interface_table_compact'] == 0 ) ? 'checked' : '' ) . '>&nbsp;normal&nbsp;&nbsp;&nbsp;';
-$aus['global3'].='<input type="radio" class="radio" name="interface_table_compact" value="1" ' . ( ( $config['interface_table_compact'] == 1 ) ? 'checked' : '' ) . '>&nbsp;compact</td></tr>';
+$aus['global3'] .= '</td></tr><tr><td>'.Help('', '').'SQL-Grid:&nbsp;</td>';
+$aus['global3'] .= '<td><input type="radio" class="radio" name="interface_table_compact" value="0" '.((isset($config['interface_table_compact']) && (0 == $config['interface_table_compact'])) ? 'checked' : '').'>&nbsp;normal&nbsp;&nbsp;&nbsp;';
+$aus['global3'] .= '<input type="radio" class="radio" name="interface_table_compact" value="1" '.((isset($config['interface_table_compact']) && (1 == $config['interface_table_compact'])) ? 'checked' : '').'>&nbsp;compact</td></tr>';
 
-$aus['global3'].='</table></fieldset>' . print_save_button() . '</div>';
+$aus['global3'] .= '</table></fieldset>'.print_save_button().'</div>';
 
-//automatisches L&ouml;schen-->
-$aus['global2']='<div id="global2"><fieldset><legend>' . $lang['L_CONFIG_AUTODELETE'] . '</legend><table>';
-$aus['global2'].='<tr><td>' . Help($lang['L_HELP_AD1'],"conf8") . $lang['L_AUTODELETE'] . ':&nbsp;</td>';
-$aus['global2'].='<td><input type="radio" class="radio" value="1" name="auto_delete" ' . ( ( $config['auto_delete'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_ACTIVATED'];
-$aus['global2'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="auto_delete" ' . ( ( $config['auto_delete'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NOT_ACTIVATED'];
-$aus['global2'].='</td>';
-$aus['global2'].='</tr><tr><td>' . Help($lang['L_HELP_AD3'],"conf10") . $lang['L_NUMBER_OF_FILES_FORM'] . ':&nbsp;</td>';
-$aus['global2'].='<td><input type="text" class="text" size="3" name="max_backup_files" value="' . $config['max_backup_files'] . '">   ';
-$aus['global2'].='</td></tr></table></fieldset>' . print_save_button() . '</div>';
+//automatic delete-->
+$aus['global2'] = '<div id="global2"><fieldset><legend>'.$lang['L_CONFIG_AUTODELETE'].'</legend><table>';
+$aus['global2'] .= '<tr><td>'.Help($lang['L_HELP_AD1'], 'conf8').$lang['L_AUTODELETE'].':&nbsp;</td>';
+$aus['global2'] .= '<td><input type="checkbox" class="checkbox" value="1" name="auto_delete" '.((isset($config['auto_delete']) && (1 == $config['auto_delete'])) ? ' checked' : '').'>';
+$aus['global2'] .= '</td></tr>';
+
+$aus['global2'] .= '<tr><td>'.Help($lang['L_HELP_AD3'], 'conf10').$lang['L_NUMBER_OF_FILES_FORM'].':&nbsp;</td>';
+$aus['global2'] .= '<td><input type="text" class="text" size="3" name="max_backup_files" style="text-align:right;" value="'.((isset($config['max_backup_files'])) ? $config['max_backup_files'] : '').'">   ';
+$aus['global2'] .= '</td></tr></table></fieldset>'.print_save_button().'</div>';
 
 //Email-->
-if (!isset($config['email_recipient_cc'])) $config['email_recipient_cc']=''; // backwards compatibility if field is undefined
-$aus['transfer1']='<div id="transfer1"><fieldset><legend>' . $lang['L_CONFIG_EMAIL'] . '</legend><table>';
-$aus['transfer1'].='<tr><td>' . $lang['L_SEND_MAIL_FORM'] . ':&nbsp;</td>';
-$aus['transfer1'].='<td><input type="radio" class="radio" value="1" name="send_mail" ' . ( ( $config['send_mail'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['transfer1'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="send_mail" ' . ( ( $config['send_mail'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'];
-$aus['transfer1'].='</td></tr><tr><td>' . $lang['L_EMAIL_ADRESS'] . ':&nbsp;</td><td><input type="text" class="text" name="email0" value="' . $config['email_recipient'] . '" size="30"></td></tr>';
-$aus['transfer1'].='<tr><td>' . $lang['L_EMAIL_CC'] . ':&nbsp;</td><td><input type="text" class="text" name="email_recipient_cc" value="' . $config['email_recipient_cc'] . '" size="60" maxlength="255"></td></tr>';
+if (!isset($config['email_recipient_cc'])) {
+    $config['email_recipient_cc'] = '';
+} // backwards compatibility if field is undefined
+$aus['transfer1'] = '<div id="transfer1"><fieldset><legend>'.$lang['L_EMAIL_NOTIFICATION'].'</legend><table>';
+$aus['transfer1'] .= '<tr><td>'.$lang['L_SEND_MAIL_FORM'].':&nbsp;</td>';
+$aus['transfer1'] .= '<td><input type="checkbox" class="checkbox" value="1" name="send_mail" '.((isset($config['send_mail']) && (1 == $config['send_mail'])) ? ' checked' : '').'>';
+$aus['global3'] .= '</td></tr>';
 
-$aus['transfer1'].='<tr><td>' . $lang['L_EMAIL_SENDER'] . ':&nbsp;</td><td><input type="text" class="text" name="email1" value="' . $config['email_sender'] . '" size="30"></td></tr>';
-$aus['transfer1'].='<tr><td>' . $lang['L_SEND_MAIL_DUMP'] . ':&nbsp;</td><td>';
-$aus['transfer1'].='<input type="radio" class="radio" value="1" name="send_mail_dump" ' . ( ( $config['send_mail_dump'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['transfer1'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="send_mail_dump"' . ( ( $config['send_mail_dump'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'];
-$aus['transfer1'].='</td></tr><tr><td>' . $lang['L_EMAIL_MAXSIZE'] . ':&nbsp;</td><td>';
-$aus['transfer1'].='<input type="text" class="text" name="email_maxsize1" size="3" maxlength="3" value="' . $config['email_maxsize1'] . '">&nbsp;&nbsp;';
-$aus['transfer1'].='<select name="email_maxsize2"><option value="1" ' . ( ( $config['email_maxsize2'] == 1 ) ? ' SELECTED' : '' ) . '>Kilobytes</option>';
-$aus['transfer1'].='<option value="2" ' . ( ( $config['email_maxsize2'] == 2 ) ? ' SELECTED' : '' ) . '>Megabytes</option></select></td></tr>';
-$aus['transfer1'].='<tr><td>' . $lang['L_CRON_MAILPRG'] . ':&nbsp;</td>';
-$aus['transfer1'].='<td><table><tr><td><input type="radio" class="radio" name="cron_use_sendmail" value="1" ' . ( ( $config['cron_use_sendmail'] == 1 ) ? " checked" : "" ) . '>&nbsp;sendmail</td><td><input type="text" class="text" size="30" name="cron_sendmail" value="' . $config['cron_sendmail'] . '"></td></tr>';
-$aus['transfer1'].='<tr><td><input type="radio" class="radio" name="cron_use_sendmail" value="0" ' . ( ( $config['cron_use_sendmail'] == 0 ) ? " checked" : "" ) . '>&nbsp;SMTP</td><td><input type="text" class="text" size="30" name="cron_smtp" value="' . $config['cron_smtp'] . '"></td></tr><tr><td>&nbsp;</td><td>SMTP-Port: <strong>' . $config['cron_smtp_port'] . '</strong></td></tr>';
-$aus['transfer1'].='</table></td></tr></table></fieldset>' . print_save_button() . '</div>';
+$aus['transfer1'] .= '<tr><td>'.$lang['L_EMAIL_ADRESS'].':&nbsp;</td><td><input type="text" class="text" name="email0" value="'.((isset($config['email_recipient'])) ? $config['email_recipient'] : '').'" size="30"></td></tr>';
+$aus['transfer1'] .= '<tr><td>'.$lang['L_EMAIL_CC'].':&nbsp;</td><td><input type="text" class="text" name="email_recipient_cc" value="'.((isset($config['email_recipient_cc'])) ? $config['email_recipient_cc'] : '').'" size="60" maxlength="255">';
+$aus['global3'] .= '</td></tr>';
+
+$aus['transfer1'] .= '<tr><td>'.$lang['L_EMAIL_SENDER'].':&nbsp;</td><td><input type="text" class="text" name="email1" value="'.((isset($config['email_sender'])) ? $config['email_sender'] : '').'" size="30">';
+$aus['global3'] .= '</td></tr>';
+
+$aus['transfer1'] .= '<tr><td>'.$lang['L_SEND_MAIL_DUMP'].':&nbsp;</td><td>';
+$aus['transfer1'] .= '<input type="checkbox" class="checkbox" value="1" name="send_mail_dump" '.((isset($config['send_mail_dump']) && (1 == $config['send_mail_dump'])) ? ' checked' : '').'>';
+$aus['global3'] .= '</td></tr>';
+
+$aus['transfer1'] .= '<tr><td>'.$lang['L_EMAIL_MAXSIZE'].':&nbsp;</td><td>';
+$aus['transfer1'] .= '<input type="text" class="text" name="email_maxsize1" size="3" maxlength="3" style="text-align:right;" value="'.((isset($config['email_maxsize1'])) ? $config['email_maxsize1'] : '').'">&nbsp;&nbsp;';
+$aus['transfer1'] .= '<select name="email_maxsize2"><option value="1" '.((1 == $config['email_maxsize2']) ? ' SELECTED' : '').'>Kilobytes</option>';
+$aus['transfer1'] .= '<option value="2" '.((2 == $config['email_maxsize2']) ? ' SELECTED' : '').'>Megabytes</option></select></td></tr>';
+
+$aus['transfer1'] .= '<tr><td>'.$lang['L_CRON_MAILPRG'].':&nbsp;</td>';
+$aus['transfer1'] .= '<td><table><tr><td><input type="radio" class="radio" name="cron_use_sendmail" value="1" '.((isset($config['cron_use_sendmail']) && (1 == $config['cron_use_sendmail'])) ? ' checked' : '').'>&nbsp;sendmail</td><td><input type="text" class="text" size="30" name="cron_sendmail" value="'.((isset($config['cron_sendmail'])) ? $config['cron_sendmail'] : '').'"></td></tr>';
+$aus['transfer1'] .= '<tr><td><input type="radio" class="radio" name="cron_use_sendmail" value="0" '.((isset($config['cron_use_sendmail']) && (0 == $config['cron_use_sendmail'])) ? ' checked' : '').'>&nbsp;SMTP</td><td><input type="text" class="text" size="30" name="cron_smtp" value="'.((isset($config['cron_smtp'])) ? $config['cron_smtp'] : '').'"></td></tr><tr><td>&nbsp;</td><td>SMTP-Port: <strong>'.$config['cron_smtp_port'].'</strong>';
+$aus['global3'] .= '</td></tr>';
+$aus['transfer1'] .= '</table></td></tr></table></fieldset>'.print_save_button().'</div>';
 
 //FTP-->
-$aus['transfer2']='<div id="transfer2"><fieldset><legend>' . $lang['L_CONFIG_FTP'] . '</legend>';
-for ($i=0; $i < 3; $i++)
-{
-	$aus['transfer2'].='<fieldset><legend>FTP-Connection ' . ( $i + 1 ) . '</legend><table>';
+$aus['transfer2'] = '<div id="transfer2"><fieldset><legend>'.$lang['L_CONFIG_FTP'].'</legend>';
+for ($i = 0; $i < 3; ++$i) {
+    $aus['transfer2'] .= '<fieldset><legend>FTP-Connection '.($i + 1).'</legend><table>';
 
-	$aus['transfer2'].='<tr><td>' . Help($lang['L_HELP_FTPTRANSFER'],"") . $lang['L_FTP_TRANSFER'] . ':&nbsp;</td>';
-	$aus['transfer2'].='<td><input type="radio" class="radio" value="1" name="ftp_transfer[' . $i . ']" ' . ( ( !extension_loaded("ftp") ) ? "disabled " : "" ) . ( ( $config['ftp_transfer'][$i] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_ACTIVATED'];
-	$aus['transfer2'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="ftp_transfer[' . $i . ']" ' . ( ( $config['ftp_transfer'][$i] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NOT_ACTIVATED'] . '</td></tr>';
+    $aus['transfer2'] .= '<tr><td>'.Help($lang['L_HELP_FTPTRANSFER'], '').$lang['L_FTP_TRANSFER'].':&nbsp;</td>';
+    $aus['transfer2'] .= '<td><input type="checkbox" class="checkbox" value="1" name="ftp_transfer['.$i.']" '.((!extension_loaded('ftp')) ? 'disabled ' : '').((isset($config['ftp_transfer'][$i]) && (1 == $config['ftp_transfer'][$i])) ? ' checked' : '').'></td></tr>';
 
-	$aus['transfer2'].='<tr><td>' . Help($lang['L_HELP_FTPTIMEOUT'],"") . $lang['L_FTP_TIMEOUT'] . ':&nbsp;</td>';
-	$aus['transfer2'].='<td><input type="text" class="text" size="10" name="ftp_timeout[' . $i . ']" maxlength="3" style="text-align:right;" value="' . $config['ftp_timeout'][$i] . '">&nbsp;sec</td></tr>';
+    $aus['transfer2'] .= '<tr><td>'.Help($lang['SFTP'], '').$lang['L_FTP_TIMEOUT'].':&nbsp;</td>';
+    $aus['transfer2'] .= '<td><input type="text" class="text" size="10" name="ftp_timeout['.$i.']" maxlength="3" style="text-align:right;" value="'.((isset($config['ftp_timeout'][$i])) ? $config['ftp_timeout'][$i] : '').'">&nbsp;sec</td></tr>';
 
-	$aus['transfer2'].='<tr><td>' . Help($lang['L_HELP_FTP_MODE'],"") . $lang['L_FTP_CHOOSE_MODE'] . ':&nbsp;</td>';
-	$aus['transfer2'].='<td><input type="checkbox" class="checkbox" name="ftp_mode[' . $i . ']" value="1" ' . ( ( $config['ftp_mode'][$i] == 1 ) ? 'checked' : '' ) . '>&nbsp;';
-	$aus['transfer2'].=$lang['L_FTP_PASSIVE'] . '</td></tr><tr><td colspan="2">';
+    $aus['transfer2'] .= '<tr><td>'.Help($lang['L_HELP_FTP_MODE'], '').$lang['L_FTP_CHOOSE_MODE'].':&nbsp;</td>';
+    $aus['transfer2'] .= '<td><input type="checkbox" class="checkbox" name="ftp_mode['.$i.']" value="1" '.((isset($config['ftp_mode'][$i]) && (1 == $config['ftp_mode'][$i])) ? 'checked' : '').'>&nbsp;';
+    $aus['transfer2'] .= $lang['L_FTP_PASSIVE'].'</td></tr><tr><td colspan="2">';
 
-	$aus['transfer2'].='<tr><td>' . Help($lang['L_HELP_FTPSSL'],"") . $lang['L_FTP_SSL'] . ':&nbsp;</td>';
-	$aus['transfer2'].='<td><input type="checkbox" class="checkbox" name="ftp_useSSL[' . $i . ']" value="1" ' . ( ( $config['ftp_useSSL'][$i] == 1 ) ? 'checked' : '' ) . ' ' . ( ( !extension_loaded("openssl") ) ? "disabled " : "" ) . '>';
-	$aus['transfer2'].='&nbsp;<span ' . ( ( !extension_loaded("openssl") ) ? 'style="color:#999999;"' : '' ) . '>' . $lang['L_FTP_USESSL'] . '</span></td></tr><tr><td colspan="2">';
+    $aus['transfer2'] .= '<tr><td>'.Help($lang['L_HELP_FTPSSL'], '').$lang['L_FTP_SSL'].':&nbsp;</td>';
+    $aus['transfer2'] .= '<td><input type="checkbox" class="checkbox" name="ftp_useSSL['.$i.']" value="1" '.((isset($config['ftp_useSSL'][$i]) && (1 == $config['ftp_useSSL'][$i])) ? 'checked' : '').' '.((!extension_loaded('openssl')) ? 'disabled ' : '').'>';
+    $aus['transfer2'] .= '&nbsp;<span '.((!extension_loaded('openssl')) ? 'style="color:#999999;"' : '').'>'.$lang['L_FTP_USESSL'].'</span></td></tr><tr><td colspan="2">';
 
-	$aus['transfer2'].='<tr><td><input type="submit" name="testFTP' . $i . '" value="' . $lang['L_TESTCONNECTION'] . '" class="Formbutton"><br>' . $checkFTP[$i] . '</td><td><table>';
-	$aus['transfer2'].='<tr><td class="small">' . Help($lang['L_HELP_FTPSERVER'],"conf14",12) . $lang['L_FTP_SERVER'] . ':&nbsp;</td><td><input class="text" type="text" size="30" name="ftp_server[' . $i . ']" value="' . $config['ftp_server'][$i] . '"></td></tr>';
-	$aus['transfer2'].='<tr><td class="small">' . Help($lang['L_HELP_FTPPORT'],"conf15",12) . $lang['L_FTP_PORT'] . ':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="ftp_port[' . $i . ']" value="' . $config['ftp_port'][$i] . '"></td></tr>';
-	$aus['transfer2'].='<tr><td class="small">' . Help($lang['L_HELP_FTPUSER'],"conf16",12) . $lang['L_FTP_USER'] . ':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="ftp_user[' . $i . ']" value="' . $config['ftp_user'][$i] . '"></td></tr>';
-	$aus['transfer2'].='<tr><td class="small">' . Help($lang['L_HELP_FTPPASS'],"conf17",12) . $lang['L_FTP_PASS'] . ':&nbsp;</td><td class="small"><input class="text" type="password" size="30" name="ftp_pass[' . $i . ']" value="' . $config['ftp_pass'][$i] . '"></td></tr>';
-	$aus['transfer2'].='<tr><td class="small">' . Help($lang['L_HELP_FTPDIR'],"conf18",12) . $lang['L_FTP_DIR'] . ':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="ftp_dir[' . $i . ']" value="' . $config['ftp_dir'][$i] . '"></td></tr>';
-	$aus['transfer2'].='</table></td></tr></table>' . print_save_button() . '</fieldset>';
+    $aus['transfer2'] .= '<tr><td><input type="submit" name="testFTP'.$i.'" value="'.$lang['L_TESTCONNECTION'].'" class="Formbutton"><br>'.$checkFTP[$i].'</td><td><table>';
+    $aus['transfer2'] .= '<tr><td class="small">'.Help($lang['L_HELP_FTPSERVER'], 'conf14', 12).$lang['L_FTP_SERVER'].':&nbsp;</td><td><input class="text" type="text" size="30" name="ftp_server['.$i.']" value="'.((isset($config['ftp_server'][$i])) ? $config['ftp_server'][$i] : '').'"></td></tr>';
+    $aus['transfer2'] .= '<tr><td class="small">'.Help($lang['L_HELP_FTPPORT'], 'conf15', 12).$lang['L_FTP_PORT'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="ftp_port['.$i.']" style="text-align:right;" value="'.((isset($config['ftp_port'][$i])) ? $config['ftp_port'][$i] : '').'"></td></tr>';
+    $aus['transfer2'] .= '<tr><td class="small">'.Help($lang['L_HELP_FTPUSER'], 'conf16', 12).$lang['L_FTP_USER'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="ftp_user['.$i.']" value="'.((isset($config['ftp_user'][$i])) ? $config['ftp_user'][$i] : '').'"></td></tr>';
+    $aus['transfer2'] .= '<tr><td class="small">'.Help($lang['L_HELP_FTPPASS'], 'conf17', 12).$lang['L_FTP_PASS'].':&nbsp;</td><td class="small"><input class="text" type="password" size="30" name="ftp_pass['.$i.']" value="'.((isset($config['ftp_pass'][$i])) ? $config['ftp_pass'][$i] : '').'"></td></tr>';
+    $aus['transfer2'] .= '<tr><td class="small">'.Help($lang['L_HELP_FTPDIR'], 'conf18', 12).$lang['L_FTP_DIR'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="ftp_dir['.$i.']" value="'.((isset($config['ftp_dir'][$i])) ? $config['ftp_dir'][$i] : '').'"></td></tr>';
+    $aus['transfer2'] .= '</table></td></tr></table>'.print_save_button().'</fieldset>';
 }
-$aus['transfer2'].='</fieldset></div>';
+$aus['transfer2'] .= '</fieldset></div>';
 
-//Crondump
-$aus['cron']='<div id="cron"><fieldset><legend>' . $lang['L_CONFIG_CRONPERL'] . '</legend><table>';
-$aus['cron'].='<tr><td>' . Help($lang['L_HELP_CRONEXTENDER'],"") . $lang['L_CRON_EXTENDER'] . ':&nbsp;</td>';
-$aus['cron'].='<td><input type="radio" class="radio" value="0" name="cron_extender" ' . ( ( $config['cron_extender'] == 0 ) ? " checked" : "" ) . '>&nbsp;.pl';
-$aus['cron'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="1" name="cron_extender" ' . ( ( $config['cron_extender'] == 1 ) ? " checked" : "" ) . '>&nbsp;.cgi';
-$aus['cron'].='</tr><tr><td>' . Help($lang['L_HELP_CRONEXECPATH'],"") . $lang['L_CRON_EXECPATH'] . ':&nbsp;</td>';
-$aus['cron'].='<td><input type="text" class="text" size="30" name="cron_execution_path" value="' . $config['cron_execution_path'] . '"></td>';
-$aus['cron'].='</tr><tr><td>' . Help($lang['L_HELP_CRONPRINTOUT'],"") . $lang['L_CRON_PRINTOUT'] . ':&nbsp;</td>';
-$aus['cron'].='<td><input type="radio" class="radio" value="1" name="cron_printout" ' . ( ( $config['cron_printout'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['cron'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="cron_printout" ' . ( ( $config['cron_printout'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'] . '</td></tr>';
-$aus['cron'].='<tr><td>' . Help($lang['L_HELP_CRONCOMPLETELOG'],"") . $lang['L_CRON_COMPLETELOG'] . ':&nbsp;</td>';
-$aus['cron'].='<td><input type="radio" class="radio" value="1" name="cron_completelog" ' . ( ( $config['cron_completelog'] == 1 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_YES'];
-$aus['cron'].='&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="0" name="cron_completelog" ' . ( ( $config['cron_completelog'] == 0 ) ? " checked" : "" ) . '>&nbsp;' . $lang['L_NO'] . '</td></tr>';
+// SFTP-->
+$aus['transfer3'] = '<div id="transfer3"><fieldset><legend>'.$lang['L_CONFIG_SFTP'].'</legend>';
+for ($i = 0; $i < 3; ++$i) {
+    $aus['transfer3'] .= '<fieldset><legend>SFTP-Connection '.($i + 1).'</legend><table>';
 
-$aus['cron'].='<tr><td>' . Help($lang['L_HELP_CRONDBINDEX'],"conf14") . $lang['L_CRON_CRONDBINDEX'] . ':&nbsp;</td>';
-$aus['cron'].='<td><select name="cron_dbindex" id="cron_dbindex">';
-$aus['cron'].='<option value="-3" ';
-if ($config['cron_dbindex'] == -3) $aus['cron'].='SELECTED';
-$aus['cron'].='>' . $lang['L_MULTIDUMPALL'] . "</option>\n";
-$aus['cron'].='<option value="-2" ';
-if ($config['cron_dbindex'] == -2) $aus['cron'].='SELECTED';
-$aus['cron'].='>' . $lang['L_MULTIDUMPCONF'] . "</option>\n";
+    $aus['transfer3'] .= '<tr><td>'.Help($lang['L_HELP_SFTPTRANSFER'], '').$lang['L_SFTP_TRANSFER'].':&nbsp;</td>';
+    $aus['transfer3'] .= '<td><input type="checkbox" class="checkbox" value="1" name="sftp_transfer['.$i.']" '.((!extension_loaded('ftp')) ? 'disabled ' : '').((isset($config['sftp_transfer'][$i]) && (1 == $config['sftp_transfer'][$i])) ? ' checked' : '').'></td></tr>';
+    $aus['transfer3'] .= '<tr><td>'.Help($lang['SFTP'], '').$lang['L_SFTP_TIMEOUT'].':&nbsp;</td>';
+    $aus['transfer3'] .= '<td><input type="text" class="text" size="10" name="sftp_timeout['.$i.']" maxlength="3" style="text-align:right;" value="'.((isset($config['sftp_timeout'][$i])) ? $config['sftp_timeout'][$i] : '').'">&nbsp;sec</td></tr>';
 
-if (isset($databases['Name'][0]) && $databases['Name'][0] > '')
-{
-	$datenbanken=count($databases['Name']);
-	for ($i=0; $i < $datenbanken; $i++)
-	{
-		$aus['cron'].='<option value="' . $i . '"';
-		if ($i == $config['cron_dbindex']) $aus['cron'].=' selected="selected"';
+    $aus['transfer3'] .= '<tr><td><input type="submit" name="testSFTP'.$i.'" value="'.$lang['L_TESTCONNECTION'].'" class="Formbutton"><br>'.$checkSFTP[$i].'</td><td><table>';
+    $aus['transfer3'] .= '<tr><td class="small">'.Help($lang['L_HELP_SFTPSERVER'], 'conf14', 12).$lang['L_SFTP_SERVER'].':&nbsp;</td><td><input class="text" type="text" size="30" name="sftp_server['.$i.']" value="'.((isset($config['sftp_server'][$i])) ? $config['sftp_server'][$i] : '').'"></td></tr>';
+    $aus['transfer3'] .= '<tr><td class="small">'.Help($lang['L_HELP_SFTPPORT'], 'conf15', 12).$lang['L_SFTP_PORT'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="sftp_port['.$i.']" style="text-align:right;" value="'.((isset($config['sftp_port'][$i])) ? $config['sftp_port'][$i] : '').'"></td></tr>';
+    $aus['transfer3'] .= '<tr><td class="small">'.Help($lang['L_HELP_SFTPUSER'], 'conf16', 12).$lang['L_SFTP_USER'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="sftp_user['.$i.']" value="'.((isset($config['sftp_user'][$i])) ? $config['sftp_user'][$i] : '').'"></td></tr>';
+    $aus['transfer3'] .= '<tr><td class="small">'.Help($lang['L_HELP_SFTPPASS'], 'conf17', 12).$lang['L_SFTP_PASS'].':&nbsp;</td><td class="small"><input class="text" type="password" size="30" name="sftp_pass['.$i.']" value="'.((isset($config['sftp_pass'][$i])) ? $config['sftp_pass'][$i] : '').'"></td></tr>';
+    $aus['transfer3'] .= '<tr><td class="small">'.Help($lang['L_HELP_SFTPDIR'], 'conf18', 12).$lang['L_SFTP_DIR'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="sftp_dir['.$i.']" value="'.((isset($config['sftp_dir'][$i])) ? $config['sftp_dir'][$i] : '').'"></td></tr>';
+
+    $aus['transfer3'] .= '<tr><td class="small">'.$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="sftp_path_to_private_key['.$i.']" value="'.((isset($config['sftp_path_to_private_key'][$i])) ? $config['sftp_path_to_private_key'][$i] : '').'"> (optional, default: null)</td></tr>';
+
+    $aus['transfer3'] .= '<tr><td class="small">'.$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="sftp_secret_passphrase_for_private_key['.$i.']" value="'.((isset($config['sftp_secret_passphrase_for_private_key'][$i])) ? $config['sftp_secret_passphrase_for_private_key'][$i] : '').'"> (optional, default: null)</td></tr>';
+
+    $aus['transfer3'] .= '<tr><td class="small">'.$lang['L_SFTP_FINGERPRINT'].':&nbsp;</td><td class="small"><input class="text" type="text" size="30" name="sftp_fingerprint['.$i.']" value="'.((isset($config['sftp_fingerprint'][$i])) ? $config['sftp_fingerprint'][$i] : '').'"> (optional, default: null)</td></tr>';
+
+    $aus['transfer3'] .= '</table></td></tr></table>'.print_save_button().'</fieldset>';
+}
+$aus['transfer3'] .= '</fieldset></div>';
+
+// Crondump
+$aus['cron'] = '<div id="cron"><fieldset><legend>'.$lang['L_CONFIG_CRONPERL'].'</legend><table>';
+$aus['cron'] .= '<tr><td>'.Help($lang['L_HELP_CRONEXTENDER'], '').$lang['L_CRON_EXTENDER'].':&nbsp;</td>';
+$aus['cron'] .= '<td><input type="radio" class="radio" value="0" name="cron_extender" '.((isset($config['cron_extender']) && (0 == $config['cron_extender'])) ? ' checked' : '').'>&nbsp;.pl';
+$aus['cron'] .= '&nbsp;&nbsp;&nbsp;<input type="radio" class="radio" value="1" name="cron_extender" '.((isset($config['cron_extender']) && (1 == $config['cron_extender'])) ? ' checked' : '').'>&nbsp;.cgi';
+
+$aus['cron'] .= '</tr><tr><td>'.Help($lang['L_HELP_CRONEXECPATH'], '').$lang['L_CRON_EXECPATH'].':&nbsp;</td>';
+$aus['cron'] .= '<td><input type="text" class="text" size="30" name="cron_execution_path" value="'.$config['cron_execution_path'].'"></td>';
+
+$aus['cron'] .= '</tr><tr><td>'.Help($lang['L_HELP_CRONPRINTOUT'], '').$lang['L_CRON_PRINTOUT'].':&nbsp;</td>';
+$aus['cron'] .= '<td><input type="checkbox" class="checkbox" value="1" name="cron_printout" '.((isset($config['cron_printout']) && (1 == $config['cron_printout'])) ? ' checked' : '').'>';
+
+$aus['cron'] .= '<tr><td>'.Help($lang['L_HELP_CRONCOMPLETELOG'], '').$lang['L_CRON_COMPLETELOG'].':&nbsp;</td>';
+$aus['cron'] .= '<td><input type="checkbox" class="checkbox" value="1" name="cron_completelog" '.((isset($config['cron_completelog']) && (1 == $config['cron_completelog'])) ? ' checked' : '').'>';
+
+$aus['cron'] .= '<tr><td>'.Help($lang['L_HELP_CRONDBINDEX'], 'conf14').$lang['L_CRON_CRONDBINDEX'].':&nbsp;</td>';
+$aus['cron'] .= '<td><select name="cron_dbindex" id="cron_dbindex">';
+$aus['cron'] .= '<option value="-3" ';
+if (-3 == $config['cron_dbindex']) {
+    $aus['cron'] .= 'SELECTED';
+}
+$aus['cron'] .= '>'.$lang['L_MULTIDUMPALL']."</option>\n";
+$aus['cron'] .= '<option value="-2" ';
+if (-2 == $config['cron_dbindex']) {
+    $aus['cron'] .= 'SELECTED';
+}
+$aus['cron'] .= '>'.$lang['L_MULTIDUMPCONF']."</option>\n";
+
+if (isset($databases['Name'][0]) && $databases['Name'][0] > '') {
+    $datenbanken = count($databases['Name']);
+    for ($i = 0; $i < $datenbanken; ++$i) {
+        $aus['cron'] .= '<option value="'.$i.'"';
+        if ($i == $config['cron_dbindex']) {
+            $aus['cron'] .= ' selected="selected"';
+        }
         if (in_array($databases['Name'][$i], $dontBackupDatabases)) {
             $aus['cron'] .= ' disabled="disabled"';
         }
-		$aus['cron'].='>' . $databases['Name'][$i] . "</option>\n";
-	}
-}
-else
-{
-	$config['cron_dbindex']=0;
+        $aus['cron'] .= '>'.$databases['Name'][$i]."</option>\n";
+    }
+} else {
+    $config['cron_dbindex'] = 0;
 }
 
-$aus['cron'].='</select>' . "\n";
-$aus['cron'].='</td></tr>';
+$aus['cron'] .= '</select>'."\n";
+$aus['cron'] .= '</td></tr>';
 
 // comment
-$aus['cron'].='<tr><td>' . $lang['L_CRON_COMMENT'] . ':&nbsp;</td>';
-$aus['cron'].='<td><input type="text" class="text" name="cron_comment" size="30" maxlength="100" value="' . htmlspecialchars($config['cron_comment']) . '"></td></tr>';
-$aus['cron'].='</table></fieldset>' . print_save_button() . '</div>';
+$config['cron_comment'] = isset($config['cron_comment']) ? $config['cron_comment'] : '';
+$aus['cron'] .= '<tr><td>'.$lang['L_CRON_COMMENT'].':&nbsp;</td>';
+$aus['cron'] .= '<td><input type="text" class="text" name="cron_comment" size="30" maxlength="100" value="'.htmlspecialchars($config['cron_comment']).'"></td></tr>';
+$aus['cron'] .= '</table></fieldset>'.print_save_button().'</div>';
 
 //Formular-Buttons -->
-$aus['formende']='</div></form><br style="clear:both;">';
+$aus['formende'] = '</div></form><br style="clear:both;">';
 
 // AUSGABE
 echo $aus['formstart'];
@@ -1009,16 +1253,21 @@ echo $aus['global2'];
 echo $aus['global3'];
 echo $aus['transfer1'];
 echo $aus['transfer2'];
+echo $aus['transfer3'];
 echo $aus['cron'];
 echo $aus['conf'];
 
 echo $aus['formende'];
 
-echo '<script language="JavaScript" type="text/javascript">show_pardivs("' . $sel . '");';
-// Wenn irgendetwas beim Wechsel eines Users nicht stimmt oder keine Db gefunden wurde oder eine DB nicht hinzugefügt
-// werden konnte --> User mit der Nase drauf stossen und Verbindungsdaten einblenden
-if (( $showVP ) || ( !isset($databases['Name']) ) || ( isset($databases['name']) && count($databases['Name'] == 0) ) || ( isset($add_db_message) )) echo 'SwitchVP();';
+echo '<script>show_pardivs("'.$sel.'");';
+
+// If something is wrong when changing a user or no DB was found or a DB could
+// not be added --> poke user with nose and show connection data
+if (($showVP) || (!isset($databases['Name'])) || (isset($databases['name']) && count(0 == $databases['Name'])) || (isset($add_db_message))) {
+    echo 'SwitchVP();';
+}
 echo '</script>';
-echo MSDFooter();
-$_SESSION['config']=$config;
+echo MODFooter();
+$_SESSION['config'] = $config;
 ob_end_flush();
+exit();
diff --git a/msd/css/msd/icons/arrow_down.gif b/msd/css/mod/icons/arrow_down.gif
similarity index 100%
rename from msd/css/msd/icons/arrow_down.gif
rename to msd/css/mod/icons/arrow_down.gif
diff --git a/msd/css/msd/icons/arrow_up.gif b/msd/css/mod/icons/arrow_up.gif
similarity index 100%
rename from msd/css/msd/icons/arrow_up.gif
rename to msd/css/mod/icons/arrow_up.gif
diff --git a/msd/css/msd/icons/arrowdown.gif b/msd/css/mod/icons/arrowdown.gif
similarity index 100%
rename from msd/css/msd/icons/arrowdown.gif
rename to msd/css/mod/icons/arrowdown.gif
diff --git a/msd/css/msd/icons/arrowleft.gif b/msd/css/mod/icons/arrowleft.gif
similarity index 100%
rename from msd/css/msd/icons/arrowleft.gif
rename to msd/css/mod/icons/arrowleft.gif
diff --git a/msd/css/msd/icons/arrowup.gif b/msd/css/mod/icons/arrowup.gif
similarity index 100%
rename from msd/css/msd/icons/arrowup.gif
rename to msd/css/mod/icons/arrowup.gif
diff --git a/msd/css/msd/icons/blank.gif b/msd/css/mod/icons/blank.gif
similarity index 100%
rename from msd/css/msd/icons/blank.gif
rename to msd/css/mod/icons/blank.gif
diff --git a/msd/css/msd/icons/browse.gif b/msd/css/mod/icons/browse.gif
similarity index 100%
rename from msd/css/msd/icons/browse.gif
rename to msd/css/mod/icons/browse.gif
diff --git a/msd/css/msd/icons/close.gif b/msd/css/mod/icons/close.gif
similarity index 100%
rename from msd/css/msd/icons/close.gif
rename to msd/css/mod/icons/close.gif
diff --git a/msd/css/msd/icons/delete.gif b/msd/css/mod/icons/delete.gif
similarity index 100%
rename from msd/css/msd/icons/delete.gif
rename to msd/css/mod/icons/delete.gif
diff --git a/msd/css/msd/icons/edit.gif b/msd/css/mod/icons/edit.gif
similarity index 100%
rename from msd/css/msd/icons/edit.gif
rename to msd/css/mod/icons/edit.gif
diff --git a/msd/css/msd/icons/gz.gif b/msd/css/mod/icons/gz.gif
similarity index 100%
rename from msd/css/msd/icons/gz.gif
rename to msd/css/mod/icons/gz.gif
diff --git a/msd/css/msd/icons/index.gif b/msd/css/mod/icons/index.gif
similarity index 100%
rename from msd/css/msd/icons/index.gif
rename to msd/css/mod/icons/index.gif
diff --git a/msd/css/msd/icons/key_fulltext.gif b/msd/css/mod/icons/key_fulltext.gif
similarity index 100%
rename from msd/css/msd/icons/key_fulltext.gif
rename to msd/css/mod/icons/key_fulltext.gif
diff --git a/msd/css/msd/icons/key_nokey.gif b/msd/css/mod/icons/key_nokey.gif
similarity index 100%
rename from msd/css/msd/icons/key_nokey.gif
rename to msd/css/mod/icons/key_nokey.gif
diff --git a/msd/css/msd/icons/key_primary.gif b/msd/css/mod/icons/key_primary.gif
similarity index 100%
rename from msd/css/msd/icons/key_primary.gif
rename to msd/css/mod/icons/key_primary.gif
diff --git a/msd/css/msd/icons/key_unique.gif b/msd/css/mod/icons/key_unique.gif
similarity index 100%
rename from msd/css/msd/icons/key_unique.gif
rename to msd/css/mod/icons/key_unique.gif
diff --git a/msd/css/msd/icons/mysql_help.gif b/msd/css/mod/icons/mysql_help.gif
similarity index 100%
rename from msd/css/msd/icons/mysql_help.gif
rename to msd/css/mod/icons/mysql_help.gif
diff --git a/msd/css/msd/icons/notok.gif b/msd/css/mod/icons/notok.gif
similarity index 100%
rename from msd/css/msd/icons/notok.gif
rename to msd/css/mod/icons/notok.gif
diff --git a/msd/css/msd/icons/ok.gif b/msd/css/mod/icons/ok.gif
similarity index 100%
rename from msd/css/msd/icons/ok.gif
rename to msd/css/mod/icons/ok.gif
diff --git a/msd/css/msd/icons/openfile.gif b/msd/css/mod/icons/openfile.gif
similarity index 100%
rename from msd/css/msd/icons/openfile.gif
rename to msd/css/mod/icons/openfile.gif
diff --git a/msd/css/msd/icons/progressbar_dump.gif b/msd/css/mod/icons/progressbar_dump.gif
similarity index 100%
rename from msd/css/msd/icons/progressbar_dump.gif
rename to msd/css/mod/icons/progressbar_dump.gif
diff --git a/msd/css/msd/icons/progressbar_restore.gif b/msd/css/mod/icons/progressbar_restore.gif
similarity index 100%
rename from msd/css/msd/icons/progressbar_restore.gif
rename to msd/css/mod/icons/progressbar_restore.gif
diff --git a/msd/css/msd/icons/progressbar_speed.gif b/msd/css/mod/icons/progressbar_speed.gif
similarity index 100%
rename from msd/css/msd/icons/progressbar_speed.gif
rename to msd/css/mod/icons/progressbar_speed.gif
diff --git a/msd/css/msd/icons/rename.gif b/msd/css/mod/icons/rename.gif
similarity index 100%
rename from msd/css/msd/icons/rename.gif
rename to msd/css/mod/icons/rename.gif
diff --git a/msd/css/msd/icons/search.gif b/msd/css/mod/icons/search.gif
similarity index 100%
rename from msd/css/msd/icons/search.gif
rename to msd/css/mod/icons/search.gif
diff --git a/msd/css/msd/icons/table_truncate.gif b/msd/css/mod/icons/table_truncate.gif
similarity index 100%
rename from msd/css/msd/icons/table_truncate.gif
rename to msd/css/mod/icons/table_truncate.gif
diff --git a/msd/css/msd/icons/table_truncate_reset.gif b/msd/css/mod/icons/table_truncate_reset.gif
similarity index 100%
rename from msd/css/msd/icons/table_truncate_reset.gif
rename to msd/css/mod/icons/table_truncate_reset.gif
diff --git a/msd/css/msd/pics/bg-body.gif b/msd/css/mod/pics/bg-body.gif
similarity index 100%
rename from msd/css/msd/pics/bg-body.gif
rename to msd/css/mod/pics/bg-body.gif
diff --git a/msd/css/msd/pics/bg-buttons.gif b/msd/css/mod/pics/bg-buttons.gif
similarity index 100%
rename from msd/css/msd/pics/bg-buttons.gif
rename to msd/css/mod/pics/bg-buttons.gif
diff --git a/msd/css/msd/pics/bg-headings.gif b/msd/css/mod/pics/bg-headings.gif
similarity index 100%
rename from msd/css/msd/pics/bg-headings.gif
rename to msd/css/mod/pics/bg-headings.gif
diff --git a/msd/css/msd/pics/blank.gif b/msd/css/mod/pics/blank.gif
similarity index 100%
rename from msd/css/msd/pics/blank.gif
rename to msd/css/mod/pics/blank.gif
diff --git a/msd/css/msd/pics/h1_logo.gif b/msd/css/mod/pics/h1_logo.gif
similarity index 100%
rename from msd/css/msd/pics/h1_logo.gif
rename to msd/css/mod/pics/h1_logo.gif
diff --git a/msd/css/msd/pics/loveyourdata.gif b/msd/css/mod/pics/loveyourdata.gif
similarity index 100%
rename from msd/css/msd/pics/loveyourdata.gif
rename to msd/css/mod/pics/loveyourdata.gif
diff --git a/msd/css/msd/pics/navi_bg.jpg b/msd/css/mod/pics/navi_bg.jpg
similarity index 100%
rename from msd/css/msd/pics/navi_bg.jpg
rename to msd/css/mod/pics/navi_bg.jpg
diff --git a/msd/css/msd/style.css b/msd/css/mod/style.css
similarity index 99%
rename from msd/css/msd/style.css
rename to msd/css/mod/style.css
index edab7691..fa7f7c3d 100644
--- a/msd/css/msd/style.css
+++ b/msd/css/mod/style.css
@@ -3,7 +3,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -17,7 +17,7 @@
 
 /*
     @MySQLDumper STYLESHEET
-    @name			msd
+    @name			mod
     @copyright		MySQLDumper - Daniel Schlichtholz <http://www.mysqldumper.de>
     @author			Ingo Wagener <http://www.vorderdeck.de>, Daniel Schlichtholz, Christian Gresshoener <http://www.gresshoener.de>
     @date			2008-02-28 13:39:07
diff --git a/msd/css/msd_green/icons/arrow_down.gif b/msd/css/mod_green/icons/arrow_down.gif
similarity index 100%
rename from msd/css/msd_green/icons/arrow_down.gif
rename to msd/css/mod_green/icons/arrow_down.gif
diff --git a/msd/css/msd_green/icons/arrow_up.gif b/msd/css/mod_green/icons/arrow_up.gif
similarity index 100%
rename from msd/css/msd_green/icons/arrow_up.gif
rename to msd/css/mod_green/icons/arrow_up.gif
diff --git a/msd/css/msd_green/icons/arrowdown.gif b/msd/css/mod_green/icons/arrowdown.gif
similarity index 100%
rename from msd/css/msd_green/icons/arrowdown.gif
rename to msd/css/mod_green/icons/arrowdown.gif
diff --git a/msd/css/msd_green/icons/arrowleft.gif b/msd/css/mod_green/icons/arrowleft.gif
similarity index 100%
rename from msd/css/msd_green/icons/arrowleft.gif
rename to msd/css/mod_green/icons/arrowleft.gif
diff --git a/msd/css/msd_green/icons/arrowup.gif b/msd/css/mod_green/icons/arrowup.gif
similarity index 100%
rename from msd/css/msd_green/icons/arrowup.gif
rename to msd/css/mod_green/icons/arrowup.gif
diff --git a/msd/css/msd_green/icons/blank.gif b/msd/css/mod_green/icons/blank.gif
similarity index 100%
rename from msd/css/msd_green/icons/blank.gif
rename to msd/css/mod_green/icons/blank.gif
diff --git a/msd/css/msd_green/icons/browse.gif b/msd/css/mod_green/icons/browse.gif
similarity index 100%
rename from msd/css/msd_green/icons/browse.gif
rename to msd/css/mod_green/icons/browse.gif
diff --git a/msd/css/msd_green/icons/close.gif b/msd/css/mod_green/icons/close.gif
similarity index 100%
rename from msd/css/msd_green/icons/close.gif
rename to msd/css/mod_green/icons/close.gif
diff --git a/msd/css/msd_green/icons/delete.gif b/msd/css/mod_green/icons/delete.gif
similarity index 100%
rename from msd/css/msd_green/icons/delete.gif
rename to msd/css/mod_green/icons/delete.gif
diff --git a/msd/css/msd_green/icons/edit.gif b/msd/css/mod_green/icons/edit.gif
similarity index 100%
rename from msd/css/msd_green/icons/edit.gif
rename to msd/css/mod_green/icons/edit.gif
diff --git a/msd/css/msd_green/icons/gz.gif b/msd/css/mod_green/icons/gz.gif
similarity index 100%
rename from msd/css/msd_green/icons/gz.gif
rename to msd/css/mod_green/icons/gz.gif
diff --git a/msd/css/msd_green/icons/index.gif b/msd/css/mod_green/icons/index.gif
similarity index 100%
rename from msd/css/msd_green/icons/index.gif
rename to msd/css/mod_green/icons/index.gif
diff --git a/msd/css/msd_green/icons/key_fulltext.gif b/msd/css/mod_green/icons/key_fulltext.gif
similarity index 100%
rename from msd/css/msd_green/icons/key_fulltext.gif
rename to msd/css/mod_green/icons/key_fulltext.gif
diff --git a/msd/css/msd_green/icons/key_nokey.gif b/msd/css/mod_green/icons/key_nokey.gif
similarity index 100%
rename from msd/css/msd_green/icons/key_nokey.gif
rename to msd/css/mod_green/icons/key_nokey.gif
diff --git a/msd/css/msd_green/icons/key_primary.gif b/msd/css/mod_green/icons/key_primary.gif
similarity index 100%
rename from msd/css/msd_green/icons/key_primary.gif
rename to msd/css/mod_green/icons/key_primary.gif
diff --git a/msd/css/msd_green/icons/key_unique.gif b/msd/css/mod_green/icons/key_unique.gif
similarity index 100%
rename from msd/css/msd_green/icons/key_unique.gif
rename to msd/css/mod_green/icons/key_unique.gif
diff --git a/msd/css/msd_green/icons/mysql_help.gif b/msd/css/mod_green/icons/mysql_help.gif
similarity index 100%
rename from msd/css/msd_green/icons/mysql_help.gif
rename to msd/css/mod_green/icons/mysql_help.gif
diff --git a/msd/css/msd_green/icons/nokey.gif b/msd/css/mod_green/icons/nokey.gif
similarity index 100%
rename from msd/css/msd_green/icons/nokey.gif
rename to msd/css/mod_green/icons/nokey.gif
diff --git a/msd/css/msd_green/icons/notok.gif b/msd/css/mod_green/icons/notok.gif
similarity index 100%
rename from msd/css/msd_green/icons/notok.gif
rename to msd/css/mod_green/icons/notok.gif
diff --git a/msd/css/msd_green/icons/ok.gif b/msd/css/mod_green/icons/ok.gif
similarity index 100%
rename from msd/css/msd_green/icons/ok.gif
rename to msd/css/mod_green/icons/ok.gif
diff --git a/msd/css/msd_green/icons/openfile.gif b/msd/css/mod_green/icons/openfile.gif
similarity index 100%
rename from msd/css/msd_green/icons/openfile.gif
rename to msd/css/mod_green/icons/openfile.gif
diff --git a/msd/css/msd_green/icons/progressbar_dump.gif b/msd/css/mod_green/icons/progressbar_dump.gif
similarity index 100%
rename from msd/css/msd_green/icons/progressbar_dump.gif
rename to msd/css/mod_green/icons/progressbar_dump.gif
diff --git a/msd/css/msd_green/icons/progressbar_restore.gif b/msd/css/mod_green/icons/progressbar_restore.gif
similarity index 100%
rename from msd/css/msd_green/icons/progressbar_restore.gif
rename to msd/css/mod_green/icons/progressbar_restore.gif
diff --git a/msd/css/msd_green/icons/progressbar_speed.gif b/msd/css/mod_green/icons/progressbar_speed.gif
similarity index 100%
rename from msd/css/msd_green/icons/progressbar_speed.gif
rename to msd/css/mod_green/icons/progressbar_speed.gif
diff --git a/msd/css/msd_green/icons/rename.gif b/msd/css/mod_green/icons/rename.gif
similarity index 100%
rename from msd/css/msd_green/icons/rename.gif
rename to msd/css/mod_green/icons/rename.gif
diff --git a/msd/css/msd_green/icons/search.gif b/msd/css/mod_green/icons/search.gif
similarity index 100%
rename from msd/css/msd_green/icons/search.gif
rename to msd/css/mod_green/icons/search.gif
diff --git a/msd/css/msd_green/icons/table_truncate.gif b/msd/css/mod_green/icons/table_truncate.gif
similarity index 100%
rename from msd/css/msd_green/icons/table_truncate.gif
rename to msd/css/mod_green/icons/table_truncate.gif
diff --git a/msd/css/msd_green/icons/table_truncate_reset.gif b/msd/css/mod_green/icons/table_truncate_reset.gif
similarity index 100%
rename from msd/css/msd_green/icons/table_truncate_reset.gif
rename to msd/css/mod_green/icons/table_truncate_reset.gif
diff --git a/msd/css/msd_green/pics/body_bg.gif b/msd/css/mod_green/pics/body_bg.gif
similarity index 100%
rename from msd/css/msd_green/pics/body_bg.gif
rename to msd/css/mod_green/pics/body_bg.gif
diff --git a/msd/css/msd_green/pics/h1_logo.gif b/msd/css/mod_green/pics/h1_logo.gif
similarity index 100%
rename from msd/css/msd_green/pics/h1_logo.gif
rename to msd/css/mod_green/pics/h1_logo.gif
diff --git a/msd/css/msd_green/pics/loveyourdata.gif b/msd/css/mod_green/pics/loveyourdata.gif
similarity index 100%
rename from msd/css/msd_green/pics/loveyourdata.gif
rename to msd/css/mod_green/pics/loveyourdata.gif
diff --git a/msd/css/msd_green/pics/mainnavi.gif b/msd/css/mod_green/pics/mainnavi.gif
similarity index 100%
rename from msd/css/msd_green/pics/mainnavi.gif
rename to msd/css/mod_green/pics/mainnavi.gif
diff --git a/msd/css/msd_green/pics/navi_bg.jpg b/msd/css/mod_green/pics/navi_bg.jpg
similarity index 100%
rename from msd/css/msd_green/pics/navi_bg.jpg
rename to msd/css/mod_green/pics/navi_bg.jpg
diff --git a/msd/css/msd_green/pics/overall_bg.gif b/msd/css/mod_green/pics/overall_bg.gif
similarity index 100%
rename from msd/css/msd_green/pics/overall_bg.gif
rename to msd/css/mod_green/pics/overall_bg.gif
diff --git a/msd/css/msd_green/pics/pagetitle.gif b/msd/css/mod_green/pics/pagetitle.gif
similarity index 100%
rename from msd/css/msd_green/pics/pagetitle.gif
rename to msd/css/mod_green/pics/pagetitle.gif
diff --git a/msd/css/msd_green/style.css b/msd/css/msd_green/style.css
deleted file mode 100644
index 57b3afdf..00000000
--- a/msd/css/msd_green/style.css
+++ /dev/null
@@ -1,725 +0,0 @@
-/* ----------------------------------------------------------------------
-
-   MyOOS [Dumper]
-   http://www.oos-shop.de/
-
-   Copyright (c) 2016 by the MyOOS Development Team.
-   ----------------------------------------------------------------------
-   Based on:
-
-   MySqlDumper
-   http://www.mysqldumper.de
-
-   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
-   ----------------------------------------------------------------------
-   Released under the GNU General Public License
-   ---------------------------------------------------------------------- */
-
-/*
-    @MySQLDumper STYLESHEET
-    @name			msd_green
-    @copyright		MySQLDumper - Daniel Schlichtholz <http://www.mysqldumper.de>
-    @author			Ingo Wagener <http://www.vorderdeck.de>, Daniel Schlichtholz, Christian Gresshoener <http://www.gresshoener.de>
-    @date			2006-04-11 16:26:00
-    @lastmodified	2009-09-15 00:21:30
-    @media			screen and projection
-*/
-*,.normargin {
-	margin: 0;
-	padding: 0;
-}
-
-img {
-	border: 0;
-}
-
-body {
-	font: 12px/1.5 Verdana, Helvetica, sans-serif; /* Important IE Bugfix: No spaces in font-attribute between px and slash */
-	color: #4E5665;
-	background: #C7D1D0;
-}
-
-body.content {
-	min-width: 540px;
-}
-
-.menu-frame {
-	font: 12px/1.5 Verdana, Helvetica, sans-serif;
-	background-color: #738C88;
-	color: #eee;
-}
-
-/* LINKS */
-a {
-	color: #4E5665;
-	text-decoration: underline;
-	font: 12px verdana, sans-serif
-}
-
-a:hover {
-	color: #E87B00;
-	text-decoration: none
-}
-
-a.ul {
-	text-decoration: underline;
-}
-
-/* general */
-#pagetitle {
-	font-size: 1.5em;
-	font-weight: bold;
-	background: url(pics/pagetitle.gif);
-	background-repeat: repeat-x;
-	letter-spacing: 2px;
-	color: white;
-	padding: 2px 6px;
-	border-bottom: 1px solid #A9AFBB;
-	height: 26px;
-	overflow: hidden;
-}
-
-#server0 {
-	position: absolute;
-	bottom: 4px;
-	text-align: center;
-	left: 10px;
-	color: white;
-}
-
-#server1 {
-	position: absolute;
-	right: 16px;
-	text-align: center;
-	padding: 10px;
-}
-
-a.server {
-	color: #333333;
-	font-size: 10px;
-}
-
-a.server:hover {
-	text-decoration: underline;
-	color: white;
-}
-
-.version {
-	display: block;
-	position: absolute;
-	top: 31px;
-	left: 0;
-	width: 190px;
-	z-index: 5;
-	text-align: center;
-	font-size: 11px;
-	font-weight: bold;
-}
-
-.small {
-	font-size: 11px;
-}
-
-.ssmall {
-	font-size: 10px;
-}
-
-.success {
-	font-weight: bold;
-}
-
-.error {
-	color: red;
-	font-weight: bold;
-}
-
-.explain {
-	text-decoration: none;
-	border-bottom: 1px dotted;
-}
-
-.explain:hover {
-	cursor: help;
-}
-
-.active_db {
-	font-weight: bold;
-	border-bottom: 1px dotted;
-	color: #9AA2B1;
-}
-
-table td {
-	text-align: left;
-	vertical-align: top;
-	padding: 0 6px;
-}
-
-table th {
-	padding: 0 6px;
-}
-
-table.bdr,.bdr {
-	border: 1px solid #ddd !important;
-	border-collapse: collapse !important;
-}
-
-/* MENU */
-#wrapmenu {
-	background: url(pics/pagetitle.gif) #A9AFBB;
-	background-repeat: repeat-x;
-}
-
-#db-select {
-	font: 12px Verdana, Helvetica, sans-serif;
-	color: #4E5665;
-	background: #A9AFBB;
-}
-
-#menu {
-	position:absolute;
-	margin: 0px;
-	top: 222px;
-	left:0;
-	width:190px;
-	height:160px;
-	background-color: #738C88;
-	border-top: 1px solid #9AA2B1
-}
-
-#menu ul {
-	list-style: none;
-}
-
-#menu ul li {
-	height: 20px;
-}
-
-#menu ul li a {
-	display: block;
-	position: relative; /*fuer den ie*/
-	font: 11px/20px verdana, sans-serif;
-	text-decoration: none;
-	color: #4E5665;
-	background: url(pics/mainnavi.gif) repeat-x 0 -20px;
-	padding: 0 15px;
-	height: 20px;
-	text-align: left;
-}
-
-#menu ul li a:hover {
-	color: #fff;
-	background: url(pics/mainnavi.gif) repeat-x 0 0px;
-}
-
-/*der aktive link in der navi*/
-#menu ul li.active a {
-	font-weight: bold;
-	color: #fff;
-	background: url(pics/mainnavi.gif) repeat-x 0 -40px;
-	display: block;
-}
-
-#menu p,#menu p a {
-	color: #fff;
-	line-height: 1.5;
-	font-size: 11px;
-}
-
-#version {
-	position:absolute;
-	top:30px;
-	left:0;
-	margin:0;
-	padding:0;
-	height:191px;
-	color: #4E5665;
-	z-index:10;
-	border-top:1px solid #A9AFBB;
-}
-.version-line
-{
-	position:absolute;
-	top:-1px;
-	left:0;
-	width:190px;
-	text-align:center;
-	font: 11px/20px verdana, sans-serif;
-}
-
-#version a:link,
-#version a:active,
-#version a:hover,
-#version a:visited
-{ 	color: #4E5665; }
-	
-
-#selectConfig 
-{
-	position:absolute;
-	top:380px;	
-	left:0;
-	width:190px;
-	height: 196px;
-	z-index:5;
-}
-
-table.bdr,.bdr {
-	border: 1px solid #4E5665 !important;
-	border-collapse: collapse !important;
-}
-
-#db-selectbox,#config-selectbox {
-	position: relative;
-	top: 0px;
-	width: 190px;
-	background: transparent;
-	text-align: center;
-	font: 11px/1.5 Verdana, Helvetica, sans-serif;
-	color: white;
-}
-
-#db-selectbox a,#config-selectbox a {
-	font: 11px/1.5 Verdana, Helvetica, sans-serif;
-	color: white;
-	text-decoration: underline;
-}
-
-#db-selectbox a:hover,#config-selectbox a:hover {
-	text-decoration: none
-}
-
-fieldset {
-	margin: 10px;
-	padding: 5px;
-	border: 1px solid #ddd;
-	color: #256777;
-}
-
-body.content legend {
-	font-weight: bold;
-}
-
-body.menu fieldset p {
-	margin: 5px 0 0;
-	text-align: center;
-}
-
-#configSelect legend,#dbSelect legend,#dbSelect a {
-	font: 11px/1.5 Verdana, Helvetica, sans-serif;
-	color: #eee;
-}
-
-/* MAIN */
-#topnavi {
-	list-style: none;
-	margin: 10px 0 20px;
-	padding: 5px 0px;
-}
-
-#topnavi li {
-	float: left;
-	margin-right: 6px;
-}
-
-#topnavi li a {
-	float: left;
-	font: 0.8em verdana, arial, sans-serif;
-	border: 1px solid #4E5665;
-	background-color: #A9B2B1;
-	color: #4E5665;
-	margin: 3px;
-	padding: 3px 23px 4px 23px;
-	cursor: pointer;
-	text-decoration: none;
-	white-space: nowrap;
-}
-
-#topnavi li a span {
-	display: none;
-}
-
-#content {
-	margin-left: 12px;
-	background-color: #C7D1D0;
-}
-
-#content p {
-	margin-bottom: 8px;
-}
-
-/*Tabellen */
-table tr.dbrow {
-	background: #E4E9E8;
-}
-
-table tr.dbrow1 {
-	background: #D5DDDC;
-}
-
-table tr.dbrowsel {
-	background: #fff;
-}
-
-table td.treffer {
-	background: #000;
-}
-
-/* Treffer bei der MySQL-Suche */
-table tr.dbrow .treffer,table tr.dbrow1 .treffer {
-	color: yellow;
-	background-color: #738C88;
-}
-
-table.bordersmall,table.border {
-	border: 2px solid #738C88;
-	width: 84%;
-}
-
-table.border th,table.bordersmall th {
-	font-size: 11px;
-	color: #738C88;
-}
-
-table tr.thead th,table tr.thead td {
-	background-color: #A5B6B4;
-	color: #738C88;
-	border: 1px solid #738C88;
-}
-
-table.border tr.thead,table.bordersmall tr.thead {
-	height: 24px;
-}
-
-table td.sum {
-	background-color: red;
-	font-weight: bold;
-	text-align: right;
-}
-
-table.bordersmall input,table.bordersmall select,table.bordersmall td,#sqlheaderbox select
-	{
-	border: 1px solid #738C88;
-	font-size: 11px;
-}
-
-.tdcompact {
-	width: 100px;
-	height: 16px;
-	overflow: hidden;
-	font-size: 11px;
-}
-
-.tdnormal {
-	white-space: nowrap;
-	padding: 4px;
-}
-
-.sqlheadmenu a {
-	
-}
-
-/* FORM-Elements */
-#content .Formbutton,#content .Formtext {
-	white-space: nowrap;
-	margin: 6px;
-	font: 10px verdana, sans-serif;
-	border: 1px solid #4E5665;
-	background: #A9B2B1;
-	color: #4E5665;
-	padding: 2px 10px;
-	cursor: pointer;
-	overflow: visible;
-	text-decoration: none;
-}
-
-#content a.Formbutton {
-	padding: 2px 23px 3px 23px;
-}
-
-label {
-	cursor: pointer;
-}
-
-.Formbutton {
-	cursor: pointer;
-}
-
-.Formbutton:disabled {
-	cursor: default !important;
-}
-
-#content .Formtext {
-	padding: 2px;
-	overflow: hidden;
-	cursor: text;
-}
-
-#content .SQLbutton {
-	font-size: 11px;
-	background: #E4E9E8;
-	cursor: pointer;
-}
-
-#content textarea #thta {
-	font-size: 11px;
-	color: blue;
-	width: 400px;
-	height: 300px;
-	overflow: scroll;
-}
-
-#content textarea {
-	width: 100%;
-	background: #B3C2C0;
-}
-
-input.radio,input.checkbox {
-	background-color: transparent;
-}
-
-/* Colors for Formelements */
-input.text,input.small {
-	background: #B3C2C0;
-	color: #4E5665;
-}
-
-select {
-	background: #B3C2C0;
-	color: #4E5665;
-}
-
-textarea {
-	background: #B3C2C0;
-	color: #4E5665;
-}
-
-/* for Geckos */
-input[disabled] {
-	color: #888 !important;
-}
-
-/*horizontales Men� */
-#hormenu {
-	
-}
-
-#hormenu ul {
-	border-bottom: thin solid #D5DDDC;
-	margin-bottom: 8px;
-	width: 80%;
-}
-
-#hormenu ul li {
-	display: inline;
-}
-
-#hormenu ul li a {
-	font: 11px/20px verdana, sans-serif;
-	text-decoration: none;
-	color: #4E5665;
-	padding: 0 14px;
-	border: 0;
-}
-
-#hormenu ul li a:hover {
-	color: #E87B00;
-}
-
-#hormenu ul li#active a {
-	font: bold 11px/20px verdana, sans-serif;
-	text-decoration: none;
-	color: #E87B00;
-	float: left;
-	padding: 0 14px;
-}
-
-#hormenu ul li#active a:hover {
-	color: #E87B00;
-}
-
-/* spezielle Elemente */
-.MySQLbox {
-	font-size: 10pt;
-	padding: 6px;
-	background: #000;
-	color: #fff;
-	border: thin solid #999999;
-	height: 200px;
-	width: 80%;
-	text-align: left;
-	overflow: auto;
-}
-
-#content #mysqlbox {
-	border: 1px solid #738C88;
-	background: #D5DDDC;
-}
-
-#content #sqlheaderbox,.sqlbox-warning {
-	white-space: nowrap;
-	vertical-align: top;
-	padding: 8px;
-	border: 1px solid #738C88;
-	color: #256777;
-	line-height: 22px;
-}
-
-#sqlheaderbox .Formbutton {
-	line-height: 12px;
-	padding: 2px;
-	margin: 0px;
-}
-
-#sqltextarea {
-	width: 100% !important;
-	overflow: auto;
-	background-color: #B3C2C0;
-}
-
-#content #sqlheaderbox {
-	white-space: nowrap;
-	height: 20px;
-	vertical-align: middle;
-	padding-top: 2px;
-}
-
-#content #sqleditbox {
-	border: 1px solid #738C88;
-	background: #E4E9E8;
-	margin-bottom: 10px;
-}
-
-#content #sqleditbox form {
-	margin: 10px;
-}
-
-#content #sqleditbox p {
-	background: #A5B6B4;
-	font-weight: bold;
-	text-align: center;
-}
-
-#content #sqlnewbox {
-	border: 1px solid #738C88;
-	background: #E4E9E8;
-}
-
-#content #sqlnewbox p {
-	background: #A5B6B4;
-	font-weight: bold;
-	text-align: center;
-}
-
-#content #sqloutbox {
-	font-size: 11px;
-	width: 700px;
-	padding: 6px;
-	background: #D5DDDC;
-	border: 1px solid #738C88;
-	overflow: auto;
-	height: 240px;
-}
-
-#content p.autodel {
-	font-size: 11px;
-	border-bottom: 1px dashed #fff;
-	margin-bottom: 12px;
-}
-
-#content .Logbox {
-	font: 12px/1.2 "Courier New", Courier, monospace;
-	padding: 6px;
-	border: thin solid #738C88;
-	height: 320px;
-	width: 90%;
-	text-align: left;
-	overflow: auto;
-}
-
-#content .Logbox span {
-	color: #738C88;
-}
-
-#content .backupmsg {
-	padding-left: 20px;
-	font-size: 11px;
-}
-
-#content .backupmsg .success,#content .backupmsg a {
-	color: #999;
-	font-size: 11px;
-}
-
-#content .backupmsg .error {
-	color: red;
-}
-
-/* TEXT */
-h1 {
-	font-size: 16px;
-}
-
-h5 {
-	font-size: 14px;
-	margin: 12px 0;
-}
-
-h6 {
-	font-size: 11px;
-	background: #D1D4DC;
-	border: 1px solid #9AA2B1;
-	text-indent: 12px;
-	margin: 8px 0;
-}
-
-/* Config */
-#configleft {
-	float: left;
-	width: 160px;
-	margin-top: 24px;
-}
-
-#configleft .Formbutton {
-	width: 130px;
-	margin: 8px 0;
-}
-
-#configleft .ConfigButton {
-	width: 130px;
-	font-size: 11px;
-	background: #E4E9E8;
-	cursor: pointer;
-}
-
-#configleft .ConfigButtonSelected {
-	width: 130px;
-	font-size: 11px;
-	background: #D5DDDC;
-}
-
-#configright {
-	font-size: 11px;
-	margin-left: 160px;
-}
-
-#configright fieldset {
-	border: 1px solid #D5DDDC;
-	padding: 12px;
-	width: 90%;
-}
-
-#configright legend {
-	color: #646968;
-	margin: 8px 0;
-}
-
-#footer {
-	font-size: 11px;
-	text-align: center;
-	border-top: 1px dashed #eee;
-	margin-top: 36px;
-}
-
-#footer a {
-	font-size: 11px;
-}
\ No newline at end of file
diff --git a/msd/dump.php b/msd/dump.php
index 5678c431..5d3359b4 100644
--- a/msd/dump.php
+++ b/msd/dump.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,454 +18,461 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
 session_name('MyOOSDumperID');
 session_start();
-$aus2=$page_parameter=$a=$out='';
-include_once ('./inc/functions_dump.php');
+$aus2 = $page_parameter = $a = $out = '';
+include_once './inc/functions_dump.php';
 
-// beim Erstaufruf Konfigurationsdatei auslesen und in Session speichern
-if (isset($_GET['config']))
-{
-	// Session loeschen, damit keine alten Werte des letzten Laufs uebernommen werden
-	if (isset($_SESSION['dump'])) unset($_SESSION['dump']);
-	$search=array(
-
-	'/','\\',':','@');
-	$replace=array(
-
-	'','','','');
-	$config_file=str_replace($search,$replace,$_GET['config']);
-	if (is_readable($config['paths']['config'].$config_file.'.php'))
-	{
-		$config['files']['parameter']=$config['paths']['config'].$config_file.'.php';
-		$_SESSION['config_file']=$config_file;
-		read_config($config['paths']['config'].$config['files']['parameter']);
-		$_SESSION['config']=$config;
-	}
-	else
-		die("Hacking attempt or configuration not found!");
+// read configuration file on first call and save it in session
+if (isset($_GET['config'])) {
+    // Session loeschen, damit keine alten Werte des letzten Laufs uebernommen werden
+    if (isset($_SESSION['dump'])) {
+        unset($_SESSION['dump']);
+    }
+    $search = [
+    '/', '\\', ':', '@', ];
+    $replace = [
+    '', '', '', '', ];
+    $config_file = str_replace($search, $replace, $_GET['config']);
+    if (is_readable($config['paths']['config'].$config_file.'.php')) {
+        $config['files']['parameter'] = $config['paths']['config'].$config_file.'.php';
+        $_SESSION['config_file'] = $config_file;
+        read_config($config['paths']['config'].$config['files']['parameter']);
+        $_SESSION['config'] = $config;
+    } else {
+        exit('Hacking attempt or configuration not found!');
+    }
 }
-$config=$_SESSION['config'];
-include ('./'.$config['files']['parameter']);
-$config['files']['iconpath']='./css/'.$config['theme'].'/icons/';
-include ('./inc/mysql.php');
-include ('./language/'.$config['language'].'/lang.php');
-include ('./language/'.$config['language'].'/lang_dump.php');
+$config = $_SESSION['config'];
 
-$pageheader=MSDHeader();
-$DumpFertig=0;
-$relativ_path='./';
-$flipped=array_flip($databases['Name']);
+include './'.$config['files']['parameter'];
+$config['files']['iconpath'] = './css/'.$config['theme'].'/icons/';
+include './inc/mysqli.php';
+include './language/'.$config['language'].'/lang.php';
+include './language/'.$config['language'].'/lang_dump.php';
 
-if (isset($_SESSION['dump'])&&!isset($_GET['config']))
-{
-	$dump=$_SESSION['dump'];
-}
-else
-{
-	$dump['tables']=Array();
-	$dump['records']=Array();
-	$dump['skip_data']=Array();
-	$dump['totalrecords']=0;
-	$dump['dbindex']=0;
-	//$_POST-Parameter lesen
-	$dump['kommentar']=(isset($_GET['comment'])) ? urldecode($_GET['comment']):'';
-	if (isset($_POST['kommentar'])) $dump['kommentar']=urldecode($_POST['kommentar']);
-	if (get_magic_quotes_gpc()) $dump['kommentar']=stripslashes($dump['kommentar']);
+$pageheader = MODHeader();
+$DumpFertig = 0;
+$relativ_path = './';
+$flipped = array_flip($databases['Name']);
 
-	$dump['backupdatei']=(isset($_POST['backupdatei'])) ? $_POST['backupdatei']:'';
-	$dump['part']=(isset($_POST['part'])) ? $_POST['part']:1;
-	$dump['part_offset']=(isset($_POST['part_offset'])) ? $_POST['part_offset']:0;
-	$dump['verbraucht']=(isset($_POST['verbraucht'])) ? $_POST['verbraucht']:0;
-	$dump['errors']=(isset($_POST['errors'])) ? $_POST['errors']:0;
-	$dump['table_offset']=(isset($_POST['table_offset'])) ? $_POST['table_offset']:-1;
-	$dump['zeilen_offset']=(isset($_POST['zeilen_offset'])) ? $_POST['zeilen_offset']:0;
-	$dump['filename_stamp']=(isset($_POST['filename_stamp'])) ? $_POST['filename_stamp']:'';
-	$dump['anzahl_zeilen']=(isset($_POST['anzahl_zeilen'])) ? $_POST['anzahl_zeilen']:(($config['minspeed']>0) ? $config['minspeed']:50);
-	$dump['dump_encoding']=(isset($_POST['dump_encoding'])) ? urldecode($_POST['dump_encoding']):'';
+if (isset($_SESSION['dump']) && !isset($_GET['config'])) {
+    $dump = $_SESSION['dump'];
+} else {
+    $dump['tables'] = [];
+    $dump['records'] = [];
+    $dump['skip_data'] = [];
+    $dump['totalrecords'] = 0;
+    $dump['dbindex'] = 0;
+    // Read $_POST parameter
+    $dump['kommentar'] = (isset($_GET['comment'])) ? urldecode($_GET['comment']) : '';
+    if (isset($_POST['kommentar'])) {
+        $dump['kommentar'] = urldecode($_POST['kommentar']);
+    }
 
-	if (isset($_GET['sel_dump_encoding']))
-	{
-		// Erstaufruf -> encoding auswerten
-		include_once ('./inc/functions_sql.php');
-		get_sql_encodings();
-		$encodingline=$config['mysql_possible_character_sets'][$_GET['sel_dump_encoding']];
-		$encoding=explode(' ',$encodingline);
-		$dump['dump_encoding']=isset($encoding[0]) ? $encoding[0]:$encodingline;
-	}
-	include ('./inc/define_icons.php');
-	$dump['tabellen_gesamt']=0;
+    $dump['backupdatei'] = (isset($_POST['backupdatei'])) ? $_POST['backupdatei'] : '';
+    $dump['part'] = (isset($_POST['part'])) ? $_POST['part'] : 1;
+    $dump['part_offset'] = (isset($_POST['part_offset'])) ? $_POST['part_offset'] : 0;
+    $dump['verbraucht'] = (isset($_POST['verbraucht'])) ? $_POST['verbraucht'] : 0;
+    $dump['errors'] = (isset($_POST['errors'])) ? $_POST['errors'] : 0;
+    $dump['table_offset'] = (isset($_POST['table_offset'])) ? $_POST['table_offset'] : -1;
+    $dump['zeilen_offset'] = (isset($_POST['zeilen_offset'])) ? $_POST['zeilen_offset'] : 0;
+    $dump['filename_stamp'] = (isset($_POST['filename_stamp'])) ? $_POST['filename_stamp'] : '';
+    $dump['anzahl_zeilen'] = (isset($_POST['anzahl_zeilen'])) ? $_POST['anzahl_zeilen'] : (((isset($config['minspeed']) && $config['minspeed'] > 0)) ? $config['minspeed'] : 50);
+    $dump['dump_encoding'] = (isset($_POST['dump_encoding'])) ? urldecode($_POST['dump_encoding']) : '';
+
+    if (isset($_GET['sel_dump_encoding'])) {
+        // First call -> evaluate encoding
+        include_once './inc/functions_sql.php';
+        get_sql_encodings();
+        $encodingline = $config['mysql_possible_character_sets'][$_GET['sel_dump_encoding']];
+        $encoding = explode(' ', $encodingline);
+        $dump['dump_encoding'] = isset($encoding[0]) ? $encoding[0] : $encodingline;
+    }
+    include './inc/define_icons.php';
+    $dump['tabellen_gesamt'] = 0;
 }
 
-$mp2=array(
+$mp2 = [
+'Bytes', 'Kilobytes', 'Megabytes', 'Gigabytes', ];
 
-'Bytes','Kilobytes','Megabytes','Gigabytes');
-
-FillMultiDBArrays();
-if ($databases['db_actual_tableselected']!=''&&$config['multi_dump']==0)
-{
-	$dump['tblArray']=explode('|',$databases['db_actual_tableselected']);
-	$tbl_sel=true;
-	$msgTbl=sprintf($lang['L_NR_TABLES_SELECTED'],count($dump['tblArray']));
+FillMultiDBarrays();
+if ('' != $databases['db_actual_tableselected'] && 0 == $config['multi_dump']) {
+    $dump['tblArray'] = explode('|', $databases['db_actual_tableselected']);
+    $tbl_sel = true;
+    $msgTbl = sprintf($lang['L_NR_TABLES_SELECTED'], count($dump['tblArray']));
 }
-// Korrektur -> Multi-DB-Array ist gefuellt (damit die Infos in der Konfig nicht verloren gehen), aber Multidump ist nicht aktiviert)
-if ($config['multi_dump']==0)
-{
-	unset($databases['multi']);
-	$databases['multi']=array();
-	$databases['multi'][0]=$databases['db_actual'];
-}
-else
-{
-	// wenn Multidump aktiviert ist, aber keine DB gewaehlt wurde -> aktuelle DB uebernehmen
-	if (!isset($databases['multi'][0])) $databases['multi'][0]=$databases['db_actual'];
-	// find correct dbindex -> take dbname from $databases['multi'] and get the correct index
-	// from $databases['Name'] -> needed to set $dump['dbindex'] for first run of command_before_dump
-	$dump['dbindex']=$flipped[$databases['multi'][0]];
+// Correction -> Multi-DB-array is filled (so that the info is not lost in the config), but multidump is not activated)
+if (isset($config['multi_dump']) && (0 == $config['multi_dump'])) {
+    unset($databases['multi']);
+    $databases['multi'] = [];
+    $databases['multi'][0] = $databases['db_actual'];
+} else {
+    // if multidump is activated, but no DB is selected -> take over current DB
+    if (!isset($databases['multi'][0])) {
+        $databases['multi'][0] = $databases['db_actual'];
+    }
+    // find correct dbindex -> take dbname from $databases['multi'] and get the correct index
+    // from $databases['Name'] -> needed to set $dump['dbindex'] for first run of command_before_dump
+    $dump['dbindex'] = $flipped[$databases['multi'][0]];
 }
 
-//Zeitzähler aktivieren
-$dump['max_zeit']=intval($config['max_execution_time']*$config['time_buffer']);
-$dump['startzeit']=time();
-$xtime=(isset($_POST['xtime'])) ? $_POST['xtime']:time();
-$dump['countdata']=(!empty($_POST['countdata'])) ? $_POST['countdata']:0;
-$dump['aufruf']=(!empty($_POST['aufruf'])) ? $_POST['aufruf']:0;
-MSD_mysql_connect($dump['dump_encoding']);
-if ($dump['table_offset']==-1) ExecuteCommand('b');
+// Activate time counter
+$dump['max_zeit'] = intval($config['max_execution_time'] * $config['time_buffer']);
+$dump['startzeit'] = time();
+$xtime = (isset($_POST['xtime'])) ? $_POST['xtime'] : time();
+$dump['countdata'] = (!empty($_POST['countdata'])) ? $_POST['countdata'] : 0;
+$dump['aufruf'] = (!empty($_POST['aufruf'])) ? $_POST['aufruf'] : 0;
+mod_mysqli_connect($dump['dump_encoding']);
+
+if (-1 == $dump['table_offset']) {
+    ExecuteCommand('b');
+}
 
 // only read tableinfos the first time and save it to session to speed up backing up process
-if (!isset($_SESSION['dump'])) getDBInfos();
-
-$num_tables=count($dump['tables']);
-
-if ($config['optimize_tables_beforedump']==1&&$dump['table_offset']==-1) $out.=sprintf($lang['L_NR_TABLES_OPTIMIZED'],$num_tables).'<br>';
-$dump['data']='';
-$dump['dbindex']=(isset($_POST['dbindex'])) ? $_POST['dbindex']:$flipped[$databases['multi'][0]];
-
-//Ausgaben-Header bauen
-$aus_header[]=headline('Backup: '.(($config['multi_dump']==1) ? 'Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')':$lang['L_DB'].': '.$databases['Name'][$dump['dbindex']].(($databases['praefix'][$dump['dbindex']]!='') ? ' ('.$lang['L_WITHPRAEFIX'].' <span>'.$databases['praefix'][$dump['dbindex']].'</span>)':'')));
-if (isset($aus_error)&&count($aus_error)>0) $aus_header=array_merge($aus_header,$aus_error);
-
-if ($num_tables==0)
-{
-	//keine Tabellen gefunden
-	$aus[]='<br><br><p class="error">'.$lang['L_ERROR'].': '.sprintf($lang['L_DUMP_NOTABLES'],$databases['Name'][$dump['dbindex']]).'</p>';
-    if (!$config['multi_dump']==1)
-	{
-		echo $pageheader;
-		echo get_page_parameter($dump);
-		echo implode("\n",$aus);
-		echo '</body></html>';
-		exit();
-	}
+if (!isset($_SESSION['dump'])) {
+    getDBInfos();
 }
-else
-{
-	if ($dump['table_offset']==-1)
-	{
-		// File anlegen, da Erstaufruf
-		new_file();
-		$dump['table_offset']=0; // jetzt kanns losgehen
-		flush();
-	}
-	else
-	{
-		// SQL-Befehle ermitteln
-		$dump['restzeilen']=$dump['anzahl_zeilen'];
-		while (($dump['table_offset']<$num_tables)&&($dump['restzeilen']>0))
-		{
-			$table=substr($dump['tables'][$dump['table_offset']],strpos($dump['tables'][$dump['table_offset']],'|')+1);
-			$adbname=substr($dump['tables'][$dump['table_offset']],0,strpos($dump['tables'][$dump['table_offset']],'|'));
-			if ($databases['Name'][$dump['dbindex']]!=$adbname)
-			{
-				//neue Datenbank
-				$dump['data'].="\nSET FOREIGN_KEY_CHECKS=1;";
-				$dump['data'].="\n".$mysql_commentstring.' EOB'."\n\n";
-				WriteToDumpFile();
-				WriteLog('Dump \''.$dump['backupdatei'].'\' finished.');
-				ExecuteCommand('a');
-				if ($config['multi_part']==1)
-				{
-					$out.=$lang['L_FINISHED'].'<br><div class="backupmsg">';
-					$dateistamm=substr($dump['backupdatei'],0,strrpos($dump['backupdatei'],'part_')).'part_';
-					$dateiendung=($config['compression']==1) ? '.sql.gz':'.sql';
-					for($i=1;$i<($dump['part']-$dump['part_offset']);$i++)
-					{
-						$mpdatei=$dateistamm.$i.$dateiendung;
-						clearstatcache();
-						$sz=byte_output(@filesize($config['paths']['backup'].$mpdatei));
-						$out.=$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$mpdatei.'" class="smallblack">'.$mpdatei.' ('.$sz.')</a> '.$lang['L_DUMP_SUCCESSFUL'].'<br>';
-					}
-				}
-				else
-				{
-					clearstatcache();
-					$out.=$lang['L_FINISHED'].'<br><div class="backupmsg"><a href="'.$config['paths']['backup'].$dump['backupdatei'].'" class="smallblack">'.$dump['backupdatei'].' ('.byte_output(filesize($config['paths']['backup'].$dump['backupdatei'])).')</a><br>';
-				}
-				if ($config['send_mail']==1) DoEmail();
 
-				for($i=0;$i<3;$i++)
-				{
-					if ($config['ftp_transfer'][$i]==1) DoFTP($i);
-				}
-				if (isset($flipped[$adbname])) $dump['dbindex']=$flipped[$adbname];
-				$dump['part_offset']=$dump['part']-1;
-				$out.='</div><br>';
-				ExecuteCommand('b');
-				new_file();
-			}
+$num_tables = count($dump['tables']);
 
-			$aktuelle_tabelle=$dump['table_offset'];
-			if ($dump['zeilen_offset']==0)
-			{
-				if ($config['minspeed']>0)
-				{
-					$dump['anzahl_zeilen']=$config['minspeed'];
-					$dump['restzeilen']=$config['minspeed'];
-				}
+if ((isset($config['optimize_tables_beforedump']) && (1 == $config['optimize_tables_beforedump'])) && -1 == $dump['table_offset']) {
+    $out .= sprintf($lang['L_NR_TABLES_OPTIMIZED'], $num_tables).'<br>';
+}
+$dump['data'] = '';
+$dump['dbindex'] = (isset($_POST['dbindex'])) ? $_POST['dbindex'] : $flipped[$databases['multi'][0]];
 
-				$create_statement='';
-				$create_statement=get_def($adbname,$table);
+// Build output header
+$aus_header[] = headline('Backup: '.((isset($config['multi_dump']) && (1 == $config['multi_dump'])) ? 'Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')' : $lang['L_DB'].': '.$databases['Name'][$dump['dbindex']].(('' != $databases['praefix'][$dump['dbindex']]) ? ' ('.$lang['L_WITHPRAEFIX'].' <span>'.$databases['praefix'][$dump['dbindex']].'</span>)' : '')));
+if (isset($aus_error) && count($aus_error) > 0) {
+    $aus_header = array_merge($aus_header, $aus_error);
+}
 
-				if (!($create_statement===false))
-				{
-					$dump['data'].=$create_statement;
-				}
-				else
-				{
-					WriteToDumpFile(); // save data we have up to now
-					// error reading table definition
-					$read_create_error=sprintf($lang['L_FATAL_ERROR_DUMP'],$table,$adbname).': '.mysqli_error($config['dbconnection']);
-					Errorlog("DUMP",$databases['db_actual'],'',$read_create_error,0);
-					WriteLog($read_create_error);
-					if ($config['stop_with_error']>0)
-					{
-						die($read_create_error);
-					}
-					$dump['errors']++;
-				}
-			}
-			WriteToDumpFile();
-			if (!in_array($adbname.'|'.$table,$dump['skip_data'])&&$dump['table_types'][getDBIndex($adbname,$table)]!='VIEW')
-			{
-				get_content($adbname,$table);
-				$dump['restzeilen']--;
-			}
-			else
-			{
-				// skip data
-				if ($dump['table_types'][getDBIndex($adbname,$table)]!='VIEW') $dump['data'].='/*!40000 ALTER TABLE `'.$table.'` ENABLE KEYS */;'."\n";
-				WriteToDumpFile();
-				$dump['table_offset']++;
-			}
-			if ($config['memory_limit']>0&&strlen($dump['data'])>$config['memory_limit']) WriteToDumpFile();
-		}
-	}
+if (0 == $num_tables) {
+    // no tables found
+    $aus[] = '<br><br><p class="error">'.$lang['L_ERROR'].': '.sprintf($lang['L_DUMP_NOTABLES'], $databases['Name'][$dump['dbindex']]).'</p>';
+    if (1 == !$config['multi_dump']) {
+        echo $pageheader;
+        echo get_page_parameter($dump);
+        echo implode("\n", $aus);
+        echo '</body></html>';
+        exit();
+    }
+} else {
+    if (-1 == $dump['table_offset']) {
+        // Create file, since first call
+        new_file();
+        $dump['table_offset'] = 0; // now it can start
+        flush();
+    } else {
+        // Determine SQL commands
+        $dump['restzeilen'] = $dump['anzahl_zeilen'];
+        while (($dump['table_offset'] < $num_tables) && ($dump['restzeilen'] > 0)) {
+            $table = substr($dump['tables'][$dump['table_offset']], strpos($dump['tables'][$dump['table_offset']], '|') + 1);
+            $adbname = substr($dump['tables'][$dump['table_offset']], 0, strpos($dump['tables'][$dump['table_offset']], '|'));
+            if ($databases['Name'][$dump['dbindex']] != $adbname) {
+                //neue Datenbank
+                $dump['data'] .= "\nSET FOREIGN_KEY_CHECKS=1;";
+                $dump['data'] .= "\n".$mysql_commentstring.' EOB'."\n\n";
+                WriteToDumpFile();
+                WriteLog('Dump \''.$dump['backupdatei'].'\' finished.');
+                ExecuteCommand('a');
+                if (1 == $config['multi_part']) {
+                    $out .= $lang['L_FINISHED'].'<br><div class="backupmsg">';
+                    $dateistamm = substr($dump['backupdatei'], 0, strrpos($dump['backupdatei'], 'part_')).'part_';
+                    $dateiendung = (1 == $config['compression']) ? '.sql.gz' : '.sql';
+                    for ($i = 1; $i < ($dump['part'] - $dump['part_offset']); ++$i) {
+                        $mpdatei = $dateistamm.$i.$dateiendung;
+                        clearstatcache();
+                        $sz = byte_output(@filesize($config['paths']['backup'].$mpdatei));
+                        $out .= $lang['L_FILE'].' <a href="'.$config['paths']['backup'].$mpdatei.'" class="smallblack">'.$mpdatei.' ('.$sz.')</a> '.$lang['L_DUMP_SUCCESSFUL'].'<br>';
+                    }
+                } else {
+                    clearstatcache();
+                    $out .= $lang['L_FINISHED'].'<br><div class="backupmsg"><a href="'.$config['paths']['backup'].$dump['backupdatei'].'" class="smallblack">'.$dump['backupdatei'].' ('.byte_output(filesize($config['paths']['backup'].$dump['backupdatei'])).')</a><br>';
+                }
+                if (1 == $config['send_mail']) {
+                    DoEmail();
+                }
 
-	/////////////////////////////////
-	// Anzeige - Fortschritt
-	/////////////////////////////////
-	if ($config['multi_dump']==1)
-	{
-		$mudbs='';
-		$count_dbs=count($databases['multi']);
-		for($i=0;$i<$count_dbs;$i++)
-		{
-			if ($databases['Name'][$dump['dbindex']]==$databases['multi'][$i]) $mudbs.='<span class="active_db">'.$databases['multi'][$i].'&nbsp;&nbsp;</span> ';
-			else
-				$mudbs.='<span class="success">'.$databases['multi'][$i].'&nbsp;&nbsp;</span> ';
-		}
-	}
-	if ($config['multi_part']==1) $aus[]='<h5>Multipart-Backup: '.$config['multipartgroesse1'].' '.$mp2[$config['multipartgroesse2']].'</h5>';
+                for ($i = 0; $i < 3; ++$i) {
+                    if (isset($config['ftp_transfer'][$i]) && (1 == $config['ftp_transfer'][$i])) {
+                        DoFTP($i);
+                    }
+                    if (isset($config['sftp_transfer'][$i]) && (1 == $config['sftp_transfer'][$i])) {
+                        DoSFTP($i);
+                    }
+                }
+                if (isset($flipped[$adbname])) {
+                    $dump['dbindex'] = $flipped[$adbname];
+                }
+                $dump['part_offset'] = $dump['part'] - 1;
+                $out .= '</div><br>';
+                ExecuteCommand('b');
+                new_file();
+            }
 
-	$aus[]='<h4>'.$lang['L_DUMP_HEADLINE'].'</h4>';
+            $aktuelle_tabelle = $dump['table_offset'];
+            if (0 == $dump['zeilen_offset']) {
+                if (isset($config['minspeed']) && ($config['minspeed'] > 0)) {
+                    $dump['anzahl_zeilen'] = $config['minspeed'];
+                    $dump['restzeilen'] = $config['minspeed'];
+                }
 
-	if ($dump['kommentar']>'') $aus[]=$lang['L_COMMENT'].': <span><em>'.$dump['kommentar'].'</em></span><br>';
-	$aus[]=($config['multi_dump']==1) ? $lang['L_DB'].': '.$mudbs:$lang['L_DB'].': <strong>'.$databases['Name'][$dump['dbindex']].'</strong>';
-	$aus[]=(($databases['praefix'][$dump['dbindex']]!='') ? ' ('.$lang['L_WITHPRAEFIX'].' <span>'.$databases['praefix'][$dump['dbindex']].'</span>)':'').'<br>';
-	if (isset($tbl_sel)) $aus[]=$msgTbl.'<br><br>';
+                $create_statement = '';
+                $create_statement = get_def($adbname, $table);
 
-	if ($config['multi_part']==1)
-	{
-		$aus[]='<span>Multipart-Backup File <strong>'.($dump['part']-$dump['part_offset']-1).'</strong></span><br>';
-		$aus2=', '.($dump['part']-1).' files';
-	}
-	$aus[]=$lang['L_DUMP_FILENAME'].'<b>'.$dump['backupdatei'].'</b><br>'.$lang['L_CHARSET'].': <strong>'.$dump['dump_encoding'].'</strong>'.
+                if (!(false === $create_statement)) {
+                    $dump['data'] .= $create_statement;
+                } else {
+                    WriteToDumpFile(); // save data we have up to now
+                    // error reading table definition
+                    $read_create_error = sprintf($lang['L_FATAL_ERROR_DUMP'], $table, $adbname).': '.mysqli_error($config['dbconnection']);
+                    Errorlog('DUMP', $databases['db_actual'], '', $read_create_error, 0);
+                    WriteLog($read_create_error);
+                    if ($config['stop_with_error'] > 0) {
+                        exit($read_create_error);
+                    }
+                    ++$dump['errors'];
+                }
+            }
+            WriteToDumpFile();
+            if (!in_array($adbname.'|'.$table, $dump['skip_data']) && 'VIEW' != $dump['table_types'][getDBIndex($adbname, $table)]) {
+                get_content($adbname, $table);
+                --$dump['restzeilen'];
+            } else {
+                // skip data
+                if ('VIEW' != $dump['table_types'][getDBIndex($adbname, $table)]) {
+                    $dump['data'] .= '/*!40000 ALTER TABLE `'.$table.'` ENABLE KEYS */;'."\n";
+                }
+                WriteToDumpFile();
+                ++$dump['table_offset'];
+            }
+            if ((isset($config['memory_limit']) && $config['memory_limit'] > 0) && strlen($dump['data']) > $config['memory_limit']) {
+                WriteToDumpFile();
+            }
+        }
+    }
 
-	'<br>'.$lang['L_FILESIZE'].': <b>'.byte_output($dump['filesize']).'</b><br><br>'.$lang['L_GZIP_COMPRESSION'].' <b>';
-	$aus[]=($config['compression']==1) ? $lang['L_ACTIVATED']:$lang['L_NOT_ACTIVATED'];
-	$aus[]='</b>.<br>';
-	if ($out>'') $aus[]='<br><span class="smallgrey">'.$out.'</span>';
+    /*
+     * Display - Progress
+     */
+    if (isset($config['multi_dump']) && (1 == $config['multi_dump'])) {
+        $mudbs = '';
+        $count_dbs = count($databases['multi']);
+        for ($i = 0; $i < $count_dbs; ++$i) {
+            if ($databases['Name'][$dump['dbindex']] == $databases['multi'][$i]) {
+                $mudbs .= '<span class="active_db">'.$databases['multi'][$i].'&nbsp;&nbsp;</span> ';
+            } else {
+                $mudbs .= '<span class="success">'.$databases['multi'][$i].'&nbsp;&nbsp;</span> ';
+            }
+        }
+    }
+    if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+        $aus[] = '<h5>Multipart-Backup: '.$config['multipartgroesse1'].' '.$mp2[$config['multipartgroesse2']].'</h5>';
+    }
 
-	if (isset($dump['tables'][$dump['table_offset']]))
-	{
-		$table=substr($dump['tables'][$dump['table_offset']],strpos($dump['tables'][$dump['table_offset']],'|')+1);
-		$adbname=substr($dump['tables'][$dump['table_offset']],0,strpos($dump['tables'][$dump['table_offset']],'|'));
+    $aus[] = '<h4>'.$lang['L_DUMP_HEADLINE'].'</h4>';
 
-		// get nr of recorsd from dump-array
-		$record_string=$dump['records'][$dump['table_offset']];
-		$record_string=explode('|',$record_string);
-		$dump['zeilen_total']=$record_string[1];
+    if ($dump['kommentar'] > '') {
+        $aus[] = $lang['L_COMMENT'].': <span><em>'.$dump['kommentar'].'</em></span><br>';
+    }
+    $aus[] = ((isset($config['multi_dump']) && 1 == $config['multi_dump'])) ? $lang['L_DB'].': '.$mudbs : $lang['L_DB'].': <strong>'.$databases['Name'][$dump['dbindex']].'</strong>';
+    $aus[] = (('' != $databases['praefix'][$dump['dbindex']]) ? ' ('.$lang['L_WITHPRAEFIX'].' <span>'.$databases['praefix'][$dump['dbindex']].'</span>)' : '').'<br>';
+    if (isset($tbl_sel)) {
+        $aus[] = $msgTbl.'<br><br>';
+    }
 
-		if ($dump['zeilen_total']>0) $fortschritt=intval((100*$dump['zeilen_offset'])/$dump['zeilen_total']);
-		else
-			$fortschritt=100;
+    if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+        $aus[] = '<span>Multipart-Backup File <strong>'.($dump['part'] - $dump['part_offset'] - 1).'</strong></span><br>';
+        $aus2 = ', '.($dump['part'] - 1).' files';
+    }
+    $aus[] = $lang['L_DUMP_FILENAME'].'<b>'.$dump['backupdatei'].'</b><br>'.$lang['L_CHARSET'].': <strong>'.$dump['dump_encoding'].'</strong>'.
 
-		$aus[]=$lang['L_SAVING_TABLE'].'<b>'.($dump['table_offset']+1).'</b> '.$lang['L_OF'].'<b> '.sizeof($dump['tables']).'</b><br>'.$lang['L_ACTUAL_TABLE'].': <b>'.$table.'</b><br><br>'.$lang['L_PROGRESS_TABLE'].':<br>';
+    '<br>'.$lang['L_FILESIZE'].': <b>'.byte_output($dump['filesize']).'</b><br><br>'.$lang['L_GZIP_COMPRESSION'].' <b>';
+    $aus[] = (isset($config['compression']) && (1 == $config['compression'])) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED'];
+    $aus[] = '</b>.<br>';
+    if ($out > '') {
+        $aus[] = '<br><span class="smallgrey">'.$out.'</span>';
+    }
 
-		$aus[]='<table border="0" width="380"><tr>'.'<td width="'.($fortschritt*3).'"><img src="'.$config['files']['iconpath'].'progressbar_dump.gif" alt="" width="'.($fortschritt*3).'" height="16" border="0"></td>'.'<td width="'.((100-$fortschritt)*3).'">&nbsp;</td>'.'<td width="80" align="right">'.($fortschritt).'%</td>';
+    if (isset($dump['tables'][$dump['table_offset']])) {
+        $table = substr($dump['tables'][$dump['table_offset']], strpos($dump['tables'][$dump['table_offset']], '|') + 1);
+        $adbname = substr($dump['tables'][$dump['table_offset']], 0, strpos($dump['tables'][$dump['table_offset']], '|'));
 
-		if ($dump['anzahl_zeilen']+$dump['zeilen_offset']>=$dump['zeilen_total'])
-		{
-			$eintrag=$dump['zeilen_offset']+1;
-			$zeilen_gesamt=$dump['zeilen_total'];
-			if ($zeilen_gesamt==0) $eintrag=0;
-		}
-		else
-		{
-			$zeilen_gesamt=$dump['zeilen_offset']+$dump['anzahl_zeilen'];
-			$eintrag=$dump['zeilen_offset']+1;
-		}
+        // get nr of recorsd from dump-array
+        $record_string = $dump['records'][$dump['table_offset']];
+        $record_string = explode('|', $record_string);
+        $dump['zeilen_total'] = $record_string[1];
 
-		$aus[]='</tr><tr>'.'<td colspan="3">'.$lang['L_ENTRY'].' <b>'.number_format($eintrag,0,',','.').'</b> '.$lang['L_UPTO'].' <b>'.number_format(($zeilen_gesamt),0,',','.').'</b> '.$lang['L_OF'].' <b>'.number_format($dump['zeilen_total'],0,',','.').'</b></td></tr></table>';
+        if ($dump['zeilen_total'] > 0) {
+            $fortschritt = intval((100 * $dump['zeilen_offset']) / $dump['zeilen_total']);
+        } else {
+            $fortschritt = 100;
+        }
 
-		$dump['tabellen_gesamt']=(isset($dump['tables'])) ? count($dump['tables']):0;
+        $aus[] = $lang['L_SAVING_TABLE'].'<b>'.($dump['table_offset'] + 1).'</b> '.$lang['L_OF'].'<b> '.sizeof($dump['tables']).'</b><br>'.$lang['L_ACTUAL_TABLE'].': <b>'.$table.'</b><br><br>'.$lang['L_PROGRESS_TABLE'].':<br>';
 
-		$noch_zu_speichern=$dump['totalrecords']-$dump['countdata'];
-		$prozent=($dump['totalrecords']>0) ? round(((100*$noch_zu_speichern)/$dump['totalrecords']),0):100;
-		if ($noch_zu_speichern==0||$prozent>100) $prozent=100;
+        $aus[] = '<table border="0" width="380"><tr>'.'<td width="'.($fortschritt * 3).'"><img src="'.$config['files']['iconpath'].'progressbar_dump.gif" alt="" width="'.($fortschritt * 3).'" height="16" border="0"></td>'.'<td width="'.((100 - $fortschritt) * 3).'">&nbsp;</td>'.'<td width="80" align="right">'.($fortschritt).'%</td>';
 
-		$aus[]="\n".'<br>'.$lang['L_PROGRESS_OVER_ALL'].':'."\n".'<table border="0" width="550" cellpadding="0" cellspacing="0"><tr>'.'<td width="'.(5*(100-$prozent)).'"><img src="'.$config['files']['iconpath'].'progressbar_dump.gif" alt="" width="'.(5*(100-$prozent)).'" height="16" border="0"></td>'.'<td width="'.($prozent*5).'" align="center"></td>'.'<td width="50">'.(100-$prozent).'%</td></tr></table>';
+        if ($dump['anzahl_zeilen'] + $dump['zeilen_offset'] >= $dump['zeilen_total']) {
+            $eintrag = $dump['zeilen_offset'] + 1;
+            $zeilen_gesamt = $dump['zeilen_total'];
+            if (0 == $zeilen_gesamt) {
+                $eintrag = 0;
+            }
+        } else {
+            $zeilen_gesamt = $dump['zeilen_offset'] + $dump['anzahl_zeilen'];
+            $eintrag = $dump['zeilen_offset'] + 1;
+        }
 
-		//Speed-Anzeige
-		$fw=($config['maxspeed']==$config['minspeed']) ? 300:round(($dump['anzahl_zeilen']-$config['minspeed'])/($config['maxspeed']-$config['minspeed'])*300,0);
-		if ($fw>300) $fw=300;
-		$aus[]='<br><table border="0" cellpadding="0" cellspacing="0"><tr>'.'<td class="nomargin" width="60" valign="top" align="center" style="font-size:10px;" >'.'<strong>Speed</strong><br>'.$dump['anzahl_zeilen'].'</td><td class="nomargin" width="300">'.'<table border="0" width="100%" cellpadding="0" cellspacing="0"><tr>'.'<td class="nomargin small" align="left" width="300" nowrap="nowrap">'.'<img src="'.$config['files']['iconpath'].'progressbar_speed.gif" alt="" width="'.$fw.'" height="14" border="0" vspace="0" hspace="0">'.'</td></tr></table><table border="0" width="100%" cellpadding="0" cellspacing="0"><tr>'.'<td class="nomargin" align="left" nowrap="nowrap" style="font-size:10px;" >'.$config['minspeed'].'</td>'.'<td class="nomargin" nowrap="nowrap" style="font-size:10px;text-align:right;" >'.$config['maxspeed'].'</td>'.'</tr></table>'."\n".'</td></tr></table>'.
+        $aus[] = '</tr><tr>'.'<td colspan="3">'.$lang['L_ENTRY'].' <b>'.number_format($eintrag, 0, ',', '.').'</b> '.$lang['L_UPTO'].' <b>'.number_format(($zeilen_gesamt), 0, ',', '.').'</b> '.$lang['L_OF'].' <b>'.number_format($dump['zeilen_total'], 0, ',', '.').'</b></td></tr></table>';
 
-		//Status-Text
-		'<p class="small">'.zeit_format(time()-$xtime).', '.$dump['aufruf'].' '.$lang['L_PAGE_REFRESHS'].$aus2;
-		$aus[]=($dump['errors']>0) ? ', <span style="color:red;">'.$dump['errors'].' errors</span>':'';
-		$aus[]='</p>';
-	}
-	else
-		$dump['table_offset']++;
-		// Ende Anzeige
-	WriteToDumpFile();
-	if (!isset($summe_eintraege)) $summe_eintraege=0;
+        $dump['tabellen_gesamt'] = (isset($dump['tables'])) ? count($dump['tables']) : 0;
 
-	if ($dump['table_offset']<=$dump['tabellen_gesamt'])
-	{
-		$dauer=time()-($xtime+$dump['verbraucht']);
-		$dump['verbraucht']+=$dauer;
-		$summe_eintraege+=$dump['anzahl_zeilen'];
+        $noch_zu_speichern = $dump['totalrecords'] - $dump['countdata'];
+        $prozent = ($dump['totalrecords'] > 0) ? round(((100 * $noch_zu_speichern) / $dump['totalrecords']), 0) : 100;
+        if (0 == $noch_zu_speichern || $prozent > 100) {
+            $prozent = 100;
+        }
 
-		//Zeitanpassung
-		if ($dauer<$dump['max_zeit'])
-		{
-			$dump['anzahl_zeilen']=$dump['anzahl_zeilen']*$config['tuning_add'];
-			if ($dauer<$dump['max_zeit']/2) $dump['anzahl_zeilen']*=1.8;
-			if ($dump['anzahl_zeilen']>$config['maxspeed']) $dump['anzahl_zeilen']=$config['maxspeed'];
-		}
-		else
-		{
-			$dump['anzahl_zeilen']=$dump['anzahl_zeilen']*$config['tuning_sub'];
-			if ($dump['anzahl_zeilen']<$config['minspeed']) $dump['anzahl_zeilen']=$config['minspeed'];
-		}
-		$dump['anzahl_zeilen']=intval($dump['anzahl_zeilen']);
-		$dump['aufruf']++;
-	}
-	else
-	{
-		//Backup fertig
-		$dump['data']="\nSET FOREIGN_KEY_CHECKS=1;";
-		$dump['data'].="\n".$mysql_commentstring.' EOB'."\n\n";
-		WriteToDumpFile();
-		ExecuteCommand('a');
-		chmod($config['paths']['backup'].$dump['backupdatei'],0777);
-		if ($config['multi_part']==1)
-		{
-			$out.="\n".'<br><div class="backupmsg">';
-			$dateistamm=substr($dump['backupdatei'],0,strrpos($dump['backupdatei'],'part_')).'part_';
-			$dateiendung=($config['compression']==1) ? '.sql.gz':'.sql';
-			clearstatcache();
-			for($i=1;$i<($dump['part']-$dump['part_offset']);$i++)
-			{
-				$mpdatei=$dateistamm.$i.$dateiendung;
-				$sz=byte_output(@filesize($config['paths']['backup'].$mpdatei));
-				$out.="\n".$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$mpdatei.'" class="smallblack">'.$mpdatei.' ('.$sz.')</a> '.$lang['L_DUMP_SUCCESSFUL'].'<br>';
-			}
+        $aus[] = "\n".'<br>'.$lang['L_PROGRESS_OVER_ALL'].':'."\n".'<table border="0" width="550" cellpadding="0" cellspacing="0"><tr>'.'<td width="'.(5 * (100 - $prozent)).'"><img src="'.$config['files']['iconpath'].'progressbar_dump.gif" alt="" width="'.(5 * (100 - $prozent)).'" height="16" border="0"></td>'.'<td width="'.($prozent * 5).'" align="center"></td>'.'<td width="50">'.(100 - $prozent).'%</td></tr></table>';
 
-		}
-		else
-			$out.="\n".'<div class="backupmsg">'.$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$dump['backupdatei'].'" class="smallblack">'.$dump['backupdatei'].' ('.byte_output(filesize($config['paths']['backup'].$dump['backupdatei'])).')'.'</a>'.$lang['L_DUMP_SUCCESSFUL'].'<br>';
+        //Speed-Anzeige
+        $config['maxspeed'] = isset($config['maxspeed']) ? $config['maxspeed'] : '1';
+        $config['minspeed'] = isset($config['minspeed']) ? $config['minspeed'] : '1';
+        $fw = ($config['maxspeed'] == $config['minspeed']) ? 300 : round(($dump['anzahl_zeilen'] - $config['minspeed']) / ($config['maxspeed'] - $config['minspeed']) * 300, 0);
+        if ($fw > 300) {
+            $fw = 300;
+        }
+        $aus[] = '<br><table border="0" cellpadding="0" cellspacing="0"><tr>'.'<td class="nomargin" width="60" valign="top" align="center" style="font-size:10px;" >'.'<strong>Speed</strong><br>'.$dump['anzahl_zeilen'].'</td><td class="nomargin" width="300">'.'<table border="0" width="100%" cellpadding="0" cellspacing="0"><tr>'.'<td class="nomargin small" align="left" width="300" nowrap="nowrap">'.'<img src="'.$config['files']['iconpath'].'progressbar_speed.gif" alt="" width="'.$fw.'" height="14" border="0" vspace="0" hspace="0">'.'</td></tr></table><table border="0" width="100%" cellpadding="0" cellspacing="0"><tr>'.'<td class="nomargin" align="left" nowrap="nowrap" style="font-size:10px;" >'.$config['minspeed'].'</td>'.'<td class="nomargin" nowrap="nowrap" style="font-size:10px;text-align:right;" >'.$config['maxspeed'].'</td>'.'</tr></table>'."\n".'</td></tr></table>'.
 
-		$xtime=time()-$xtime;
-		$aus=Array();
-		$aus[]='<br>'."\n";
-		if ($config['multi_dump']==1)
-		{
-			WriteLog('Dump \''.$dump['backupdatei'].'\' finished.');
-			WriteLog('Multidump: '.count($databases['multi']).' Databases in '.zeit_format($xtime).'.');
-		}
-		else
-			WriteLog('Dump \''.$dump['backupdatei'].'\' finished in '.zeit_format($xtime).'.');
+        //Status-Text
+        '<p class="small">'.zeit_format(time() - $xtime).', '.$dump['aufruf'].' '.$lang['L_PAGE_REFRESHS'].$aus2;
+        $aus[] = ($dump['errors'] > 0) ? ', <span style="color:red;">'.$dump['errors'].' errors</span>' : '';
+        $aus[] = '</p>';
+    } else {
+        ++$dump['table_offset'];
+    }
+    // End display
+    WriteToDumpFile();
+    if (!isset($summe_eintraege)) {
+        $summe_eintraege = 0;
+    }
 
-		if ($config['send_mail']==1) DoEmail();
-		for($i=0;$i<3;$i++)
-		{
-			if ($config['ftp_transfer'][$i]==1) DoFTP($i);
-		}
+    if ($dump['table_offset'] <= $dump['tabellen_gesamt']) {
+        $dauer = time() - ($xtime + $dump['verbraucht']);
+        $dump['verbraucht'] += $dauer;
+        $summe_eintraege += $dump['anzahl_zeilen'];
 
-		$aus[]='<strong>'.$lang['L_DONE'].'</strong><br>';
+        // Time adjustment
+        if ($dauer < $dump['max_zeit']) {
+            $dump['anzahl_zeilen'] = $dump['anzahl_zeilen'] * $config['tuning_add'];
+            if ($dauer < $dump['max_zeit'] / 2) {
+                $dump['anzahl_zeilen'] *= 1.8;
+            }
+            if ($dump['anzahl_zeilen'] > $config['maxspeed']) {
+                $dump['anzahl_zeilen'] = $config['maxspeed'];
+            }
+        } else {
+            $dump['anzahl_zeilen'] = $dump['anzahl_zeilen'] * $config['tuning_sub'];
+            if ($dump['anzahl_zeilen'] < $config['minspeed']) {
+                $dump['anzahl_zeilen'] = $config['minspeed'];
+            }
+        }
+        $dump['anzahl_zeilen'] = intval($dump['anzahl_zeilen']);
+        ++$dump['aufruf'];
+    } else {
+        // Backup ready
+        $dump['data'] = "\nSET FOREIGN_KEY_CHECKS=1;";
+        $dump['data'] .= "\n".$mysql_commentstring.' EOB'."\n\n";
+        WriteToDumpFile();
+        ExecuteCommand('a');
+        chmod($config['paths']['backup'].$dump['backupdatei'], 0777);
+        if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+            $out .= "\n".'<br><div class="backupmsg">';
+            $dateistamm = substr($dump['backupdatei'], 0, strrpos($dump['backupdatei'], 'part_')).'part_';
+            $dateiendung = (1 == $config['compression']) ? '.sql.gz' : '.sql';
+            clearstatcache();
+            for ($i = 1; $i < ($dump['part'] - $dump['part_offset']); ++$i) {
+                $mpdatei = $dateistamm.$i.$dateiendung;
+                $sz = byte_output(@filesize($config['paths']['backup'].$mpdatei));
+                $out .= "\n".$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$mpdatei.'" class="smallblack">'.$mpdatei.' ('.$sz.')</a> '.$lang['L_DUMP_SUCCESSFUL'].'<br>';
+            }
+        } else {
+            $out .= "\n".'<div class="backupmsg">'.$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$dump['backupdatei'].'" class="smallblack">'.$dump['backupdatei'].' ('.byte_output(filesize($config['paths']['backup'].$dump['backupdatei'])).')'.'</a>'.$lang['L_DUMP_SUCCESSFUL'].'<br>';
+        }
 
-		if ($config['multi_dump']==1)
-		{
-			$aus[]=sprintf($lang['L_MULTIDUMP'],count($databases['multi'])).': ';
-			$aus[]='<strong>'.implode(', ',$databases['multi']).'</strong>';
-			$aus2='';
-			$out='';
-		}
-		else
-		{
-			$aus[]='<br>'.sprintf($lang['L_DUMP_ENDERGEBNIS'],$num_tables,number_format($dump['countdata'],0,',','.'));
-		}
-		if ($dump['errors']>0) $aus[]=sprintf($lang['L_DUMP_ERRORS'],$dump['errors']);
+        $xtime = time() - $xtime;
+        $aus = [];
+        $aus[] = '<br>'."\n";
+        if (isset($config['multi_dump']) && (1 == $config['multi_dump'])) {
+            WriteLog('Dump \''.$dump['backupdatei'].'\' finished.');
+            WriteLog('Multidump: '.count($databases['multi']).' Databases in '.zeit_format($xtime).'.');
+        } else {
+            WriteLog('Dump \''.$dump['backupdatei'].'\' finished in '.zeit_format($xtime).'.');
+        }
 
-		$aus[]='<form action="dump.php?MySQLDumper='.session_id().'" method="POST">'.$out.'<br>'.'<p class="small">'.zeit_format($xtime).', '.$dump['aufruf'].' '.$lang['L_PAGE_REFRESHS'].$aus2.'</p>'."\n";
-		$aus[]="\n".'<br><input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_CONTROL'].'" onclick="self.location.href=\''.$relativ_path.'filemanagement.php\'">';
-		$aus[]='&nbsp;&nbsp;&nbsp;<input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_MINISQL'].'" onclick="self.location.href=\''.$relativ_path.'sql.php\'">';
-		$aus[]='&nbsp;&nbsp;&nbsp;<input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_OVERVIEW'].'" onclick="self.location.href=\''.$relativ_path.'main.php?action=db&amp;dbid='.$dump['dbindex'].'#dbid\'"><br><br>';
-		$aus[]='</div></form>';
+        if (isset($config['send_mail']) && (1 == $config['send_mail'])) {
+            DoEmail();
+        }
+        for ($i = 0; $i < 3; ++$i) {
+            if (isset($config['ftp_transfer'][$i]) && (1 == $config['ftp_transfer'][$i])) {
+                DoFTP($i);
+            }
+            if (isset($config['sftp_transfer'][$i]) && (1 == $config['sftp_transfer'][$i])) {
+                DoSFTP($i);
+            }
+        }
 
-		$DumpFertig=1;
-	}
+        $aus[] = '<strong>'.$lang['L_DONE'].'</strong><br>';
+
+        if (isset($config['multi_dump']) && (1 == $config['multi_dump'])) {
+            $aus[] = sprintf($lang['L_MULTIDUMP'], count($databases['multi'])).': ';
+            $aus[] = '<strong>'.implode(', ', $databases['multi']).'</strong>';
+            $aus2 = '';
+            $out = '';
+        } else {
+            $aus[] = '<br>'.sprintf($lang['L_DUMP_ENDERGEBNIS'], $num_tables, number_format($dump['countdata'], 0, ',', '.'));
+        }
+        if ($dump['errors'] > 0) {
+            $aus[] = sprintf($lang['L_DUMP_ERRORS'], $dump['errors']);
+        }
+
+        $aus[] = '<form action="dump.php?MyOOSDumperID='.session_id().'" method="POST">'.$out.'<br>'.'<p class="small">'.zeit_format($xtime).', '.$dump['aufruf'].' '.$lang['L_PAGE_REFRESHS'].$aus2.'</p>'."\n";
+        $aus[] = "\n".'<br><input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_CONTROL'].'" onclick="self.location.href=\''.$relativ_path.'filemanagement.php\'">';
+        $aus[] = '&nbsp;&nbsp;&nbsp;<input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_MINISQL'].'" onclick="self.location.href=\''.$relativ_path.'sql.php\'">';
+        $aus[] = '&nbsp;&nbsp;&nbsp;<input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_OVERVIEW'].'" onclick="self.location.href=\''.$relativ_path.'main.php?action=db&amp;dbid='.$dump['dbindex'].'#dbid\'"><br><br>';
+        $aus[] = '</div></form>';
+
+        $DumpFertig = 1;
+    }
 }
 
 //=====================================================================
-//================= Anzeige ===========================================
+//================= Display ===========================================
 //=====================================================================
 
+// Craft page
+$aus = array_merge($aus_header, $aus);
 
-//Seite basteln
-$aus=array_merge($aus_header,$aus);
-
-$dump['xtime']=$xtime;
-if ($DumpFertig!=1)
-{
-	// save actual values to session
-	$_SESSION['dump']=$dump;
-	$page_parameter=get_page_parameter($dump);
-	$pagefooter='</body></html>';
-	$selbstaufruf=$page_parameter.'<script language="javascript" type="text/javascript">setTimeout("document.dump.submit()", 10);</script></div>';
+$dump['xtime'] = $xtime;
+if (1 != $DumpFertig) {
+    // save actual values to session
+    $_SESSION['dump'] = $dump;
+    $page_parameter = get_page_parameter($dump);
+    $pagefooter = '</body></html>';
+    $selbstaufruf = $page_parameter.'<script>setTimeout("document.dump.submit()", 10);</script></div>';
+} else {
+    $dump = [];
+    $_SESSION['dump'] = $dump;
+    $pagefooter = MODFooter('', 1);
+    $selbstaufruf = '';
 }
-else
-{
-	$dump=array();
-	$_SESSION['dump']=$dump;
-	$pagefooter=MSDFooter('',1);
-	$selbstaufruf='';
-}
-$complete_page=$pageheader.implode("\n",$aus)."\n".$selbstaufruf."\n".$pagefooter;
+$complete_page = $pageheader.implode("\n", $aus)."\n".$selbstaufruf."\n".$pagefooter;
 echo $complete_page;
 ob_end_flush();
diff --git a/msd/filemanagement.php b/msd/filemanagement.php
index c25a2e46..1011bf19 100644
--- a/msd/filemanagement.php
+++ b/msd/filemanagement.php
@@ -1,10 +1,13 @@
 <?php
+error_reporting(E_ALL & ~E_STRICT);
+ini_set('display_errors', true);
+
 /* ----------------------------------------------------------------------
 
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,542 +21,530 @@
 
 define('OOS_VALID_MOD', true);
 
-if (isset($_GET['action'])&&$_GET['action']=='dl') $download=true;
-include ('./inc/header.php');
-include_once ('./language/'.$config['language'].'/lang.php');
-include_once ('./language/'.$config['language'].'/lang_filemanagement.php');
-include_once ('./language/'.$config['language'].'/lang_config_overview.php');
-include_once ('./language/'.$config['language'].'/lang_main.php');
-include_once ('./inc/functions_files.php');
-include_once ('./inc/functions_sql.php');
-$msg='';
-$dump=array();
-if ($config['auto_delete']==1) $msg=AutoDelete();
+if (isset($_GET['action']) && 'dl' == $_GET['action']) {
+    $download = true;
+}
+include './inc/header.php';
+include_once './language/'.$config['language'].'/lang.php';
+include_once './language/'.$config['language'].'/lang_dump.php';
+include_once './language/'.$config['language'].'/lang_filemanagement.php';
+include_once './language/'.$config['language'].'/lang_config_overview.php';
+include_once './language/'.$config['language'].'/lang_main.php';
+include_once './inc/functions_files.php';
+include_once './inc/functions_sql.php';
+$msg = '';
+$dump = [];
+if (isset($config['auto_delete']) && (1 == $config['auto_delete'])) {
+    $msg = AutoDelete();
+}
 get_sql_encodings(); // get possible sql charsets and also get default charset
 //0=Datenbank  1=Struktur
-$action=(isset($_GET['action'])) ? $_GET['action'] : 'files';
-$kind=(isset($_GET['kind'])) ? $_GET['kind'] : 0;
-$expand=(isset($_GET['expand'])) ? $_GET['expand'] : -1;
-$selectfile=(isset($_POST['selectfile'])) ? $_POST['selectfile'] : "";
-$destfile=(isset($_POST['destfile'])) ? $_POST['destfile'] : "";
-$compressed=(isset($_POST['compressed'])) ? $_POST['compressed'] : "";
-$dk=(isset($_POST['dumpKommentar'])) ? ((get_magic_quotes_gpc()) ? stripslashes($_POST['dumpKommentar']) : $_POST['dumpKommentar']) : "";
-$dk=str_replace(':','|',$dk); // remove : because of statusline
-$dump['sel_dump_encoding']=(isset($_POST['sel_dump_encoding'])) ? $_POST['sel_dump_encoding'] : get_index($config['mysql_possible_character_sets'],$config['mysql_standard_character_set']);
-$dump['dump_encoding']=isset($config['mysql_possible_character_sets'][$dump['sel_dump_encoding']]) ? $config['mysql_possible_character_sets'][$dump['sel_dump_encoding']] : 0;
+$action = (isset($_GET['action'])) ? $_GET['action'] : 'files';
+$kind = (isset($_GET['kind'])) ? $_GET['kind'] : 0;
+$expand = (isset($_GET['expand'])) ? $_GET['expand'] : -1;
+$selectfile = (isset($_POST['selectfile'])) ? $_POST['selectfile'] : '';
+$destfile = (isset($_POST['destfile'])) ? $_POST['destfile'] : '';
+$compressed = (isset($_POST['compressed'])) ? $_POST['compressed'] : '';
+$dk = (isset($_POST['dumpKommentar'])) ? $_POST['dumpKommentar'] : '';
 
-if ($action=='dl')
-{
-	// Download of a backup file wanted
-	$file='./'.$config['paths']['backup'].urldecode($_GET['f']);
-	if (is_readable($file))
-	{
-		header('Content-Description: File Transfer');
-		header('Content-Type: application/octet-stream');
-		header('Content-Disposition: attachment; filename='.basename($file));
-		header('Content-Transfer-Encoding: binary');
-		header('Expires: 0');
-		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-		header('Pragma: public');
-		header('Content-Length: '.(string) filesize($file));
-		flush();
-		$file=fopen($file,"rb");
-		while (!feof($file))
-		{
-			print fread($file,round(100*1024));
-			flush();
-		}
-		fclose($file);
-	}
+$dk = str_replace(':', '|', $dk); // remove : because of statusline
+$dump['sel_dump_encoding'] = (isset($_POST['sel_dump_encoding'])) ? $_POST['sel_dump_encoding'] : get_index($config['mysql_possible_character_sets'], $config['mysql_standard_character_set']);
+$dump['dump_encoding'] = isset($config['mysql_possible_character_sets'][$dump['sel_dump_encoding']]) ? $config['mysql_possible_character_sets'][$dump['sel_dump_encoding']] : 0;
 
-	//readfile($file);
-	exit();
+if ('dl' == $action) {
+    // Download of a backup file wanted
+    $file = './'.$config['paths']['backup'].urldecode($_GET['f']);
+    if (is_readable($file)) {
+        header('Content-Description: File Transfer');
+        header('Content-Type: application/octet-stream');
+        header('Content-Disposition: attachment; filename='.basename($file));
+        header('Content-Transfer-Encoding: binary');
+        header('Expires: 0');
+        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+        header('Pragma: public');
+        header('Content-Length: '.(string) filesize($file));
+        flush();
+        $file = fopen($file, 'rb');
+        while (!feof($file)) {
+            echo fread($file, round(100 * 1024));
+            flush();
+        }
+        fclose($file);
+    }
+
+    //readfile($file);
+    exit();
 }
-if (!@ob_start("ob_gzhandler")) @ob_start();
-echo MSDHeader();
 
-$toolboxstring='';
-$fpath=$config['paths']['backup'];
-$dbactiv=(isset($_GET['dbactiv'])) ? $_GET['dbactiv'] : $databases['db_actual'];
-$databases['multi']=Array();
-if ($databases['multisetting']=="")
-{
-	$databases['multi'][0]=$databases['db_actual'];
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
 }
-else
-{
-	$databases['multi']=explode(";",$databases['multisetting']);
-	$multi_praefixe=array();
-	$multi_praefixe=explode(";",$databases['multisetting_praefix']);
-	$toolboxstring='<br>';
-	if (is_array($databases['multi']))
-	{
-		for ($i=0; $i<sizeof($databases['multi']); $i++)
-		{
-			if ($i>0) $toolboxstring.=', ';
-			$toolboxstring.=$databases['multi'][$i];
-			if ($multi_praefixe[$i]>'') $toolboxstring.=' (<i>\''.$multi_praefixe[$i].'\'</i>)';
-		}
-	}
+echo MODHeader();
+
+$toolboxstring = '';
+$fpath = $config['paths']['backup'];
+$dbactiv = (isset($_GET['dbactiv'])) ? $_GET['dbactiv'] : $databases['db_actual'];
+$databases['multi'] = [];
+if ('' == $databases['multisetting']) {
+    $databases['multi'][0] = $databases['db_actual'];
+} else {
+    $databases['multi'] = explode(';', $databases['multisetting']);
+    $multi_praefixe = [];
+    $multi_praefixe = explode(';', $databases['multisetting_praefix']);
+    $toolboxstring = '<br>';
+    if (is_array($databases['multi'])) {
+        for ($i = 0; $i < sizeof($databases['multi']); ++$i) {
+            if ($i > 0) {
+                $toolboxstring .= ', ';
+            }
+            $toolboxstring .= $databases['multi'][$i];
+            if ($multi_praefixe[$i] > '') {
+                $toolboxstring .= ' (<i>\''.$multi_praefixe[$i].'\'</i>)';
+            }
+        }
+    }
 }
 
 //*** Abfrage ob Dump nach Tabellenaufruf ***
-if (isset($_POST['dump_tbl']))
-{
-	$check_dirs=TestWorkDir();
-	if (!$check_dirs===true) die($check_dirs);
-	$databases['db_actual_tableselected']=substr($_POST['tbl_array'],0,strlen($_POST['tbl_array'])-1);
-	WriteParams();
-	$dump['fileoperations']=0;
-	echo '<script language="JavaScript" type="text/javascript">parent.MyOOS_Dumper_content.location.href="dump.php?comment='.urlencode($dk).'&sel_dump_encoding='.$dump['sel_dump_encoding'].'&config='.urlencode($config['config_file']).'";</script></body></html>';
-	exit();
+if (isset($_POST['dump_tbl'])) {
+    $check_dirs = TestWorkDir();
+    if (true === !$check_dirs) {
+        exit($check_dirs);
+    }
+    $databases['db_actual_tableselected'] = substr($_POST['tbl_array'], 0, strlen($_POST['tbl_array']) - 1);
+    WriteParams();
+    $dump['fileoperations'] = 0;
+    echo '<script>parent.MyOOS_Dumper_content.location.href="dump.php?comment='.urlencode($dk).'&sel_dump_encoding='.$dump['sel_dump_encoding'].'&config='.urlencode($config['config_file']).'";</script></body></html>';
+    exit();
 }
 
 //*** Abfrage ob Dump ***
-if (isset($_POST['dump']))
-{
-	if (isset($_POST['tblfrage'])&&$_POST['tblfrage']==1)
-	{
-		//Tabellenabfrage
-		$tblfrage_refer="dump";
-		include ("inc/tabellenabfrage.php");
-		exit();
-	}
-	else
-	{
-		@$check_dir=TestWorkDir();
-		if (!$check_dir===true) die($check_dir);
-		$databases['db_actual_tableselected']="";
-		WriteParams();
+if (isset($_POST['dump'])) {
+    if (isset($_POST['tblfrage']) && 1 == $_POST['tblfrage']) {
+        //Tabellenabfrage
+        $tblfrage_refer = 'dump';
+        include 'inc/table_query.php';
+        exit();
+    } else {
+        @$check_dir = TestWorkDir();
+        if (true === !$check_dir) {
+            exit($check_dir);
+        }
+        $databases['db_actual_tableselected'] = '';
+        WriteParams();
+        $dump['fileoperations'] = 0;
 
-		$dump['fileoperations']=0;
-		echo '<script language="JavaScript" type="text/javascript">parent.MyOOS_Dumper_content.location.href="dump.php?comment='.urlencode($dk).'&sel_dump_encoding='.$dump['sel_dump_encoding'].'&config='.urlencode($config['config_file']).'";</script></body></html>';
-		exit();
-	}
+        $sUrl = 'dump.php?comment='.urlencode($dk).'&sel_dump_encoding='.$dump['sel_dump_encoding'].'&config='.urlencode($config['config_file']);
+        if ((isset($config['optimize_tables_beforedump']) && (1 == $config['optimize_tables_beforedump']))) {
+            echo '<div id="pagetitle">'.$lang['L_DUMP_HEADLINE'].'</div><div id="content"><p>';
+            echo '<br><br><p>'.sprintf($lang['L_DUMP_INFO'], $sUrl).'</p></div>';
+        }
+        echo '<script>parent.MyOOS_Dumper_content.location.href="dump.php?comment='.urlencode($dk).'&sel_dump_encoding='.$dump['sel_dump_encoding'].'&config='.urlencode($config['config_file']).'";</script></body></html>';
+        exit();
+    }
 }
 
 //*** Abfrage ob Restore nach Tabellenaufruf ***
-if (isset($_POST['restore_tbl']))
-{
-	$databases['db_actual_tableselected']=substr($_POST['tbl_array'],0,strlen($_POST['tbl_array'])-1);
-	WriteParams();
-	echo '<script language="JavaScript" type="text/javascript">parent.MyOOS_Dumper_content.location.href="restore.php?filename='.urlencode($_POST['filename']).'";</script></body></html>';
+if (isset($_POST['restore_tbl'])) {
+    $databases['db_actual_tableselected'] = substr($_POST['tbl_array'], 0, strlen($_POST['tbl_array']) - 1);
+    WriteParams();
+    echo '<script>parent.MyOOS_Dumper_content.location.href="restore.php?filename='.urlencode($_POST['filename']).'";</script></body></html>';
 
-	exit();
+    exit();
 }
 
 //*** Abfrage ob Restore ***
-if (isset($_POST['restore']))
-{
-	if (isset($_POST['file']))
-	{
-		if (isset($_POST['tblfrage'])&&$_POST['tblfrage']==1)
-		{
-			//Tabellenabfrage
-			$tblfrage_refer="restore";
-			$filename=urldecode($_POST['file'][0]);
-			include ("inc/tabellenabfrage.php");
-			exit();
-		}
-		else
-		{
-			$file=$_POST['file'][0];
-			$statusline=read_statusline_from_file($file);
-			if (isset($_POST['sel_dump_encoding_restore']))
-			{
-				$encodingstring=$config['mysql_possible_character_sets'][$_POST['sel_dump_encoding_restore']];
-				$encoding=explode(' ',$encodingstring);
-				$dump_encoding=$encoding[0];
-			}
-			else
-			{
-				if (!isset($statusline['charset'])||trim($statusline['charset'])=='?')
-				{
-					echo headline($lang['L_FM_RESTORE'].': '.$file);
+if (isset($_POST['restore'])) {
+    if (isset($_POST['file'])) {
+        if (isset($_POST['tblfrage']) && 1 == $_POST['tblfrage']) {
+            //Tabellenabfrage
+            $tblfrage_refer = 'restore';
+            $filename = urldecode($_POST['file'][0]);
+            include 'inc/table_query.php';
+            exit();
+        } else {
+            $file = $_POST['file'][0];
+            $statusline = read_statusline_from_file($file);
+            if (isset($_POST['sel_dump_encoding_restore'])) {
+                $encodingstring = $config['mysql_possible_character_sets'][$_POST['sel_dump_encoding_restore']];
+                $encoding = explode(' ', $encodingstring);
+                $dump_encoding = $encoding[0];
+            } else {
+                if (!isset($statusline['charset']) || '?' == trim($statusline['charset'])) {
+                    echo headline($lang['L_FM_RESTORE'].': '.$file);
 
-					// if we can't detect encoding ask user
-					echo '<br>'.$lang['L_CHOOSE_CHARSET'].'<br><br>';
-					echo '<form action="filemanagement.php?action=restore&amp;kind=0" method="POST">';
-					echo '<table><tr><td>'.$lang['L_FM_CHOOSE_ENCODING'].':</td><td>';
-					echo '<select name="sel_dump_encoding_restore">';
-					echo make_options($config['mysql_possible_character_sets'],$dump['sel_dump_encoding']);
-					echo '</select></td></tr><tr><td>';
-					echo $lang['L_MYSQL_CONNECTION_ENCODING'].':</td><td><strong>'.$config['mysql_standard_character_set'].'</strong></td></tr>';
+                    // if we can't detect encoding ask user
+                    echo '<br>'.$lang['L_CHOOSE_CHARSET'].'<br><br>';
+                    echo '<form action="filemanagement.php?action=restore&amp;kind=0" method="POST">';
+                    echo '<table><tr><td>'.$lang['L_FM_CHOOSE_ENCODING'].':</td><td>';
+                    echo '<select name="sel_dump_encoding_restore">';
+                    echo make_options($config['mysql_possible_character_sets'], $dump['sel_dump_encoding']);
+                    echo '</select></td></tr><tr><td>';
+                    echo $lang['L_MYSQL_CONNECTION_ENCODING'].':</td><td><strong>'.$config['mysql_standard_character_set'].'</strong></td></tr>';
 
-					echo '<tr><td colspan="2"><br><input type="submit" name="restore" class="Formbutton" value="'.$lang['L_FM_RESTORE'].'">';
-					echo '<input type="hidden" name="file[0]" value="'.$file.'">';
-					echo '</td></tr></table></form></body></html>';
-					exit();
-				}
-				else
-					$dump_encoding=$statusline['charset'];
-			}
+                    echo '<tr><td colspan="2"><br><input type="submit" name="restore" class="Formbutton" value="'.$lang['L_FM_RESTORE'].'">';
+                    echo '<input type="hidden" name="file[0]" value="'.$file.'">';
+                    echo '</td></tr></table></form></body></html>';
+                    exit();
+                } else {
+                    $dump_encoding = $statusline['charset'];
+                }
+            }
 
-			$databases['db_actual_tableselected']="";
-			WriteParams();
-			echo '<script language="JavaScript" type="text/javascript">parent.MyOOS_Dumper_content.location.href="restore.php?filename='.$file.'&dump_encoding='.$dump_encoding.'&kind='.$kind.'";</script></body></html>';
-			exit();
-		}
-	}
-	else
-		$msg.='<p class="error">'.$lang['L_FM_NOFILE'].'</p>';
+            $databases['db_actual_tableselected'] = '';
+            WriteParams();
+            echo '<script>parent.MyOOS_Dumper_content.location.href="restore.php?filename='.$file.'&dump_encoding='.$dump_encoding.'&kind='.$kind.'";</script></body></html>';
+            exit();
+        }
+    } else {
+        $msg .= '<p class="error">'.$lang['L_FM_NOFILE'].'</p>';
+    }
 }
 
 //*** Abfrage ob Delete ***
-$del=array();
-if (isset($_POST['delete']))
-{
-	if (isset($_POST['file']))
-	{
-		$delfiles=Array();
-		for ($i=0; $i<count($_POST['file']); $i++)
-		{
-			if (!strpos($_POST['file'][$i],"_part_")===false)
-			{
-				$delfiles[]=substr($_POST['file'][$i],0,strpos($_POST['file'][$i],"_part_")+6).'*';
-			}
-			else
-				$delfiles[]=$_POST['file'][$i];
-		}
-		for ($i=0; $i<count($delfiles); $i++)
-		{
-			$del=array_merge($del,DeleteFilesM($fpath,$delfiles[$i]));
-		}
-	}
-	else
-		$msg.='<p class="error">'.$lang['L_FM_NOFILE'].'</p>';
+$del = [];
+if (isset($_POST['delete'])) {
+    if (isset($_POST['file'])) {
+        $delfiles = [];
+        for ($i = 0; $i < count($_POST['file']); ++$i) {
+            if (false === !strpos($_POST['file'][$i], '_part_')) {
+                $delfiles[] = substr($_POST['file'][$i], 0, strpos($_POST['file'][$i], '_part_') + 6).'*';
+            } else {
+                $delfiles[] = $_POST['file'][$i];
+            }
+        }
+        for ($i = 0; $i < count($delfiles); ++$i) {
+            $del = array_merge($del, DeleteFilesM($fpath, $delfiles[$i]));
+        }
+    } else {
+        $msg .= '<p class="error">'.$lang['L_FM_NOFILE'].'</p>';
+    }
 }
-if (isset($_POST['deleteauto']))
-{
-	$delete_result=AutoDelete();
-	if ($delete_result>'') $msg.='<p class="small">'.$delete_result.'</p>';
+if (isset($_POST['deleteauto'])) {
+    $delete_result = AutoDelete();
+    if ($delete_result > '') {
+        $msg .= '<p class="small">'.$delete_result.'</p>';
+    }
 }
 
-if (isset($_POST['deleteall'])||isset($_POST['deleteallfilter']))
-{
-	if (isset($_POST['deleteall']))
-	{
-		$del=DeleteFilesM($fpath,"*.sql");
-		$del=array_merge($del,DeleteFilesM($fpath,"*.gz"));
-	}
-	else
-		$del=DeleteFilesM($fpath,$databases['db_actual']."*");
+if (isset($_POST['deleteall']) || isset($_POST['deleteallfilter'])) {
+    if (isset($_POST['deleteall'])) {
+        $del = DeleteFilesM($fpath, '*.sql');
+        $del = array_merge($del, DeleteFilesM($fpath, '*.gz'));
+    } else {
+        $del = DeleteFilesM($fpath, $databases['db_actual'].'*');
+    }
 }
 
 // print file-delete-messages
-if (is_array($del)&&sizeof($del)>0)
-{
-	foreach ($del as $filename=>$success)
-	{
-		if ($success)
-		{
-			$msg.='<span class="small">';
-			$msg.=$lang['L_FM_DELETE1'].' \''.$filename.'\' '.$lang['L_FM_DELETE2'];
-			WriteLog("deleted '$filename'.");
-			$msg.='</span><br>';
-		}
-		else
-		{
-			$msg.='<span class="small error">';
-			$msg.=$lang['L_FM_DELETE1'].' \''.$filename.'\' '.$lang['L_FM_DELETE3'];
-			WriteLog("deleted '$filename'.");
-			$msg.='</span><br>';
-		}
-	}
+if (is_array($del) && sizeof($del) > 0) {
+    foreach ($del as $filename => $success) {
+        if ($success) {
+            $msg .= '<span class="small">';
+            $msg .= $lang['L_FM_DELETE1'].' \''.$filename.'\' '.$lang['L_FM_DELETE2'];
+            WriteLog("deleted '$filename'.");
+            $msg .= '</span><br>';
+        } else {
+            $msg .= '<span class="small error">';
+            $msg .= $lang['L_FM_DELETE1'].' \''.$filename.'\' '.$lang['L_FM_DELETE3'];
+            WriteLog("deleted '$filename'.");
+            $msg .= '</span><br>';
+        }
+    }
 }
 
 // Upload
-if (isset($_POST['upload']))
-{
-	$error=false;
-	if (!isset($_FILES['upfile']['name'])) echo '<span class="error">'.$lang['L_FM_UPLOADFILEREQUEST'].'</span><br><br>';
-	else
-	{
-		if (!file_exists($fpath.$_FILES['upfile']['name']))
-		{
-			// Extension ermitteln -strrpos f&auml;ngt hinten an und ermittelt somit den letzten Punkt
-			$endung=strrchr($_FILES['upfile']['name'],".");
-			$erlaubt= array (
-
-			".gz", ".sql");
-			if (!in_array($endung,$erlaubt))
-			{
-				$msg.="<font color=\"red\">".$lang['L_FM_UPLOADNOTALLOWED1']."<br>";
-				$msg.=$lang['L_FM_UPLOADNOTALLOWED2']."</font>";
-			}
-			else
-			{
-				if (!$error)
-				{
-					if (move_uploaded_file($_FILES['upfile']['tmp_name'],$fpath.$_FILES['upfile']['name'])) @chmod($fpath.$upfile_name,0777);
-					else
-						$error.="<font color=\"red\">".$lang['L_FM_UPLOADMOVEERROR']."<br>";
-				}
-				if ($error) $msg.=$error."<font color=\"red\">".$lang['L_FM_UPLOADFAILED']."</font><br>";
-			}
-		}
-		else
-			$msg.="<font color=\"red\">".$lang['L_FM_UPLOADFILEEXISTS']."</font><br>";
-	}
+if (isset($_POST['upload'])) {
+    $error = false;
+    if (!isset($_FILES['upfile']['name'])) {
+        echo '<span class="error">'.$lang['L_FM_UPLOADFILEREQUEST'].'</span><br><br>';
+    } else {
+        if (!file_exists($fpath.$_FILES['upfile']['name'])) {
+            // Extension ermitteln -strrpos f&auml;ngt hinten an und ermittelt somit den letzten Punkt
+            $endung = strrchr($_FILES['upfile']['name'], '.');
+            $erlaubt = [
+            '.gz', '.sql', ];
+            if (!in_array($endung, $erlaubt)) {
+                $msg .= '<font color="red">'.$lang['L_FM_UPLOADNOTALLOWED1'].'<br>';
+                $msg .= $lang['L_FM_UPLOADNOTALLOWED2'].'</font>';
+            } else {
+                if (!$error) {
+                    if (move_uploaded_file($_FILES['upfile']['tmp_name'], $fpath.$_FILES['upfile']['name'])) {
+                        @chmod($fpath.$upfile_name, 0777);
+                    } else {
+                        $error .= '<font color="red">'.$lang['L_FM_UPLOADMOVEERROR'].'<br>';
+                    }
+                }
+                if ($error) {
+                    $msg .= $error.'<font color="red">'.$lang['L_FM_UPLOADFAILED'].'</font><br>';
+                }
+            }
+        } else {
+            $msg .= '<font color="red">'.$lang['L_FM_UPLOADFILEEXISTS'].'</font><br>';
+        }
+    }
 }
 
 //Seitenteile vordefinieren
-$href='filemanagement.php?action='.$action.'&amp;kind='.$kind;
-$tbl_abfrage='';
-if ($config['multi_dump']==0) $tbl_abfrage='<tr><td>'.$lang['L_FM_SELECTTABLES'].'</td><td><input type="checkbox" class="checkbox" name="tblfrage" value="1"></td></tr>';
-$dk=(isset($_POST['dumpKommentar'])) ? htmlentities($_POST['dumpKommentar']) : '';
-$tbl_abfrage.='<tr><td>'.$lang['L_FM_COMMENT'].':</td><td><input type="text" class="text" style="width:260px;" name="dumpKommentar" value="'.$dk.'"></td></tr>';
-$autodel='<p class="autodel">'.$lang['L_AUTODELETE'].": ";
-$autodel.=($config['auto_delete']==0) ? $lang['L_NOT_ACTIVATED'] : $lang['L_ACTIVATED'].' ('.$config['max_backup_files'].' '.$lang['L_MAX_BACKUP_FILES_EACH2'].')';
-$autodel.='</p>';
+$href = 'filemanagement.php?action='.$action.'&amp;kind='.$kind;
+$tbl_abfrage = '';
+if (isset($config['multi_dump']) && (0 == $config['multi_dump'])) {
+    $tbl_abfrage = '<tr><td>'.$lang['L_FM_SELECTTABLES'].'</td><td><input type="checkbox" class="checkbox" name="tblfrage" value="1"></td></tr>';
+}
+$dk = (isset($_POST['dumpKommentar'])) ? htmlentities($_POST['dumpKommentar']) : '';
+$tbl_abfrage .= '<tr><td>'.$lang['L_FM_COMMENT'].':</td><td><input type="text" class="text" style="width:260px;" name="dumpKommentar" value="'.$dk.'"></td></tr>';
+$autodel = '<p class="autodel">'.$lang['L_AUTODELETE'].': ';
+$autodel .= (isset($config['auto_delete']) && (0 == $config['auto_delete'])) ? $lang['L_NOT_ACTIVATED'] : $lang['L_ACTIVATED'];
+if (isset($config['max_backup_files'])) {
+    $autodel .= '  ('.$config['max_backup_files'].' '.$lang['L_MAX_BACKUP_FILES_EACH2'].')';
+}
+
+$autodel .= '</p>';
 
 //Fallunterscheidung
-switch ($action)
-{
-	case 'dump':
+switch ($action) {
+    case 'dump':
         $dbName = $databases['Name'][$databases['db_selected_index']];
-        if ($config['multi_dump']==0 && in_array($dbName, $dontBackupDatabases)) {
+        if ((isset($config['multi_dump']) && (0 == $config['multi_dump'])) && in_array($dbName, $dontBackupDatabases)) {
             echo headline($lang['L_FM_DUMP_HEADER'].' <span class="small">("'.$lang['L_CONFIG_HEADLINE'].': '.$config['config_file'].'")</span>');
             echo '<span class="error">'.sprintf($lang['L_BACKUP_NOT_POSSIBLE'], $dbName).'</span>';
             break;
         }
-		if ($config['multi_dump']==0) DBDetailInfo($databases['db_selected_index']);
-		$cext=($config['cron_extender']==0) ? "pl" : "cgi";
-		$actualUrl=substr($_SERVER['SCRIPT_NAME'],0,strrpos($_SERVER['SCRIPT_NAME'],"/")+1);
-		if (substr($actualUrl,-1)!="/") $actualUrl.="/";
-		if (substr($actualUrl,0,1)!="/") $actualUrl="/$actualUrl";
-		$refdir=(substr($config['cron_execution_path'],0,1)=="/") ? "" : $actualUrl;
-		$scriptdir=$config['cron_execution_path'].'crondump.'.$cext;
-		$sfile=$config['cron_execution_path']."perltest.$cext";
-		$simplefile=$config['cron_execution_path']."simpletest.$cext";
-		$scriptentry=Realpfad("./").$config['paths']['config'];
-		$cronabsolute=(substr($config['cron_execution_path'],0,1)=="/") ? $_SERVER['DOCUMENT_ROOT'].$scriptdir : Realpfad("./").$scriptdir;
-		$confabsolute=$config['config_file'];
-		$scriptref=getServerProtocol().$_SERVER['SERVER_NAME'].$refdir.$config['cron_execution_path'].'crondump.'.$cext."?config=".$confabsolute;
-		$cronref="perl ".$cronabsolute." -config=".$confabsolute." -html_output=0";
+        if (isset($config['multi_dump']) && (0 == $config['multi_dump'])) {
+            DBDetailInfo($databases['db_selected_index']);
+        }
+        $cext = (isset($config['cron_extender']) && (0 == $config['cron_extender'])) ? 'pl' : 'cgi';
+        $actualUrl = substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/') + 1);
+        if ('/' != substr($actualUrl, -1)) {
+            $actualUrl .= '/';
+        }
+        if ('/' != substr($actualUrl, 0, 1)) {
+            $actualUrl = "/$actualUrl";
+        }
+        $refdir = ('/' == substr($config['cron_execution_path'], 0, 1)) ? '' : $actualUrl;
+        $scriptdir = $config['cron_execution_path'].'crondump.'.$cext;
+        $sfile = $config['cron_execution_path']."perltest.$cext";
+        $simplefile = $config['cron_execution_path']."simpletest.$cext";
+        $scriptentry = Realpfad('./').$config['paths']['config'];
+        $cronabsolute = ('/' == substr($config['cron_execution_path'], 0, 1)) ? $_SERVER['DOCUMENT_ROOT'].$scriptdir : Realpfad('./').$scriptdir;
+        $confabsolute = $config['config_file'];
+        $scriptref = getServerProtocol().$_SERVER['SERVER_NAME'].$refdir.$config['cron_execution_path'].'crondump.'.$cext.'?config='.$confabsolute;
+        $cronref = 'perl '.$cronabsolute.' -config='.$confabsolute.' -html_output=0';
 
-		//Ausgabe
-		echo headline($lang['L_FM_DUMP_HEADER'].' <span class="small">("'.$lang['L_CONFIG_HEADLINE'].': '.$config['config_file'].'")</span>');
-		if (!is_writable($config['paths']['backup'])) die('<span class="error">'.sprintf($lang['L_WRONG_RIGHTS'],'work/backup','777').'</span>');
-		echo ($msg>'') ? $msg.'<br>' : '';
-		echo $autodel;
+        //Ausgabe
+        echo headline($lang['L_FM_DUMP_HEADER'].' <span class="small">("'.$lang['L_CONFIG_HEADLINE'].': '.$config['config_file'].'")</span>');
+        if (!is_writable($config['paths']['backup'])) {
+            exit('<span class="error">'.sprintf($lang['L_WRONG_RIGHTS'], 'work/backup', '777').'</span>');
+        }
+        echo ($msg > '') ? $msg.'<br>' : '';
+        echo $autodel;
 
-		//Auswahl
-		echo '<div>
+        //Auswahl
+        echo '<div>
 		<input type="button" value=" '.$lang['L_DUMP'].' PHP " class="Formbutton" onclick="document.getElementById(\'buperl\').style.display=\'none\';document.getElementById(\'buphp\').style.display=\'block\';">
 		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 		<input type="button" value=" '.$lang['L_DUMP'].' PERL " class="Formbutton" onclick="document.getElementById(\'buphp\').style.display=\'none\';document.getElementById(\'buperl\').style.display=\'block\';">
 		</div>';
-		echo '<div id="buphp">';
+        echo '<div id="buphp">';
 
-		//Dumpsettings
-		echo '<h6>'.$lang['L_DUMP'].' (PHP)</h6>';
+        //Dumpsettings
+        echo '<h6>'.$lang['L_DUMP'].' (PHP)</h6>';
 
-		echo '<div><form name="fm" id="fm" method="post" action="'.$href.'">';
-		echo '<input class="Formbutton" name="dump" type="submit" value="';
-		echo $lang['L_FM_STARTDUMP'].'"><br>';
+        echo '<div><form name="fm" id="fm" method="post" action="'.$href.'">';
+        echo '<input class="Formbutton" name="dump" type="submit" value="';
+        echo $lang['L_FM_STARTDUMP'].'"><br>';
 
-		echo '<br><table>';
-		echo $tbl_abfrage;
-		echo '<tr><td><label for="sel_dump_encoding">'.$lang['L_FM_CHOOSE_ENCODING'].'</label></td>';
-		echo '<td><select name="sel_dump_encoding" id="sel_dump_encoding">';
-		echo make_options($config['mysql_possible_character_sets'],$dump['sel_dump_encoding']);
-		echo '</select></td></tr>';
-		echo '<tr><td>'.$lang['L_MYSQL_CONNECTION_ENCODING'].':</td><td><strong>'.$config['mysql_standard_character_set'].'</strong></td></tr>';
-		echo '</table>';
-		echo '</form><br></div>';
+        echo '<br><table>';
+        echo $tbl_abfrage;
+        echo '<tr><td><label for="sel_dump_encoding">'.$lang['L_FM_CHOOSE_ENCODING'].'</label></td>';
+        echo '<td><select name="sel_dump_encoding" id="sel_dump_encoding">';
+        echo make_options($config['mysql_possible_character_sets'], $dump['sel_dump_encoding']);
+        echo '</select></td></tr>';
+        echo '<tr><td>'.$lang['L_MYSQL_CONNECTION_ENCODING'].':</td><td><strong>'.$config['mysql_standard_character_set'].'</strong></td></tr>';
+        echo '</table>';
+        echo '</form><br></div>';
 
-		echo '<h6>'.$lang['L_FM_DUMPSETTINGS'].' (PHP)</h6>';
+        echo '<h6>'.$lang['L_FM_DUMPSETTINGS'].' (PHP)</h6>';
 
-		echo '<table>';
-		echo '<tr><td>'.$lang['L_DB'].':</td><td><strong>';
-		if ($config['multi_dump']==1)
-		{
-			echo 'Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')</strong>';
-			echo '<span class="small">'.$toolboxstring.'</span>';
-		}
-		else
-		{
-			echo $databases['db_actual'].'&nbsp;&nbsp;<span>('.$databases['Detailinfo']['tables']." Tables, ".$databases['Detailinfo']['records']." Records, ".byte_output($databases['Detailinfo']['size']).')</span></strong>';
+        echo '<table>';
+        echo '<tr><td>'.$lang['L_DB'].':</td><td><strong>';
+        if (isset($config['multi_dump']) && (1 == $config['multi_dump'])) {
+            echo 'Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')</strong>';
+            echo '<span class="small">'.$toolboxstring.'</span>';
+        } else {
+            echo $databases['db_actual'];
+            if (isset($databases['Detailinfo'])) {
+                echo '&nbsp;&nbsp;<span> ('.$databases['Detailinfo']['tables'].' Tables, '.$databases['Detailinfo']['records'].' Records, '.byte_output($databases['Detailinfo']['size']).')</span>';
+            }
+            echo '</strong>';
+        }
+        echo '</td></tr>';
 
-		}
-		echo '</td></tr>';
+        if ((isset($config['multi_dump']) && (0 == $config['multi_dump'])) && $databases['praefix'][$databases['db_selected_index']] > '') {
+            echo '<tr><td>'.$lang['L_PRAEFIX'].':</td><td><strong>';
+            echo $databases['praefix'][$databases['db_selected_index']];
+            echo '</strong></td></tr>';
+        }
 
-		if ($config['multi_dump']==0&&$databases['praefix'][$databases['db_selected_index']]>'')
-		{
-			echo '<tr><td>'.$lang['L_PRAEFIX'].':</td><td><strong>';
-			echo $databases['praefix'][$databases['db_selected_index']];
-			echo '</strong></td></tr>';
-		}
+        echo '<tr><td>'.$lang['L_GZIP'].':</td><td><strong>'.((isset($config['compression']) && (1 == $config['compression'])) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED']);
+        echo '</strong></td></tr>';
 
-		echo '<tr><td>'.$lang['L_GZIP'].':</td><td><strong>'.(($config['compression']==1) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED']);
-		echo '</strong></td></tr>';
+        echo '<tr><td>'.$lang['L_MULTI_PART'].':</td><td><strong>'.((isset($config['multi_part']) && (1 == $config['multi_part'])) ? $lang['L_YES'] : $lang['L_NO']);
+        echo '</strong></td></tr>';
 
-		echo '<tr><td>'.$lang['L_MULTI_PART'].':</td><td><strong>'.(($config['multi_part']==1) ? $lang['L_YES'] : $lang['L_NO']);
-		echo '</strong></td></tr>';
+        if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+            echo '<tr><td>'.$lang['L_MULTI_PART_GROESSE'].':</td><td><strong>'.byte_output($config['multipart_groesse']).'</strong></td></tr>';
+        }
 
-		if ($config['multi_part']==1)
-		{
-			echo '<tr><td>'.$lang['L_MULTI_PART_GROESSE'].':</td><td><strong>'.byte_output($config['multipart_groesse']).'</strong></td></tr>';
-		}
+        if (isset($config['send_mail']) && (1 == $config['send_mail'])) {
+            $t = $config['email_recipient'].((1 == $config['send_mail_dump']) ? $lang['L_WITHATTACH'] : $lang['L_WITHOUTATTACH']);
+        }
+        echo '<tr><td>'.$lang['L_SEND_MAIL_FORM'].':</td><td><strong>'.((isset($config['send_mail']) && (1 == $config['send_mail'])) ? $t : $lang['L_NOT_ACTIVATED']);
+        echo '</strong></td></tr>';
 
-		if ($config['send_mail']==1)
-		{
-			$t=$config['email_recipient'].(($config['send_mail_dump']==1) ? $lang['L_WITHATTACH'] : $lang['L_WITHOUTATTACH']);
-		}
-		echo '<tr><td>'.$lang['L_SEND_MAIL_FORM'].':</td><td><strong>'.(($config['send_mail']==1) ? $t : $lang['L_NOT_ACTIVATED']);
-		echo '</strong></td></tr>';
+        for ($x = 0; $x < 3; ++$x) {
+            if (isset($config['ftp_transfer'][$x]) && $config['ftp_transfer'][$x] > 0) {
+                echo table_output($lang['L_FTP_TRANSFER'], sprintf(str_replace('<br>', ' ', $lang['L_FTP_SEND_TO']), $config['ftp_server'][$x], $config['ftp_dir'][$x]), 1, 2);
+            }
+            if (isset($config['sftp_transfer'][$x]) && $config['sftp_transfer'][$x] > 0) {
+                echo table_output($lang['L_SFTP_TRANSFER'], sprintf(str_replace('<br>', ' ', $lang['L_SFTP_SEND_TO']), $config['sftp_server'][$x], $config['sftp_dir'][$x]), 1, 2);
+            }
+        }
+        //echo '</td></tr>';
+        echo '</table>';
 
-		for ($x=0; $x<3; $x++)
-		{
-			if (isset($config['ftp_transfer'][$x])&&$config['ftp_transfer'][$x]>0)
-			{
-				echo table_output($lang['L_FTP_TRANSFER'],sprintf(str_replace('<br>',' ',$lang['L_FTP_SEND_TO']),$config['ftp_server'][$x],$config['ftp_dir'][$x]),1,2);
-			}
-		}
-		//echo '</td></tr>';
-		echo '</table>';
+        echo '<div style="display:none"><img src="'.$config['files']['iconpath'].'progressbar_dump.gif" alt=""><br><img src="'.$config['files']['iconpath'].'progressbar_speed.gif" alt=""></div>';
 
-		echo '<div style="display:none"><img src="'.$config['files']['iconpath'].'progressbar_dump.gif" alt=""><br><img src="'.$config['files']['iconpath'].'progressbar_speed.gif" alt=""></div>';
+        echo '</div><div id="buperl" style="display:none;">';
 
-		echo '</div><div id="buperl" style="display:none;">';
+        //crondumpsettings
+        echo '<h6>'.$lang['L_DUMP'].' (PERL)</h6>';
 
-		//crondumpsettings
-		echo '<h6>'.$lang['L_DUMP'].' (PERL)</h6>';
+        echo '<p><input class="Formbutton" type="Button" name="DoCronscript" value="'.$lang['L_DOCRONBUTTON'].'" onclick="self.location.href=\''.$scriptref.'\'">&nbsp;&nbsp;';
+        echo '<input class="Formbutton" type="Button" name="DoPerlTest" value="'.$lang['L_DOPERLTEST'].'" onclick="self.location.href=\''.$sfile.'\'">&nbsp;&nbsp;';
+        echo '<input class="Formbutton" type="Button" name="DoSimpleTest" value="'.$lang['L_DOSIMPLETEST'].'" onclick="self.location.href=\''.$simplefile.'\'"></p>';
 
-		echo '<p><input class="Formbutton" type="Button" name="DoCronscript" value="'.$lang['L_DOCRONBUTTON'].'" onclick="self.location.href=\''.$scriptref.'\'">&nbsp;&nbsp;';
-		echo '<input class="Formbutton" type="Button" name="DoPerlTest" value="'.$lang['L_DOPERLTEST'].'" onclick="self.location.href=\''.$sfile.'\'">&nbsp;&nbsp;';
-		echo '<input class="Formbutton" type="Button" name="DoSimpleTest" value="'.$lang['L_DOSIMPLETEST'].'" onclick="self.location.href=\''.$simplefile.'\'"></p>';
+        echo '<h6>'.$lang['L_FM_DUMPSETTINGS'].' (PERL)</h6>';
 
-		echo '<h6>'.$lang['L_FM_DUMPSETTINGS'].' (PERL)</h6>';
+        if (-3 == $config['cron_dbindex']) {
+            $cron_dbname = $lang['L_MULTIDUMPALL'];
+            $cron_dbpraefix = '';
+        } elseif (-2 == $config['cron_dbindex']) {
+            //$cron_dbname='Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')';
+            $cron_dbname = 'Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')</strong>';
+            $cron_dbname .= '<span class="small">'.$toolboxstring.'</span>';
+            $cron_dbpraefix = '';
+        } else {
+            $cron_dbname = $databases['Name'][$config['cron_dbindex']];
+            $cron_dbpraefix = $databases['praefix'][$config['cron_dbindex']];
+        }
 
-		if ($config['cron_dbindex']==-3)
-		{
-			$cron_dbname=$lang['L_MULTIDUMPALL'];
-			$cron_dbpraefix="";
-		}
-		elseif ($config['cron_dbindex']==-2)
-		{
-			//$cron_dbname='Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')';
-			$cron_dbname='Multidump ('.count($databases['multi']).' '.$lang['L_DBS'].')</strong>';
-			$cron_dbname.='<span class="small">'.$toolboxstring.'</span>';
-			$cron_dbpraefix="";
-		}
-		else
-		{
-			$cron_dbname=$databases['Name'][$config['cron_dbindex']];
-			$cron_dbpraefix=$databases['praefix'][$config['cron_dbindex']];
-		}
+        echo '<table>';
+        echo '<tr><td>'.$lang['L_DB'].':</td><td><strong>'.$cron_dbname.'</strong></td></tr>';
 
-		echo '<table>';
-		echo '<tr><td>'.$lang['L_DB'].':</td><td><strong>'.$cron_dbname.'</strong></td></tr>';
+        if ($cron_dbpraefix > '') {
+            echo '<tr><td>'.$lang['L_PRAEFIX'].':</td><td><strong>';
+            echo $cron_dbpraefix.'</strong></td></tr>';
+        }
 
-		if ($cron_dbpraefix>'')
-		{
-			echo '<tr><td>'.$lang['L_PRAEFIX'].":</td><td><strong>";
-			echo $cron_dbpraefix.'</strong></td></tr>';
-		}
+        echo '<tr><td>'.$lang['L_GZIP'].':</td><td><strong>'.((isset($config['cron_compression']) && (1 == $config['cron_compression'])) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED']);
+        echo '</strong></td></tr>';
 
-		echo '<tr><td>'.$lang['L_GZIP'].":</td><td><strong>".(($config['cron_compression']==1) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED']);
-		echo '</strong></td></tr>';
+        echo '<tr><td>'.$lang['L_MULTI_PART'].':</td><td><strong>'.((isset($config['multi_part']) && (1 == $config['multi_part'])) ? $lang['L_YES'] : $lang['L_NO']);
+        echo '</strong></td></tr>';
 
-		echo '<tr><td>'.$lang['L_MULTI_PART'].":</td><td><strong>".(($config['multi_part']==1) ? $lang['L_YES'] : $lang['L_NO']);
-		echo '</strong></td></tr>';
+        if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+            echo '<tr><td>'.$lang['L_MULTI_PART_GROESSE'].':</td><td><strong>'.byte_output($config['multipart_groesse']).'</td></tr>';
+        }
+        echo '<tr><td>'.$lang['L_CRON_PRINTOUT'].':</td><td><strong>'.((isset($config['cron_printout']) && (1 == $config['cron_printout'])) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED']).'</strong></td></tr>';
 
-		if ($config['multi_part']==1)
-		{
-			echo '<tr><td>'.$lang['L_MULTI_PART_GROESSE'].':</td><td><strong>'.byte_output($config['multipart_groesse']).'</td></tr>';
-		}
-		echo '<tr><td>'.$lang['L_CRON_PRINTOUT'].':</td><td><strong>'.(($config['cron_printout']==1) ? $lang['L_ACTIVATED'] : $lang['L_NOT_ACTIVATED']).'</strong></td></tr>';
+        if (isset($config['send_mail']) && (1 == $config['send_mail'])) {
+            $t = $config['email_recipient'].((1 == $config['send_mail_dump']) ? $lang['L_WITHATTACH'] : $lang['L_WITHOUTATTACH']);
+        }
+        echo '<tr><td>'.$lang['L_SEND_MAIL_FORM'].':</td><td><strong>'.((isset($config['send_mail']) && (1 == $config['send_mail'])) ? $t : $lang['L_NOT_ACTIVATED']).'</strong></td></tr>';
 
-		if ($config['send_mail']==1)
-		{
-			$t=$config['email_recipient'].(($config['send_mail_dump']==1) ? $lang['L_WITHATTACH'] : $lang['L_WITHOUTATTACH']);
-		}
-		echo '<tr><td>'.$lang['L_SEND_MAIL_FORM'].':</td><td><strong>'.(($config['send_mail']==1) ? $t : $lang['L_NOT_ACTIVATED']).'</strong></td></tr>';
+        for ($x = 0; $x < 3; ++$x) {
+            if (isset($config['ftp_transfer'][$x]) && $config['ftp_transfer'][$x] > 0) {
+                echo table_output($lang['L_FTP_TRANSFER'], sprintf(str_replace('<br>', ' ', $lang['L_FTP_SEND_TO']), $config['ftp_server'][$x], $config['ftp_dir'][$x]), 1, 2);
+            }
+            if (isset($config['sftp_transfer'][$x]) && $config['sftp_transfer'][$x] > 0) {
+                echo table_output($lang['L_SFTP_TRANSFER'], sprintf(str_replace('<br>', ' ', $lang['L_SFTP_SEND_TO']), $config['sftp_server'][$x], $config['sftp_dir'][$x]), 1, 2);
+            }
+        }
+        //echo '</td></tr>';
+        echo '</table>';
 
-		for ($x=0; $x<3; $x++)
-		{
-			if (isset($config['ftp_transfer'][$x])&&$config['ftp_transfer'][$x]>0)
-			{
-				echo table_output($lang['L_FTP_TRANSFER'],sprintf(str_replace('<br>',' ',$lang['L_FTP_SEND_TO']),$config['ftp_server'][$x],$config['ftp_dir'][$x]),1,2);
-			}
-		}
-		//echo '</td></tr>';
-		echo '</table>';
+        //	Eintraege fuer Perl
+        echo '<br><p class="small">'.$lang['L_PERLOUTPUT1'].':<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>'.$scriptentry.'</strong><br>';
+        echo $lang['L_PERLOUTPUT2'].':<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>'.$scriptref.'</strong><br>';
+        echo $lang['L_PERLOUTPUT3'].':<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>'.$cronref.'</strong></p>';
 
-		//	Eintraege fuer Perl
-		echo '<br><p class="small">'.$lang['L_PERLOUTPUT1'].':<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>'.$scriptentry.'</strong><br>';
-		echo $lang['L_PERLOUTPUT2'].':<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>'.$scriptref.'</strong><br>';
-		echo $lang['L_PERLOUTPUT3'].':<br>&nbsp;&nbsp;&nbsp;&nbsp;<strong>'.$cronref.'</strong></p>';
+        echo '</div>';
 
-		echo '</div>';
+        break;
 
-		break;
+    case 'restore':
+        echo headline(sprintf($lang['L_FM_RESTORE_HEADER'], $databases['db_actual']));
+        echo ($msg > '') ? $msg : '';
+        echo $autodel;
+        echo '<form name="fm" id="fm" method="post" action="'.$href.'">';
+        echo '<div>';
+        echo '<input class="Formbutton" name="restore" type="submit" value="'.$lang['L_FM_RESTORE'].'" onclick="if (!confirm(\''.$lang['L_FM_ALERTRESTORE1'].' `'.$databases['db_actual'].'`  '.$lang['L_FM_ALERTRESTORE2'].' `\' + GetSelectedFilename() + \'` '.$lang['L_FM_ALERTRESTORE3'].'\')) return false;">';
+        echo '<input class="Formbutton" name="restore" type="submit" value="'.$lang['L_RESTORE_OF_TABLES'].'" onclick="document.forms[0].tblfrage.value=1;">';
 
-	case 'restore':
-		echo headline(sprintf($lang['L_FM_RESTORE_HEADER'],$databases['db_actual']));
-		echo ($msg>'') ? $msg : '';
-		echo $autodel;
-		echo '<form name="fm" id="fm" method="post" action="'.$href.'">';
-		echo '<div>';
-		echo '<input class="Formbutton" name="restore" type="submit" value="'.$lang['L_FM_RESTORE'].'" onclick="if (!confirm(\''.$lang['L_FM_ALERTRESTORE1'].' `'.$databases['db_actual'].'`  '.$lang['L_FM_ALERTRESTORE2'].' `\' + GetSelectedFilename() + \'` '.$lang['L_FM_ALERTRESTORE3'].'\')) return false;">';
-		echo '<input class="Formbutton" name="restore" type="submit" value="'.$lang['L_RESTORE_OF_TABLES'].'" onclick="document.forms[0].tblfrage.value=1;">';
-		echo FileList();
-		echo '<input type="hidden" name="tblfrage" value="0">';
-		echo '</div></form>';
-		break;
-	case 'files':
-		$sysfedit=(isset($_POST['sysfedit'])) ? 1 : 0;
-		$sysfedit=(isset($_GET['sysfedit'])) ? $_GET['sysfedit'] : $sysfedit;
-		echo headline($lang['L_FILE_MANAGE']);
-		echo ($msg>'') ? $msg.'<br>' : '';
-		echo $autodel;
-		echo '<form name="fm" id="fm" method="post" action="'.$href.'">';
-		echo '<input class="Formbutton" name="delete" type="submit" value="'.$lang['L_FM_DELETE'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE1'].'\n\' + GetSelectedFilename() + \'\n\n'.$lang['L_FM_ASKDELETE2'].'\')) return false;">';
-		echo '<input class="Formbutton" name="deleteauto" type="submit" value="'.$lang['L_FM_DELETEAUTO'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE3'].'\')) return false;">';
-		echo '<input class="Formbutton" name="deleteall" type="submit" value="'.$lang['L_FM_DELETEALL'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE4'].'\')) return false;">';
-		echo '<input class="Formbutton" name="deleteallfilter" type="submit" value="'.$lang['L_FM_DELETEALLFILTER'].$databases['db_actual'].$lang['L_FM_DELETEALLFILTER2'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE5'].$databases['db_actual'].$lang['L_FM_ASKDELETE5_2'].'\')) return false;">';
 
-		echo FileList().'</form>';
+        echo FileList();
+        echo '<input type="hidden" name="tblfrage" value="0">';
+        echo '</div></form>';
+        break;
+    case 'files':
+        $sysfedit = (isset($_POST['sysfedit'])) ? 1 : 0;
+        $sysfedit = (isset($_GET['sysfedit'])) ? $_GET['sysfedit'] : $sysfedit;
+        echo headline($lang['L_FILE_MANAGE']);
+        echo ($msg > '') ? $msg.'<br>' : '';
+        echo $autodel;
+        echo '<form name="fm" id="fm" method="post" action="'.$href.'">';
+        echo '<input class="Formbutton" name="delete" type="submit" value="'.$lang['L_FM_DELETE'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE1'].'\n\' + GetSelectedFilename() + \'\n\n'.$lang['L_FM_ASKDELETE2'].'\')) return false;">';
+        echo '<input class="Formbutton" name="deleteauto" type="submit" value="'.$lang['L_FM_DELETEAUTO'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE3'].'\')) return false;">';
+        echo '<input class="Formbutton" name="deleteall" type="submit" value="'.$lang['L_FM_DELETEALL'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE4'].'\')) return false;">';
+        echo '<input class="Formbutton" name="deleteallfilter" type="submit" value="'.$lang['L_FM_DELETEALLFILTER'].$databases['db_actual'].$lang['L_FM_DELETEALLFILTER2'].'"	onclick="if (!confirm(\''.$lang['L_FM_ASKDELETE5'].$databases['db_actual'].$lang['L_FM_ASKDELETE5_2'].'\')) return false;">';
+        echo FileList().'</form>';
 
-		echo '<h6>'.$lang['L_FM_FILEUPLOAD'].'</h6>';
-		echo '<div align="left"><form action="'.$href.'" method="POST" enctype="multipart/form-data">';
-		echo '<input type="file" name="upfile" class="Formtext" size="60">';
-		echo '<input type="submit" name="upload" value="'.$lang['L_FM_FILEUPLOAD'].'" class="Formbutton">';
-		echo '<br>'.$lang['L_MAX_UPLOAD_SIZE'].': <strong>'.$config['upload_max_filesize'].'</strong>';
-		echo '<br>'.$lang['L_MAX_UPLOAD_SIZE_INFO'];
+        echo '<h6>'.$lang['L_FM_FILEUPLOAD'].'</h6>';
+        echo '<div align="left"><form action="'.$href.'" method="POST" enctype="multipart/form-data">';
+        echo '<input type="file" name="upfile" class="Formtext" size="60">';
+        echo '<input type="submit" name="upload" value="'.$lang['L_FM_FILEUPLOAD'].'" class="Formbutton">';
+        echo '<br>'.$lang['L_MAX_UPLOAD_SIZE'].': <strong>'.$config['upload_max_filesize'].'</strong>';
+        echo '<br>'.$lang['L_MAX_UPLOAD_SIZE_INFO'];
 
-		echo '</form></div>';
+        echo '</form></div>';
 
-		echo '<h6>Tools</h6><div align="left">';
-		echo '<input type="Button" onclick="document.location=\'filemanagement.php?action=convert\'" class="Formbutton" value="'.$lang['L_CONVERTER'].'">';
-		echo '</div>';
+        echo '<h6>Tools</h6><div align="left">';
+        echo '<input type="Button" onclick="document.location=\'filemanagement.php?action=convert\'" class="Formbutton" value="'.$lang['L_CONVERTER'].'">';
+        echo '</div>';
 
-		break;
-	case "convert":
-		// Konverter
-		echo headline($lang['L_CONVERTER']);
-		echo '<br><br><form action="filemanagement.php?action=convert" method="post">';
-		echo '<table class="bdr"><tr><th colspan="2">'.$lang['L_CONVERT_TITLE'].'</th></tr>';
-		echo '<tr><td>'.$lang['L_CONVERT_FILE'].'</td><td>'.FilelisteCombo($config['paths']['backup'],$selectfile).'</td></tr>';
-		echo '<tr><td>'.$lang['L_CONVERT_FILENAME'].':</td><td><input type="text" name="destfile" size="50" value="'.$destfile.'"></td></tr>';
-		echo '<tr><td><input type="checkbox" name="compressed" value="1" '.(($compressed==1) ? "checked" : "").'>&nbsp;'.$lang['L_COMPRESSED'].'</td>';
-		echo '<td><input type="submit" name="startconvert" value=" '.$lang['L_CONVERT_START'].' " class="Formbutton"></td></tr>';
-		echo '</table></form><br>';
-		if (isset($_POST['startconvert']))
-		{
-			//$destfile.=($compressed==1) ? ".sql.gz" : ".sql";
-			echo $lang['L_CONVERTING']." $selectfile ==&gt; $destfile<br>";
-
-			if ($selectfile!=""&&file_exists($config['paths']['backup'].$selectfile)&&strlen($destfile)>2)
-			{
-				Converter($selectfile,$destfile,$compressed);
-			}
-			else
-				echo $lang['L_CONVERT_WRONG_PARAMETERS'];
-		}
+        break;
+    case 'convert':
+        // Konverter
+        echo headline($lang['L_CONVERTER']);
+        echo '<br><br><form action="filemanagement.php?action=convert" method="post">';
+        echo '<table class="bdr"><tr><th colspan="2">'.$lang['L_CONVERT_TITLE'].'</th></tr>';
+        echo '<tr><td>'.$lang['L_CONVERT_FILE'].'</td><td>'.FilelisteCombo($config['paths']['backup'], $selectfile).'</td></tr>';
+        echo '<tr><td>'.$lang['L_CONVERT_FILENAME'].':</td><td><input type="text" name="destfile" size="50" value="'.$destfile.'"></td></tr>';
+        echo '<tr><td><input type="checkbox" name="compressed" value="1" '.((1 == $compressed) ? 'checked' : '').'>&nbsp;'.$lang['L_COMPRESSED'].'</td>';
+        echo '<td><input type="submit" name="startconvert" value=" '.$lang['L_CONVERT_START'].' " class="Formbutton"></td></tr>';
+        echo '</table></form><br>';
+        if (isset($_POST['startconvert'])) {
+            //$destfile.=($compressed==1) ? ".sql.gz" : ".sql";
+            echo $lang['L_CONVERTING']." $selectfile ==&gt; $destfile<br>";
 
+            if ('' != $selectfile && file_exists($config['paths']['backup'].$selectfile) && strlen($destfile) > 2) {
+                Converter($selectfile, $destfile, $compressed);
+            } else {
+                echo $lang['L_CONVERT_WRONG_PARAMETERS'];
+            }
+        }
 }
-echo MSDFooter();
+echo MODFooter();
 ob_end_flush();
+exit();
diff --git a/msd/help.php b/msd/help.php
index bd964f0d..d50ad13d 100644
--- a/msd/help.php
+++ b/msd/help.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,62 +18,16 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-include ( './inc/header.php' );
-include ( MSD_PATH . 'language/' . $config['language'] . '/lang.php' );
-include ( MSD_PATH . 'language/' . $config['language'] . '/lang_help.php' );
-echo MSDHeader(0);
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
+include './inc/header.php';
+include MOD_PATH.'language/'.$config['language'].'/lang.php';
+include MOD_PATH.'language/'.$config['language'].'/lang_help.php';
+echo MODHeader(0);
 echo headline($lang['L_CREDITS']);
-include ( MSD_PATH . 'language/' . $config['language'] . '/help.php' );
-?>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<?php
-echo MSDFooter();
+readfile(MOD_PATH.'language/'.$config['language'].'/help.html');
+echo MODFooter();
 ob_end_flush();
+exit();
diff --git a/msd/images/logo.gif b/msd/images/logo.gif
deleted file mode 100644
index fa6d5c0d..00000000
Binary files a/msd/images/logo.gif and /dev/null differ
diff --git a/msd/images/qrcode.png b/msd/images/qrcode.png
new file mode 100644
index 00000000..c5892871
Binary files /dev/null and b/msd/images/qrcode.png differ
diff --git a/msd/inc/define_icons.php b/msd/inc/define_icons.php
index 45611adf..4c2932cf 100644
--- a/msd/inc/define_icons.php
+++ b/msd/inc/define_icons.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,28 +16,29 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 //define icons
-$icon['arrow_up']='<img src="' . $config['files']['iconpath'] . 'arrow_up.gif" alt="">';
-$icon['arrow_down']='<img src="' . $config['files']['iconpath'] . 'arrow_down.gif" alt="">';
-$icon['blank']=$config['files']['iconpath'] . 'blank.gif';
-$icon['browse']='<img src="' . $config['files']['iconpath'] . 'browse.gif" alt="' . $lang['L_TITLE_SHOW_DATA'] . '" title="' . $lang['L_TITLE_SHOW_DATA'] . '">';
-$icon['edit']='<img src="' . $config['files']['iconpath'] . 'edit.gif" alt="' . $lang['L_EDIT'] . '" title="' . $lang['L_EDIT'] . '">';
-$icon['delete']='<img src="' . $config['files']['iconpath'] . 'delete.gif" alt="' . $lang['L_DELETE'] . '" title="' . $lang['L_DELETE'] . '">';
+$icon['arrow_up'] = '<img src="'.$config['files']['iconpath'].'arrow_up.gif" alt="">';
+$icon['arrow_down'] = '<img src="'.$config['files']['iconpath'].'arrow_down.gif" alt="">';
+$icon['blank'] = $config['files']['iconpath'].'blank.gif';
+$icon['browse'] = '<img src="'.$config['files']['iconpath'].'browse.gif" alt="'.$lang['L_TITLE_SHOW_DATA'].'" title="'.$lang['L_TITLE_SHOW_DATA'].'">';
+$icon['edit'] = '<img src="'.$config['files']['iconpath'].'edit.gif" alt="'.$lang['L_EDIT'].'" title="'.$lang['L_EDIT'].'">';
+$icon['delete'] = '<img src="'.$config['files']['iconpath'].'delete.gif" alt="'.$lang['L_DELETE'].'" title="'.$lang['L_DELETE'].'">';
 
-$icon['index']='<img src="' . $config['files']['iconpath'] . 'index.gif" alt="' . $lang['L_TITLE_INDEX'] . '" title="' . $lang['L_TITLE_INDEX'] . '">';
-$icon['key_primary']='<img src="' . $config['files']['iconpath'] . 'key_primary.gif" alt="' . $lang['L_TITLE_KEY_PRIMARY'] . '" title="' . $lang['L_TITLE_KEY_PRIMARY'] . '">';
-$icon['key_fulltext']='<img src="' . $config['files']['iconpath'] . 'key_fulltext.gif" alt="' . $lang['L_TITLE_KEY_FULLTEXT'] . '" title="' . $lang['L_TITLE_KEY_FULLTEXT'] . '">';
-$icon['key_unique']='<img src="' . $config['files']['iconpath'] . 'key_unique.gif" alt="' . $lang['L_TITLE_KEY_UNIQUE'] . '" title="' . $lang['L_TITLE_KEY_UNIQUE'] . '">';
-$icon['key_nokey']='<img src="' . $config['files']['iconpath'] . 'key_nokey.gif" alt="' . $lang['L_TITLE_NOKEY'] . '" title="' . $lang['L_TITLE_NOKEY'] . '">';
-$icon['table_truncate']='<img src="' . $config['files']['iconpath'] . 'table_truncate.gif" alt="' . $lang['L_EMPTY'] . '" title="' . $lang['L_EMPTY'] . '">';
-$icon['table_truncate_reset']='<img src="' . $config['files']['iconpath'] . 'table_truncate_reset.gif" alt="' . $lang['L_EMPTYKEYS'] . '" title="' . $lang['L_EMPTYKEYS'] . '">';
-$icon['back2db_overview']='<img src="' . $config['files']['iconpath'] . 'arrowleft.gif" alt="' . $lang['L_SQL_BACKDBOVERVIEW'] . '" title="' . $lang['L_SQL_BACKDBOVERVIEW'] . '">';
+$icon['index'] = '<img src="'.$config['files']['iconpath'].'index.gif" alt="'.$lang['L_TITLE_INDEX'].'" title="'.$lang['L_TITLE_INDEX'].'">';
+$icon['key_primary'] = '<img src="'.$config['files']['iconpath'].'key_primary.gif" alt="'.$lang['L_TITLE_KEY_PRIMARY'].'" title="'.$lang['L_TITLE_KEY_PRIMARY'].'">';
+$icon['key_fulltext'] = '<img src="'.$config['files']['iconpath'].'key_fulltext.gif" alt="'.$lang['L_TITLE_KEY_FULLTEXT'].'" title="'.$lang['L_TITLE_KEY_FULLTEXT'].'">';
+$icon['key_unique'] = '<img src="'.$config['files']['iconpath'].'key_unique.gif" alt="'.$lang['L_TITLE_KEY_UNIQUE'].'" title="'.$lang['L_TITLE_KEY_UNIQUE'].'">';
+$icon['key_nokey'] = '<img src="'.$config['files']['iconpath'].'key_nokey.gif" alt="'.$lang['L_TITLE_NOKEY'].'" title="'.$lang['L_TITLE_NOKEY'].'">';
+$icon['table_truncate'] = '<img src="'.$config['files']['iconpath'].'table_truncate.gif" alt="'.$lang['L_EMPTY'].'" title="'.$lang['L_EMPTY'].'">';
+$icon['table_truncate_reset'] = '<img src="'.$config['files']['iconpath'].'table_truncate_reset.gif" alt="'.$lang['L_EMPTYKEYS'].'" title="'.$lang['L_EMPTYKEYS'].'">';
+$icon['back2db_overview'] = '<img src="'.$config['files']['iconpath'].'arrowleft.gif" alt="'.$lang['L_SQL_BACKDBOVERVIEW'].'" title="'.$lang['L_SQL_BACKDBOVERVIEW'].'">';
 
-$icon['search']='<img src="' . $config['files']['iconpath'] . 'search.gif" alt="' . $lang['L_TITLE_SEARCH'] . '" title="' . $lang['L_TITLE_SEARCH'] . '">';
-$icon['mysql_help']='<img src="' . $config['files']['iconpath'] . 'mysql_help.gif" alt="' . $lang['L_TITLE_MYSQL_HELP'] . '" title="' . $lang['L_TITLE_MYSQL_HELP'] . '">';
-$icon['upload']='<img src="' . $config['files']['iconpath'] . 'openfile.gif" alt="' . $lang['L_TITLE_UPLOAD'] . '" title="' . $lang['L_TITLE_UPLOAD'] . '">';
+$icon['search'] = '<img src="'.$config['files']['iconpath'].'search.gif" alt="'.$lang['L_TITLE_SEARCH'].'" title="'.$lang['L_TITLE_SEARCH'].'">';
+$icon['mysql_help'] = '<img src="'.$config['files']['iconpath'].'mysql_help.gif" alt="'.$lang['L_TITLE_MYSQL_HELP'].'" title="'.$lang['L_TITLE_MYSQL_HELP'].'">';
+$icon['upload'] = '<img src="'.$config['files']['iconpath'].'openfile.gif" alt="'.$lang['L_TITLE_UPLOAD'].'" title="'.$lang['L_TITLE_UPLOAD'].'">';
 
 //other pics
-$icon['logo']=$config['theme'] . 'pics/h1_logo.gif';
-
+$icon['logo'] = $config['theme'].'pics/h1_logo.gif';
diff --git a/msd/inc/functions.php b/msd/inc/functions.php
index afe8a374..e62cce2f 100644
--- a/msd/inc/functions.php
+++ b/msd/inc/functions.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,390 +16,393 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-/** ensure this file is being included by a parent file */
-defined( 'OOS_VALID_MOD' ) OR die( 'Direct Access to this location is not allowed.' );
+/* ensure this file is being included by a parent file */
+defined('OOS_VALID_MOD') or exit('Direct Access to this location is not allowed.');
 
-if (!function_exists('get_page_parameter')) include ( './inc/functions_global.php' );
-
-if (!function_exists('str_ireplace')) // borrowed from http://www.dscripts.net
-{
-
-	function str_ireplace($find, $replace, $string)
-	{
-		if (!is_array($find)) $find=array(
-
-											$find
-		);
-		if (!is_array($replace))
-		{
-			if (!is_array($find)) $replace=array(
-
-													$replace
-			);
-			else
-			{
-				// this will duplicate the string into an array the size of $find
-				$c=count($find);
-				$rString=$replace;
-				unset($replace);
-				for ($i=0; $i < $c; $i++)
-				{
-					$replace[$i]=$rString;
-				}
-			}
-		}
-		foreach ($find as $fKey=>$fItem)
-		{
-			$between=explode(strtolower($fItem),strtolower($string));
-			$pos=0;
-			foreach ($between as $bKey=>$bItem)
-			{
-				$between[$bKey]=substr($string,$pos,strlen($bItem));
-				$pos+=strlen($bItem) + strlen($fItem);
-			}
-			$string=implode($replace[$fKey],$between);
-		}
-		return ( $string );
-	}
+if (!function_exists('get_page_parameter')) {
+    include './inc/functions_global.php';
 }
 
-if (!function_exists('stripos')) // borrowed from php.net comments
-{
-
-	function stripos($haystack, $needle)
-	{
-		return strpos($haystack,stristr($haystack,$needle));
-	}
+if (!function_exists('str_ireplace')) { // borrowed from http://www.dscripts.net
+    function str_ireplace($find, $replace, $string)
+    {
+        if (!is_array($find)) {
+            $find = [
+                                            $find,
+        ];
+        }
+        if (!is_array($replace)) {
+            if (!is_array($find)) {
+                $replace = [
+                                                    $replace,
+            ];
+            } else {
+                // this will duplicate the string into an array the size of $find
+                $c = count($find);
+                $rString = $replace;
+                unset($replace);
+                for ($i = 0; $i < $c; ++$i) {
+                    $replace[$i] = $rString;
+                }
+            }
+        }
+        foreach ($find as $fKey => $fItem) {
+            $between = explode(strtolower($fItem), strtolower($string));
+            $pos = 0;
+            foreach ($between as $bKey => $bItem) {
+                $between[$bKey] = substr($string, $pos, strlen($bItem));
+                $pos += strlen($bItem) + strlen($fItem);
+            }
+            $string = implode($replace[$fKey], $between);
+        }
+        return $string;
+    }
 }
 
-function Help($ToolTip, $Anker, $imgsize=12)
+if (!function_exists('stripos')) { // borrowed from php.net comments
+    function stripos($haystack, $needle)
+    {
+        return strpos($haystack, stristr($haystack, $needle));
+    }
+}
+
+function Help($ToolTip, $Anker, $imgsize = 12)
 {/*
-	global $config;
-	if($Anker!=""){
-	return '<a href="language/'.$config['language'].'/help.php#'.$Anker.'" title="'.$ToolTip.'"><img src="'.$config['files']['iconpath'].'help16.gif" width="'.$imgsize.'" height="'.$imgsize.'" hspace="'.(round($imgsize/4,0)).'" vspace="0" border="0" alt="Help"></a>';
-	} else {
-	return '<img src="'.$config['files']['iconpath'].'help16.gif" width="'.$imgsize.'" height="'.$imgsize.'" alt="Help" title="'.$ToolTip.'" border="0" hspace="'.(round($imgsize/4,0)).'" vspace="0" >';
-	}
+    global $config;
+    if($Anker!=""){
+    return '<a href="language/'.$config['language'].'/help.html#'.$Anker.'" title="'.$ToolTip.'"><img src="'.$config['files']['iconpath'].'help16.gif" width="'.$imgsize.'" height="'.$imgsize.'" hspace="'.(round($imgsize/4,0)).'" vspace="0" border="0" alt="Help"></a>';
+    } else {
+    return '<img src="'.$config['files']['iconpath'].'help16.gif" width="'.$imgsize.'" height="'.$imgsize.'" alt="Help" title="'.$ToolTip.'" border="0" hspace="'.(round($imgsize/4,0)).'" vspace="0" >';
+    }
 */
 }
 
-function DeleteFilesM($dir, $pattern="*.*")
+function DeleteFilesM($dir, $pattern = '*.*')
 {
-	$deleted=array();
-	$pattern=str_replace(array(
-
-								"\*",
-								"\?"
-	),array(
-
-			".*",
-			"."
-	),preg_quote($pattern));
-	if (substr($dir,-1) != "/") $dir.="/";
-	if (is_dir($dir))
-	{
-		$d=dir($dir);
-		while ($file=$d->read())
-		{
-			if (is_file($dir . $file) && preg_match("/^" . $pattern . "$/",$file))
-			{
-				if (unlink($dir . $file)) $deleted[$file]=true;
-				else $deleted[$file]=false;
-			}
-		}
-		$d->close();
-		return $deleted;
-	}
+    $deleted = [];
+    $pattern = str_replace([
+                                "\*",
+                                "\?",
+    ], [
+            '.*',
+            '.',
+    ], preg_quote($pattern));
+    if ('/' != substr($dir, -1)) {
+        $dir .= '/';
+    }
+    if (is_dir($dir)) {
+        $d = dir($dir);
+        while ($file = $d->read()) {
+            if (is_file($dir.$file) && preg_match('/^'.$pattern.'$/', $file)) {
+                if (unlink($dir.$file)) {
+                    $deleted[$file] = true;
+                } else {
+                    $deleted[$file] = false;
+                }
+            }
+        }
+        $d->close();
+        return $deleted;
+    }
 }
 
-function SetDefault($load_default=false)
+function SetDefault($load_default = false)
 {
-	global $config,$databases,$nl,$out,$lang,$preConfig;
+    global $config, $databases, $nl, $out, $lang, $preConfig;
 
-	if ($load_default == true)
-	{
-		if (file_exists($config['files']['parameter']) && ( is_readable($config['files']['parameter']) )) include ( $config['files']['parameter'] ); // alte Config lesen
-	}
-	$restore_values=array();
-	$restore_values['cron_dbindex']=isset($config['cron_dbindex']) ? $config['cron_dbindex'] : -3;
-	$restore_values['cron_dbpraefix_array']=isset($config['cron_dbpraefix_array']) ? $config['cron_dbpraefix_array'] : '';
-	if ($restore_values['cron_dbindex'] >= 0 && isset($databases['Name'][$config['cron_dbindex']])) // eine bestimmte Db gewaehlt?
-	{
-		// Ja, Namen merken, um spaeter den Index wieder herzustellen
-		$restore_values['db_actual_cron']=$databases['Name'][$config['cron_dbindex']];
-	}
-	$restore_values['db_actual']=isset($databases['db_actual']) ? $databases['db_actual'] : '';
+    if (true == $load_default) {
+        if (file_exists($config['files']['parameter']) && (is_readable($config['files']['parameter']))) {
+            include $config['files']['parameter'];
+        } // alte Config lesen
+    }
+    $restore_values = [];
+    $restore_values['cron_dbindex'] = isset($config['cron_dbindex']) ? $config['cron_dbindex'] : -3;
+    $restore_values['cron_dbpraefix_array'] = isset($config['cron_dbpraefix_array']) ? $config['cron_dbpraefix_array'] : '';
+    if ($restore_values['cron_dbindex'] >= 0 && isset($databases['Name'][$config['cron_dbindex']])) { // eine bestimmte Db gewaehlt?
+        // Ja, Namen merken, um spaeter den Index wieder herzustellen
+        $restore_values['db_actual_cron'] = $databases['Name'][$config['cron_dbindex']];
+    }
+    $restore_values['db_actual'] = isset($databases['db_actual']) ? $databases['db_actual'] : '';
 
-	$old_lang=isset($config['language']) && in_array($config['language'],$lang['languages']) ? $config['language'] : '';
-	if ($load_default == true)
-	{
-		if (file_exists($config['files']['parameter'])) @unlink($config['files']['parameter']);
-		include ( "./config.php" );
-		if (is_array($preConfig))
-		{
-			foreach ($preConfig as $key=>$val)
-			{
-				$config[$key]=$val;
-			}
-		}
+    $old_lang = isset($config['language']) && in_array($config['language'], $lang['languages']) ? $config['language'] : '';
+    if (true == $load_default) {
+        if (file_exists($config['files']['parameter'])) {
+            @unlink($config['files']['parameter']);
+        }
+        include './config.php';
+        if (is_array($preConfig)) {
+            foreach ($preConfig as $key => $val) {
+                $config[$key] = $val;
+            }
+        }
 
-		if ($old_lang != '') $config['language']=$old_lang;
-		include ( "./language/" . $config['language'] . "/lang.php" );
-	}
+        if ('' != $old_lang) {
+            $config['language'] = $old_lang;
+        }
+        include './language/'.$config['language'].'/lang.php';
+    }
 
-	$oldVals = array();
-	// Zuordnung nach Namen der Db zwischenspeichern, um Eingaben nicht zu verlieren
-	if (isset($databases) && isset($databases['Name'])) {
-    	foreach ($databases['Name'] as $k=>$v) {
-    	    if (!isset($oldVals[$k])) $oldVals[$v] = array();
+    $oldVals = [];
+    // Zuordnung nach Namen der Db zwischenspeichern, um Eingaben nicht zu verlieren
+    if (isset($databases) && isset($databases['Name'])) {
+        foreach ($databases['Name'] as $k => $v) {
+            if (!isset($oldVals[$k])) {
+                $oldVals[$v] = [];
+            }
             $oldVals[$v]['praefix'] = $databases['praefix'][$k];
             $oldVals[$v]['command_before_dump'] = $databases['command_before_dump'][$k];
             $oldVals[$v]['command_after_dump'] = $databases['command_after_dump'][$k];
-    	}
-	}
-	$oldDbArray = array();
-	if (isset($databases['Name'])) {
-	    $oldDbArray = $databases['Name'];
-	}
-	$databases['Name']=array();
-	$found_dbs = array();
-	//DB-Liste holen
-	MSD_mysql_connect();
+        }
+    }
+    $oldDbArray = [];
+    if (isset($databases['Name'])) {
+        $oldDbArray = $databases['Name'];
+    }
+    $databases['Name'] = [];
+    $found_dbs = [];
+    //DB-Liste holen
+    mod_mysqli_connect();
 
-	$create_statement='CREATE TABLE `myoosdumper_test_abcxyvfgh` (`test` varchar(200) default NULL, `id` bigint(20) unsigned NOT NULL auto_increment,' . 'PRIMARY KEY  (`id`)) TYPE=MyISAM;';
+    $create_statement = 'CREATE TABLE `myoosdumper_test_abcxyvfgh` (`test` varchar(200) default NULL, `id` bigint(20) unsigned NOT NULL auto_increment,'.'PRIMARY KEY  (`id`)) TYPE=MyISAM;';
 
-	$res=mysqli_query($config['dbconnection'], "SHOW DATABASES");
-	while ($row=mysqli_fetch_row($res)) {
-	    $found_dbs[] = $row[0];
-	}
-	$found_dbs = array_merge($oldDbArray, $found_dbs);
+    $res = mysqli_query($config['dbconnection'], 'SHOW DATABASES');
+    while ($row = mysqli_fetch_row($res)) {
+        $found_dbs[] = $row[0];
+    }
+    $found_dbs = array_merge($oldDbArray, $found_dbs);
     $found_dbs = array_unique($found_dbs);
     sort($found_dbs);
     // now check each db
-	$a=0;
-	for ($i=0; $i<count($found_dbs);$i++)
-	{
-	    $found_db = $found_dbs[$i];
-		// Testverbindung - Tabelle erstellen, nachschauen, ob es geklappt hat und dann wieder löschen
-		$use=@mysqli_select_db($config['dbconnection'], $found_db);
-		if ($use)
-		{
-			if (isset($old_db) && $found_db == $old_db) $databases['db_selected_index']=$a;
-			$databases['Name'][$a]=$found_db;
-			$databases['praefix'][$a]="";
-			$databases['command_before_dump'][$a]="";
-			$databases['command_after_dump'][$a]="";
-			if (isset($oldVals[$found_db])) {
-                $databases['praefix'][$a]= $oldVals[$found_db]['praefix'];
-                $databases['command_before_dump'][$a]=$oldVals[$found_db]['command_before_dump'];
-                $databases['command_after_dump'][$a]=$oldVals[$found_db]['command_after_dump'];
-			}
-			    $out.=$lang['L_SAVING_DB_FORM'] . " " . $found_db . " " . $lang['L_ADDED'] . "$nl";
-			$a++;
-		}
-	}
-	if (!isset($databases['db_selected_index']))
-	{
-		$databases['db_selected_index']=0;
-		$databases['db_actual']=$databases['Name'][0];
-	}
-	WriteParams(1,$restore_values);
-	if ($load_default === true) WriteLog("default settings loaded.");
+    $a = 0;
+    for ($i = 0; $i < count($found_dbs); ++$i) {
+        $found_db = $found_dbs[$i];
+        // Testverbindung - Tabelle erstellen, nachschauen, ob es geklappt hat und dann wieder löschen
+        $use = mysqli_select_db($config['dbconnection'], $found_db);
+        if ($use) {
+            /*
+            Undefined variable: $old_db
+            if (isset($old_db) && $found_db == $old_db) {
+                $databases['db_selected_index'] = $a;
+            }
+            */
 
-	return $out;
+            $databases['Name'][$a] = $found_db;
+            $databases['praefix'][$a] = '';
+            $databases['command_before_dump'][$a] = '';
+            $databases['command_after_dump'][$a] = '';
+            if (isset($oldVals[$found_db])) {
+                $databases['praefix'][$a] = $oldVals[$found_db]['praefix'];
+                $databases['command_before_dump'][$a] = $oldVals[$found_db]['command_before_dump'];
+                $databases['command_after_dump'][$a] = $oldVals[$found_db]['command_after_dump'];
+            }
+            $out .= $lang['L_SAVING_DB_FORM'].' '.$found_db.' '.$lang['L_ADDED']."$nl";
+            ++$a;
+        }
+    }
+    if (!isset($databases['db_selected_index'])) {
+        $databases['db_selected_index'] = 0;
+        $databases['db_actual'] = $databases['Name'][0];
+    }
+    WriteParams(1, $restore_values);
+    if (true === $load_default) {
+        WriteLog('default settings loaded.');
+    }
+
+    return $out;
 }
 
-function WriteParams($as=0, $restore_values=false)
+function WriteParams($as = 0, $restore_values = false)
 {
-	// wenn $as=1 wird versucht den aktuellen Index der Datenbank nach dem Einlesen wieder zu ermitteln
-	// auch wenn sich die Indexnummer durch Loeschaktionen geaendert hat
-	global $config,$databases,$config_dontsave;
-	$nl="\n";
-	// alte Werte retten
-	if ($as)
-	{
-		if (is_array($restore_values))
-		{
-			if ($restore_values['cron_dbindex'] < 0)
-			{
-				// Multidump oder "alle Datenbanken" war gewaehlt
-				$config['cron_dbindex']=$restore_values['cron_dbindex'];
-			}
-			else
-			{
-				//den Index der konkreten Datenbank aus der alten Konfiguration ermitteln
-				$db_names=array();
-				$db_names=array_flip($databases['Name']);
-				if (isset($db_names[$restore_values['db_actual']]))
-				{
-					// alte Db existiert noch -> Index uebernehmen
-					$databases['db_actual']=$restore_values['db_actual'];
-				}
-				else
-					$databases['db_actual']=$databases['Name'][0];
+    // wenn $as=1 wird versucht den aktuellen Index der Datenbank nach dem Einlesen wieder zu ermitteln
+    // auch wenn sich die Indexnummer durch Loeschaktionen geaendert hat
+    global $config, $databases, $config_dontsave;
+    $nl = "\n";
+    // alte Werte retten
+    if ($as) {
+        if (is_array($restore_values)) {
+            if ($restore_values['cron_dbindex'] < 0) {
+                // Multidump oder "alle Datenbanken" war gewaehlt
+                $config['cron_dbindex'] = $restore_values['cron_dbindex'];
+            } else {
+                //den Index der konkreten Datenbank aus der alten Konfiguration ermitteln
+                $db_names = [];
+                $db_names = array_flip($databases['Name']);
+                if (isset($db_names[$restore_values['db_actual']])) {
+                    // alte Db existiert noch -> Index uebernehmen
+                    $databases['db_actual'] = $restore_values['db_actual'];
+                } else {
+                    $databases['db_actual'] = $databases['Name'][0];
+                }
 
-				//Cron-Index wiederfinden
-				if (isset($db_names[$restore_values['cron_dbindex']]))
-				{
-					$config['cron_dbindex']=$db_names[$restore_values['cron_dbindex']];
-				}
-				else
-				{
-					// DB wurde zwischenzeitlich geloescht - sicherheitshalber alle DBs sichern
-					$databases['cron_dbindex']=-3;
-				}
-			}
-		}
-	}
-	FillMultiDBArrays();
+                //Cron-Index wiederfinden
+                if (isset($db_names[$restore_values['cron_dbindex']])) {
+                    $config['cron_dbindex'] = $db_names[$restore_values['cron_dbindex']];
+                } else {
+                    // DB wurde zwischenzeitlich geloescht - sicherheitshalber alle DBs sichern
+                    $databases['cron_dbindex'] = -3;
+                }
+            }
+        }
+    }
+    FillMultiDBArrays();
 
-	//Parameter zusammensetzen
-	$config['multipart_groesse']=$config['multipartgroesse1'] * ( ( $config['multipartgroesse2'] == 1 ) ? 1024 : 1024 * 1024 );
-	$param=$pars_all='<?php ' . $nl;
-	if (!isset($config['email_maxsize'])) $config['email_maxsize']=$config['email_maxsize1'] * ( ( $config['email_maxsize2'] == 1 ) ? 1024 : 1024 * 1024 );
-	if (!isset($config['cron_execution_path'])) $config['cron_execution_path']="msd_cron/";
-	if ($as == 0) $config['paths']['root']=addslashes(Realpfad("./"));
-	$config['files']['parameter']=$config['paths']['config'] . $config['config_file'] . '.php';
-	$config['files']['iconpath']='./css/' . $config['theme'] . '/icons/';
+    //Parameter zusammensetzen
+    $config['multipartgroesse1'] = isset($config['multipartgroesse1']) ? $config['multipartgroesse1'] : 1;
+    $config['multipartgroesse2'] = isset($config['multipartgroesse2']) ? $config['multipartgroesse2'] : 1;
+    $config['multipart_groesse'] = $config['multipartgroesse1'] * ((1 == $config['multipartgroesse2']) ? 1024 : 1024 * 1024);
+    $param = $pars_all = '<?php '.$nl;
+    $config['email_maxsize1'] = isset($config['email_maxsize1']) ? $config['email_maxsize1'] : 1;
+    $config['email_maxsize2'] = isset($config['email_maxsize2']) ? $config['email_maxsize2'] : 1;
+    if (!isset($config['email_maxsize'])) {
+        $config['email_maxsize'] = $config['email_maxsize1'] * ((1 == $config['email_maxsize2']) ? 1024 : 1024 * 1024);
+    }
+    if (!isset($config['cron_execution_path'])) {
+        $config['cron_execution_path'] = 'mod_cron/';
+    }
+    if (0 == $as) {
+        $config['paths']['root'] = addslashes(Realpfad('./'));
+    }
+    $config['files']['parameter'] = $config['paths']['config'].$config['config_file'].'.php';
+    $config['theme'] = isset($config['theme']) ? $config['theme'] : 'mod';
+    $config['files']['iconpath'] = './css/'.$config['theme'].'/icons/';
 
-	foreach ($config as $var=>$val)
-	{
-		if (!in_array($var,$config_dontsave))
-		{
-			if (is_array($val))
-			{
-				$pars_all.='$config[\'' . $var . '\']=array();' . $nl;
-				foreach ($val as $var2=>$val2)
-				{
-					if ($config['magic_quotes_gpc'] == 1)
-					{
-						$val2=stripslashes($val2);
-					}
-					$pars_all.='$config[\'' . $var . '\'][' . ( ( is_int($var2) ) ? $var2 : "'" . $var2 . "'" ) . '] = \'' . my_addslashes($val2) . "';$nl";
-				}
-			}
-			else
-			{
-				if ($config['magic_quotes_gpc'] == 1)
-				{
-					$val=stripslashes($val);
-				}
-				if (!in_array($var,$config_dontsave)) $pars_all.='$config[\'' . $var . '\'] = \'' . my_addslashes($val) . "';$nl";
-			}
-		}
-	}
-	foreach ($databases as $var=>$val)
-	{
-		if (is_array($val))
-		{
-			$pars_all.='$databases[\'' . $var . '\']=array();' . $nl;
-			foreach ($val as $var2=>$val2)
-			{
-				if ($config['magic_quotes_gpc'] == 1 || $as == 1)
-				{
-					$pars_all.='$databases[\'' . $var . '\'][' . ( ( is_int($var2) ) ? $var2 : "'" . $var2 . "'" ) . '] = \'' . my_addslashes(stripslashes($val2)) . "';$nl";
-				}
-				else
-				{
-					$pars_all.='$databases[\'' . $var . '\'][' . ( ( is_int($var2) ) ? $var2 : "'" . $var2 . "'" ) . '] = \'' . my_addslashes($val2) . "';$nl";
-				}
-			}
-		}
-		else
-		{
-			if ($config['magic_quotes_gpc'] == 0 || $as == 1)
-			{
-				$pars_all.='$databases[\'' . $var . '\'] = \'' . addslashes($val) . "';$nl";
-			}
-			else
-			{
-				$pars_all.='$databases[\'' . $var . '\'] = \'' . $val . "';$nl";
-			}
-		}
-	}
+    foreach ($config as $var => $val) {
+        if (!in_array($var, $config_dontsave)) {
+            if (is_array($val)) {
+                $pars_all .= '$config[\''.$var.'\'] = [];'.$nl;
+                foreach ($val as $var2 => $val2) {
+                    $pars_all .= '$config[\''.$var.'\']['.((is_int($var2)) ? $var2 : "'".$var2."'").'] = \''.my_addslashes($val2)."';$nl";
+                }
+            } else {
+                if (!in_array($var, $config_dontsave)) {
+                    $pars_all .= '$config[\''.$var.'\'] = \''.my_addslashes($val)."';$nl";
+                }
+            }
+        }
+    }
+    foreach ($databases as $var => $val) {
+        if (is_array($val)) {
+            $pars_all .= '$databases[\''.$var.'\'] = [];'.$nl;
+            foreach ($val as $var2 => $val2) {
+                if (1 == $as) {
+                    $pars_all .= '$databases[\''.$var.'\']['.((is_int($var2)) ? $var2 : "'".$var2."'").'] = \''.my_addslashes(stripslashes($val2))."';$nl";
+                } else {
+                    $pars_all .= '$databases[\''.$var.'\']['.((is_int($var2)) ? $var2 : "'".$var2."'").'] = \''.my_addslashes($val2)."';$nl";
+                }
+            }
+        } else {
+            if (1 == $as) {
+                $pars_all .= '$databases[\''.$var.'\'] = \''.addslashes($val)."';$nl";
+            } else {
+                $pars_all .= '$databases[\''.$var.'\'] = \''.$val."';$nl";
+            }
+        }
+    }
 
-	$param.='?>';
-	$pars_all.='?>';
+    $param .= '?>';
+    $pars_all .= '?>';
 
-	//Datei öffnen und schreiben
-	$ret=true;
-	$file=$config['paths']['config'] . $config['config_file'] . '.php';
-	if ($fp=fopen($file,"wb"))
-	{
-		if (!fwrite($fp,$pars_all)) $ret=false;
-		if (!fclose($fp)) $ret=false;
-		@chmod($file,0777);
-	}
-	else
-		$ret=false;
+    //Datei öffnen und schreiben
+    $ret = true;
+    $file = $config['paths']['config'].$config['config_file'].'.php';
+    if ($fp = fopen($file, 'wb')) {
+        if (!fwrite($fp, $pars_all)) {
+            $ret = false;
+        }
+        if (!fclose($fp)) {
+            $ret = false;
+        }
+        @chmod($file, 0777);
+    } else {
+        $ret = false;
+    }
 
-	$ret=WriteCronScript($restore_values);
-	return $ret;
+    $ret = WriteCronScript($restore_values);
+    return $ret;
 }
 
 function escape_specialchars($text)
 {
-	$suchen= array (
-
-				'@',
-				'$',
-				'\\\\',
-				'"'
-	);
-	$ersetzen= array (
-
-					'\@',
-					'\$',
-					'\\',
-					'\"'
-	);
-	$text=str_replace($suchen,$ersetzen,$text);
-	return $text;
+    $suchen = [
+                '@',
+                '$',
+                '\\\\',
+                '"',
+    ];
+    $ersetzen = [
+                    '\@',
+                    '\$',
+                    '\\',
+                    '\"',
+    ];
+    $text = str_replace($suchen, $ersetzen, $text);
+    return $text;
 }
 
-// definiert einen SAtring, der ein Array nach Perlsyntax aufbaut
-function my_implode($arr, $mode=0) // 0=String, 1=intval
+// definiert einen String, der ein Array nach Perlsyntax aufbaut
+function my_implode($arr, $mode = 0) // 0=String, 1=intval
 {
-	global $nl;
-	if (!is_array($arr)) return false;
-	foreach ($arr as $key=>$val)
-	{
-		if ($mode == 0) $arr[$key]=escape_specialchars($val);
-		else $arr[$key]=intval($val);
-	}
-	if ($mode == 0) $ret='("' . implode('","',$arr) . '");' . $nl;
-	else $ret='(' . implode(',',$arr) . ');' . $nl;
-	return $ret;
-}
-
-function WriteCronScript($restore_values=false)
-{
-	global $nl,$config,$databases,$cron_db_array,$cron_dbpraefix_array,$cron_db_cbd_array,$cron_db_cad_array, $dontBackupDatabases;
-
-	if (!isset($databases['db_selected_index'])) $databases['db_selected_index']=0;
-	if (!isset($databases['command_before_dump'])) $databases['command_before_dump']="";
-	if (!isset($databases['command_after_dump'])) $databases['command_after_dump']="";
-	if (!isset($databases['praefix'][$databases['db_selected_index']])) $databases['praefix'][$databases['db_selected_index']]="";
-	if (!isset($databases['db_actual_cronindex'])) $databases['db_actual_cronindex']=$databases['db_selected_index'];
-	if (!isset($config['email_maxsize'])) $config['email_maxsize']=$config['email_maxsize1'] * ( ( $config['email_maxsize2'] == 1 ) ? 1024 : 1024 * 1024 );
-	$cron_dbname=$databases['db_actual'];
-
-	// -2 = Multidump configuration
-	// -3 = all databases - nothing to do
-	// get standard values for all databases
-	$cron_db_array = $databases['Name'];
-	$cron_dbpraefix_array=$databases['praefix'];
-	$cron_command_before_dump=$databases['command_before_dump'];
-	$cron_command_after_dump=$databases['command_after_dump'];
-	if (!isset($config['cron_dbindex'])) $config['cron_dbindex']=-3;
-    if (intval($config['cron_dbindex']) == -2)
-    {
-        // get selected dbs from multidump-settings
-        $cron_db_array=$databases['multi'];
-        $cron_dbpraefix_array=$databases['multi_praefix'];
-        $cron_command_before_dump=$databases['multi_commandbeforedump'];
-        $cron_command_after_dump=$databases['multi_commandafterdump'];
+    global $nl;
+    if (!is_array($arr)) {
+        return false;
     }
+    foreach ($arr as $key => $val) {
+        if (0 == $mode) {
+            $arr[$key] = escape_specialchars($val);
+        } else {
+            $arr[$key] = intval($val);
+        }
+    }
+    if ($mode == 0) {
+        $ret='("' . implode('","', $arr) . '");' . $nl;
+    } else {
+        $ret='(' . implode(',', $arr) . ');' . $nl;
+    }
+    return $ret;
+}
+
+function WriteCronScript($restore_values = false)
+{
+    global $nl, $config, $databases, $cron_db_array, $cron_dbpraefix_array, $cron_db_cbd_array, $cron_db_cad_array, $dontBackupDatabases;
+
+    if (!isset($databases['db_selected_index'])) {
+        $databases['db_selected_index'] = 0;
+    }
+    if (!isset($databases['command_before_dump'])) {
+        $databases['command_before_dump'] = '';
+    }
+    if (!isset($databases['command_after_dump'])) {
+        $databases['command_after_dump'] = '';
+    }
+    if (!isset($databases['praefix'][$databases['db_selected_index']])) {
+        $databases['praefix'][$databases['db_selected_index']] = '';
+    }
+    if (!isset($databases['db_actual_cronindex'])) {
+        $databases['db_actual_cronindex'] = $databases['db_selected_index'];
+    }
+    if (!isset($config['email_maxsize'])) {
+        $config['email_maxsize'] = $config['email_maxsize1'] * ((1 == $config['email_maxsize2']) ? 1024 : 1024 * 1024);
+    }
+    $cron_dbname = $databases['db_actual'];
+
+    // -2 = Multidump configuration
+    // -3 = all databases - nothing to do
+    // get standard values for all databases
+    $cron_db_array = $databases['Name'];
+    $cron_dbpraefix_array = $databases['praefix'];
+    $cron_command_before_dump = $databases['command_before_dump'];
+    $cron_command_after_dump = $databases['command_after_dump'];
+    if (!isset($config['cron_dbindex'])) {
+        $config['cron_dbindex'] = -3;
+    }
+    if (-2 == intval($config['cron_dbindex'])) {
+        // get selected dbs from multidump-settings
+        $cron_db_array = $databases['multi'];
+        $cron_dbpraefix_array = $databases['multi_praefix'];
+        $cron_command_before_dump = $databases['multi_commandbeforedump'];
+        $cron_command_after_dump = $databases['multi_commandafterdump'];
+    }
+
     // we need to correct the index of the selected database after we cleaned
     // the db-array from information_schema and mysql if it points to a db-name
     if ($config['cron_dbindex'] >= 0) {
@@ -410,13 +413,20 @@ function WriteCronScript($restore_values=false)
 
     $newDbNames = $databases['Name'];
     //remove database we don't want to backup
+    // from newDbNames
     foreach ($databases['Name'] as $k=>$v) {
+        if (in_array($v, $dontBackupDatabases)) {
+            unset($newDbNames[$k]);
+        }
+    }
+    // and from cron (cron_db_array has different length to newDbNames: at least mysql and information_schema are missing)
+    foreach ($cron_db_array as $k=>$v) {
         if (in_array($v, $dontBackupDatabases)) {
             unset($cron_db_array[$k],
-                   $cron_dbpraefix_array[$k],
-                   $cron_command_before_dump[$k],
-                   $cron_command_after_dump[$k],
-                   $newDbNames[$k]);
+                $cron_dbpraefix_array[$k],
+                $cron_command_before_dump[$k],
+                $cron_command_after_dump[$k]
+            );
         }
     }
 
@@ -430,348 +440,402 @@ function WriteCronScript($restore_values=false)
             $cronDbIndex = 0;
         }
     }
-	$r=str_replace("\\\\","/",$config['paths']['root']);
-	$r=str_replace("@","\@",$r);
-	$p1=$r . $config['paths']['backup'];
-	$p2=$r . $config['files']['perllog'] . ( ( $config['logcompression'] == 1 ) ? '.gz' : '' );
-	$p3=$r . $config['files']['perllogcomplete'] . ( ( $config['logcompression'] == 1 ) ? '.gz' : '' );
+    $r = str_replace('\\\\', '/', $config['paths']['root']);
+    $r = str_replace('@', "\@", $r);
+    $p1 = $r.$config['paths']['backup'];
+    $p2 = $r.$config['files']['perllog'].((isset($config['logcompression']) && (1 == $config['logcompression'])) ? '.gz' : '');
+    $p3 = $r.$config['files']['perllogcomplete'].((isset($config['logcompression']) && (1 == $config['logcompression'])) ? '.gz' : '');
 
-	// auf manchen Server wird statt 0 ein leerer String gespeichert -> fuehrt zu einem Syntax-Fehler
-	// hier die entsprechenden Ja/Nein-Variablen sicherheitshalber in intvalues aendern
-	$int_array=array(
-					'dbport',
-					'cron_compression',
-					'cron_printout',
-					'multi_part',
-					'multipart_groesse',
-					'email_maxsize',
-					'auto_delete',
-					'max_backup_files',
-					'perlspeed',
-					'optimize_tables_beforedump',
-					'logcompression',
-					'log_maxsize',
-					'cron_completelog',
-					'cron_use_sendmail',
-					'cron_smtp_port'
-	);
-	foreach ($int_array as $i)
-	{
-		if (is_array($i))
-		{
-			foreach ($i as $key=>$val)
-			{
-				$int_array[$key]=intval($val);
-			}
-		}
-		else
-			$config[$i]=intval($config[$i]);
-	}
-	if ($config['dbport'] == 0) $config['dbport']=3306;
+    // auf manchen Server wird statt 0 ein leerer String gespeichert -> fuehrt zu einem Syntax-Fehler
+    // hier die entsprechenden Ja/Nein-Variablen sicherheitshalber in intvalues aendern
+    $int_array = [
+                    'dbport',
+                    'cron_compression',
+                    'cron_printout',
+                    'multi_part',
+                    'multipart_groesse',
+                    'email_maxsize',
+                    'auto_delete',
+                    'max_backup_files',
+                    'perlspeed',
+                    'optimize_tables_beforedump',
+                    'logcompression',
+                    'log_maxsize',
+                    'cron_completelog',
+                    'cron_use_sendmail',
+                    'cron_smtp_port',
+    ];
+    foreach ($int_array as $i) {
+        if (is_array($i)) {
+            foreach ($i as $key => $val) {
+                $int_array[$key] = intval($val);
+            }
+        } else {
+            $config[$i] = isset($config[$i]) ? intval($config[$i]) : 0;
+        }
+    }
+    if (0 == $config['dbport']) {
+        $config['dbport'] = 3306;
+    }
 
-	$cronscript="<?php\n#Vars - written at " . date("Y-m-d") . $nl;
-	$cronscript.='$dbhost="' . $config['dbhost'] . '";' . $nl;
-	$cronscript.='$dbname="' . $cron_dbname . '";' . $nl;
-	$cronscript.='$dbuser="' . escape_specialchars($config['dbuser']) . '";' . $nl;
-	$cronscript.='$dbpass="' . escape_specialchars($config['dbpass']) . '";' . $nl;
-	$cronscript.='$dbport=' . $config['dbport'] . ';' . $nl;
-	$cronscript.='$dbsocket="' . escape_specialchars($config['dbsocket']) . '";' . $nl;
-	$cronscript.='$compression=' . $config['cron_compression'] . ';' . $nl;
-	$cronscript.='$backup_path="' . $p1 . '";' . $nl;
-	$cronscript.='$logdatei="' . $p2 . '";' . $nl;
-	$cronscript.='$completelogdatei="' . $p3 . '";' . $nl;
-	$cronscript.='$sendmail_call="' . escape_specialchars($config['cron_sendmail']) . '";' . $nl;
-	$cronscript.='$nl="\n";' . $nl;
-	$cronscript.='$cron_dbindex=' . $cronDbIndex . ';' . $nl;
-	$cronscript.='$cron_printout=' . $config['cron_printout'] . ';' . $nl;
-	$cronscript.='$cronmail=' . $config['send_mail'] . ';' . $nl;
-	$cronscript.='$cronmail_dump=' . $config['send_mail_dump'] . ';' . $nl;
-	$cronscript.='$cronmailto="' . escape_specialchars($config['email_recipient']) . '";' . $nl;
-	$cronscript.='$cronmailto_cc="' . escape_specialchars($config['email_recipient_cc']) . '";' . $nl;
-	$cronscript.='$cronmailfrom="' . escape_specialchars($config['email_sender']) . '";' . $nl;
-	$cronscript.='$cron_use_sendmail=' . $config['cron_use_sendmail'] . ';' . $nl;
-	$cronscript.='$cron_smtp="' . escape_specialchars($config['cron_smtp']) . '";' . $nl;
-	$cronscript.='$cron_smtp_port="' . $config['cron_smtp_port'] . '";' . $nl;
+    $config['cron_sendmail'] = isset($config['cron_sendmail']) ? $config['cron_sendmail'] : '';
+    $config['cron_printout'] = isset($config['cron_printout']) ? $config['cron_printout'] : '';
+    $config['send_mail'] = isset($config['send_mail']) ? $config['send_mail'] : '';
+    $config['send_mail_dump'] = isset($config['send_mail_dump']) ? $config['send_mail_dump'] : '';
+    $config['email_recipient'] = isset($config['email_recipient']) ? $config['email_recipient'] : '';
+    $config['email_recipient_cc'] = isset($config['email_recipient_cc']) ? $config['email_recipient_cc'] : '';
+    $config['email_sender'] = isset($config['email_sender']) ? $config['email_sender'] : '';
+    $config['cron_smtp'] = isset($config['cron_smtp']) ? $config['cron_smtp'] : '';
+    $config['ftp_server'] = isset($config['ftp_server']) ? $config['ftp_server'] : '';
+    $config['ftp_port'] = isset($config['ftp_port']) ? $config['ftp_port'] : '';
+    $config['ftp_mode'] = isset($config['ftp_mode']) ? $config['ftp_mode'] : '';
+    $config['ftp_user'] = isset($config['ftp_user']) ? $config['ftp_user'] : '';
+    $config['ftp_pass'] = isset($config['ftp_pass']) ? $config['ftp_pass'] : '';
+    $config['ftp_dir'] = isset($config['ftp_dir']) ? $config['ftp_dir'] : '';
+    $config['ftp_timeout'] = isset($config['ftp_timeout']) ? $config['ftp_timeout'] : '';
+    $config['ftp_useSSL'] = isset($config['ftp_useSSL']) ? $config['ftp_useSSL'] : '';
+    $config['ftp_transfer'] = isset($config['ftp_transfer']) ? $config['ftp_transfer'] : '';
+    $config['sftp_server'] = isset($config['sftp_server']) ? $config['sftp_server'] : '';
+    $config['sftp_port'] = isset($config['sftp_port']) ? $config['sftp_port'] : '';
+    $config['sftp_user'] = isset($config['sftp_user']) ? $config['sftp_user'] : '';
+    $config['sftp_pass'] = isset($config['sftp_pass']) ? $config['sftp_pass'] : '';
+    $config['sftp_dir'] = isset($config['sftp_dir']) ? $config['sftp_dir'] : '';
+    $config['sftp_path_to_private_key'] = isset($config['sftp_path_to_private_key']) ? $config['sftp_path_to_private_key'] : null;
+    $config['sftp_secret_passphrase_for_private_key'] = isset($config['sftp_secret_passphrase_for_private_key']) ? $config['sftp_secret_passphrase_for_private_key'] : null;
+    $config['sftp_fingerprint'] = isset($config['sftp_fingerprint']) ? $config['sftp_fingerprint'] : null;
+    $config['sftp_timeout'] = isset($config['sftp_timeout']) ? $config['sftp_timeout'] : '';
+    $config['sftp_transfer'] = isset($config['sftp_transfer']) ? $config['sftp_transfer'] : '';
+    $config['cron_comment'] = isset($config['cron_comment']) ? $config['cron_comment'] : '';
 
-	$cronscript.='@cron_db_array=' . my_implode($cron_db_array);
-	$cronscript.='@cron_dbpraefix_array=' . my_implode($cron_dbpraefix_array);
-	$cronscript.='@cron_command_before_dump=' . my_implode($cron_command_before_dump);
-	$cronscript.='@cron_command_after_dump=' . my_implode($cron_command_after_dump);
+    $cronscript = "<?php\n#Vars - written at ".date('Y-m-d').$nl;
+    $cronscript .= '$dbhost="'.$config['dbhost'].'";'.$nl;
+    $cronscript .= '$dbname="'.$cron_dbname.'";'.$nl;
+    $cronscript .= '$dbuser="'.escape_specialchars($config['dbuser']).'";'.$nl;
+    $cronscript .= '$dbpass="'.escape_specialchars($config['dbpass']).'";'.$nl;
+    $cronscript .= '$dbport='.$config['dbport'].';'.$nl;
+    $cronscript .= '$dbsocket="'.escape_specialchars($config['dbsocket']).'";'.$nl;
+    $cronscript .= '$compression='.$config['cron_compression'].';'.$nl;
+    $cronscript .= '$backup_path="'.$p1.'";'.$nl;
+    $cronscript .= '$logdatei="'.$p2.'";'.$nl;
+    $cronscript .= '$completelogdatei="'.$p3.'";'.$nl;
+    $cronscript .= '$sendmail_call="'.escape_specialchars($config['cron_sendmail']).'";'.$nl;
+    $cronscript .= '$nl="\n";'.$nl;
+    $cronscript .= '$cron_dbindex='.$cronDbIndex.';'.$nl;
+    $cronscript .= '$cron_printout='.$config['cron_printout'].';'.$nl;
+    $cronscript .= '$cronmail='.$config['send_mail'].';'.$nl;
+    $cronscript .= '$cronmail_dump='.$config['send_mail_dump'].';'.$nl;
+    $cronscript .= '$cronmailto="'.escape_specialchars($config['email_recipient']).'";'.$nl;
+    $cronscript .= '$cronmailto_cc="'.escape_specialchars($config['email_recipient_cc']).'";'.$nl;
+    $cronscript .= '$cronmailfrom="'.escape_specialchars($config['email_sender']).'";'.$nl;
+    $cronscript .= '$cron_use_sendmail='.$config['cron_use_sendmail'].';'.$nl;
+    $cronscript .= '$cron_smtp="'.escape_specialchars($config['cron_smtp']).'";'.$nl;
+    $cronscript .= '$cron_smtp_port="'.$config['cron_smtp_port'].'";'.$nl;
 
-	$cronscript.='@ftp_server=' . my_implode($config['ftp_server']);
-	$cronscript.='@ftp_port=' . my_implode($config['ftp_port'],1);
-	$cronscript.='@ftp_mode=' . my_implode($config['ftp_mode'],1);
-	$cronscript.='@ftp_user=' . my_implode($config['ftp_user']);
-	$cronscript.='@ftp_pass=' . my_implode($config['ftp_pass']);
-	$cronscript.='@ftp_dir=' . my_implode($config['ftp_dir']);
-	$cronscript.='@ftp_timeout=' . my_implode($config['ftp_timeout'],1);
-	$cronscript.='@ftp_useSSL=' . my_implode($config['ftp_useSSL'],1);
-	$cronscript.='@ftp_transfer=' . my_implode($config['ftp_transfer'],1);
-	$cronscript.='$mp=' . $config['multi_part'] . ';' . $nl;
-	$cronscript.='$multipart_groesse=' . $config['multipart_groesse'] . ';' . $nl;
-	$cronscript.='$email_maxsize=' . $config['email_maxsize'] . ';' . $nl;
-	$cronscript.='$auto_delete=' . $config['auto_delete'] . ';' . $nl;
-	$cronscript.='$max_backup_files=' . $config['max_backup_files'] . ';' . $nl;
-	$cronscript.='$perlspeed=' . $config['perlspeed'] . ';' . $nl;
-	$cronscript.='$optimize_tables_beforedump=' . $config['optimize_tables_beforedump'] . ';' . $nl;
-	$cronscript.='$logcompression=' . $config['logcompression'] . ';' . $nl;
-	$cronscript.='$log_maxsize=' . $config['log_maxsize'] . ';' . $nl;
-	$cronscript.='$complete_log=' . $config['cron_completelog'] . ';' . $nl;
-	$cronscript.='$my_comment="' . escape_specialchars(stripslashes($config['cron_comment'])) . '";' . $nl;
-	$cronscript.="";
+    $cronscript .= '@cron_db_array='.my_implode($cron_db_array);
+    $cronscript .= '@cron_dbpraefix_array='.my_implode($cron_dbpraefix_array);
+    $cronscript .= '@cron_command_before_dump='.my_implode($cron_command_before_dump);
+    $cronscript .= '@cron_command_after_dump='.my_implode($cron_command_after_dump);
 
-	// Save config
-	$ret=true;
-	$sfile=$config['paths']['config'] . $config['config_file'] . '.conf.php';
-	if (file_exists($sfile)) @unlink($sfile);
+    $cronscript .= '@ftp_server='.my_implode($config['ftp_server']);
+    $cronscript .= '@ftp_port='.my_implode($config['ftp_port'], 1);
+    $cronscript .= '@ftp_mode='.my_implode($config['ftp_mode'], 1);
+    $cronscript .= '@ftp_user='.my_implode($config['ftp_user']);
+    $cronscript .= '@ftp_pass='.my_implode($config['ftp_pass']);
+    $cronscript .= '@ftp_dir='.my_implode($config['ftp_dir']);
+    $cronscript .= '@ftp_timeout='.my_implode($config['ftp_timeout'], 1);
+    $cronscript .= '@ftp_useSSL='.my_implode($config['ftp_useSSL'], 1);
+    $cronscript .= '@ftp_transfer='.my_implode($config['ftp_transfer'], 1);
+    $cronscript .= '$mp='.$config['multi_part'].';'.$nl;
+    $cronscript .= '$multipart_groesse='.$config['multipart_groesse'].';'.$nl;
+    $cronscript .= '$email_maxsize='.$config['email_maxsize'].';'.$nl;
+    $cronscript .= '$auto_delete='.$config['auto_delete'].';'.$nl;
+    $cronscript .= '$max_backup_files='.$config['max_backup_files'].';'.$nl;
+    $cronscript .= '$perlspeed='.$config['perlspeed'].';'.$nl;
+    $cronscript .= '$optimize_tables_beforedump='.$config['optimize_tables_beforedump'].';'.$nl;
+    $cronscript .= '$logcompression='.$config['logcompression'].';'.$nl;
+    $cronscript .= '$log_maxsize='.$config['log_maxsize'].';'.$nl;
+    $cronscript .= '$complete_log='.$config['cron_completelog'].';'.$nl;
+    $cronscript .= '$my_comment="'.escape_specialchars(stripslashes($config['cron_comment'])).'";'.$nl;
+    $cronscript .= '';
 
-	if ($fp=fopen($sfile,"wb"))
-	{
-		if (!fwrite($fp,$cronscript)) $ret=false;
-		if (!fclose($fp)) $ret=false;
-		@chmod("$sfile",0777);
-	}
-	else
-		$ret=false;
+    // Save config
+    $ret = true;
+    $sfile = $config['paths']['config'].$config['config_file'].'.conf.php';
+    if (file_exists($sfile)) {
+        @unlink($sfile);
+    }
 
-	// if standard config was deleted -> restore it with the actual values
-	if (!file_exists($config['paths']['config'] . "myoosdumper.conf.php"))
-	{
-		$sfile=$config['paths']['config'] . 'myoosdumper.conf.php';
-		if ($fp=fopen($sfile,"wb"))
-		{
-			if (!fwrite($fp,$cronscript)) $ret=false;
-			if (!fclose($fp)) $ret=false;
-			@chmod("$sfile",0777);
-		}
-		else
-			$ret=false;
-	}
-	return $ret;
+    if ($fp = fopen($sfile, 'wb')) {
+        if (!fwrite($fp, $cronscript)) {
+            $ret = false;
+        }
+        if (!fclose($fp)) {
+            $ret = false;
+        }
+        @chmod("$sfile", 0777);
+    } else {
+        $ret = false;
+    }
 
+    // if standard config was deleted -> restore it with the actual values
+    if (!file_exists($config['paths']['config'].'myoosdumper.conf.php')) {
+        $sfile = $config['paths']['config'].'myoosdumper.conf.php';
+        if ($fp = fopen($sfile, 'wb')) {
+            if (!fwrite($fp, $cronscript)) {
+                $ret = false;
+            }
+            if (!fclose($fp)) {
+                $ret = false;
+            }
+            @chmod("$sfile", 0777);
+        } else {
+            $ret = false;
+        }
+    }
+    return $ret;
 }
 
 function LogFileInfo($logcompression)
 {
-	global $config;
+    global $config;
 
-	$l=Array();
-	$sum=$s=$l['log_size']=$l['perllog_size']=$l['perllogcomplete_size']=$l['errorlog_size']=$l['log_totalsize']=0;
-	if ($logcompression == 1)
-	{
-		$l['log']=$config['files']['log'] . ".gz";
-		$l['perllog']=$config['files']['perllog'] . ".gz";
-		$l['perllogcomplete']=$config['files']['perllogcomplete'] . ".gz";
-		$l['errorlog']=$config['paths']['log'] . "error.log.gz";
-	}
-	else
-	{
-		$l['log']=$config['files']['log'];
-		$l['perllog']=$config['files']['perllog'];
-		$l['perllogcomplete']=$config['files']['perllogcomplete'];
-		$l['errorlog']=$config['paths']['log'] . "error.log";
-	}
-	$l['log_size']+=@filesize($l['log']);
-	$sum+=$l['log_size'];
-	$l['perllog_size']+=@filesize($l['perllog']);
-	$sum+=$l['perllog_size'];
-	$l['perllogcomplete_size']+=@filesize($l['perllogcomplete']);
-	$sum+=$l['perllogcomplete_size'];
-	$l['errorlog_size']+=@filesize($l['errorlog']);
-	$sum+=$l['errorlog_size'];
-	$l['log_totalsize']+=$sum;
+    $l = [];
+    $sum = $s
+        = $l['log_size'] = $l['perllog_size'] = $l['perllogcomplete_size'] = $l['errorlog_size'] = $l['log_totalsize'] = 0;
 
-	return $l;
+    if ((isset($config['logcompression']) && 1 == $config['logcompression'])) {
+        $l['log'] = $config['files']['log'].'.gz';
+        $l['perllog'] = $config['files']['perllog'].'.gz';
+        $l['perllogcomplete'] = $config['files']['perllogcomplete'].'.gz';
+        $l['errorlog'] = $config['paths']['log'].'error.log.gz';
+    } else {
+        $l['log'] = $config['files']['log'];
+        $l['perllog'] = $config['files']['perllog'];
+        $l['perllogcomplete'] = $config['files']['perllogcomplete'];
+        $l['errorlog'] = $config['paths']['log'].'error.log';
+    }
+    $l['log_size'] += @filesize($l['log']);
+    $sum += $l['log_size'];
+    $l['perllog_size'] += @filesize($l['perllog']);
+    $sum += $l['perllog_size'];
+    $l['perllogcomplete_size'] += @filesize($l['perllogcomplete']);
+    $sum += $l['perllogcomplete_size'];
+    $l['errorlog_size'] += @filesize($l['errorlog']);
+    $sum += $l['errorlog_size'];
+    $l['log_totalsize'] += $sum;
+
+    return $l;
 }
 
 function DeleteLog()
 {
-	global $config;
-	//Datei öffnen und schreiben
-	$log=date('d.m.Y H:i:s') . " Log created.\n";
-	if (file_exists($config['files']['log'] . '.gz')) @unlink($config['files']['log'] . '.gz');
-	if (file_exists($config['files']['log'] . '.gz')) @unlink($config['files']['log']);
-	if ($config['logcompression'] == 1)
-	{
-		$fp=@gzopen($config['files']['log'] . '.gz',"wb");
-		@gzwrite($fp,$log);
-		@gzclose($fp);
-		@chmod($config['files']['log'] . '.gz',0777);
-	}
-	else
-	{
-		$fp=@fopen($config['files']['log'],"wb");
-		@fwrite($fp,$log);
-		@fclose($fp);
-		@chmod($config['files']['log'],0777);
-	}
+    global $config;
+    //Datei öffnen und schreiben
+    $log = date('d.m.Y H:i:s')." Log created.\n";
+    if (file_exists($config['files']['log'].'.gz')) {
+        @unlink($config['files']['log'].'.gz');
+    }
+    if (file_exists($config['files']['log'].'.gz')) {
+        @unlink($config['files']['log']);
+    }
+    if ((isset($config['logcompression']) && 1 == $config['logcompression'])) {
+        $fp = @gzopen($config['files']['log'].'.gz', 'wb');
+        @gzwrite($fp, $log);
+        @gzclose($fp);
+        @chmod($config['files']['log'].'.gz', 0777);
+    } else {
+        $fp = @fopen($config['files']['log'], 'wb');
+        @fwrite($fp, $log);
+        @fclose($fp);
+        @chmod($config['files']['log'], 0777);
+    }
 }
 
 function CreateDirsFTP()
 {
+    global $config, $lang, $install_ftp_server, $install_ftp_port, $install_ftp_user_name, $install_ftp_user_pass, $install_ftp_path;
+    // Herstellen der Basis-Verbindung
+    echo '<hr>'.$lang['L_CONNECT_TO'].' `'.$install_ftp_server.'` Port '.$install_ftp_port.' ...<br>';
+    $conn_id = ftp_connect($install_ftp_server);
+    // Einloggen mit Benutzername und Kennwort
+    $login_result = ftp_login($conn_id, $install_ftp_user_name, $install_ftp_user_pass);
+    // Verbindung überprüfen
+    if ((!$conn_id) || (!$login_result)) {
+        echo $lang['L_FTP_NOTCONNECTED'];
+        echo $lang['L_CONNWITH']." $install_ftp_server ".$lang['L_ASUSER']." $install_ftp_user_name ".$lang['L_NOTPOSSIBLE'];
+        return 0;
+    } else {
+        if (1 == $config['ftp_mode']) {
+            ftp_pasv($conn_id, true);
+        }
+        //Wechsel in betroffenes Verzeichnis
+        echo $lang['L_CHANGEDIR'].' `'.$install_ftp_path.'` ...<br>';
+        ftp_chdir($conn_id, $install_ftp_path);
+        // Erstellen der Verzeichnisse
+        echo $lang['L_DIRCR1'].' ...<br>';
+        ftp_mkdir($conn_id, 'work');
+        ftp_site($conn_id, 'CHMOD 0777 work');
+        echo $lang['L_CHANGEDIR'].' `work` ...<br>';
+        ftp_chdir($conn_id, 'work');
+        echo $lang['L_INDIR'].' `'.ftp_pwd($conn_id).'`<br>';
+        echo $lang['L_DIRCR5'].' ...<br>';
+        ftp_mkdir($conn_id, 'config');
+        ftp_site($conn_id, 'CHMOD 0777 config');
+        echo $lang['L_DIRCR2'].' ...<br>';
+        ftp_mkdir($conn_id, 'backup');
+        ftp_site($conn_id, 'CHMOD 0777 backup');
+        echo $lang['L_DIRCR4'].' ...<br>';
+        ftp_mkdir($conn_id, 'log');
+        ftp_site($conn_id, 'CHMOD 0777 log');
 
-	global $config,$lang,$install_ftp_server,$install_ftp_port,$install_ftp_user_name,$install_ftp_user_pass,$install_ftp_path;
-	// Herstellen der Basis-Verbindung
-	echo '<hr>' . $lang['L_CONNECT_TO'] . ' `' . $install_ftp_server . '` Port ' . $install_ftp_port . ' ...<br>';
-	$conn_id=ftp_connect($install_ftp_server);
-	// Einloggen mit Benutzername und Kennwort
-	$login_result=ftp_login($conn_id,$install_ftp_user_name,$install_ftp_user_pass);
-	// Verbindung überprüfen
-	if (( !$conn_id ) || ( !$login_result ))
-	{
-		echo $lang['L_FTP_NOTCONNECTED'];
-		echo $lang['L_CONNWITH'] . " $tinstall_ftp_server " . $lang['L_ASUSER'] . " $install_ftp_user_name " . $lang['L_NOTPOSSIBLE'];
-		return 0;
-	}
-	else
-	{
-		if ($config['ftp_mode'] == 1) ftp_pasv($conn_id,true);
-		//Wechsel in betroffenes Verzeichnis
-		echo $lang['L_CHANGEDIR'] . ' `' . $install_ftp_path . '` ...<br>';
-		ftp_chdir($conn_id,$install_ftp_path);
-		// Erstellen der Verzeichnisse
-		echo $lang['L_DIRCR1'] . ' ...<br>';
-		ftp_mkdir($conn_id,"work");
-		ftp_site($conn_id,"CHMOD 0777 work");
-		echo $lang['L_CHANGEDIR'] . ' `work` ...<br>';
-		ftp_chdir($conn_id,"work");
-		echo $lang['L_INDIR'] . ' `' . ftp_pwd($conn_id) . '`<br>';
-		echo $lang['L_DIRCR5'] . ' ...<br>';
-		ftp_mkdir($conn_id,"config");
-		ftp_site($conn_id,"CHMOD 0777 config");
-		echo $lang['L_DIRCR2'] . ' ...<br>';
-		ftp_mkdir($conn_id,"backup");
-		ftp_site($conn_id,"CHMOD 0777 backup");
-		echo $lang['L_DIRCR4'] . ' ...<br>';
-		ftp_mkdir($conn_id,"log");
-		ftp_site($conn_id,"CHMOD 0777 log");
-
-		// Schließen des FTP-Streams
-		ftp_quit($conn_id);
-		return 1;
-	}
+        // Schließen des FTP-Streams
+        ftp_quit($conn_id);
+        return 1;
+    }
 }
 
 function ftp_mkdirs($config, $dirname)
 {
-	$dir=preg_split("/\//",$dirname);
-	for ($i=0; $i < count($dir) - 1; $i++)
-	{
-		$path.=$dir[$i] . "/";
-		@ftp_mkdir($config['dbconnection'],$path);
-	}
-	if (@ftp_mkdir($config['dbconnection'],$dirname)) return 1;
+    $path = '';
+    $dir = preg_split('/\//', $dirname);
+    for ($i = 0; $i < count($dir) - 1; ++$i) {
+        $path .= $dir[$i].'/';
+        @ftp_mkdir($config['dbconnection'], $path);
+    }
+    if (@ftp_mkdir($config['dbconnection'], $dirname)) {
+        return 1;
+    }
 }
 
 function IsWritable($dir)
 {
-	$testfile=$dir . "/.writetest";
-	if ($writable=@fopen($testfile,'w'))
-	{
-		@fclose($writable);
-		@unlink($testfile);
-	}
-	return $writable;
+    $testfile = $dir.'/.writetest';
+    if ($writable = @fopen($testfile, 'w')) {
+        @fclose($writable);
+        @unlink($testfile);
+    }
+
+    return $writable;
 }
 
-function SearchDatabases($printout, $db='')
+function IsAccessProtected()
 {
-	global $databases,$config,$lang;
+    $rc = false;
+    $url = sprintf('%s://%s%s', $_SERVER['REQUEST_SCHEME'], $_SERVER['HTTP_HOST'], dirname($_SERVER['PHP_SELF']));
+    $headers = @get_headers($url);
+    if (is_array($headers) && count($headers) > 0) {
+        $rc = (preg_match('/\s+(?:401|403)\s+/', $headers[0])) ? 1 : 0;
+    }
+    return $rc;
+}
 
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$db_list=array();
-	if ($db > '') {
-	    $db_list[]=$db; // DB wurde manuell angegeben
-	}
-	// Datenbanken automatisch erkennen
-	$show_dbs=mysqli_query($config['dbconnection'],"SHOW DATABASES");
-	if (!$show_dbs === false)
-	{
-		while ($row=mysqli_fetch_row($show_dbs))
-		{
-			if (trim($row[0]) > '') $db_list[]=$row[0];
-		}
-	}
+function SearchDatabases($printout, $db = '')
+{
+    global $databases, $config, $lang;
+
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $db_list = [];
+    if ($db > '') {
+        $db_list[] = $db; // DB wurde manuell angegeben
+    }
+    // Datenbanken automatisch erkennen
+    $show_dbs = mysqli_query($config['dbconnection'], 'SHOW DATABASES');
+    if (false === !$show_dbs) {
+        while ($row = mysqli_fetch_row($show_dbs)) {
+            if (trim($row[0]) > '') {
+                $db_list[] = $row[0];
+            }
+        }
+    }
     $db_list = array_unique($db_list);
     sort($db_list);
-	if (sizeof($db_list) > 0)
-	{
-		$databases['db_selected_index']=0;
-		for ($i=0; $i < sizeof($db_list); $i++)
-		{
-			// Test-Select um zu sehen, ob Berechtigungen existieren
-			if (!@mysqli_query($config['dbconnection'], "SHOW TABLES FROM `" . $db_list[$i] . "`") === false)
-			{
-				$databases['Name'][$i]=$db_list[$i];
-				$databases['praefix'][$i]='';
-				$databases['command_before_dump'][$i]='';
-				$databases['command_after_dump'][$i]='';
-				if ($printout == 1) echo $lang['L_FOUND_DB'] . ' `' . $db_list[$i] . '`<br />';
-			} else {
-    			if ($printout == 1) echo '<span class="error">'.sprintf($lang['L_DB_MANUAL_ERROR'], $db_list[$i]) . '</span><br />';
-			}
-		}
-	}
-	if (isset($databases['Name'][0])) $databases['db_actual']=$databases['Name'][0];
+    if (sizeof($db_list) > 0) {
+        $databases['db_selected_index'] = 0;
+        for ($i = 0; $i < sizeof($db_list); ++$i) {
+            // Test-Select um zu sehen, ob Berechtigungen existieren
+            if (false === !@mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `'.$db_list[$i].'`')) {
+                $databases['Name'][$i] = $db_list[$i];
+                $databases['praefix'][$i] = '';
+                $databases['command_before_dump'][$i] = '';
+                $databases['command_after_dump'][$i] = '';
+                if (1 == $printout) {
+                    echo $lang['L_FOUND_DB'].' `'.$db_list[$i].'`<br />';
+                }
+            } else {
+                if (1 == $printout) {
+                    echo '<span class="error">'.sprintf($lang['L_DB_MANUAL_ERROR'], $db_list[$i]).'</span><br />';
+                }
+            }
+        }
+    }
+    if (isset($databases['Name'][0])) {
+        $databases['db_actual'] = $databases['Name'][0];
+    }
 }
 
 // removes tags from inputs recursivly
 function my_strip_tags($value)
 {
-	global $dont_strip;
-	if (is_array($value))
-	{
-		foreach ($value as $key=>$val)
-		{
-			if (!in_array($key,$dont_strip)) $ret[$key]=my_strip_tags($val);
-			else $ret[$key]=$val;
-		}
-	}
-	else
-		$ret=trim(strip_tags($value));
-	return $ret;
+    global $dont_strip;
+    if (is_array($value)) {
+        foreach ($value as $key => $val) {
+            if (!in_array($key, $dont_strip)) {
+                $ret[$key] = my_strip_tags($val);
+            } else {
+                $ret[$key] = $val;
+            }
+        }
+    } else {
+        $ret = trim(strip_tags($value));
+    }
+    return $ret;
 }
 
 /**
- * Add a slashes only before '
+ * Add a slashes only before '.
  *
  * Used for escaping strings in JS-alerts and config-files
  *
  * @param $string
+ *
  * @return string
  */
 function my_addslashes($string)
 {
-	return str_replace("'","\'",$string);
+    if (is_string($string)) {
+        $string = str_replace("'", "\'", $string);
+    }
+
+    return $string;
 }
 
 /**
- * Replaces quotes for outputting value in HTML-attributes
+ * Replaces quotes for outputting value in HTML-attributes.
  *
  * Replaces quotes for outputing value in HTML-attributes without breaking HTML
  *
  * @param string $value value to output
+ *
  * @return string
  */
 function my_quotes($value)
 {
-	return str_replace('"','&quot;',$value);
+    return str_replace('"', '&quot;', $value);
 }
 
-
 // prepares a string for executing it as query
 function db_escape($string)
 {
-	global $config;
-	if (function_exists('mysqli_real_escape_string'))
-	{
-		$string=mysqli_real_escape_string($config['dbconnection'], $string);
-	}
-	elseif (function_exists('mysqli_escape_string'))
-	{
-		$string=mysqli_escape_string($config['dbconnection'], $string);
-	}
-	else $string=addslashes($string);
-	return $string;
-}
+    global $config;
+    if (function_exists('mysqli_real_escape_string')) {
+        $string = mysqli_real_escape_string($config['dbconnection'], $string);
+    } elseif (function_exists('mysqli_escape_string')) {
+        $string = mysqli_escape_string($config['dbconnection'], $string);
+    } else {
+        $string = addslashes($string);
+    }
 
+    return $string;
+}
diff --git a/msd/inc/functions_dump.php b/msd/inc/functions_dump.php
index 86280a45..d473300a 100644
--- a/msd/inc/functions_dump.php
+++ b/msd/inc/functions_dump.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,562 +16,553 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-/** ensure this file is being included by a parent file */
-defined( 'OOS_VALID_MOD' ) OR die( 'Direct Access to this location is not allowed.' );
+/* ensure this file is being included by a parent file */
+defined('OOS_VALID_MOD') or exit('Direct Access to this location is not allowed.');
 
-include ('./inc/functions_global.php');
+include './inc/functions_global.php';
 
 //Buffer fuer Multipart-Filesizepruefung
-$buffer=10*1024;
+$buffer = 10 * 1024;
 
-function new_file($last_groesse=0)
+function new_file($last_groesse = 0)
 {
-	global $dump,$databases,$config,$out,$lang,$nl,$mysql_commentstring;
+    global $dump, $databases, $config, $out, $lang, $nl, $mysql_commentstring;
 
-	// Dateiname aus Datum und Uhrzeit bilden
-	if ($dump['part']-$dump['part_offset']==1) $dump['filename_stamp']=date("Y_m_d_H_i",time());
-	if ($config['multi_part']==1)
-	{
-		$dateiname=$databases['Name'][$dump['dbindex']].'_'.$dump['filename_stamp'].'_part_'.($dump['part']-$dump['part_offset']);
-	}
-	else
-		$dateiname=$databases['Name'][$dump['dbindex']].'_'.date("Y_m_d_H_i",time());
-	$endung=($config['compression']) ? '.sql.gz':'.sql';
-	$dump['backupdatei']=$dateiname.$endung;
+    // Dateiname aus Datum und Uhrzeit bilden
+    if ($dump['part'] - $dump['part_offset'] == 1) {
+        $dump['filename_stamp'] = date('Y_m_d_H_i', time());
+    }
+    if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+        $dateiname = $databases['Name'][$dump['dbindex']].'_'.$dump['filename_stamp'].'_part_'.($dump['part'] - $dump['part_offset']);
+    } else {
+        $dateiname = $databases['Name'][$dump['dbindex']].'_'.date('Y_m_d_H_i', time());
+    }
+    $endung = (isset($config['compression']) && ($config['compression'])) ? '.sql.gz' : '.sql';
+    $dump['backupdatei'] = $dateiname.$endung;
 
-	if (file_exists($config['paths']['backup'].$dump['backupdatei'])) unlink($config['paths']['backup'].$dump['backupdatei']);
-	$cur_time=date("Y-m-d H:i");
-	$statuszeile=GetStatusLine().$nl.$mysql_commentstring.' Dump by MySQLDumper '.MSD_VERSION.' ('.$config['homepage'].')'.$nl;
-	$statuszeile.='/*!40101 SET NAMES \''.$dump['dump_encoding'].'\' */;'.$nl;
-	$statuszeile.='SET FOREIGN_KEY_CHECKS=0;'.$nl;
+    if (file_exists($config['paths']['backup'].$dump['backupdatei'])) {
+        unlink($config['paths']['backup'].$dump['backupdatei']);
+    }
+    $cur_time = date('Y-m-d H:i');
+    $statuszeile = GetStatusLine().$nl.$mysql_commentstring.' Dump by MyOOS [Dumper] '.MOD_VERSION.' ('.$config['homepage'].')'.$nl;
+    $statuszeile .= '/*!40101 SET NAMES \''.$dump['dump_encoding'].'\' */;'.$nl;
+    $statuszeile .= 'SET FOREIGN_KEY_CHECKS=0;'.$nl;
 
-	if ($dump['part']-$dump['part_offset']==1)
-	{
-		if ($config['multi_part']==0)
-		{
-			if ($config['multi_dump']==1 && $dump['dbindex']==0) WriteLog('starting Multidump with '.count($databases['multi']).' Datenbases.');
-			WriteLog('Start Dump \''.$dump['backupdatei'].'\'');
-		}
-		else
-			WriteLog('Start Multipart-Dump \''.$dateiname.'\'');
+    if ($dump['part'] - $dump['part_offset'] == 1) {
+        if (isset($config['multi_part']) && (0 == $config['multi_part'])) {
+            if (isset($config['multi_part']) && 1 == $config['multi_dump'] && 0 == $dump['dbindex']) {
+                WriteLog('starting Multidump with '.count($databases['multi']).' Datenbases.');
+            }
+            WriteLog('Start Dump \''.$dump['backupdatei'].'\'');
+        } else {
+            WriteLog('Start Multipart-Dump \''.$dateiname.'\'');
+        }
 
-		$out.='<strong>'.$lang['L_STARTDUMP'].' `'.$databases['Name'][$dump['dbindex']].'`</strong>'.(($databases['praefix'][$dump['dbindex']]!="") ? ' ('.$lang['L_WITHPRAEFIX'].' <span style="color:blue">'.$databases['praefix'][$dump['dbindex']].'</span>)':'').'...   ';
-		if ($dump['part']==1)
-		{
-			$dump['table_offset']=0;
-			$dump['countdata']=0;
-		}
-		// Seitenerstaufruf -> Backupdatei anlegen
-		$dump['data']=$statuszeile.$mysql_commentstring.' Dump created: '.$cur_time;
-	}
-	else
-	{
-		if ($config['multi_part']!=0)
-		{
-			WriteLog('Continue Multipart-Dump with File '.($dump['part']-$dump['part_offset']).' (last file was '.$last_groesse.' Bytes)');
-			$dump['data']=$statuszeile.$mysql_commentstring.' This is part '.($dump['part']-$dump['part_offset']).' of the backup.'.$nl.$nl.$dump['data'];
-
-		}
-	}
-	WriteToDumpFile();
-	$dump['part']++;
+        $out .= '<strong>'.$lang['L_STARTDUMP'].' `'.$databases['Name'][$dump['dbindex']].'`</strong>'.(('' != $databases['praefix'][$dump['dbindex']]) ? ' ('.$lang['L_WITHPRAEFIX'].' <span style="color:blue">'.$databases['praefix'][$dump['dbindex']].'</span>)' : '').'...   ';
+        if (1 == $dump['part']) {
+            $dump['table_offset'] = 0;
+            $dump['countdata'] = 0;
+        }
+        // Seitenerstaufruf -> Backupdatei anlegen
+        $dump['data'] = $statuszeile.$mysql_commentstring.' Dump created: '.$cur_time;
+    } else {
+        if (0 != $config['multi_part']) {
+            WriteLog('Continue Multipart-Dump with File '.($dump['part'] - $dump['part_offset']).' (last file was '.$last_groesse.' Bytes)');
+            $dump['data'] = $statuszeile.$mysql_commentstring.' This is part '.($dump['part'] - $dump['part_offset']).' of the backup.'.$nl.$nl.$dump['data'];
+        }
+    }
+    WriteToDumpFile();
+    ++$dump['part'];
 }
 
-function GetStatusLine($kind="php")
+function GetStatusLine($kind = 'php')
 {
-	/*AUFBAU der Statuszeile:
-		-- Status:tabellenzahl:datensätze:Multipart:Datenbankname:script:scriptversion:Kommentar:MySQLVersion:Backupflags:SQLBefore:SQLAfter:Charset:CharsetEXTINFO
-		Aufbau Backupflags (1 Zeichen pro Flag, 0 oder 1, 2=unbekannt)
-		(complete inserts)(extended inserts)(ignore inserts)(delayed inserts)(downgrade)(lock tables)(optimize tables)
-	*/
+    /*AUFBAU der Statuszeile:
+        -- Status:tabellenzahl:datensätze:Multipart:Datenbankname:script:scriptversion:Kommentar:MySQLVersion:Backupflags:SQLBefore:SQLAfter:Charset:CharsetEXTINFO
+        Aufbau Backupflags (1 Zeichen pro Flag, 0 oder 1, 2=unbekannt)
+        (complete inserts)(extended inserts)(ignore inserts)(delayed inserts)(downgrade)(lock tables)(optimize tables)
+    */
 
-	global $databases,$config,$lang,$dump,$mysql_commentstring;
+    global $databases, $config, $lang, $dump, $mysql_commentstring;
 
-	$t_array=explode("|",$databases['db_actual_tableselected']);
-	$t=0;
-	$r=0;
-	$t_zeile="$mysql_commentstring\n$mysql_commentstring TABLE-INFO\r\n";
-	MSD_mysql_connect();
-	$res=mysqli_query($config['dbconnection'], "SHOW TABLE STATUS FROM `".$databases['Name'][$dump['dbindex']]."`");
-	$numrows=intval(@mysqli_num_rows($res));
-	for($i=0;$i<$numrows;$i++)
-	{
-		$erg=mysqli_fetch_array($res);
-		// Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
-		$sql_2="SELECT count(*) as `count_records` FROM `".$databases['Name'][$dump['dbindex']]."`.`".$erg['Name']."`";
-		$res2=@mysqli_query($config['dbconnection'], $sql_2);
-		if ($res2===false)
-		{
-			// error reading table definition
-			$read_create_error=sprintf($lang['L_FATAL_ERROR_DUMP'],$databases['Name'][$dump['dbindex']],$erg['Name']).': '.mysqli_error($config['dbconnection']);
-			Errorlog("DUMP",$databases['Name'][$dump['dbindex']],'',$read_create_error,0);
-			WriteLog($read_create_error);
-			if ($config['stop_with_error']>0)
-			{
-				die($read_create_error);
-			}
-			$dump['errors']++;
-			//$i++; // skip corrupted table
-		}
-		else
-		{
-			$row2=mysqli_fetch_array($res2);
-			$erg['Rows']=$row2['count_records'];
+    $t_array = explode('|', $databases['db_actual_tableselected']);
+    $t = 0;
+    $r = 0;
+    $t_zeile = "$mysql_commentstring\n$mysql_commentstring TABLE-INFO\r\n";
+    mod_mysqli_connect();
+    $res = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['Name'][$dump['dbindex']].'`');
+    $numrows = intval(@mysqli_num_rows($res));
+    for ($i = 0; $i < $numrows; ++$i) {
+        $erg = mysqli_fetch_array($res);
+        // Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
+        $sql_2 = 'SELECT count(*) as `count_records` FROM `'.$databases['Name'][$dump['dbindex']].'`.`'.$erg['Name'].'`';
+        $res2 = mysqli_query($config['dbconnection'], $sql_2);
+        if (false === $res2) {
+            // error reading table definition
+            $read_create_error = sprintf($lang['L_FATAL_ERROR_DUMP'], $databases['Name'][$dump['dbindex']], $erg['Name']).': '.mysqli_error($config['dbconnection']);
+            Errorlog('DUMP', $databases['Name'][$dump['dbindex']], '', $read_create_error, 0);
+            WriteLog($read_create_error);
+            if ($config['stop_with_error'] > 0) {
+                exit($read_create_error);
+            }
+            ++$dump['errors'];
+        //$i++; // skip corrupted table
+        } else {
+            $row2 = mysqli_fetch_array($res2);
+            $erg['Rows'] = $row2['count_records'];
 
-			if (($databases['db_actual_tableselected']==''||($databases['db_actual_tableselected']!=''&&(in_array($erg[0],$t_array))))&&(substr($erg[0],0,strlen($databases['praefix'][$dump['dbindex']]))==$databases['praefix'][$dump['dbindex']]))
-			{
-				$t++;
-				$r+=$erg['Rows'];
-				if (isset($erg['Type'])) $erg['Engine']=$erg['Type'];
-				$t_zeile.="$mysql_commentstring TABLE|".$erg['Name'].'|'.$erg['Rows'].'|'.($erg['Data_length']+$erg['Index_length']).'|'.$erg['Update_time'].'|'.$erg['Engine']."\n";
-			}
-		}
-	}
-	//$dump['totalrecords']=$r;
-	$flags=1;
+            if (('' == $databases['db_actual_tableselected'] || ('' != $databases['db_actual_tableselected'] && (in_array($erg[0], $t_array)))) && (substr($erg[0], 0, strlen($databases['praefix'][$dump['dbindex']])) == $databases['praefix'][$dump['dbindex']])) {
+                ++$t;
+                $r += $erg['Rows'];
+                if (isset($erg['Type'])) {
+                    $erg['Engine'] = $erg['Type'];
+                }
+                $t_zeile .= "$mysql_commentstring TABLE|".$erg['Name'].'|'.$erg['Rows'].'|'.($erg['Data_length'] + $erg['Index_length']).'|'.$erg['Update_time'].'|'.$erg['Engine']."\n";
+            }
+        }
+    }
+    //$dump['totalrecords'] = $r;
+    $flags = 1;
 
-	$mp=($config['multi_part']==1) ? $mp="MP_".($dump['part']-$dump['part_offset']):'MP_0';
-	$statusline="$mysql_commentstring Status:$t:$r:$mp:".$databases['Name'][$dump['dbindex']].":$kind:".MSD_VERSION.":".$dump['kommentar'].":";
-	$statusline.=MSD_MYSQL_VERSION.":$flags:::".$dump['dump_encoding'].":EXTINFO\n".$t_zeile."$mysql_commentstring"." EOF TABLE-INFO\n$mysql_commentstring";
-	return $statusline;
+    $mp = (isset($config['multi_part']) && (1 == $config['multi_part'])) ? $mp = 'MP_'.($dump['part'] - $dump['part_offset']) : 'MP_0';
+    $statusline = "$mysql_commentstring Status:$t:$r:$mp:".$databases['Name'][$dump['dbindex']].":$kind:".MOD_VERSION.':'.$dump['kommentar'].':';
+    $statusline .= MOD_MYSQL_VERSION.":$flags:::".$dump['dump_encoding'].":EXTINFO\n".$t_zeile."$mysql_commentstring"." EOF TABLE-INFO\n$mysql_commentstring";
+    return $statusline;
 }
 
 // Liest die Eigenschaften der Tabelle aus der DB und baut die CREATE-Anweisung zusammen
-function get_def($db,$table,$withdata=1)
+function get_def($db, $table, $withdata = 1)
 {
-	global $config,$nl,$mysql_commentstring,$dump;
+    global $config, $nl, $mysql_commentstring, $dump;
 
-	$def="\n\n$mysql_commentstring\n$mysql_commentstring Create Table `$table`\n$mysql_commentstring\n\n";
-	if ($dump['table_types'][getDBIndex($db,$table)]=='VIEW')
-	{
-		$def.="DROP VIEW IF EXISTS `$table`;\n";
-		$withdata=0;
-	}
-	else
-		$def.="DROP TABLE IF EXISTS `$table`;\n";
-	mysqli_select_db($config['dbconnection'], $db);
-	$result=mysqli_query($config['dbconnection'], 'SHOW CREATE TABLE `'.$table.'`');
-	$row=@mysqli_fetch_row($result);
-	if ($row===false) return false;
-	$def.=$row[1].';'."\n\n";
-	if ($withdata==1)
-	{
-		$def.="$mysql_commentstring\n$mysql_commentstring Data for Table `$table`\n$mysql_commentstring\n\n";
-		$def.="/*!40000 ALTER TABLE `$table` DISABLE KEYS */;".$nl;
-	}
-	return $def;
+    $def = "\n\n$mysql_commentstring\n$mysql_commentstring Create Table `$table`\n$mysql_commentstring\n\n";
+    if ('VIEW' == $dump['table_types'][getDBIndex($db, $table)]) {
+        $def .= "DROP VIEW IF EXISTS `$table`;\n";
+        $withdata = 0;
+    } else {
+        $def .= "DROP TABLE IF EXISTS `$table`;\n";
+    }
+    mysqli_select_db($config['dbconnection'], $db);
+    $result = mysqli_query($config['dbconnection'], 'SHOW CREATE TABLE `'.$table.'`');
+    $row = mysqli_fetch_row($result);
+    if (false === $row) {
+        return false;
+    }
+    $def .= $row[1].';'."\n\n";
+    if (1 == $withdata) {
+        $def .= "$mysql_commentstring\n$mysql_commentstring Data for Table `$table`\n$mysql_commentstring\n\n";
+        $def .= "/*!40000 ALTER TABLE `$table` DISABLE KEYS */;".$nl;
+    }
+    return $def;
 }
 
 // Liest die Daten aus der DB aus und baut die INSERT-Anweisung zusammen
-function get_content($db,$table)
+function get_content($db, $table)
 {
-	global $config,$nl,$dump,$buffer;
+    global $config, $nl, $dump, $buffer;
 
-	$content='';
-	$complete=Fieldlist($db,$table).' ';
+    $content = '';
+    $complete = Fieldlist($db, $table).' ';
 
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
 
-	$table_ready=0;
-	$query='SELECT * FROM `'.$table.'` LIMIT '.$dump['zeilen_offset'].','.($dump['restzeilen']+1);
-	mysqli_select_db($config['dbconnection'], $db);
-	$result=mysqli_query($config['dbconnection'], $query);
-	$ergebnisse=@mysqli_num_rows($result);
-	if ($ergebnisse!==false)
-	{
-		// $num_felder=mysqli_field_count($result);
-		$num_felder=mysqli_field_count($config['dbconnection']);
+    $table_ready = 0;
+    $query = 'SELECT * FROM `'.$table.'` LIMIT '.$dump['zeilen_offset'].','.($dump['restzeilen'] + 1);
+    mysqli_select_db($config['dbconnection'], $db);
+    $result = mysqli_query($config['dbconnection'], $query);
+    $ergebnisse = mysqli_num_rows($result);
+    if (false !== $ergebnisse) {
+        // $num_felder=mysqli_field_count($result);
+        $num_felder = mysqli_field_count($config['dbconnection']);
 
-		$first=1;
+        $first = 1;
 
-		if ($ergebnisse>$dump['restzeilen'])
-		{
-			$dump['zeilen_offset']+=$dump['restzeilen'];
-			$ergebnisse--;
-			$dump['restzeilen']=0;
-		}
-		else
-		{
-			$dump['table_offset']++;
-			$dump['zeilen_offset']=0;
-			$dump['restzeilen']=$dump['restzeilen']-$ergebnisse;
-			$table_ready=1;
-		}
-		$ax=0;
-		for($x=0;$x<$ergebnisse;$x++)
-		{
-			$row=mysqli_fetch_row($result);
-			$ax++;
+        if ($ergebnisse > $dump['restzeilen']) {
+            $dump['zeilen_offset'] += $dump['restzeilen'];
+            --$ergebnisse;
+            $dump['restzeilen'] = 0;
+        } else {
+            ++$dump['table_offset'];
+            $dump['zeilen_offset'] = 0;
+            $dump['restzeilen'] = $dump['restzeilen'] - $ergebnisse;
+            $table_ready = 1;
+        }
+        $ax = 0;
+        for ($x = 0; $x < $ergebnisse; ++$x) {
+            $row = mysqli_fetch_row($result);
+            ++$ax;
 
-			$insert='INSERT INTO `'.$table.'` '.$complete.'VALUES (';
+            $insert = 'INSERT INTO `'.$table.'` '.$complete.'VALUES (';
 
-			for($j=0;$j<$num_felder;$j++)
-			{
-				if (!isset($row[$j])) $insert.='NULL,';
-				else
-					if ($row[$j]!='') $insert.='\''.mysqli_real_escape_string($config['dbconnection'], $row[$j]).'\',';
-					else
-						$insert.='\'\',';
-			}
-			$insert=substr($insert,0,-1).');'.$nl;
-			$dump['data'].=$insert;
-			$dump['countdata']++;
-			if (strlen($dump['data'])>$config['memory_limit']||($config['multi_part']==1&&strlen($dump['data'])+$buffer>$config['multipart_groesse']))
-			{
-				WriteToDumpFile();
-			}
-		}
-		if ($table_ready==1&&$dump['table_types'][getDBIndex($db,$table)]!='VIEW') $dump['data'].="/*!40000 ALTER TABLE `$table` ENABLE KEYS */;\n";
-	}
-	else
-	{
-		// table corrupt -> skip it
-		$dump['table_offset']++;
-		$dump['zeilen_offset']=0;
-		$dump['restzeilen']=$dump['restzeilen']-$ergebnisse;
-		$dump['data'].="/*!40000 ALTER TABLE `$table` ENABLE KEYS */;\n";
-		if (strlen($dump['data'])>$config['memory_limit']||($config['multi_part']==1&&strlen($dump['data'])+$buffer>$config['multipart_groesse']))
-		{
-			WriteToDumpFile();
-		}
-	}
-	@mysqli_free_result($result);
+            for ($j = 0; $j < $num_felder; ++$j) {
+                if (!isset($row[$j])) {
+                    $insert .= 'NULL,';
+                } else {
+                    $fieldinfo = mysqli_fetch_field_direct($result, $j);
+                    if (($fieldinfo->flags & 128) == true && isset($config['use_binary_container']) && 1 == $config['use_binary_container']) {
+                        if ('' != $row[$j]) {
+                            $insert .= '_binary 0x'.bin2hex($row[$j]).',';
+                        } else {
+                            $insert .= '_binary \'\',';
+                        }
+                    } elseif ('' != $row[$j]) {
+                        $insert .= '\''.mysqli_real_escape_string($config['dbconnection'], $row[$j]).'\',';
+                    } else {
+                        $insert .= '\'\',';
+                    }
+                }
+            }
+            $insert = substr($insert, 0, -1).');'.$nl;
+            $dump['data'] .= $insert;
+            ++$dump['countdata'];
+            $config['memory_limit'] = isset($config['memory_limit']) ? $config['memory_limit'] : 0;
+            if (strlen($dump['data']) > $config['memory_limit'] || (1 == $config['multi_part'] && strlen($dump['data']) + $buffer > $config['multipart_groesse'])) {
+                WriteToDumpFile();
+            }
+        }
+        if (1 == $table_ready && 'VIEW' != $dump['table_types'][getDBIndex($db, $table)]) {
+            $dump['data'] .= "/*!40000 ALTER TABLE `$table` ENABLE KEYS */;\n";
+        }
+    } else {
+        // table corrupt -> skip it
+        ++$dump['table_offset'];
+        $dump['zeilen_offset'] = 0;
+        $dump['restzeilen'] = $dump['restzeilen'] - $ergebnisse;
+        $dump['data'] .= "/*!40000 ALTER TABLE `$table` ENABLE KEYS */;\n";
+        if (strlen($dump['data']) > $config['memory_limit'] || (1 == $config['multi_part'] && strlen($dump['data']) + $buffer > $config['multipart_groesse'])) {
+            WriteToDumpFile();
+        }
+    }
+    @mysqli_free_result($result);
 }
 
 function WriteToDumpFile()
 {
-	global $config,$dump,$buffer;
-	$dump['filesize']=0;
+    global $config, $dump, $buffer;
+    $dump['filesize'] = 0;
 
-	$df=$config['paths']['backup'].$dump['backupdatei'];
+    $df = $config['paths']['backup'].$dump['backupdatei'];
 
-	if ($config['compression']==1)
-	{
-		if ($dump['data']!='')
-		{
-			$fp=gzopen($df,'ab');
-			gzwrite($fp,$dump['data']);
-			gzclose($fp);
-		}
-	}
-	else
-	{
-		if ($dump['data']!='')
-		{
-			$fp=fopen($df,'ab');
-			fwrite($fp,$dump['data']);
-			fclose($fp);
-		}
-	}
-	$dump['data']='';
-	if (!isset($dump['fileoperations'])) $dump['fileoperations']=0;
-	$dump['fileoperations']++;
+    if (isset($config['compression']) && (1 == $config['compression'])) {
+        if ('' != $dump['data']) {
+            $fp = gzopen($df, 'ab');
+            gzwrite($fp, $dump['data']);
+            gzclose($fp);
+        }
+    } else {
+        if ('' != $dump['data']) {
+            $fp = fopen($df, 'ab');
+            fwrite($fp, $dump['data']);
+            fclose($fp);
+        }
+    }
+    $dump['data'] = '';
+    if (!isset($dump['fileoperations'])) {
+        $dump['fileoperations'] = 0;
+    }
+    ++$dump['fileoperations'];
 
-	if ($config['multi_part']==1) clearstatcache();
-	$dump['filesize']=filesize($df);
-	if ($config['multi_part']==1&&$dump['filesize']+$buffer>$config['multipart_groesse'])
-	{
-		@chmod($df,0777);
-		new_file($dump['filesize']); // Wenn maximale Dateigroesse erreicht -> neues File starten
-	}
+    if (isset($config['multi_part']) && (1 == $config['multi_part'])) {
+        clearstatcache();
+    }
+    $dump['filesize'] = filesize($df);
+    if ((isset($config['multi_part']) && 1 == $config['multi_part']) && ($dump['filesize'] + $buffer > $config['multipart_groesse'])) {
+        @chmod($df, 0777);
+        new_file($dump['filesize']); // Wenn maximale Dateigroesse erreicht -> neues File starten
+    }
 }
 
 function ExecuteCommand($when)
 {
-	global $config,$databases,$dump,$out,$lang;
-	$lf='<br>';
-	if (!isset($dump['dbindex'])) return;
-	if ($when=='b')
-	{ // before dump
-		$cd=$databases['command_before_dump'][$dump['dbindex']];
-		//WriteLog('DbIndex: '.$dump['dbindex'].' Before: '.$databases['command_before_dump'][$dump['dbindex']]);
-	}
-	else
-	{
+    global $config, $databases, $dump, $out, $lang;
+    $lf = '<br>';
+    if (!isset($dump['dbindex'])) {
+        return;
+    }
+    if ('b' == $when) { // before dump
+        $cd = $databases['command_before_dump'][$dump['dbindex']];
+    //WriteLog('DbIndex: '.$dump['dbindex'].' Before: '.$databases['command_before_dump'][$dump['dbindex']]);
+    } else {
+        $cd = $databases['command_after_dump'][$dump['dbindex']];
+        //WriteLog('DbIndex: '.$dump['dbindex'].' After: '.$databases['command_after_dump'][$dump['dbindex']]);
+    }
 
-		$cd=$databases['command_after_dump'][$dump['dbindex']];
-		//WriteLog('DbIndex: '.$dump['dbindex'].' After: '.$databases['command_after_dump'][$dump['dbindex']]);
-	}
+    if ('' != $cd) {
+        //jetzt ausführen
+        if ('system:' != substr(strtolower($cd), 0, 7)) {
+            $cad = [];
+            @mysqli_select_db($config['dbconnection'], $databases['Name'][$dump['dbindex']]);
+            if (strpos($cd, ';')) {
+                $cad = explode(';', $cd);
+            } else {
+                $cad[0] = $cd;
+            }
 
-	if ($cd!='')
-	{
-		//jetzt ausführen
-		if (substr(strtolower($cd),0,7)!='system:')
-		{
-			$cad=array();
-			@mysqli_select_db($databases['Name'][$dump['dbindex']]);
-			if (strpos($cd,';'))
-			{
-				$cad=explode(';',$cd);
-			}
-			else
-				$cad[0]=$cd;
-
-			for($i=0;$i<sizeof($cad);$i++)
-			{
-				if (trim($cad[$i])>'')
-				{
-					$result=@mysqli_query($config['dbconnection'], $cad[$i]);
-
-					if ($result===false)
-					{
-						WriteLog("Error executing Query '$cad[$i]'! MySQL returns: ".trim(mysqli_error($config['dbconnection'])));
-						ErrorLog("Error executing Query '$cad[$i]'!",$databases['Name'][$dump['dbindex']],$cad[$i],mysqli_error($config['dbconnection']),0);
-						$dump['errors']++;
-						$out.='<span class="error">Error executing Query '.$cad[$i].'</span>'.$lf;
-					}
-					else
-					{
-						WriteLog("Successfully executed Query: '$cad[$i]'");
-						$out.='<span class="success">Successfully executed Query: \''.$cad[$i].'\'</span>'.$lf;
-					}
-				}
-			}
-		}
-		elseif (substr(strtolower($cd),0,7)=="system:")
-		{
-			$command=substr($cd,7);
-			$result=@system($command,$returnval);
-			if (!$result)
-			{
-				WriteLog("Error while executing System Command '$command'");
-				$dump['errors']++;
-				$out.=$lf.'<span class="error">ERROR executing System Command \''.$ommand.'\'</span><br>';
-			}
-			else
-			{
-				WriteLog("Successfully executed System Command '$command'. [$returnval]");
-				$out.=$lf.'<span class="success">Successfully executed System Command \''.$ommand.'.</span><br>';
-			}
-		}
-	}
+            for ($i = 0; $i < sizeof($cad); ++$i) {
+                if (trim($cad[$i]) > '') {
+                    $result = mysqli_query($config['dbconnection'], $cad[$i]);
 
+                    if (false === $result) {
+                        WriteLog("Error executing Query '$cad[$i]'! MySQL returns: ".trim(mysqli_error($config['dbconnection'])));
+                        ErrorLog("Error executing Query '$cad[$i]'!", $databases['Name'][$dump['dbindex']], $cad[$i], mysqli_error($config['dbconnection']), 0);
+                        ++$dump['errors'];
+                        $out .= '<span class="error">Error executing Query '.$cad[$i].'</span>'.$lf;
+                    } else {
+                        WriteLog("Successfully executed Query: '$cad[$i]'");
+                        $out .= '<span class="success">Successfully executed Query: \''.$cad[$i].'\'</span>'.$lf;
+                    }
+                }
+            }
+        } elseif ('system:' == substr(strtolower($cd), 0, 7)) {
+            $command = substr($cd, 7);
+            $result = @system($command, $returnval);
+            if (!$result) {
+                WriteLog("Error while executing System Command '$command'");
+                ++$dump['errors'];
+                $out .= $lf.'<span class="error">ERROR executing System Command \''.$command.'\'</span><br>';
+            } else {
+                WriteLog("Successfully executed System Command '$command'. [$returnval]");
+                $out .= $lf.'<span class="success">Successfully executed System Command \''.$command.'.</span><br>';
+            }
+        }
+    }
 }
 
 function DoEmail()
 {
-	global $config,$dump,$databases,$email,$lang,$out,$REMOTE_ADDR;
+    global $config, $dump, $databases, $email, $lang, $out, $REMOTE_ADDR;
 
-	$header="";
-	if ($config['cron_use_sendmail']==1)
-	{
-		//sendmail
-		if (ini_get("sendmail_path")!=$config['cron_sendmail']) @ini_set("SMTP",$config['cron_sendmail']);
-		if (ini_get("sendmail_from")!=$config['email_sender']) @ini_set("SMTP",$config['email_sender']);
-	}
-	else
-	{
-		//SMTP
-	}
-	if (ini_get("SMTP")!=$config['cron_smtp']) @ini_set("SMTP",$config['cron_smtp']);
-	if (ini_get("smtp_port")!=25) @ini_set("smtp_port",25);
+    $header = '';
+    if (1 == $config['cron_use_sendmail']) {
+        //sendmail
+        if (ini_get('sendmail_path') != $config['cron_sendmail']) {
+            @ini_set('SMTP', $config['cron_sendmail']);
+        }
+        if (ini_get('sendmail_from') != $config['email_sender']) {
+            @ini_set('SMTP', $config['email_sender']);
+        }
+    } else {
+        //SMTP
+    }
+    if (ini_get('SMTP') != $config['cron_smtp']) {
+        @ini_set('SMTP', $config['cron_smtp']);
+    }
+    if (25 != ini_get('smtp_port')) {
+        @ini_set('smtp_port', 25);
+    }
 
-	if ($config['multi_part']==0)
-	{
-		$file=$dump['backupdatei'];
-		$file_name=(strpos("/",$file)) ? substr($file,strrpos("/",$file)):$file;
-		$file_type=filetype($config['paths']['backup'].$file);
-		$file_size=filesize($config['paths']['backup'].$file);
-		if (($config['email_maxsize']>0&&$file_size>$config['email_maxsize'])||$config['send_mail_dump']==0)
-		{
-			//anhang zu gross
-			$subject="Backup '".$databases['Name'][$dump['dbindex']]."' - ".date("d\.m\.Y H:i",time());
-			$header.="FROM:".$config['email_sender']."\n";
-			if (isset($config['email_recipient_cc'])&&trim($config['email_recipient_cc'])>'') $header.="Cc:     ".$config['email_recipient_cc']."\r\n";
-			$header.="MIME-version: 1.0\n";
-			$header.="X-Mailer: PHP/".phpversion()."\n";
-			$header.="X-Sender-IP: $REMOTE_ADDR\n";
-			$header.="Content-Type: text/html; charset=utf-8\n";
-			if ($config['send_mail_dump']!=0)
-			{
-				$msg_body=sprintf(addslashes($lang['L_EMAILBODY_TOOBIG']),byte_output($config['email_maxsize']),$databases['Name'][$dump['dbindex']],"$file (".byte_output(filesize($config['paths']['backup'].$file)).")<br>");
-			}
-			else
-			{
-				$msg_body=sprintf(addslashes($lang['L_EMAILBODY_NOATTACH']),$databases['Name'][$dump['dbindex']],"$file (".byte_output(filesize($config['paths']['backup'].$file)).")");
-			}
-			include_once ('./inc/functions.php');
-			$msg_body.='<a href="'.getServerProtocol().$_SERVER['HTTP_HOST'].substr($_SERVER["PHP_SELF"],0,strrpos($_SERVER["PHP_SELF"],"/")).'/'.$config['paths']['backup'].$file.'">'.$file.'</a>';
-			$email_log="Email sent to '".$config['email_recipient']."'";
-			$email_out=$lang['L_EMAIL_WAS_SEND']."`".$config['email_recipient']."`<br>";
-		}
-		else
-		{
-			//alles ok, anhang generieren
-			$msg_body=sprintf(addslashes($lang['L_EMAILBODY_ATTACH']),$databases['Name'][$dump['dbindex']],"$file (".byte_output(filesize($config['paths']['backup'].$file)).")");
-			$subject="Backup '".$databases['Name'][$dump['dbindex']]."' - ".date("d\.m\.Y",time());
-			$fp=fopen($config['paths']['backup'].$file,"r");
-			$contents=fread($fp,$file_size);
-			$encoded_file=chunk_split(base64_encode($contents));
-			fclose($fp);
-			$header.="FROM:".$config['email_sender']."\n";
-			if (isset($config['email_recipient_cc'])&&trim($config['email_recipient_cc'])>'') $header.="Cc:     ".$config['email_recipient_cc']."\r\n";
-			$header.="MIME-version: 1.0\n";
-			$header.="Content-type: multipart/mixed; ";
-			$header.="boundary=\"Message-Boundary\"\n";
-			$header.="Content-transfer-encoding: 7BIT\n";
-			$header.="X-attachments: $file_name";
-			$body_top="--Message-Boundary\n";
-			$body_top.="Content-type: text/html; charset=utf-8\n";
-			$body_top.="Content-transfer-encoding: 7BIT\n";
-			$body_top.="Content-description: Mail message body\n\n";
-			$msg_body=$body_top.$msg_body;
-			$msg_body.="\n\n--Message-Boundary\n";
-			$msg_body.="Content-type: $file_type; name=\"$file\"\n";
-			$msg_body.="Content-Transfer-Encoding: BASE64\n";
-			$msg_body.="Content-disposition: attachment; filename=\"$file\"\n\n";
-			$msg_body.="$encoded_file\n";
-			$msg_body.="--Message-Boundary--\n";
-			$email_log="Email was sent to '".$config['email_recipient']."' with '".$dump['backupdatei']."'.";
-			$email_out=$lang['L_EMAIL_WAS_SEND']."`".$config['email_recipient']."`".$lang['L_WITH']."`".$dump['backupdatei']."`.<br>";
-		}
-	}
-	else
-	{
-		//Multipart
-		$mp_sub="Backup '".$databases['Name'][$dump['dbindex']]."' - ".date("d\.m\.Y",time());
-		$subject=$mp_sub;
-		$header.="FROM:".$config['email_sender']."\n";
-		if (isset($config['email_recipient_cc'])&&trim($config['email_recipient_cc'])>'') $header.="Cc:     ".$config['email_recipient_cc']."\r\n";
-		$header.="MIME-version: 1.0\n";
-		$header.="X-Mailer: PHP/".phpversion()."\n";
-		$header.="X-Sender-IP: $REMOTE_ADDR\n";
-		$header.="Content-Type: text/html; charset=utf-8";
-		$dateistamm=substr($dump['backupdatei'],0,strrpos($dump['backupdatei'],"part_"))."part_";
-		$dateiendung=($config['compression']==1) ? ".sql.gz":".sql";
-		$mpdatei=Array();
-		$mpfiles="";
-		for($i=1;$i<($dump['part']-$dump['part_offset']);$i++)
-		{
-			$mpdatei[$i-1]=$dateistamm.$i.$dateiendung;
-			$sz=byte_output(@filesize($config['paths']['backup'].$mpdatei[$i-1]));
-			$mpfiles.=$mpdatei[$i-1]." (".$sz.")<br>";
-		}
-		$msg_body=($config['send_mail_dump']==1) ? sprintf(addslashes($lang['L_EMAILBODY_MP_ATTACH']),$databases['Name'][$dump['dbindex']],$mpfiles):sprintf(addslashes($lang['L_EMAILBODY_MP_NOATTACH']),$databases['Name'][$dump['dbindex']],$mpfiles);
-		$email_log="Email was sent to '".$config['email_recipient']."'";
-		$email_out=$lang['L_EMAIL_WAS_SEND']."`".$config['email_recipient']."`<br>";
-	}
-	if (@mail($config['email_recipient'],stripslashes($subject),$msg_body,$header))
-	{
-		$out.='<span class="success">'.$email_out.'</span>';
-		WriteLog("$email_log");
-	}
-	else
-	{
-		$out.='<span class="error">'.$lang['L_MAILERROR'].'</span><br>';
-		WriteLog("Email to '".$config['email_recipient']."' failed !");
-		ErrorLog("Email ",$databases['Name'][$dump['dbindex']],'Subject: '.stripslashes($subject),$lang['L_MAILERROR']);
-		$dump['errors']++;
-	}
+    if (0 == $config['multi_part']) {
+        $file = $dump['backupdatei'];
+        $file_name = (strpos('/', $file)) ? substr($file, strrpos('/', $file)) : $file;
+        $file_type = filetype($config['paths']['backup'].$file);
+        $file_size = filesize($config['paths']['backup'].$file);
+        if (($config['email_maxsize'] > 0 && $file_size > $config['email_maxsize']) || 0 == $config['send_mail_dump']) {
+            //anhang zu gross
+            $subject = "Backup '".$databases['Name'][$dump['dbindex']]."' - ".date("d\.m\.Y H:i", time());
+            $header .= 'FROM:'.$config['email_sender']."\n";
+            if (isset($config['email_recipient_cc']) && trim($config['email_recipient_cc']) > '') {
+                $header .= 'Cc:     '.$config['email_recipient_cc']."\r\n";
+            }
+            $header .= "MIME-version: 1.0\n";
+            $header .= 'X-Mailer: PHP/'.phpversion()."\n";
+            $header .= "X-Sender-IP: $REMOTE_ADDR\n";
+            $header .= "Content-Type: text/html; charset=utf-8\n";
+            if (0 != $config['send_mail_dump']) {
+                $msg_body = sprintf(addslashes($lang['L_EMAILBODY_TOOBIG']), byte_output($config['email_maxsize']), $databases['Name'][$dump['dbindex']], "$file (".byte_output(filesize($config['paths']['backup'].$file)).')<br>');
+            } else {
+                $msg_body = sprintf(addslashes($lang['L_EMAILBODY_NOATTACH']), $databases['Name'][$dump['dbindex']], "$file (".byte_output(filesize($config['paths']['backup'].$file)).')');
+            }
+            include_once './inc/functions.php';
+            $msg_body .= '<a href="'.getServerProtocol().$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/')).'/'.$config['paths']['backup'].$file.'">'.$file.'</a>';
+            $email_log = "Email sent to '".$config['email_recipient']."'";
+            $email_out = $lang['L_EMAIL_WAS_SEND'].'`'.$config['email_recipient'].'`<br>';
+        } else {
+            //alles ok, anhang generieren
+            $msg_body = sprintf(addslashes($lang['L_EMAILBODY_ATTACH']), $databases['Name'][$dump['dbindex']], "$file (".byte_output(filesize($config['paths']['backup'].$file)).')');
+            $subject = "Backup '".$databases['Name'][$dump['dbindex']]."' - ".date("d\.m\.Y", time());
+            $fp = fopen($config['paths']['backup'].$file, 'r');
+            $contents = fread($fp, $file_size);
+            $encoded_file = chunk_split(base64_encode($contents));
+            fclose($fp);
+            $header .= 'FROM:'.$config['email_sender']."\n";
+            if (isset($config['email_recipient_cc']) && trim($config['email_recipient_cc']) > '') {
+                $header .= 'Cc:     '.$config['email_recipient_cc']."\r\n";
+            }
+            $header .= "MIME-version: 1.0\n";
+            $header .= 'Content-type: multipart/mixed; ';
+            $header .= "boundary=\"Message-Boundary\"\n";
+            $header .= "Content-transfer-encoding: 7BIT\n";
+            $header .= "X-attachments: $file_name";
+            $body_top = "--Message-Boundary\n";
+            $body_top .= "Content-type: text/html; charset=utf-8\n";
+            $body_top .= "Content-transfer-encoding: 7BIT\n";
+            $body_top .= "Content-description: Mail message body\n\n";
+            $msg_body = $body_top.$msg_body;
+            $msg_body .= "\n\n--Message-Boundary\n";
+            $msg_body .= "Content-type: $file_type; name=\"$file\"\n";
+            $msg_body .= "Content-Transfer-Encoding: BASE64\n";
+            $msg_body .= "Content-disposition: attachment; filename=\"$file\"\n\n";
+            $msg_body .= "$encoded_file\n";
+            $msg_body .= "--Message-Boundary--\n";
+            $email_log = "Email was sent to '".$config['email_recipient']."' with '".$dump['backupdatei']."'.";
+            $email_out = $lang['L_EMAIL_WAS_SEND'].'`'.$config['email_recipient'].'`'.$lang['L_WITH'].'`'.$dump['backupdatei'].'`.<br>';
+        }
+    } else {
+        //Multipart
+        $mp_sub = "Backup '".$databases['Name'][$dump['dbindex']]."' - ".date("d\.m\.Y", time());
+        $subject = $mp_sub;
+        $header .= 'FROM:'.$config['email_sender']."\n";
+        if (isset($config['email_recipient_cc']) && trim($config['email_recipient_cc']) > '') {
+            $header .= 'Cc:     '.$config['email_recipient_cc']."\r\n";
+        }
+        $header .= "MIME-version: 1.0\n";
+        $header .= 'X-Mailer: PHP/'.phpversion()."\n";
+        $header .= "X-Sender-IP: $REMOTE_ADDR\n";
+        $header .= 'Content-Type: text/html; charset=utf-8';
+        $dateistamm = substr($dump['backupdatei'], 0, strrpos($dump['backupdatei'], 'part_')).'part_';
+        $dateiendung = (1 == $config['compression']) ? '.sql.gz' : '.sql';
+        $mpdatei = [];
+        $mpfiles = '';
+        for ($i = 1; $i < ($dump['part'] - $dump['part_offset']); ++$i) {
+            $mpdatei[$i - 1] = $dateistamm.$i.$dateiendung;
+            $sz = byte_output(@filesize($config['paths']['backup'].$mpdatei[$i - 1]));
+            $mpfiles .= $mpdatei[$i - 1].' ('.$sz.')<br>';
+        }
+        $msg_body = (1 == $config['send_mail_dump']) ? sprintf(addslashes($lang['L_EMAILBODY_MP_ATTACH']), $databases['Name'][$dump['dbindex']], $mpfiles) : sprintf(addslashes($lang['L_EMAILBODY_MP_NOATTACH']), $databases['Name'][$dump['dbindex']], $mpfiles);
+        $email_log = "Email was sent to '".$config['email_recipient']."'";
+        $email_out = $lang['L_EMAIL_WAS_SEND'].'`'.$config['email_recipient'].'`<br>';
+    }
+    if (@mail($config['email_recipient'], stripslashes($subject), $msg_body, $header)) {
+        $out .= '<span class="success">'.$email_out.'</span>';
+        WriteLog("$email_log");
+    } else {
+        $out .= '<span class="error">'.$lang['L_MAILERROR'].'</span><br>';
+        WriteLog("Email to '".$config['email_recipient']."' failed !");
+        ErrorLog('Email ', $databases['Name'][$dump['dbindex']], 'Subject: '.stripslashes($subject), $lang['L_MAILERROR']);
+        ++$dump['errors'];
+    }
 
-	if (isset($mpdatei)&&$config['send_mail_dump']==1)
-	{ // && ($config['email_maxsize']==0 || ($config['email_maxsize']>0 && $config['multipartgroesse2']<=$config['email_maxsize']))) {
-		for($i=0;$i<count($mpdatei);$i++)
-		{
-			$file_name=$mpdatei[$i];
-			$file_type=filetype($config['paths']['backup'].$mpdatei[$i]);
-			$file_size=filesize($config['paths']['backup'].$mpdatei[$i]);
-			$fp=fopen($config['paths']['backup'].$mpdatei[$i],"r");
-			$contents=fread($fp,$file_size);
-			$encoded_file=chunk_split(base64_encode($contents));
-			fclose($fp);
-			$subject=$mp_sub."  [Part ".($i+1)." / ".count($mpdatei)."]";
-			$header="FROM:".$config['email_sender']."\n";
-			if (isset($config['email_recipient_cc'])&&trim($config['email_recipient_cc'])>'') $header.="Cc:     ".$config['email_recipient_cc']."\r\n";
-			$header.="MIME-version: 1.0\n";
-			$header.="Content-type: multipart/mixed; ";
-			$header.="boundary=\"Message-Boundary\"\n";
-			$header.="Content-transfer-encoding: 7BIT\n";
-			$header.="X-attachments: $file_name";
-			$body_top="--Message-Boundary\n";
-			$body_top.="Content-type: text/html; charset=utf-8\n";
-			$body_top.="Content-transfer-encoding: 7BIT\n";
-			$body_top.="Content-description: Mail message body\n\n";
-			$msg_body=$body_top.addslashes($lang['L_EMAIL_ONLY_ATTACHMENT'].$lang['L_EMAILBODY_FOOTER']);
-			$msg_body.="\n\n--Message-Boundary\n";
-			$msg_body.="Content-type: $file_type; name=\"".$mpdatei[$i]."\"\n";
-			$msg_body.="Content-Transfer-Encoding: BASE64\n";
-			$msg_body.="Content-disposition: attachment; filename=\"".$mpdatei[$i]."\"\n\n";
-			$msg_body.="$encoded_file\n";
-			$msg_body.="--Message-Boundary--\n";
-			$email_log="Email with $mpdatei[$i] was sent to '".$config['email_recipient']."'";
-			$email_out=$lang['L_EMAIL_WAS_SEND']."`".$config['email_recipient']."`".$lang['L_WITH']."`".$mpdatei[$i]."`.<br>";
+    if (isset($mpdatei) && 1 == $config['send_mail_dump']) { // && ($config['email_maxsize'] ==0 || ($config['email_maxsize']>0 && $config['multipartgroesse2']<= $config['email_maxsize']))) {
+        for ($i = 0; $i < count($mpdatei); ++$i) {
+            $file_name = $mpdatei[$i];
+            $file_type = filetype($config['paths']['backup'].$mpdatei[$i]);
+            $file_size = filesize($config['paths']['backup'].$mpdatei[$i]);
+            $fp = fopen($config['paths']['backup'].$mpdatei[$i], 'r');
+            $contents = fread($fp, $file_size);
+            $encoded_file = chunk_split(base64_encode($contents));
+            fclose($fp);
+            $subject = $mp_sub.'  [Part '.($i + 1).' / '.count($mpdatei).']';
+            $header = 'FROM:'.$config['email_sender']."\n";
+            if (isset($config['email_recipient_cc']) && trim($config['email_recipient_cc']) > '') {
+                $header .= 'Cc:     '.$config['email_recipient_cc']."\r\n";
+            }
+            $header .= "MIME-version: 1.0\n";
+            $header .= 'Content-type: multipart/mixed; ';
+            $header .= "boundary=\"Message-Boundary\"\n";
+            $header .= "Content-transfer-encoding: 7BIT\n";
+            $header .= "X-attachments: $file_name";
+            $body_top = "--Message-Boundary\n";
+            $body_top .= "Content-type: text/html; charset=utf-8\n";
+            $body_top .= "Content-transfer-encoding: 7BIT\n";
+            $body_top .= "Content-description: Mail message body\n\n";
+            $msg_body = $body_top.addslashes($lang['L_EMAIL_ONLY_ATTACHMENT'].$lang['L_EMAILBODY_FOOTER']);
+            $msg_body .= "\n\n--Message-Boundary\n";
+            $msg_body .= "Content-type: $file_type; name=\"".$mpdatei[$i]."\"\n";
+            $msg_body .= "Content-Transfer-Encoding: BASE64\n";
+            $msg_body .= 'Content-disposition: attachment; filename="'.$mpdatei[$i]."\"\n\n";
+            $msg_body .= "$encoded_file\n";
+            $msg_body .= "--Message-Boundary--\n";
+            $email_log = "Email with $mpdatei[$i] was sent to '".$config['email_recipient']."'";
+            $email_out = $lang['L_EMAIL_WAS_SEND'].'`'.$config['email_recipient'].'`'.$lang['L_WITH'].'`'.$mpdatei[$i].'`.<br>';
 
-			if (@mail($config['email_recipient'],stripslashes($subject),$msg_body,$header))
-			{
-				$out.='<span class="success">'.$email_out.'</span>';
-				WriteLog("$email_log");
-			}
-			else
-			{
-				$out.='<span class="error">'.$lang['L_MAILERROR'].'</span><br>';
-				WriteLog("Email to '".$config['email_recipient']."' failed !");
-				ErrorLog("Email ",$databases['Name'][$dump['dbindex']],'Subject: '.stripslashes($subject),$lang['L_MAILERROR']);
-				$dump['errors']++;
-			}
-		}
-	}
+            if (@mail($config['email_recipient'], stripslashes($subject), $msg_body, $header)) {
+                $out .= '<span class="success">'.$email_out.'</span>';
+                WriteLog("$email_log");
+            } else {
+                $out .= '<span class="error">'.$lang['L_MAILERROR'].'</span><br>';
+                WriteLog("Email to '".$config['email_recipient']."' failed !");
+                ErrorLog('Email ', $databases['Name'][$dump['dbindex']], 'Subject: '.stripslashes($subject), $lang['L_MAILERROR']);
+                ++$dump['errors'];
+            }
+        }
+    }
 }
 
 function DoFTP($i)
 {
-	global $config,$dump,$out;
+    global $config, $dump, $out;
 
-	if ($config['multi_part']==0)
-	{
-		SendViaFTP($i,$dump['backupdatei'],1);
-	}
-	else
-	{
-		$dateistamm=substr($dump['backupdatei'],0,strrpos($dump['backupdatei'],"part_"))."part_";
-		$dateiendung=($config['compression']==1) ? ".sql.gz":".sql";
-		for($a=1;$a<($dump['part']-$dump['part_offset']);$a++)
-		{
-			$mpdatei=$dateistamm.$a.$dateiendung;
-			SendViaFTP($i,$mpdatei,$a);
-		}
-	}
+    if (0 == $config['multi_part']) {
+        SendViaFTP($i, $dump['backupdatei'], 1);
+    } else {
+        $dateistamm = substr($dump['backupdatei'], 0, strrpos($dump['backupdatei'], 'part_')).'part_';
+        $dateiendung = (1 == $config['compression']) ? '.sql.gz' : '.sql';
+        for ($a = 1; $a < ($dump['part'] - $dump['part_offset']); ++$a) {
+            $mpdatei = $dateistamm.$a.$dateiendung;
+            SendViaFTP($i, $mpdatei, $a);
+        }
+    }
 }
 
-function SendViaFTP($i,$source_file,$conn_msg=1)
+function SendViaFTP($i, $source_file, $conn_msg = 1)
 {
-	global $config,$out,$lang;
-	flush();
-	if ($conn_msg==1) $out.='<span class="success">'.$lang['L_FILESENDFTP']."(".$config['ftp_server'][$i]." - ".$config['ftp_user'][$i].")</span><br>";
-	// Herstellen der Basis-Verbindung
-	if ($config['ftp_useSSL'][$i]==0) $conn_id=@ftp_connect($config['ftp_server'][$i],$config['ftp_port'][$i],$config['ftp_timeout'][$i]);
-	else
-		$conn_id=@ftp_ssl_connect($config['ftp_server'][$i],$config['ftp_port'][$i],$config['ftp_timeout'][$i]);
-		// Einloggen mit Benutzername und Kennwort
-	$login_result=@ftp_login($conn_id,$config['ftp_user'][$i],$config['ftp_pass'][$i]);
-	if ($config['ftp_mode'][$i]==1) ftp_pasv($conn_id,true);
+    global $config, $out, $lang;
+    flush();
+    if (1 == $conn_msg) {
+        $out .= '<span class="success">'.$lang['L_FILESENDFTP'].'('.$config['ftp_server'][$i].' - '.$config['ftp_user'][$i].')</span><br>';
+    }
+    // Herstellen der Basis-Verbindung
+    if (0 == $config['ftp_useSSL'][$i]) {
+        $conn_id = @ftp_connect($config['ftp_server'][$i], $config['ftp_port'][$i], $config['ftp_timeout'][$i]);
+    } else {
+        $conn_id = @ftp_ssl_connect($config['ftp_server'][$i], $config['ftp_port'][$i], $config['ftp_timeout'][$i]);
+    }
+    // Einloggen mit Benutzername und Kennwort
+    $login_result = @ftp_login($conn_id, $config['ftp_user'][$i], $config['ftp_pass'][$i]);
+    if (1 == $config['ftp_mode'][$i]) {
+        ftp_pasv($conn_id, true);
+    }
 
-	// Verbindung überprüfen
-	if ((!$conn_id)||(!$login_result))
-	{
-		$out.='<span class="error">'.$lang['L_FTPCONNERROR'].$config['ftp_server'][$i].$lang['L_FTPCONNERROR1'].$config['ftp_user'][$i].$lang['L_FTPCONNERROR2'].'</span><br>';
-	}
-	else
-	{
-		if ($conn_msg==1) $out.='<span class="success">'.$lang['L_FTPCONNECTED1'].$config['ftp_server'][$i].$lang['L_FTPCONNERROR1'].$config['ftp_user'][$i].'</span><br>';
-	}
+    // Verbindung überprüfen
+    if ((!$conn_id) || (!$login_result)) {
+        $out .= '<span class="error">'.$lang['L_FTPCONNERROR'].$config['ftp_server'][$i].$lang['L_FTPCONNERROR1'].$config['ftp_user'][$i].$lang['L_FTPCONNERROR2'].'</span><br>';
+    } else {
+        if (1 == $conn_msg) {
+            $out .= '<span class="success">'.$lang['L_FTPCONNECTED1'].$config['ftp_server'][$i].$lang['L_FTPCONNERROR1'].$config['ftp_user'][$i].'</span><br>';
+        }
+    }
 
-	// Upload der Datei
-	$dest=$config['ftp_dir'][$i].$source_file;
-	$source=$config['paths']['backup'].$source_file;
-	$upload=@ftp_put($conn_id,$dest,$source,FTP_BINARY);
+    // Upload der Datei
+    $dest = $config['ftp_dir'][$i].$source_file;
+    $source = $config['paths']['backup'].$source_file;
+    $upload = @ftp_put($conn_id, $dest, $source, FTP_BINARY);
 
-	// Upload-Status überprüfen
-	if (!$upload)
-	{
-		$out.='<span class="error">'.$lang['L_FTPCONNERROR3']."<br>($source -> $dest)</span><br>";
-	}
-	else
-	{
-		$out.='<span class="success">'.$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$source_file.'" class="smallblack">'.$source_file.'</a>'.$lang['L_FTPCONNECTED2'].$config['ftp_server'][$i].$lang['L_FTPCONNECTED3'].'</span><br>';
-		WriteLog("'$source_file' sent via FTP.");
-	}
+    // Upload-Status überprüfen
+    if (!$upload) {
+        $out .= '<span class="error">'.$lang['L_FTPCONNERROR3']."<br>($source -> $dest)</span><br>";
+    } else {
+        $out .= '<span class="success">'.$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$source_file.'" class="smallblack">'.$source_file.'</a>'.$lang['L_FTPCONNECTED2'].$config['ftp_server'][$i].$lang['L_FTPCONNECTED3'].'</span><br>';
+        WriteLog("'$source_file' sent via FTP.");
+    }
 
-	// Schließen des FTP-Streams
-	@ftp_quit($conn_id);
+    // Schließen des FTP-Streams
+    @ftp_quit($conn_id);
+}
+
+function DoSFTP($i)
+{
+    global $config, $dump, $out;
+
+    if (0 == $config['multi_part']) {
+        SendViaSFTP($i, $dump['backupdatei'], 1);
+    } else {
+        $dateistamm = substr($dump['backupdatei'], 0, strrpos($dump['backupdatei'], 'part_')).'part_';
+        $dateiendung = (1 == $config['compression']) ? '.sql.gz' : '.sql';
+        for ($a = 1; $a < ($dump['part'] - $dump['part_offset']); ++$a) {
+            $mpdatei = $dateistamm.$a.$dateiendung;
+            SendViaSFTP($i, $mpdatei, $a);
+        }
+    }
 }
diff --git a/msd/inc/functions_files.php b/msd/inc/functions_files.php
index 8442792d..a3fdeee1 100644
--- a/msd/inc/functions_files.php
+++ b/msd/inc/functions_files.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,68 +16,68 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 
-function FilelisteCombo($fpath,$selected)
+function FilelisteCombo($fpath, $selected)
 {
-	$r='<select name="selectfile">';
-	$r.='<option value="" '.(($selected=="") ? "SELECTED":"").'></option>';
+    $r = '<select name="selectfile">';
+    $r .= '<option value="" '.(('' == $selected) ? 'SELECTED' : '').'></option>';
 
-	$dh=opendir($fpath);
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!="."&&$filename!=".."&&!is_dir($fpath.$filename))
-		{
-			$r.='<option value="'.$filename.'" ';
-			if ($filename==$selected) $r.=' SELECTED';
-			$r.='>'.$filename.'</option>'."\n";
-		}
-	}
-	$r.='</select>';
-	return $r;
+    $dh = opendir($fpath);
+    while (false !== ($filename = readdir($dh))) {
+        if ('.' != $filename && '..' != $filename && !is_dir($fpath.$filename)) {
+            $r .= '<option value="'.$filename.'" ';
+            if ($filename == $selected) {
+                $r .= ' selected';
+            }
+            $r .= '>'.$filename.'</option>'."\n";
+        }
+    }
+    $r .= '</select>';
+    return $r;
 }
 
 function sortierdatum($datum)
 {
-	$p=explode(' ',$datum);
-	$uhrzeit=$p[1];
-	$p2=explode('.',$p[0]);
-	$day=$p2[0];
-	$month=$p2[1];
-	$year=$p2[2];
-	return $year.'.'.$month.'.'.$day.' '.$uhrzeit;
+    $p = explode(' ', $datum);
+    $uhrzeit = $p[1];
+    $p2 = explode('.', $p[0]);
+    $day = $p2[0];
+    $month = $p2[1];
+    $year = $p2[2];
+    return $year.'.'.$month.'.'.$day.' '.$uhrzeit;
 }
 
-function FileList($multi=0)
+function FileList($multi = 0)
 {
-	global $config,$fpath,$lang,$databases,$href,$dbactiv,$action,$expand;
+    global $config, $fpath, $lang, $databases, $href, $dbactiv, $action, $expand;
 
-	$files=Array();
-	//Backup-Dateien
-	$Theader=$lang['L_FM_FILES1'].' '.$lang['L_OF'].' "'.$dbactiv.'"';
-	$akind=1;
-	$Sum_Files=0;
-	$dh=opendir($fpath);
-	$fl="";
-	$i=0;
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!='.'&&$filename!='..'&&!is_dir($fpath.$filename))
-		{
-			$files[$i]['name']=$filename;
-			$Sum_Files++;
-			$i++;
-		}
-	}
+    $files = [];
+    //Backup-Dateien
+    $Theader = $lang['L_FM_FILES1'].' '.$lang['L_OF'].' "'.$dbactiv.'"';
+    $akind = 1;
+    $Sum_Files = 0;
+    $dh = opendir($fpath);
+    $fl = '';
+    $i = 0;
+    while (false !== ($filename = readdir($dh))) {
+        if ('.' != $filename && '..' != $filename && !is_dir($fpath.$filename)) {
+            $files[$i]['name'] = $filename;
+            ++$Sum_Files;
+            ++$i;
+        }
+    }
 
-	$fl.='<div>'.$lang['L_FM_CHOOSE_FILE'].' ';
-	$fl.='<span id="gd">&nbsp;</span><br><br>';
+    $fl .= '<div>'.$lang['L_FM_CHOOSE_FILE'].' ';
+    $fl .= '<span id="gd">&nbsp;</span><br><br>';
 
-	$fl.='<table class="bdr">';
-	$fl.='<tr><td colspan="8" align="left"><strong>'.$Theader.'</strong></td><td colspan="3" align="right"></td></tr>';
+    $fl .= '<table class="bdr">';
+    $fl .= '<tr><td colspan="8" align="left"><strong>'.$Theader.'</strong></td><td colspan="3" align="right"></td></tr>';
 
-	//Tableheader
-	$fl.='<tr class="thead"><th colspan="3">'.$lang['L_DB'].'</th>
+    //Tableheader
+    $fl .= '<tr class="thead"><th colspan="3">'.$lang['L_DB'].'</th>
 	<th>gz</th>
 	<th>Script</th>
 	<th colspan="2">'.$lang['L_COMMENT'].'</th>
@@ -87,422 +87,400 @@ function FileList($multi=0)
 	<th>'.$lang['L_FM_FILESIZE'].'</th>
 	<th>'.$lang['L_ENCODING'].'</th></tr>';
 
-	$checkindex=$arrayindex=$gesamt=0;
-	$db_summary_anzahl=Array();
-	if (count($files)>0)
-	{
-		for($i=0;$i<sizeof($files);$i++)
-		{
-			// Dateigr&ouml;&szlig;e
-			$size=filesize($fpath.$files[$i]['name']);
-			$file_datum=date("d\.m\.Y H:i",filemtime($fpath.$files[$i]['name']));
+    $checkindex = $arrayindex = $gesamt = 0;
+    $db_summary_anzahl = [];
+    if (count($files) > 0) {
+        for ($i = 0; $i < sizeof($files); ++$i) {
+            // Dateigr&ouml;&szlig;e
+            $size = filesize($fpath.$files[$i]['name']);
+            $file_datum = date("d\.m\.Y H:i", filemtime($fpath.$files[$i]['name']));
 
-			//statuszeile auslesen
-			$sline='';
+            //statuszeile auslesen
+            $sline = '';
 
-			if (substr($files[$i]['name'],-3)=='.gz')
-			{
-				if ($config['zlib'])
-				{
-					$fp=gzopen($fpath.$files[$i]['name'],"r");
-					$sline=gzgets($fp,40960);
-					gzclose($fp);
-				}
-			}
-			else
-			{
-				$fp=fopen($fpath.$files[$i]['name'],"r");
-				$sline=fgets($fp,5000);
-				fclose($fp);
-			}
-			$statusline=ReadStatusline($sline);
+            if ('.gz' == substr($files[$i]['name'], -3)) {
+                if ($config['zlib']) {
+                    $fp = gzopen($fpath.$files[$i]['name'], 'r');
+                    $sline = gzgets($fp, 40960);
+                    gzclose($fp);
+                }
+            } else {
+                $fp = fopen($fpath.$files[$i]['name'], 'r');
+                $sline = fgets($fp, 5000);
+                fclose($fp);
+            }
 
-			$but=ExtractBUT($files[$i]['name']);
-			if ($but=='') $but=$file_datum;
-			$dbn=$statusline['dbname'];
-			if ($dbn=='unknown') $dbn='~unknown'; // needed for sorting - place unknown files at the end
-			//jetzt alle in ein Array packen
-			if ($statusline['part']=='MP_0'||$statusline['part']=='')
-			{
-				$db_backups[$arrayindex]['name']=$files[$i]['name'];
-				$db_backups[$arrayindex]['db']=$dbn;
-				$db_backups[$arrayindex]['size']=$size;
-				$db_backups[$arrayindex]['date']=$but;
-				$db_backups[$arrayindex]['sort']=sortierdatum($but);
-				$db_backups[$arrayindex]['tabellen']=$statusline['tables'];
-				$db_backups[$arrayindex]['eintraege']=$statusline['records'];
-				$db_backups[$arrayindex]['multipart']=0;
-				$db_backups[$arrayindex]['kommentar']=$statusline['comment'];
-				$db_backups[$arrayindex]['script']=($statusline['script']!='') ? $statusline['script'].'('.$statusline['scriptversion'].')':'';
-				$db_backups[$arrayindex]['charset']=$statusline['charset'];
+            $statusline = ReadStatusline($sline);
 
-				if (!isset($db_summary_last[$dbn])) $db_summary_last[$dbn]=$but;
-				$db_summary_anzahl[$dbn]=(isset($db_summary_anzahl[$dbn])) ? $db_summary_anzahl[$dbn]+1:1;
-				$db_summary_size[$dbn]=(isset($db_summary_size[$dbn])) ? $db_summary_size[$dbn]+$size:$size;
-				if (sortierdatum($but)>sortierdatum($db_summary_last[$dbn])) $db_summary_last[$dbn]=$but;
-			}
-			else
-			{
-				//multipart nur einmal
-				$done=0;
-				if (!isset($db_summary_size[$dbn])) $db_summary_size[$dbn]=0;
-				for($j=0;$j<$arrayindex;$j++)
-				{
-					if (isset($db_backups[$j]))
-					{
-						if (($db_backups[$j]['date']==$but)&&($db_backups[$j]['db']==$dbn))
-						{
-							$db_backups[$j]['multipart']++;
-							$db_backups[$j]['size']+=$size;
-							$db_summary_size[$dbn]+=$size;
-							$done=1;
-							break;
-						}
-					}
-				}
-				if ($done==1) $arrayindex--;
+            $but = ExtractBUT($files[$i]['name']);
+            if ('' == $but) {
+                $but = $file_datum;
+            }
+            $dbn = $statusline['dbname'];
+            if ('unknown' == $dbn) {
+                $dbn = '~unknown';
+            } // needed for sorting - place unknown files at the end
+            //jetzt alle in ein Array packen
+            if ('MP_0' == $statusline['part'] || '' == $statusline['part']) {
+                $db_backups[$arrayindex]['name'] = $files[$i]['name'];
+                $db_backups[$arrayindex]['db'] = $dbn;
+                $db_backups[$arrayindex]['size'] = $size;
+                $db_backups[$arrayindex]['date'] = $but;
+                $db_backups[$arrayindex]['sort'] = sortierdatum($but);
+                $db_backups[$arrayindex]['tabellen'] = $statusline['tables'];
+                $db_backups[$arrayindex]['eintraege'] = $statusline['records'];
+                $db_backups[$arrayindex]['multipart'] = 0;
+                $db_backups[$arrayindex]['kommentar'] = $statusline['comment'];
+                $db_backups[$arrayindex]['script'] = ('' != $statusline['script']) ? $statusline['script'].'('.$statusline['scriptversion'].')' : '';
+                $db_backups[$arrayindex]['charset'] = $statusline['charset'];
 
-				if ($done==0)
-				{
-					//Eintrag war noch nicht vorhanden
-					$db_backups[$arrayindex]['name']=$files[$i]['name'];
-					$db_backups[$arrayindex]['db']=$dbn;
-					$db_backups[$arrayindex]['size']=$size;
-					$db_backups[$arrayindex]['date']=$but;
-					$db_backups[$arrayindex]['sort']=sortierdatum($but);
-					$db_backups[$arrayindex]['tabellen']=$statusline['tables'];
-					$db_backups[$arrayindex]['eintraege']=$statusline['records'];
-					$db_backups[$arrayindex]['multipart']=1;
-					$db_backups[$arrayindex]['kommentar']=$statusline['comment'];
-					$db_backups[$arrayindex]['script']=($statusline['script']!="") ? $statusline['script']."(".$statusline['scriptversion'].")":"";
-					$db_backups[$arrayindex]['charset']=$statusline['charset'];
+                if (!isset($db_summary_last[$dbn])) {
+                    $db_summary_last[$dbn] = $but;
+                }
+                $db_summary_anzahl[$dbn] = (isset($db_summary_anzahl[$dbn])) ? $db_summary_anzahl[$dbn] + 1 : 1;
+                $db_summary_size[$dbn] = (isset($db_summary_size[$dbn])) ? $db_summary_size[$dbn] + $size : $size;
+                if (sortierdatum($but) > sortierdatum($db_summary_last[$dbn])) {
+                    $db_summary_last[$dbn] = $but;
+                }
+            } else {
+                //multipart nur einmal
+                $done = 0;
+                if (!isset($db_summary_size[$dbn])) {
+                    $db_summary_size[$dbn] = 0;
+                }
+                for ($j = 0; $j < $arrayindex; ++$j) {
+                    if (isset($db_backups[$j])) {
+                        if (($db_backups[$j]['date'] == $but) && ($db_backups[$j]['db'] == $dbn)) {
+                            ++$db_backups[$j]['multipart'];
+                            $db_backups[$j]['size'] += $size;
+                            $db_summary_size[$dbn] += $size;
+                            $done = 1;
+                            break;
+                        }
+                    }
+                }
+                if (1 == $done) {
+                    --$arrayindex;
+                }
 
-					if (!isset($db_summary_last[$dbn])) $db_summary_last[$dbn]=$but;
-					$db_summary_anzahl[$dbn]=(isset($db_summary_anzahl[$dbn])) ? $db_summary_anzahl[$dbn]+1:1;
-					$db_summary_size[$dbn]=(isset($db_summary_size[$dbn])) ? $db_summary_size[$dbn]+$size:$size;
-					if (sortierdatum($but)>sortierdatum($db_summary_last[$dbn])) $db_summary_last[$dbn]=$but;
+                if (0 == $done) {
+                    //Eintrag war noch nicht vorhanden
+                    $db_backups[$arrayindex]['name'] = $files[$i]['name'];
+                    $db_backups[$arrayindex]['db'] = $dbn;
+                    $db_backups[$arrayindex]['size'] = $size;
+                    $db_backups[$arrayindex]['date'] = $but;
+                    $db_backups[$arrayindex]['sort'] = sortierdatum($but);
+                    $db_backups[$arrayindex]['tabellen'] = $statusline['tables'];
+                    $db_backups[$arrayindex]['eintraege'] = $statusline['records'];
+                    $db_backups[$arrayindex]['multipart'] = 1;
+                    $db_backups[$arrayindex]['kommentar'] = $statusline['comment'];
+                    $db_backups[$arrayindex]['script'] = ('' != $statusline['script']) ? $statusline['script'].'('.$statusline['scriptversion'].')' : '';
+                    $db_backups[$arrayindex]['charset'] = $statusline['charset'];
 
-				}
-			}
-			// Gesamtgroesse aller Backupfiles
-			$arrayindex++;
-			$gesamt=$gesamt+$size;
-		}
-	}
-	//Schleife fertig - jetzt Ausgabe
-	if ((isset($db_backups))&&(is_array($db_backups))) $db_backups=mu_sort($db_backups,'sort,name');
+                    if (!isset($db_summary_last[$dbn])) {
+                        $db_summary_last[$dbn] = $but;
+                    }
+                    $db_summary_anzahl[$dbn] = (isset($db_summary_anzahl[$dbn])) ? $db_summary_anzahl[$dbn] + 1 : 1;
+                    $db_summary_size[$dbn] = (isset($db_summary_size[$dbn])) ? $db_summary_size[$dbn] + $size : $size;
+                    if (sortierdatum($but) > sortierdatum($db_summary_last[$dbn])) {
+                        $db_summary_last[$dbn] = $but;
+                    }
+                }
+            }
+            // Gesamtgroesse aller Backupfiles
+            ++$arrayindex;
+            $gesamt = $gesamt + $size;
+        }
+    }
+    //Schleife fertig - jetzt Ausgabe
+    if ((isset($db_backups)) && (is_array($db_backups))) {
+        $db_backups = mu_sort($db_backups, 'sort,name');
+    }
 
-	// Hier werden die Dateinamen ausgegeben
-	$rowclass=0;
-	if ($arrayindex>0)
-	{
-		for($i=$arrayindex;$i>=0;$i--)
-		{
-			if (isset($db_backups[$i]['db'])&&$db_backups[$i]['db']==$dbactiv)
-			{
-				$cl=($rowclass%2) ? 'dbrow':'dbrow1';
-				$multi=($db_summary_anzahl[$dbactiv]>1&&$action=='files') ? 1:0;
+    // Hier werden die Dateinamen ausgegeben
+    $rowclass = 0;
+    if ($arrayindex > 0) {
+        for ($i = $arrayindex; $i >= 0; --$i) {
+            if (isset($db_backups[$i]['db']) && $db_backups[$i]['db'] == $dbactiv) {
+                $cl = ($rowclass % 2) ? 'dbrow' : 'dbrow1';
+                $multi = ($db_summary_anzahl[$dbactiv] > 1 && 'files' == $action) ? 1 : 0;
 
-				if ($db_backups[$i]['multipart']>0)
-				{
-					$dbn=NextPart($db_backups[$i]['name'],1);
-				}
-				else
-				{
-					$dbn=$db_backups[$i]['name'];
-				}
-				$fl.='<tr ';
-				$fl.='class="'.(($rowclass%2) ? 'dbrow"':'dbrow1"');
-				$fl.='>';
-				$fl.='<td align="left" colspan="2" nowrap="nowrap">';
-				$fl.='<input type="hidden" name="multi" value="'.$multi.'">';
+                if ($db_backups[$i]['multipart'] > 0) {
+                    $dbn = NextPart($db_backups[$i]['name'], 1);
+                } else {
+                    $dbn = $db_backups[$i]['name'];
+                }
+                $fl .= '<tr ';
+                $fl .= 'class="'.(($rowclass % 2) ? 'dbrow"' : 'dbrow1"');
+                $fl .= '>';
+                $fl .= '<td align="left" colspan="2" nowrap="nowrap">';
+                $fl .= '<input type="hidden" name="multi" value="'.$multi.'">';
 
-				if ($multi==0)
-				{
-					$fl.='<input type="hidden" name="multipart[]" value="'.$db_backups[$i]['multipart'].'"><input name="file[]" type="radio" class="radio" value="'.$dbn.'" onClick="Check('.$checkindex++.',0);">';
-				}
-				else
-				{
-					$fl.='<input type="hidden" name="multipart[]" value="'.$db_backups[$i]['multipart'].'"><input name="file[]" type="checkbox" class="checkbox" value="'.$dbn.'" onClick="Check('.$checkindex++.',1);">';
-				}
+                if (0 == $multi) {
+                    $fl .= '<input type="hidden" name="multipart[]" value="'.$db_backups[$i]['multipart'].'"><input name="file[]" type="radio" class="radio" value="'.$dbn.'" onClick="Check('.$checkindex++.',0);">';
+                } else {
+                    $fl .= '<input type="hidden" name="multipart[]" value="'.$db_backups[$i]['multipart'].'"><input name="file[]" type="checkbox" class="checkbox" value="'.$dbn.'" onClick="Check('.$checkindex++.',1);">';
+                }
 
-				if ($db_backups[$i]['multipart']==0)
-				{
-					$fl.='&nbsp;<a href="'.$fpath.urlencode($dbn).'" title="Backupfile: '.$dbn.'" style="font-size:8pt;" target="_blank">';
-					$fl.=(($db_backups[$i]['db']=='~unknown') ? $dbn:$db_backups[$i]['db']).'</a></td>';
-					$fl.='<td><a href="filemanagement.php?action=dl&amp;f='.urlencode($dbn).'" title="'.$lang['L_DOWNLOAD_FILE'].'" alt="'.$lang['L_DOWNLOAD_FILE'].'"><img src="'.$config['files']['iconpath'].'/openfile.gif"></a></td>';
-				}
-				else
-					$fl.='&nbsp;<span style="font-size:8pt;">'.$db_backups[$i]['db'].'</span><td>&nbsp;</td></td>';
+                if (0 == $db_backups[$i]['multipart']) {
+                    $fl .= '&nbsp;<a href="'.$fpath.urlencode($dbn).'" title="Backupfile: '.$dbn.'" style="font-size:8pt;" target="_blank">';
+                    $fl .= (('~unknown' == $db_backups[$i]['db']) ? $dbn : $db_backups[$i]['db']).'</a></td>';
+                    $fl .= '<td><a href="filemanagement.php?action=dl&amp;f='.urlencode($dbn).'" title="'.$lang['L_DOWNLOAD_FILE'].'" alt="'.$lang['L_DOWNLOAD_FILE'].'"><img src="'.$config['files']['iconpath'].'/openfile.gif"></a></td>';
+                } else {
+                    $fl .= '&nbsp;<span style="font-size:8pt;">'.$db_backups[$i]['db'].'</span><td>&nbsp;</td></td>';
+                }
 
-				$fl.='<td class="sm" nowrap="nowrap" align="center">'.((substr($dbn,-3)==".gz") ? '<img src="'.$config['files']['iconpath'].'gz.gif" alt="'.$lang['L_COMPRESSED'].'" width="16" height="16" border="0">':"&nbsp;").'</td>';
-				$fl.='<td class="sm" nowrap="nowrap" align="center">'.$db_backups[$i]['script'].'</td>';
-				$fl.='<td class="sm" nowrap="nowrap" align="right">'.(($db_backups[$i]['kommentar']!="") ? '<img src="'.$config['files']['iconpath'].'rename.gif" alt="'.$db_backups[$i]['kommentar'].'" title="'.$db_backups[$i]['kommentar'].'" width="16" height="16" border="0">':"&nbsp;").'</td>';
-				$fl.='<td class="sm" nowrap="nowrap" align="left">'.(($db_backups[$i]['kommentar']!="") ? nl2br(wordwrap($db_backups[$i]['kommentar'],50)):"&nbsp;").'</td>';
+                $fl .= '<td class="sm" nowrap="nowrap" align="center">'.(('.gz' == substr($dbn, -3)) ? '<img src="'.$config['files']['iconpath'].'gz.gif" alt="'.$lang['L_COMPRESSED'].'" width="16" height="16" border="0">' : '&nbsp;').'</td>';
+                $fl .= '<td class="sm" nowrap="nowrap" align="center">'.$db_backups[$i]['script'].'</td>';
+                $fl .= '<td class="sm" nowrap="nowrap" align="right">'.(('' != $db_backups[$i]['kommentar']) ? '<img src="'.$config['files']['iconpath'].'rename.gif" alt="'.$db_backups[$i]['kommentar'].'" title="'.$db_backups[$i]['kommentar'].'" width="16" height="16" border="0">' : '&nbsp;').'</td>';
+                $fl .= '<td class="sm" nowrap="nowrap" align="left">'.(('' != $db_backups[$i]['kommentar']) ? nl2br(wordwrap($db_backups[$i]['kommentar'], 50)) : '&nbsp;').'</td>';
 
-				$fl.='<td class="sm" nowrap="nowrap">'.$db_backups[$i]['date'].'</td>';
-				$fl.='<td style="text-align:center">';
-				$fl.=($db_backups[$i]['multipart']==0) ? $lang['L_NO']:'<a style="font-size:11px;" href="filemanagement.php?action=files&amp;kind=0&amp;dbactiv='.$dbactiv.'&amp;expand='.$i.'">'.$db_backups[$i]['multipart'].' Files</a>'; //
-				$fl.='</td><td  style="text-align:right;padding-right:12px;" nowrap="nowrap">';
-				$fl.=($db_backups[$i]['eintraege']!=-1) ? $db_backups[$i]['tabellen'].' / '.number_format($db_backups[$i]['eintraege'],0,",","."):$lang['L_FM_OLDBACKUP'];
-				$fl.='</td>';
-				$fl.='<td style="font-size:8pt;text-align:right">'.byte_output($db_backups[$i]['size']).'</td>';
-				$fl.='<td style="font-size:8pt;text-align:right">'.$db_backups[$i]['charset'].'</td>';
-				$fl.='</tr>';
+                $fl .= '<td class="sm" nowrap="nowrap">'.$db_backups[$i]['date'].'</td>';
+                $fl .= '<td style="text-align:center">';
+                $fl .= (0 == $db_backups[$i]['multipart']) ? $lang['L_NO'] : '<a style="font-size:11px;" href="filemanagement.php?action=files&amp;kind=0&amp;dbactiv='.$dbactiv.'&amp;expand='.$i.'">'.$db_backups[$i]['multipart'].' Files</a>';
+                $fl .= '</td><td  style="text-align:right;padding-right:12px;" nowrap="nowrap">';
+                $fl .= (-1 != $db_backups[$i]['eintraege']) ? $db_backups[$i]['tabellen'].' / '.number_format($db_backups[$i]['eintraege'], 0, ',', '.') : $lang['L_FM_OLDBACKUP'];
+                $fl .= '</td>';
+                $fl .= '<td style="font-size:8pt;text-align:right">'.byte_output($db_backups[$i]['size']).'</td>';
+                $fl .= '<td style="font-size:8pt;text-align:right">'.$db_backups[$i]['charset'].'</td>';
+                $fl .= '</tr>';
 
-				if ($expand==$i)
-				{
-					$fl.='<tr '.(($dbactiv==$databases['db_actual']) ? 'class="dbrowsel"':'class="'.$cl.'"').'>';
-					$fl.='<td class="sm" valign="top">All Parts:</td><td  class="sm" colspan="11" align="left">'.PartListe($db_backups[$i]['name'],$db_backups[$i]['multipart']).'</td>';
-				}
-				$rowclass++;
-			}
-		}
-	}
-	//v($db_backups);
-	$fl.='<tr><td colspan="11" align="left"><br><strong>'.$lang['L_FM_ALL_BU'].'</strong></td></tr>';
-	//Tableheader
-	$fl.='<tr class="thead"><th colspan="5" align="left">'.$lang['L_FM_DBNAME'].'</th>
+                if ($expand == $i) {
+                    $fl .= '<tr '.(($dbactiv == $databases['db_actual']) ? 'class="dbrowsel"' : 'class="'.$cl.'"').'>';
+                    $fl .= '<td class="sm" valign="top">All Parts:</td><td  class="sm" colspan="11" align="left">'.PartListe($db_backups[$i]['name'], $db_backups[$i]['multipart']).'</td>';
+                }
+                ++$rowclass;
+            }
+        }
+    }
+    //v($db_backups);
+    $fl .= '<tr><td colspan="11" align="left"><br><strong>'.$lang['L_FM_ALL_BU'].'</strong></td></tr>';
+    //Tableheader
+    $fl .= '<tr class="thead"><th colspan="5" align="left">'.$lang['L_FM_DBNAME'].'</th>
 	<th align="left">'.$lang['L_FM_ANZ_BU'].'</th><th>'.$lang['L_FM_LAST_BU'].'</th>
 	<th colspan="5" style="text-align:right;">'.$lang['L_FM_TOTALSIZE'].'</th></tr>';
-	//die anderen Backups
-	if (count($db_summary_anzahl)>0)
-	{
-		//lets sort the list
-		ksort($db_summary_last);
-		ksort($db_summary_anzahl);
-		ksort($db_summary_size);
+    //die anderen Backups
+    if (count($db_summary_anzahl) > 0) {
+        //lets sort the list
+        ksort($db_summary_last);
+        ksort($db_summary_anzahl);
+        ksort($db_summary_size);
 
-		$i=0;
-		while (list ($key,$val)=each($db_summary_anzahl))
-		{
-			$cl=($i++%2) ? "dbrow":"dbrow1";
-			$keyaus=($key=="~unknown") ? '<em>'.$lang['L_NO_MSD_BACKUPFILE'].'</em>':$key;
-			$fl.='<tr class="'.$cl.'"><td colspan="5" align="left"><a href="'.$href.'&amp;dbactiv='.$key.'">'.$keyaus.'</a></td>';
-			$fl.='<td style="text-align:right">'.$val.'&nbsp;&nbsp;</td>';
-			$fl.='<td class="sm" nowrap="nowrap">'.((isset($db_summary_last[$key])) ? $db_summary_last[$key]:'').'</td>';
-			$fl.='<td style="text-align:right;font-size:8pt;" colspan="5">'.byte_output($db_summary_size[$key]).'&nbsp;</td>';
-			$fl.='</tr>';
-		}
-	}
-	if (!is_array($files)) $fl.='<tr><td colspan="11">'.$lang['L_FM_NOFILESFOUND'].'</td></tr>';
+        $i = 0;
+        foreach ($db_summary_anzahl as $key => $val) {
+            $cl = ($i++ % 2) ? 'dbrow' : 'dbrow1';
+            $keyaus = ('~unknown' == $key) ? '<em>'.$lang['L_NO_MOD_BACKUPFILE'].'</em>' : $key;
+            $fl .= '<tr class="'.$cl.'"><td colspan="5" align="left"><a href="'.$href.'&amp;dbactiv='.$key.'">'.$keyaus.'</a></td>';
+            $fl .= '<td style="text-align:right">'.$val.'&nbsp;&nbsp;</td>';
+            $fl .= '<td class="sm" nowrap="nowrap">'.((isset($db_summary_last[$key])) ? $db_summary_last[$key] : '').'</td>';
+            $fl .= '<td style="text-align:right;font-size:8pt;" colspan="5">'.byte_output($db_summary_size[$key]).'&nbsp;</td>';
+            $fl .= '</tr>';
+        }
+    }
+    if (!is_array($files)) {
+        $fl .= '<tr><td colspan="11">'.$lang['L_FM_NOFILESFOUND'].'</td></tr>';
+    }
 
-	//--------------------------------------------------------
-	//*** Ausgabe der Gesamtgr&ouml;&szlig;e aller Backupfiles ***
-	//--------------------------------------------------------
-	$space=MD_FreeDiskSpace();
-	$fl.='<tr>';
-	$fl.='<td align="left" colspan="8"><b>'.$lang['L_FM_TOTALSIZE'].' ('.$Sum_Files.' files): </b> </td>';
-	$fl.='<td style="text-align:right" colspan="4"><b>'.byte_output($gesamt).'</b></td>';
-	$fl.='</tr>';
+    //--------------------------------------------------------
+    //*** Ausgabe der Gesamtgr&ouml;&szlig;e aller Backupfiles ***
+    //--------------------------------------------------------
+    $space = MD_FreeDiskSpace();
+    $fl .= '<tr>';
+    $fl .= '<td align="left" colspan="8"><b>'.$lang['L_FM_TOTALSIZE'].' ('.$Sum_Files.' files): </b> </td>';
+    $fl .= '<td style="text-align:right" colspan="4"><b>'.byte_output($gesamt).'</b></td>';
+    $fl .= '</tr>';
 
-	//--------------------------------------------------------
-	//*** Ausgabe des freien Speicher auf dem Rechner ***
-	//--------------------------------------------------------
-	$fl.='<tr>';
-	$fl.='<td colspan="8" align="left">'.$lang['L_FM_FREESPACE'].': </td>';
-	$fl.='<td colspan="4"  style="text-align:right"><b>'.$space.'</b></td>';
-	$fl.='</tr>';
-	$fl.='</table></div>';
+    //--------------------------------------------------------
+    //*** Ausgabe des freien Speicher auf dem Rechner ***
+    //--------------------------------------------------------
+    $fl .= '<tr>';
+    $fl .= '<td colspan="8" align="left">'.$lang['L_FM_FREESPACE'].': </td>';
+    $fl .= '<td colspan="4"  style="text-align:right"><b>'.$space.'</b></td>';
+    $fl .= '</tr>';
+    $fl .= '</table></div>';
 
-	return $fl;
+    return $fl;
 }
 
 function read_statusline_from_file($filename)
 {
-	global $config;
-	if (strtolower(substr($filename,-2))=='gz')
-	{
-		$fp=gzopen($config['paths']['backup'].$filename,"r");
-		if ($fp===false) die('Can\'t open file '.$filename);
-		$sline=gzgets($fp,40960);
-		gzclose($fp);
-	}
-	else
-	{
-		$fp=fopen($config['paths']['backup'].$filename,"r");
-		if ($fp===false) die('Can\'t open file '.$filename);
-		$sline=fgets($fp,5000);
-		fclose($fp);
-	}
-	$statusline=ReadStatusline($sline);
-	return $statusline;
+    global $config;
+    if ('gz' == strtolower(substr($filename, -2))) {
+        $fp = gzopen($config['paths']['backup'].$filename, 'r');
+        if (false === $fp) {
+            exit('Can\'t open file '.$filename);
+        }
+        $sline = gzgets($fp, 40960);
+        gzclose($fp);
+    } else {
+        $fp = fopen($config['paths']['backup'].$filename, 'r');
+        if (false === $fp) {
+            exit('Can\'t open file '.$filename);
+        }
+        $sline = fgets($fp, 5000);
+        fclose($fp);
+    }
+    $statusline = ReadStatusline($sline);
+    return $statusline;
 }
 
-function PartListe($f,$nr)
+function PartListe($f, $nr)
 {
-	global $config,$lang,$fpath;
-	$dateistamm=substr($f,0,strrpos($f,"part_"))."part_";
-	$dateiendung=(substr(strtolower($f),-2)=="gz") ? ".sql.gz":".sql";
-	$s="";
-	for($i=1;$i<=$nr;$i++)
-	{
-		if ($i>1) $s.="<br>";
-		$s.='<a href="'.$fpath.urlencode($dateistamm.$i.$dateiendung).'">'.$dateistamm.$i.$dateiendung.'</a>&nbsp;&nbsp;&nbsp;'.byte_output(@filesize($config['paths']['backup'].$dateistamm.$i.$dateiendung));
-		$s.='&nbsp;<a href="filemanagement.php?action=dl&amp;f='.urlencode($dateistamm.$i.$dateiendung).'" title="'.$lang['L_DOWNLOAD_FILE'].'" alt="'.$lang['L_DOWNLOAD_FILE'].'"><img src="'.$config['files']['iconpath'].'/openfile.gif"></a>';
-
-	}
-	return $s;
+    global $config, $lang, $fpath;
+    $dateistamm = substr($f, 0, strrpos($f, 'part_')).'part_';
+    $dateiendung = ('gz' == substr(strtolower($f), -2)) ? '.sql.gz' : '.sql';
+    $s = '';
+    for ($i = 1; $i <= $nr; ++$i) {
+        if ($i > 1) {
+            $s .= '<br>';
+        }
+        $s .= '<a href="'.$fpath.urlencode($dateistamm.$i.$dateiendung).'">'.$dateistamm.$i.$dateiendung.'</a>&nbsp;&nbsp;&nbsp;'.byte_output(@filesize($config['paths']['backup'].$dateistamm.$i.$dateiendung));
+        $s .= '&nbsp;<a href="filemanagement.php?action=dl&amp;f='.urlencode($dateistamm.$i.$dateiendung).'" title="'.$lang['L_DOWNLOAD_FILE'].'" alt="'.$lang['L_DOWNLOAD_FILE'].'"><img src="'.$config['files']['iconpath'].'/openfile.gif"></a>';
+    }
+    return $s;
 }
 
-function Converter($filesource,$filedestination,$cp)
+function Converter($filesource, $filedestination, $cp)
 {
-	global $config,$lang;
+    global $config, $lang;
 
-	$filesize=0;
-	$max_filesize=1024*1024*10; //10 MB splitsize
-	$part=1;
-	$cps=(substr(strtolower($filesource),-2)=="gz") ? 1:0;
-	$filedestination.='_'.date("Y_m_d_H_i",time());
-	echo "<h5>".sprintf($lang['L_CONVERT_FILEREAD'],$filesource).".....</h5><span style=\"font-size:10px;\">";
-	if (file_exists($config['paths']['backup'].$filedestination)) unlink($config['paths']['backup'].$filedestination);
-	$f=($cps==1) ? gzopen($config['paths']['backup'].$filesource,"r"):fopen($config['paths']['backup'].$filesource,"r");
-	$z=($cp==1) ? gzopen($config['paths']['backup'].$filedestination.'_part_1.sql.gz',"w"):fopen($config['paths']['backup'].$filedestination.'_part_1.sql',"w");
+    $filesize = 0;
+    $max_filesize = 1024 * 1024 * 10; //10 MB splitsize
+    $part = 1;
+    $cps = ('gz' == substr(strtolower($filesource), -2)) ? 1 : 0;
+    $filedestination .= '_'.date('Y_m_d_H_i', time());
+    echo '<h5>'.sprintf($lang['L_CONVERT_FILEREAD'], $filesource).'.....</h5><span style="font-size:10px;">';
+    if (file_exists($config['paths']['backup'].$filedestination)) {
+        unlink($config['paths']['backup'].$filedestination);
+    }
+    $f = (1 == $cps) ? gzopen($config['paths']['backup'].$filesource, 'r') : fopen($config['paths']['backup'].$filesource, 'r');
+    $z = (1 == $cp) ? gzopen($config['paths']['backup'].$filedestination.'_part_1.sql.gz', 'w') : fopen($config['paths']['backup'].$filedestination.'_part_1.sql', 'w');
 
-	$zeile=get_pseudo_statusline($part,$filedestination)."\r\n";
-	($cp==1) ? gzwrite($z,$zeile):fwrite($z,$zeile);
-	$zeile='';
+    $zeile = get_pseudo_statusline($part, $filedestination)."\r\n";
+    (1 == $cp) ? gzwrite($z, $zeile) : fwrite($z, $zeile);
+    $zeile = '';
 
-	$insert=$mode="";
-	$n=0;
-	$eof=($cps==1) ? gzeof($f):feof($f);
-	$splitable=false; // can the file be splitted? Try to avoid splitting before a command is completed
-	while (!$eof)
-	{
-		$eof=($cps==1) ? gzeof($f):feof($f);
-		$zeile=($cps==1) ? gzgets($f,5144000):fgets($f,5144000);
+    $insert = $mode = '';
+    $n = 0;
+    $eof = (1 == $cps) ? gzeof($f) : feof($f);
+    $splitable = false; // can the file be splitted? Try to avoid splitting before a command is completed
+    while (!$eof) {
+        $eof = (1 == $cps) ? gzeof($f) : feof($f);
+        $zeile = (1 == $cps) ? gzgets($f, 5144000) : fgets($f, 5144000);
 
-		$t=strtolower(substr($zeile,0,10));
-		if ($t>'')
-		{
-			switch ($t)
-			{
-				case 'insert int':
-					{
-						// eine neue Insert Anweisung beginnt
-						if (strpos($zeile,'(')===false)
-						{
-							//Feldnamen stehen in der naechsten Zeile - holen
-							$zeile.="\n\r";
-							$zeile.=($cps==1) ? trim(gzgets($f,8192)):trim(fgets($f,8192));
-							$zeile.=' ';
-						}
+        $t = strtolower(substr($zeile, 0, 10));
+        if ($t > '') {
+            switch ($t) {
+                case 'insert int':
+                        // eine neue Insert Anweisung beginnt
+                        if (false === strpos($zeile, '(')) {
+                            //Feldnamen stehen in der naechsten Zeile - holen
+                            $zeile .= "\n\r";
+                            $zeile .= (1 == $cps) ? trim(gzgets($f, 8192)) : trim(fgets($f, 8192));
+                            $zeile .= ' ';
+                        }
 
-						// get INSERT-Satement
-						$insert=substr($zeile,0,strpos($zeile,'('));
-						if (substr(strtoupper($insert),-7)!='VALUES ') $insert.=' VALUES ';
-						$mode='insert';
-						$zeile="\n\r".$zeile;
-						$splitable=false;
-						break;
-					}
+                        // get INSERT-Satement
+                        $insert = substr($zeile, 0, strpos($zeile, '('));
+                        if ('VALUES ' != substr(strtoupper($insert), -7)) {
+                            $insert .= ' VALUES ';
+                        }
+                        $mode = 'insert';
+                        $zeile = "\n\r".$zeile;
+                        $splitable = false;
+                        break;
 
-				case 'create tab':
-					{
-						$mode='create';
-						while (substr(rtrim($zeile),-1)!=';')
-						{
-							$zeile.=fgets($f,8192);
-						}
-						$zeile="\n\r".MySQL_Ticks($zeile)."\n\r";
-						$splitable=true;
-						break;
-					}
-			}
-		}
+                case 'create tab':
+                        $mode = 'create';
+                        while (';' != substr(rtrim($zeile), -1)) {
+                            $zeile .= fgets($f, 8192);
+                        }
+                        $zeile = "\n\r".MySQLi_Ticks($zeile)."\n\r";
+                        $splitable = true;
+                        break;
+            }
+        }
 
-		if ($mode=='insert')
-		{
-			if (substr(rtrim($zeile),strlen($zeile)-3,2)==');') $splitable=true;
+        if ('insert' == $mode) {
+            if (');' == substr(rtrim($zeile), strlen($zeile) - 3, 2)) {
+                $splitable = true;
+            }
 
-			// Komma loeschen
-			$zeile=str_replace('),(',");\n\r".$insert.' (',$zeile);
-		}
+            // Komma loeschen
+            $zeile = str_replace('),(', ");\n\r".$insert.' (', $zeile);
+        }
 
-		if ($splitable==true&&$filesize>$max_filesize) // start new file?
-		{
-			$part++;
-			if ($mode=='insert') // Insert -> first complete Insert-Statement, then begin new file
-			{
-				if ($cp==1)
-				{
-					gzwrite($z,$zeile);
-					gzclose($z);
-					$z=gzopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql.gz',"w");
-					$zeile=get_pseudo_statusline($part,$filedestination)."\r\n";
-					gzwrite($z,$zeile);
-					$zeile='';
-				}
-				else
-				{
-					fwrite($z,$zeile);
-					echo "<br>Neue Datei.Zeile: <br>".htmlspecialchars(substr($zeile,0,20))."..".htmlspecialchars(substr($zeile,strlen($zeile)-41,40))."<br>";
-					fclose($z);
-					$z=fopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql',"w");
-					$zeile=get_pseudo_statusline($part,$filedestination)."\r\n";
-					gzwrite($z,$zeile);
-					$zeile='';
-				}
-			}
-			else // first close last file, then begin new one and write new beginning command
-			{
-				if ($cp==1)
-				{
-					gzclose($z);
-					$z=gzopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql.gz',"w");
-					$zeile=get_pseudo_statusline($part,$filedestination)."\r\n".$zeile;
-					gzwrite($z,$zeile);
-				}
-				else
-				{
-					fclose($z);
-					$z=fopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql',"w");
-					$zeile=get_pseudo_statusline($part,$filedestination)."\r\n".$zeile;
-					fwrite($z,$zeile);
-				}
-			}
-			$filesize=0;
-			$splitable=false;
-		}
-		else // no, append to actual file
-		{
-			$filesize+=strlen($zeile);
-			if ($n>600)
-			{
-				$n=0;
-				echo '<br>';
-			}
-			echo '.';
-			if ($cps==1) gzwrite($z,$zeile);
-			else
-				fwrite($z,$zeile);
-			flush();
-		}
-		$n++;
-		//if ($part>4) break;
-	}
-	$zeile="\n-- EOB";
-	if ($cps==1)
-	{
-		gzwrite($z,$zeile);
-		gzclose($z);
-	}
-	else
-	{
-		fwrite($z,$zeile);
-		fclose($z);
-	}
+        if (true == $splitable && $filesize > $max_filesize) { // start new file?
+            ++$part;
+            if ('insert' == $mode) { // Insert -> first complete Insert-Statement, then begin new file
+                if (1 == $cp) {
+                    gzwrite($z, $zeile);
+                    gzclose($z);
+                    $z = gzopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql.gz', 'w');
+                    $zeile = get_pseudo_statusline($part, $filedestination)."\r\n";
+                    gzwrite($z, $zeile);
+                    $zeile = '';
+                } else {
+                    fwrite($z, $zeile);
+                    echo '<br>Neue Datei.Zeile: <br>'.htmlspecialchars(substr($zeile, 0, 20)).'..'.htmlspecialchars(substr($zeile, strlen($zeile) - 41, 40)).'<br>';
+                    fclose($z);
+                    $z = fopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql', 'w');
+                    $zeile = get_pseudo_statusline($part, $filedestination)."\r\n";
+                    gzwrite($z, $zeile);
+                    $zeile = '';
+                }
+            } else { // first close last file, then begin new one and write new beginning command
+                if (1 == $cp) {
+                    gzclose($z);
+                    $z = gzopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql.gz', 'w');
+                    $zeile = get_pseudo_statusline($part, $filedestination)."\r\n".$zeile;
+                    gzwrite($z, $zeile);
+                } else {
+                    fclose($z);
+                    $z = fopen($config['paths']['backup'].$filedestination.'_part_'.$part.'.sql', 'w');
+                    $zeile = get_pseudo_statusline($part, $filedestination)."\r\n".$zeile;
+                    fwrite($z, $zeile);
+                }
+            }
+            $filesize = 0;
+            $splitable = false;
+        } else { // no, append to actual file
+            $filesize += strlen($zeile);
+            if ($n > 600) {
+                $n = 0;
+                echo '<br>';
+            }
+            echo '.';
+            if (1 == $cps) {
+                gzwrite($z, $zeile);
+            } else {
+                fwrite($z, $zeile);
+            }
+            flush();
+        }
+        ++$n;
+        //if ($part>4) break;
+    }
+    $zeile = "\n-- EOB";
+    if (1 == $cps) {
+        gzwrite($z, $zeile);
+        gzclose($z);
+    } else {
+        fwrite($z, $zeile);
+        fclose($z);
+    }
 
-	if ($cps==1) gzclose($f);
-	else
-		fclose($f);
-	echo '</span><h5>'.sprintf($lang['L_CONVERT_FINISHED'],$filedestination).'</h5>';
+    if (1 == $cps) {
+        gzclose($f);
+    } else {
+        fclose($f);
+    }
+    echo '</span><h5>'.sprintf($lang['L_CONVERT_FINISHED'], $filedestination).'</h5>';
 }
 
-function get_pseudo_statusline($part,$filedestination)
+function get_pseudo_statusline($part, $filedestination)
 {
-	echo '<br>Continue with part: '.$part.'<br>';
-	$ret='-- Status:-1:-1:MP_'.($part).':'.$filedestination.":php:converter2:converted:unknown:1:::latin1:EXTINFO\r\n"."-- TABLE-INFO\r\n"."-- TABLE|unknown|0|0|2009-01-24 20:39:39\r\n"."-- EOF TABLE-INFO\r\n";
-	return $ret;
+    echo '<br>Continue with part: '.$part.'<br>';
+    $ret = '-- Status:-1:-1:MP_'.($part).':'.$filedestination.":php:converter2:converted:unknown:1:::latin1:EXTINFO\r\n"."-- TABLE-INFO\r\n"."-- TABLE|unknown|0|0|2009-01-24 20:39:39\r\n"."-- EOF TABLE-INFO\r\n";
+    return $ret;
 }
-
diff --git a/msd/inc/functions_global.php b/msd/inc/functions_global.php
index 5a55584d..34be2790 100644
--- a/msd/inc/functions_global.php
+++ b/msd/inc/functions_global.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,1271 +16,1427 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
+ini_set('display_errors', 0);
 
-$msd_path=realpath(dirname(__FILE__) . '/../') . '/';
-if (!defined('MSD_PATH')) define('MSD_PATH',$msd_path);
-if (file_exists(MSD_PATH.'inc/runtime.php')) include (MSD_PATH.'inc/runtime.php');
-else
-	die('Couldn\'t read runtime.php!');
-if (!defined('MSD_VERSION')) die('No direct access.');
+$mod_path = realpath(dirname(__FILE__).'/../').'/';
+if (!defined('MOD_PATH')) {
+    define('MOD_PATH', $mod_path);
+}
+if (file_exists(MOD_PATH.'inc/runtime.php')) {
+    include MOD_PATH.'inc/runtime.php';
+} else {
+    exit('Couldn\'t read runtime.php!');
+}
+
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+
+use League\Flysystem\Filesystem;
+use League\Flysystem\PhpseclibV2\SftpAdapter;
+use League\Flysystem\PhpseclibV2\SftpConnectionProvider;
+use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
+
+$autoloader = require_once './vendor/autoload.php';
 
 // places all Page Parameters in hidden-fields (needed fpr backup and restore in PHP)
-function get_page_parameter($parameter, $ziel='dump')
+function get_page_parameter($parameter, $ziel = 'dump')
 {
-	$page_parameter='<form action="'.$ziel.'.php" method="POST" name="'.$ziel.'">'."\n";
-	foreach ($parameter as $key=>$val)
-	{
-		if (is_array($val))
-		{
-			foreach ($val as $key2=>$val2)
-			{
-				$page_parameter.='<input type="hidden" name="'.$key.'['.$key2.']'.'" value="'.$val2.'">'."\n";
-			}
-		}
-		else
-			$page_parameter.='<input type="hidden" name="'.$key.'" value="'.$val.'">'."\n";
-	}
-	$page_parameter.='</form>';
-	return $page_parameter;
+    $page_parameter = '<form action="'.$ziel.'.php" method="POST" name="'.$ziel.'">'."\n";
+    foreach ($parameter as $key => $val) {
+        if (is_array($val)) {
+            foreach ($val as $key2 => $val2) {
+                $page_parameter .= '<input type="hidden" name="'.$key.'['.$key2.']'.'" value="'.$val2.'">'."\n";
+            }
+        } else {
+            $page_parameter .= '<input type="hidden" name="'.$key.'" value="'.$val.'">'."\n";
+        }
+    }
+    $page_parameter .= '</form>';
+    return $page_parameter;
 }
 
 function mu_sort($array, $key_sort)
 {
-	$key_sorta=explode(',',$key_sort);
-	$keys=array_keys($array[0]);
-	$n=0;
+    $key_sorta = explode(',', $key_sort);
+    $keys = array_keys($array[0]);
+    $n = 0;
 
-	for ($m=0; $m<count($key_sorta); $m++)
-	{
-		$nkeys[$m]=trim($key_sorta[$m]);
-	}
-	$n+=count($key_sorta);
+    for ($m = 0; $m < count($key_sorta); ++$m) {
+        $nkeys[$m] = trim($key_sorta[$m]);
+    }
+    $n += count($key_sorta);
 
-	for ($i=0; $i<count($keys); $i++)
-	{
-		if (!in_array($keys[$i],$key_sorta))
-		{
-			$nkeys[$n]=$keys[$i];
-			$n+="1";
-		}
-	}
-	for ($u=0; $u<count($array); $u++)
-	{
-		$arr=$array[$u];
-		for ($s=0; $s<count($nkeys); $s++)
-		{
-			$k=$nkeys[$s];
-			if (isset($array[$u][$k])) $output[$u][$k]=$array[$u][$k];
-		}
-	}
-	// wenn die Sortierung nicht ab- sondern aufsteigend sein soll, muss sort() benutzt werden
-	sort($output); // Sort=Aufsteigend -> oder rsort=absteigend
-	return $output;
+    for ($i = 0; $i < count($keys); ++$i) {
+        if (!in_array($keys[$i], $key_sorta)) {
+            $nkeys[$n] = $keys[$i];
+            $n += '1';
+        }
+    }
+    for ($u = 0; $u < count($array); ++$u) {
+        $arr = $array[$u];
+        for ($s = 0; $s < count($nkeys); ++$s) {
+            $k = $nkeys[$s];
+            if (isset($array[$u][$k])) {
+                $output[$u][$k] = $array[$u][$k];
+            }
+        }
+    }
+    // wenn die Sortierung nicht ab- sondern aufsteigend sein soll, muss sort() benutzt werden
+    sort($output); // Sort=Aufsteigend -> oder rsort=absteigend
+    return $output;
 }
 
 function FillMultiDBArrays()
 {
-	global $config,$databases;
+    global $config, $databases;
 
-	// Nur füllen wenn überhaupt Datenbanken gefunden wurden
-	if ((isset($databases['Name']))&&(count($databases['Name'])>0))
-	{
-		$databases['multi']=Array();
-		$databases['multi_praefix']=Array();
-		if (!isset($databases['db_selected_index'])) $databases['db_selected_index']=0;
-		if (!isset($databases['db_actual'])&&isset($databases['Name'])) $databases['db_actual']=$databases['Name'][$databases['db_selected_index']];
-		if (!isset($databases['multisetting'])) $databases['multisetting']='';
+    // Nur füllen wenn überhaupt Datenbanken gefunden wurden
+    if ((isset($databases['Name'])) && (count($databases['Name']) > 0)) {
+        $databases['multi'] = [];
+        $databases['multi_praefix'] = [];
+        if (!isset($databases['db_selected_index'])) {
+            $databases['db_selected_index'] = 0;
+        }
+        if (!isset($databases['db_actual']) && isset($databases['Name'])) {
+            $databases['db_actual'] = $databases['Name'][$databases['db_selected_index']];
+        }
+        if (!isset($databases['multisetting'])) {
+            $databases['multisetting'] = '';
+        }
 
-		//		if($config['multi_dump']==1)
-		//		{
-		if ($databases['multisetting']=='')
-		{
-			//$databases['multi'][0]=$databases['db_actual'];
-		//$databases['multi_praefix'][0]=(isset($databases['praefix'][0])) ? $databases['praefix'][0] : '';
-		}
-		else
-		{
-			$databases['multi']=explode(';',$databases['multisetting']);
-			$flipped=array_flip($databases['Name']);
-			for ($i=0; $i<count($databases['multi']); $i++)
-			{
-				if (isset($flipped[$databases['multi'][$i]]))
-				{
-					$ind=$flipped[$databases['multi'][$i]];
-					$databases['multi_praefix'][$i]=(isset($databases['praefix'][$ind])) ? $databases['praefix'][$ind] : '';
-				}
-			}
-		}
+        //		if($config['multi_dump'] ==1)
+        //		{
+        if ('' == $databases['multisetting']) {
+            //$databases['multi'][0] = $databases['db_actual'];
+        //$databases['multi_praefix'][0] =(isset($databases['praefix'][0])) ? $databases['praefix'][0] : '';
+        } else {
+            $databases['multi'] = explode(';', $databases['multisetting']);
+            $flipped = array_flip($databases['Name']);
+            for ($i = 0; $i < count($databases['multi']); ++$i) {
+                if (isset($flipped[$databases['multi'][$i]])) {
+                    $ind = $flipped[$databases['multi'][$i]];
+                    $databases['multi_praefix'][$i] = (isset($databases['praefix'][$ind])) ? $databases['praefix'][$ind] : '';
+                }
+            }
+        }
 
-	//		}
-	/*
-		else
-		{
-			$databases['multi'][0]=(isset($databases['db_actual'])) ? $databases['db_actual'] : '';
-			$databases['multi_praefix'][0]=(isset($databases['praefix'])) ? $databases['praefix'][$databases['db_selected_index']] : '';
-		}
+        //		}
+    /*
+        else
+        {
+            $databases['multi'][0] =(isset($databases['db_actual'])) ? $databases['db_actual'] : '';
+            $databases['multi_praefix'][0] =(isset($databases['praefix'])) ? $databases['praefix'][$databases['db_selected_index']] : '';
+        }
 */
-	}
-
+    }
 }
 
 function DBDetailInfo($index)
 {
-	global $databases,$config;
+    global $databases, $config;
 
-	$databases['Detailinfo']['tables']=$databases['Detailinfo']['records']=$databases['Detailinfo']['size']=0;
-	MSD_mysql_connect();
-	if (isset($databases['Name'][$index]))
-	{
-		mysqli_select_db($config['dbconnection'], $databases['Name'][$index]);
-		$databases['Detailinfo']['Name']=$databases['Name'][$index];
-		$res=@mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['Name'][$index].'`');
-		if ($res) $databases['Detailinfo']['tables']=mysqli_num_rows($res);
-		if ($databases['Detailinfo']['tables']>0)
-		{
-			$s1=$s2=0;
-            while ($row= mysqli_fetch_array($res, MYSQLI_ASSOC))
-			{
-				$s1+=$row['Rows'];
-				$s2+=$row['Data_length']+$row['Index_length'];
-			}
-			$databases['Detailinfo']['records']=$s1;
-			$databases['Detailinfo']['size']=$s2;
-		}
-	}
+    $databases['Detailinfo']['tables'] = $databases['Detailinfo']['records'] = $databases['Detailinfo']['size'] = 0;
+    mod_mysqli_connect();
+    if (isset($databases['Name'][$index])) {
+        mysqli_select_db($config['dbconnection'], $databases['Name'][$index]);
+        $databases['Detailinfo']['Name'] = $databases['Name'][$index];
+        $res = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['Name'][$index].'`');
+        if ($res) {
+            $databases['Detailinfo']['tables'] = mysqli_num_rows($res);
+        }
+        if ($databases['Detailinfo']['tables'] > 0) {
+            $s1 = $s2 = 0;
+            while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+                $s1 += $row['Rows'];
+                $s2 += $row['Data_length'] + $row['Index_length'];
+            }
+            $databases['Detailinfo']['records'] = $s1;
+            $databases['Detailinfo']['size'] = $s2;
+        }
+    }
 }
 
 function Stringformat($s, $count)
 {
-	if ($count>=strlen($s)) return str_repeat("0",$count-strlen($s)).$s;
-	else
-		return $s;
+    if ($count >= strlen($s)) {
+        return str_repeat('0', $count - strlen($s)).$s;
+    } else {
+        return $s;
+    }
 }
 
 function getmicrotime()
 {
-	list ($usec, $sec)=explode(" ",microtime());
-	return ((float) $usec+(float) $sec);
+    list($usec, $sec) = explode(' ', microtime());
+    return (float) $usec + (float) $sec;
 }
 
 function MD_FreeDiskSpace()
 {
-	global $lang;
-	$dfs=@diskfreespace("../");
-	return ($dfs) ? byte_output($dfs) : $lang['L_NOTAVAIL'];
+    global $lang;
+    $dfs = @diskfreespace('../');
+    return ($dfs) ? byte_output($dfs) : $lang['L_NOTAVAIL'];
 }
 
 function WriteDynamicText($txt, $object)
 {
-	return '<script language="JavaScript">WP("'.addslashes($txt).','.$object.'");</script>';
+    return '<script>WP("'.addslashes($txt).','.$object.'");</script>';
 }
 
-function byte_output($bytes, $precision=2, $names=Array())
+function byte_output($bytes, $precision = 2, $names = [])
 {
-	if (!is_numeric($bytes)||$bytes<0)
-	{
-		return false;
-	}
-	for ($level=0; $bytes>=1024; $level++)
-	{
-		$bytes/=1024;
-	}
-	switch ($level)
-	{
-		case 0:
-			$suffix=(isset($names[0])) ? $names[0] : '<span class="explain" title="Bytes">B</span>';
-			break;
-		case 1:
-			$suffix=(isset($names[1])) ? $names[1] : '<span class="explain" title="KiloBytes">KB</span>';
-			break;
-		case 2:
-			$suffix=(isset($names[2])) ? $names[2] : '<span class="explain" title="MegaBytes">MB</span>';
-			break;
-		case 3:
-			$suffix=(isset($names[3])) ? $names[3] : '<span class="explain" title="GigaBytes">GB</span>';
-			break;
-		case 4:
-			$suffix=(isset($names[4])) ? $names[4] : '<span class="explain" title="TeraBytes">TB</span>';
-			break;
-		case 5:
-			$suffix=(isset($names[4])) ? $names[4] : '<span class="explain" title="PetaBytes">PB</span>';
-			break;
-		case 6:
-			$suffix=(isset($names[4])) ? $names[4] : '<span class="explain" title="ExaBytes">EB</span>';
-			break;
-		case 7:
-			$suffix=(isset($names[4])) ? $names[4] : '<span class="explain" title="YottaBytes">ZB</span>';
-			break;
+    if (!is_numeric($bytes) || $bytes < 0) {
+        return false;
+    }
+    for ($level = 0; $bytes >= 1024; ++$level) {
+        $bytes /= 1024;
+    }
+    switch ($level) {
+        case 0:
+            $suffix = (isset($names[0])) ? $names[0] : '<span class="explain" title="Bytes">B</span>';
+            break;
+        case 1:
+            $suffix = (isset($names[1])) ? $names[1] : '<span class="explain" title="KiloBytes">KB</span>';
+            break;
+        case 2:
+            $suffix = (isset($names[2])) ? $names[2] : '<span class="explain" title="MegaBytes">MB</span>';
+            break;
+        case 3:
+            $suffix = (isset($names[3])) ? $names[3] : '<span class="explain" title="GigaBytes">GB</span>';
+            break;
+        case 4:
+            $suffix = (isset($names[4])) ? $names[4] : '<span class="explain" title="TeraBytes">TB</span>';
+            break;
+        case 5:
+            $suffix = (isset($names[4])) ? $names[4] : '<span class="explain" title="PetaBytes">PB</span>';
+            break;
+        case 6:
+            $suffix = (isset($names[4])) ? $names[4] : '<span class="explain" title="ExaBytes">EB</span>';
+            break;
+        case 7:
+            $suffix = (isset($names[4])) ? $names[4] : '<span class="explain" title="YottaBytes">ZB</span>';
+            break;
 
-		default:
-			$suffix=(isset($names[$level])) ? $names[$level] : '';
-			break;
-	}
-	return sprintf("%01.".$precision."f",round($bytes,$precision)).' '.$suffix;
+        default:
+            $suffix = (isset($names[$level])) ? $names[$level] : '';
+            break;
+    }
+    return sprintf('%01.'.$precision.'f', round($bytes, $precision)).' '.$suffix;
 }
 
 function ExtractDBname($s)
 {
-	$sp=explode('_',$s);
-	$anz=count($sp)-1;
-	$r=0;
-	if ($anz>4)
-	{
-		$df=5; //Datumsfelder
-		if ($sp[$anz-1]=='part') $df+=2;
-		if ($sp[$anz-3]=='crondump'||$sp[$anz-1]=='crondump') $df+=2;
-		$anz=$anz-$df; //Datum weg
-		for ($i=0; $i<=$anz; $i++)
-		{
-			$r+=strlen($sp[$i])+1;
-		}
-		return substr($s,0,$r-1);
-	}
-	else
-	{
-		//Fremdformat
-		return substr($s,0,strpos($s,'.'));
-	}
+    $sp = explode('_', $s);
+    $anz = count($sp) - 1;
+    $r = 0;
+    if ($anz > 4) {
+        $df = 5; //Datumsfelder
+        if ('part' == $sp[$anz - 1]) {
+            $df += 2;
+        }
+        if ('crondump' == $sp[$anz - 3] || 'crondump' == $sp[$anz - 1]) {
+            $df += 2;
+        }
+        $anz = $anz - $df; //Datum weg
+        for ($i = 0; $i <= $anz; ++$i) {
+            $r += strlen($sp[$i]) + 1;
+        }
+        return substr($s, 0, $r - 1);
+    } else {
+        //Fremdformat
+        return substr($s, 0, strpos($s, '.'));
+    }
 }
 
 function ExtractBUT($s)
 {
-	$i=strpos(strtolower($s),"part");
-	if ($i>0) $s=substr($s,0,$i-1);
-	$i=strpos(strtolower($s),"crondump");
-	if ($i>0) $s=substr($s,0,$i-1);
-	$i=strpos(strtolower($s),".sql");
-	if ($i>0) $s=substr($s,0,$i);
-	$sp=explode("_",$s);
+    $i = strpos(strtolower($s), 'part');
+    if ($i > 0) {
+        $s = substr($s, 0, $i - 1);
+    }
+    $i = strpos(strtolower($s), 'crondump');
+    if ($i > 0) {
+        $s = substr($s, 0, $i - 1);
+    }
+    $i = strpos(strtolower($s), '.sql');
+    if ($i > 0) {
+        $s = substr($s, 0, $i);
+    }
+    $sp = explode('_', $s);
 
-	$anz=count($sp)-1;
-	if (strtolower($sp[$anz])=='perl') $anz--;
-	if ($anz>4)
-	{
-		return $sp[$anz-2].".".$sp[$anz-3].".".$sp[$anz-4]." ".$sp[$anz-1].":".$sp[$anz];
-	}
-	else
-	{
-		//Fremdformat
-		return "";
-	}
+    $anz = count($sp) - 1;
+    if ('perl' == strtolower($sp[$anz])) {
+        --$anz;
+    }
+    if ($anz > 4) {
+        return $sp[$anz - 2].'.'.$sp[$anz - 3].'.'.$sp[$anz - 4].' '.$sp[$anz - 1].':'.$sp[$anz];
+    } else {
+        //Fremdformat
+        return '';
+    }
 }
 
 function WriteLog($aktion)
 {
-	global $config,$lang;
-	$log=date('d.m.Y H:i:s').' '.htmlspecialchars($aktion)."\n";
+    global $config, $lang;
+    $log = date('d.m.Y H:i:s').' '.htmlspecialchars($aktion)."\n";
 
-	$logfile=($config['logcompression']==1) ? $config['files']['log'].'.gz' : $config['files']['log'];
-	if (@filesize($logfile)+strlen($log)>$config['log_maxsize']) @unlink($logfile);
+    $logfile = (isset($config['logcompression']) && (1 == $config['logcompression'])) ? $config['files']['log'].'.gz' : $config['files']['log'];
+    $config['log_maxsize'] = isset($config['log_maxsize']) ? $config['log_maxsize'] : 0;
 
-	//Datei öffnen und schreiben
-	if ($config['logcompression']==1)
-	{
+    if (@filesize($logfile) + strlen($log) > $config['log_maxsize']) {
+        @unlink($logfile);
+    }
 
-		$fp=@gzopen($logfile,'a');
-		if ($fp)
-		{
-			@gzwrite($fp,$log).'<br>';
-			@gzclose($fp);
-		}
-		else
-			echo '<p class="warnung">'.$lang['L_LOGFILENOTWRITABLE'].' ('.$logfile.')</p>';
-	}
-	else
-	{
-		$fp=@fopen($logfile,"ab");
-		if ($fp)
-		{
-			@fwrite($fp,$log);
-			@fclose($fp);
-		}
-		else
-			echo '<p class="warnung">'.$lang['L_LOGFILENOTWRITABLE'].' ('.$logfile.')</p>';
-	}
+    //Datei öffnen und schreiben
+    if (isset($config['logcompression']) && (1 == $config['logcompression'])) {
+        $fp = @gzopen($logfile, 'a');
+        if ($fp) {
+            @gzwrite($fp, $log).'<br>';
+            @gzclose($fp);
+        } else {
+            echo '<p class="warnung">'.$lang['L_LOGFILENOTWRITABLE'].' ('.$logfile.')</p>';
+        }
+    } else {
+        $fp = @fopen($logfile, 'ab');
+        if ($fp) {
+            @fwrite($fp, $log);
+            @fclose($fp);
+        } else {
+            echo '<p class="warnung">'.$lang['L_LOGFILENOTWRITABLE'].' ('.$logfile.')</p>';
+        }
+    }
 }
 
-function ErrorLog($dest, $db, $sql, $error, $art=1)
+function ErrorLog($dest, $db, $sql, $error, $art = 1)
 {
-	//$art=0 -> Fehlermeldung
-	//$art=1 -> Hinweis
+    //$art=0 -> Fehlermeldung
+    //$art=1 -> Hinweis
 
+    global $config;
+    if (strlen($sql) > 100) {
+        $sql = substr($sql, 0, 100).' ... (snip)';
+    }
+    //Error-Zeile generieren
+    $errormsg = date('d.m.Y H:i:s').':  ';
+    $errormsg .= ('RESTORE' == $dest) ? ' Restore of db `'.$db.'`|:|' : ' Dump of db `'.$db.'`|:|';
 
-	global $config;
-	if (strlen($sql)>100) $sql=substr($sql,0,100)." ... (snip)";
-	//Error-Zeile generieren
-	$errormsg=date('d.m.Y H:i:s').':  ';
-	$errormsg.=($dest=='RESTORE') ? ' Restore of db `'.$db.'`|:|' : ' Dump of db `'.$db.'`|:|';
+    if (0 == $art) {
+        $errormsg .= '<font color="red">Error-Message: '.$error.'</font>|:|';
+    } else {
+        $errormsg .= '<font color="green">Notice: '.$error.'</font>|:|';
+    }
 
-	if ($art==0)
-	{
-		$errormsg.='<font color="red">Error-Message: '.$error.'</font>|:|';
-	}
-	else
-	{
-		$errormsg.='<font color="green">Notice: '.$error.'</font>|:|';
-	}
+    if ($sql > '') {
+        $errormsg .= 'SQL: '.$sql."\n";
+    }
 
-	if ($sql>'') $errormsg.='SQL: '.$sql."\n";
-
-	//Datei öffnen und schreiben
-	if ($config['logcompression']==1)
-	{
-		$fp=@gzopen($config['paths']['log'].'error.log.gz','ab');
-		if ($fp)
-		{
-			@gzwrite($fp,($errormsg));
-			@gzclose($fp);
-		}
-	}
-	else
-	{
-		$fp=@fopen($config['paths']['log'].'error.log','ab');
-		if ($fp)
-		{
-			@fwrite($fp,($errormsg));
-			@fclose($fp);
-		}
-	}
+    //Datei öffnen und schreiben
+    if (1 == $config['logcompression']) {
+        $fp = @gzopen($config['paths']['log'].'error.log.gz', 'ab');
+        if ($fp) {
+            @gzwrite($fp, ($errormsg));
+            @gzclose($fp);
+        }
+    } else {
+        $fp = @fopen($config['paths']['log'].'error.log', 'ab');
+        if ($fp) {
+            @fwrite($fp, ($errormsg));
+            @fclose($fp);
+        }
+    }
 }
 
-function DirectoryWarnings($path="")
+function DirectoryWarnings($path = '')
 {
-	global $config,$lang;
-	$warn='';
-	if (!is_writable($config['paths']['work'])) $warn.=sprintf($lang['L_WRONG_RIGHTS'],$config['paths']['work'],'0777');
-	if (!is_writable($config['paths']['config'])) $warn.=sprintf($lang['L_WRONG_RIGHTS'],$config['paths']['config'],'0777');
-	if (!is_writable($config['paths']['backup'])) $warn.=sprintf($lang['L_WRONG_RIGHTS'],$config['paths']['backup'],'0777');
-	if (!is_writable($config['paths']['log'])) $warn.=sprintf($lang['L_WRONG_RIGHTS'],$config['paths']['log'],'0777');
+    global $config, $lang;
+    $warn = '';
+    if (!is_writable($config['paths']['work'])) {
+        $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['work'], '0777');
+    }
+    if (!is_writable($config['paths']['config'])) {
+        $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['config'], '0777');
+    }
+    if (!is_writable($config['paths']['backup'])) {
+        $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['backup'], '0777');
+    }
+    if (!is_writable($config['paths']['log'])) {
+        $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['log'], '0777');
+    }
+    if (!is_writable($config['paths']['temp'])) {
+        $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['temp'], '0777');
+    }
+    if (!is_writable($config['paths']['cache'])) {
+        $warn .= sprintf($lang['L_WRONG_RIGHTS'], $config['paths']['cache'], '0777');
+    }
 
-	if ($warn!='') $warn='<span class="warnung"><strong>'.$warn.'</strong></span>';
-	return $warn;
+    if ('' != $warn) {
+        $warn = '<span class="warnung"><strong>'.$warn.'</strong></span>';
+    }
+    return $warn;
 }
 
 function TestWorkDir()
 {
-	global $config;
+    global $config;
 
-	$ret=SetFileRechte($config['paths']['work']);
-	if ($ret===true) $ret=SetFileRechte($config['paths']['backup']);
-	if ($ret===true) $ret=SetFileRechte($config['paths']['log']);
-	if ($ret===true) $ret=SetFileRechte($config['paths']['config']);
+    $ret = SetFileRechte($config['paths']['work']);
+    if (true === $ret) {
+        $ret = SetFileRechte($config['paths']['backup']);
+    }
+    if (true === $ret) {
+        $ret = SetFileRechte($config['paths']['log']);
+    }
+    if (true === $ret) {
+        $ret = SetFileRechte($config['paths']['config']);
+    }
+    if (true === $ret) {
+        $ret = SetFileRechte($config['paths']['temp']);
+    }
+    if (true === $ret) {
+        $ret = SetFileRechte($config['paths']['cache']);
+    }
 
-	if ($ret===true)
-	{
-		if (!file_exists($config['files']['parameter'])) SetDefault(true);
-		if (!file_exists($config['files']['log'])) DeleteLog();
-	}
-	return $ret;
+    if (true === $ret) {
+        if (!file_exists($config['files']['parameter'])) {
+            SetDefault(true);
+        }
+        if (!file_exists($config['files']['log'])) {
+            DeleteLog();
+        }
+    }
+    return $ret;
 }
 
-function SetFileRechte($file, $is_dir=1, $perm=0777)
+function SetFileRechte($file, $is_dir = 1, $perm = 0777)
 {
-	global $lang;
-	$ret=true;
-	if ($is_dir==1)
-	{
-		if (substr($file,-1)!="/") $file.="/";
-	}
-	clearstatcache();
+    global $lang;
+    $ret = true;
+    if (1 == $is_dir) {
+        if ('/' != substr($file, -1)) {
+            $file .= '/';
+        }
+    }
+    clearstatcache();
 
-	// erst pruefen, ob Datei oder Verzeichnis existiert
-	if (!file_exists($file))
-	{
-		// Wenn es sich um ein Verzeichnis handelt -> anlegen
-		if ($is_dir==1)
-		{
-			$ret=@mkdir($file,$perm);
-			if (!$ret===true)
-			{
-				// Hat nicht geklappt -> Rueckmeldung
-				$ret=sprintf($lang['L_CANT_CREATE_DIR'],$file);
-			}
-		}
-	}
+    // erst pruefen, ob Datei oder Verzeichnis existiert
+    if (!file_exists($file)) {
+        // Wenn es sich um ein Verzeichnis handelt -> anlegen
+        if (1 == $is_dir) {
+            $ret = @mkdir($file, $perm);
+            if (true === !$ret) {
+                // Hat nicht geklappt -> Rueckmeldung
+                $ret = sprintf($lang['L_CANT_CREATE_DIR'], $file);
+            }
+        }
+    }
 
-	// wenn bisher alles ok ist -> Rechte setzen - egal ob Datei oder Verzeichnis
-	if ($ret===true)
-	{
-		$ret=@chmod($file,$perm);
-		if (!$ret===true) $ret=sprintf($lang['L_WRONG_RIGHTS'],$file,decoct($perm));
-	}
-	return $ret;
+    // wenn bisher alles ok ist -> Rechte setzen - egal ob Datei oder Verzeichnis
+    if (true === $ret) {
+        $ret = @chmod($file, $perm);
+        if (true === !$ret) {
+            $ret = sprintf($lang['L_WRONG_RIGHTS'], $file, decoct($perm));
+        }
+    }
+    return $ret;
 }
 
 function SelectDB($index)
 {
-	global $databases;
-	if (is_string($index)) {
-	    // name given
-	    $dbNames = array_flip($databases['Name']);
-	    if (array_key_exists($index, $dbNames)) {
-	        $index = $dbNames[$index];
-	    }
-	}
-	if (isset($databases['Name'][$index]))
-	{
-		$databases['db_actual']=$databases['Name'][$index];
-		if (isset($databases['praefix'][$index])) $databases['praefix'][$databases['db_selected_index']]=$databases['praefix'][$index];
-		else
-			$databases['praefix'][$databases['db_selected_index']]='';
-		if (isset($databases['db_selected_index'])) $databases['db_selected_index']=$index;
-		else
-			$databases['db_selected_index']=0;
-	}
-	else
-	{
-		// keine DB vorhanden
-		$databases['praefix'][$databases['db_selected_index']]='';
-		$databases['db_selected_index']=0;
-		$databases['db_actual']='';
-	}
+    global $databases;
+    if (is_string($index)) {
+        // name given
+        $dbNames = array_flip($databases['Name']);
+        if (array_key_exists($index, $dbNames)) {
+            $index = $dbNames[$index];
+        }
+    }
+    if (isset($databases['Name'][$index])) {
+        $databases['db_actual'] = $databases['Name'][$index];
+        if (isset($databases['praefix'][$index])) {
+            $databases['praefix'][$databases['db_selected_index']] = $databases['praefix'][$index];
+        } else {
+            $databases['praefix'][$databases['db_selected_index']] = '';
+        }
+        if (isset($databases['db_selected_index'])) {
+            $databases['db_selected_index'] = $index;
+        } else {
+            $databases['db_selected_index'] = 0;
+        }
+    } else {
+        // keine DB vorhanden
+        $databases['praefix'][$databases['db_selected_index']] = '';
+        $databases['db_selected_index'] = 0;
+        $databases['db_actual'] = '';
+    }
 }
 
 function EmptyDB($dbn)
 {
-	global $config;
-	$t_sql=array();
-	@mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=0');
-	$res=mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$dbn.'`') or die('EmptyDB: '.mysqli_error($config['dbconnection']));
-	while ($row=mysqli_fetch_array($res,MYSQLI_ASSOC))
-	{
-		if (substr(strtoupper($row['Comment']),0,4)=='VIEW')
-		{
-			$t_sql[]='DROP VIEW `'.$dbn.'`.`'.$row['Name'].'`';
-		}
-		else
-		{
-			$t_sql[]='DROP TABLE `'.$dbn.'`.`'.$row['Name'].'`';
-		}
-	}
-	if (sizeof($t_sql)>0)
-	{
-		for ($i=0; $i<count($t_sql); $i++)
-		{
-			$res=mysqli_query($config['dbconnection'], $t_sql[$i]) or die('EmptyDB-Error: '.mysqli_error($config['dbconnection']));
-		}
-	}
-	@mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=1');
+    global $config;
+    $t_sql = [];
+    @mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=0');
+    $res = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$dbn.'`') or exit('EmptyDB: '.mysqli_error($config['dbconnection']));
+    while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+        if ('VIEW' == substr(strtoupper($row['Comment']), 0, 4)) {
+            $t_sql[] = 'DROP VIEW `'.$dbn.'`.`'.$row['Name'].'`';
+        } else {
+            $t_sql[] = 'DROP TABLE `'.$dbn.'`.`'.$row['Name'].'`';
+        }
+    }
+    if (sizeof($t_sql) > 0) {
+        for ($i = 0; $i < count($t_sql); ++$i) {
+            $res = mysqli_query($config['dbconnection'], $t_sql[$i]) or exit('EmptyDB-Error: '.mysqli_error($config['dbconnection']));
+        }
+    }
+    @mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=1');
 }
 
+
 function AutoDelete()
 {
-	global $del_files,$config,$lang,$out;
-	$out='';
-	if ($config['max_backup_files']>0)
-	{
-		//Files einlesen
-		$dh=opendir($config['paths']['backup']);
-		$dbbackups=array();
-		$files=array();
+    global $del_files, $config, $lang, $out, $databases;
 
-		// Build assoc Array $db=>$timestamp=>$filenames
-		while (false!==($filename=readdir($dh)))
-		{
-			if ($filename!='.'&&$filename!='..'&&!is_dir($config['paths']['backup'].$filename))
-			{
-				//statuszeile auslesen
-				if (substr($filename,-2)=='gz')
-				{
-					$fp=gzopen($config['paths']['backup'].$filename,'r');
-					$sline=gzgets($fp,40960);
-					gzclose($fp);
-				}
-				else
-				{
-					$fp=fopen($config['paths']['backup'].$filename,'r');
-					$sline=fgets($fp,500);
-					fclose($fp);
-				}
-				$statusline=ReadStatusline($sline);
-				if ($statusline['dbname']!='unknown')
-				{
-					$tabellenanzahl=($statusline['tables']==-1) ? '' : $statusline['tables'];
-					$eintraege=($statusline['records']==-1) ? '' : $statusline['records'];
-					$part=($statusline['part']=='MP_0'||$statusline['part']='') ? 0 : substr($statusline['part'],3);
-					$db_name=$statusline['dbname'];
-					$datum=substr($filename,strlen($db_name)+1);
-					$timestamp=substr($datum,0,16);
-					if (!isset($files[$db_name])) $files[$db_name]=array();
-					if (!isset($files[$db_name][$timestamp])) $files[$db_name][$timestamp]=array();
-					$files[$db_name][$timestamp][]=$filename;
-				}
-			}
-		}
-		$out=''; // stores output messages
-		// Backups pro DB und Timestamp ermitteln
-		foreach ($files as $db=>$val)
-		{
-			//echo "<br>DB ".$db." hat ".sizeof($val)." Backups.";
-			if (sizeof($val)>$config['max_backup_files'])
-			{
-				$db_files=$val;
-				krsort($db_files,SORT_STRING);
-				//now latest backupfiles are on top -> delete all files with greater index
-				$i=0;
-				foreach ($db_files as $timestamp=>$filenames)
-				{
-					if ($i>=$config['max_backup_files'])
-					{
-						// Backup too old -> delete files
-						foreach ($filenames as $f)
-						{
-							if ($out=='') $out.=$lang['L_FM_AUTODEL1'].'<br>';
-							if (@unlink('./'.$config['paths']['backup'].$f))
-							{
-								$out.='<span class="nomargin">'.sprintf($lang['L_DELETE_FILE_SUCCESS'],$f).'</span><br>';
-							}
-							else
-							{
-								$out.=$lang['L_ERROR'].': <span class="error nomargin">'.sprintf($lang['L_DELETE_FILE_ERROR'],$f).'</span><br>';
-							}
-						}
-					}
-					$i++;
-				}
-			}
-		}
-	}
-	return $out;
+
+    $available = [];
+    if ('' == $databases['multisetting']) {
+        $available[0] = $databases['db_actual'];
+    } else {
+        $available = explode(';', $databases['multisetting']);
+    }
+
+    $out = '';
+    if (isset($config['max_backup_files']) && ($config['max_backup_files'] > 0)) {
+        //Files einlesen
+        $dh = opendir($config['paths']['backup']);
+        $dbbackups = [];
+        $files = [];
+
+        // Build assoc Array $db=>$timestamp=>$filenames
+        while (false !== ($filename = readdir($dh))) {
+            if ('.' != $filename && '..' != $filename && !is_dir($config['paths']['backup'].$filename)) {
+                foreach ($available as $item) {
+                    $pos = strpos($filename, $item);
+                    if ($pos === false) {
+                        // Der Datenbankname wurde nicht in der Konfiguration gefunden;
+                    } else {
+                        //statuszeile auslesen
+                        if ('gz' == substr($filename, -2)) {
+                            $fp = gzopen($config['paths']['backup'].$filename, 'r');
+                            $sline = gzgets($fp, 40960);
+                            gzclose($fp);
+                        } else {
+                            $fp = fopen($config['paths']['backup'].$filename, 'r');
+                            $sline = fgets($fp, 500);
+                            fclose($fp);
+                        }
+                        $statusline = ReadStatusline($sline);
+                        if ('unknown' != $statusline['dbname']) {
+                            $tabellenanzahl = (-1 == $statusline['tables']) ? '' : $statusline['tables'];
+                            $eintraege = (-1 == $statusline['records']) ? '' : $statusline['records'];
+                            $part = ('MP_0' == $statusline['part'] || $statusline['part'] = '') ? 0 : substr($statusline['part'], 3);
+                            $db_name = $statusline['dbname'];
+                            $datum = substr($filename, strlen($db_name) + 1);
+                            $timestamp = substr($datum, 0, 16);
+                            if (!isset($files[$db_name])) {
+                                $files[$db_name] = [];
+                            }
+                            if (!isset($files[$db_name][$timestamp])) {
+                                $files[$db_name][$timestamp] = [];
+                            }
+                            $files[$db_name][$timestamp][] = $filename;
+                        }
+                    }
+                }
+            }
+        }
+        $out = ''; // stores output messages
+        // Backups pro DB und Timestamp ermitteln
+        foreach ($files as $db => $val) {
+            //echo "<br>DB ".$db." hat ".sizeof($val)." Backups.";
+            if (sizeof($val) > $config['max_backup_files']) {
+                $db_files = $val;
+                krsort($db_files, SORT_STRING);
+                //now latest backupfiles are on top -> delete all files with greater index
+                $i = 0;
+                foreach ($db_files as $timestamp => $filenames) {
+                    if ($i >= $config['max_backup_files']) {
+                        // Backup too old -> delete files
+                        foreach ($filenames as $f) {
+                            if ('' == $out) {
+                                $out .= $lang['L_FM_AUTODEL1'].'<br>';
+                            }
+                            if (@unlink('./'.$config['paths']['backup'].$f)) {
+                                $out .= '<span class="nomargin">'.sprintf($lang['L_DELETE_FILE_SUCCESS'], $f).'</span><br>';
+                            } else {
+                                $out .= $lang['L_ERROR'].': <span class="error nomargin">'.sprintf($lang['L_DELETE_FILE_ERROR'], $f).'</span><br>';
+                            }
+                        }
+                    }
+                    ++$i;
+                }
+            }
+        }
+    }
+    return $out;
 }
 
-function DeleteFile($files, $function='max')
+function DeleteFile($files, $function = 'max')
 {
-	global $config,$lang;
-	$delfile=explode("|",$files);
-	$r='<p class="error">'.$lang['L_FM_AUTODEL1'].'<br>';
-	$r.=$delfile[3]."<br>";
-	$part=$delfile[2];
-	if ($part>0)
-	{
-		for ($i=$part; $i>0; $i--)
-		{
-			$delete=@unlink($config['paths']['backup'].$delfile[3]);
-			if ($delete) WriteLog("autodeleted ($function) '$delfile[3]'.");
-		}
-	}
-	else
-	{
-		WriteLog("autodeleted ($function) '$delfile[3]'.");
-		unlink($config['paths']['backup'].$delfile[3]);
-	}
-	$r.='</p>';
-	return $r;
+    global $config, $lang;
+    $delfile = explode('|', $files);
+    $r = '<p class="error">'.$lang['L_FM_AUTODEL1'].'<br>';
+    $r .= $delfile[3].'<br>';
+    $part = $delfile[2];
+    if ($part > 0) {
+        for ($i = $part; $i > 0; --$i) {
+            $delete = @unlink($config['paths']['backup'].$delfile[3]);
+            if ($delete) {
+                WriteLog("autodeleted ($function) '$delfile[3]'.");
+            }
+        }
+    } else {
+        WriteLog("autodeleted ($function) '$delfile[3]'.");
+        unlink($config['paths']['backup'].$delfile[3]);
+    }
+    $r .= '</p>';
+    return $r;
 }
 
 function ReadStatusline($line)
 {
-	/*AUFBAU der Statuszeile:
-		-- Status:tabellenzahl:datensätze:Multipart:Datenbankname:script:scriptversion:Kommentar:MySQLVersion:Backupflags:SQLBefore:SQLAfter:Charset:EXTINFO
-		Aufbau Backupflags (1 Zeichen pro Flag, 0 oder 1, 2=unbekannt)
-		(complete inserts)(extended inserts)(ignore inserts)(delayed inserts)(downgrade)(lock tables)(optimize tables)
-	*/
-	global $lang;
-	$statusline=Array();
-	if ((substr($line,0,8)!="# Status"&&substr($line,0,9)!="-- Status")||substr($line,0,10)=='-- StatusC')
-	{
-		//Fremdfile
-		$statusline['tables']=-1;
-		$statusline['records']=-1;
-		$statusline['part']='MP_0';
-		$statusline['dbname']='unknown';
-		$statusline['script']='';
-		$statusline['scriptversion']='';
-		$statusline['comment']='';
-		$statusline['mysqlversion']='unknown';
-		$statusline['flags']='2222222';
-		$statusline['sqlbefore']='';
-		$statusline['sqlafter']='';
-		$statusline['charset']='?';
-	}
-	else
-	{
-		// MySQLDumper-File - Informationen extrahieren
-		$s=explode(':',$line);
-		if (count($s)<12)
-		{
-			//fehlenden Elemente auffüllen
-			$c=count($s);
-			array_pop($s);
-			for ($i=$c-1; $i<12; $i++)
-			{
-				$s[]='';
-			}
-		}
-		$statusline['tables']=$s[1];
-		$statusline['records']=$s[2];
-		$statusline['part']=($s[3]==''||$s[3]=='MP_0') ? 'MP_0' : $s[3];
-		$statusline['dbname']=$s[4];
-		$statusline['script']=$s[5];
-		$statusline['scriptversion']=$s[6];
-		$statusline['comment']=$s[7];
-		$statusline['mysqlversion']=$s[8];
-		$statusline['flags']=$s[9];
-		$statusline['sqlbefore']=$s[10];
-		$statusline['sqlafter']=$s[11];
-		if ((isset($s[12]))&&trim($s[12])!='EXTINFO') $statusline['charset']=$s[12];
-		else
-			$statusline['charset']='?';
-	}
+    /*AUFBAU der Statuszeile:
+        -- Status:tabellenzahl:datensätze:Multipart:Datenbankname:script:scriptversion:Kommentar:MySQLVersion:Backupflags:SQLBefore:SQLAfter:Charset:EXTINFO
+        Aufbau Backupflags (1 Zeichen pro Flag, 0 oder 1, 2=unbekannt)
+        (complete inserts)(extended inserts)(ignore inserts)(delayed inserts)(downgrade)(lock tables)(optimize tables)
+    */
+    global $lang;
+    $statusline = [];
+    if (('# Status' != substr($line, 0, 8) && '-- Status' != substr($line, 0, 9)) || '-- StatusC' == substr($line, 0, 10)) {
+        //Fremdfile
+        $statusline['tables'] = -1;
+        $statusline['records'] = -1;
+        $statusline['part'] = 'MP_0';
+        $statusline['dbname'] = 'unknown';
+        $statusline['script'] = '';
+        $statusline['scriptversion'] = '';
+        $statusline['comment'] = '';
+        $statusline['mysqlversion'] = 'unknown';
+        $statusline['flags'] = '2222222';
+        $statusline['sqlbefore'] = '';
+        $statusline['sqlafter'] = '';
+        $statusline['charset'] = '?';
+    } else {
+        // MySQLDumper-File - Informationen extrahieren
+        $s = explode(':', $line);
+        if (count($s) < 12) {
+            //fehlenden Elemente auffüllen
+            $c = count($s);
+            array_pop($s);
+            for ($i = $c - 1; $i < 12; ++$i) {
+                $s[] = '';
+            }
+        }
+        $statusline['tables'] = $s[1];
+        $statusline['records'] = $s[2];
+        $statusline['part'] = ('' == $s[3] || 'MP_0' == $s[3]) ? 'MP_0' : $s[3];
+        $statusline['dbname'] = $s[4];
+        $statusline['script'] = $s[5];
+        $statusline['scriptversion'] = $s[6];
+        $statusline['comment'] = $s[7];
+        $statusline['mysqlversion'] = $s[8];
+        $statusline['flags'] = $s[9];
+        $statusline['sqlbefore'] = $s[10];
+        $statusline['sqlafter'] = $s[11];
+        if ((isset($s[12])) && 'EXTINFO' != trim($s[12])) {
+            $statusline['charset'] = $s[12];
+        } else {
+            $statusline['charset'] = '?';
+        }
+    }
 
-	//flags zerlegen
-	if (strlen($statusline['flags'])<6) $statusline['flags']="2222222";
-	$statusline['complete_inserts']=substr($statusline['flags'],0,1);
-	$statusline['extended_inserts']=substr($statusline['flags'],1,1);
-	$statusline['ignore_inserts']=substr($statusline['flags'],2,1);
-	$statusline['delayed_inserts']=substr($statusline['flags'],3,1);
-	$statusline['downgrade']=substr($statusline['flags'],4,1);
-	$statusline['lock_tables']=substr($statusline['flags'],5,1);
-	$statusline['optimize_tables']=substr($statusline['flags'],6,1);
-	return $statusline;
+    //flags zerlegen
+    if (strlen($statusline['flags']) < 6) {
+        $statusline['flags'] = '2222222';
+    }
+    $statusline['complete_inserts'] = substr($statusline['flags'], 0, 1);
+    $statusline['extended_inserts'] = substr($statusline['flags'], 1, 1);
+    $statusline['ignore_inserts'] = substr($statusline['flags'], 2, 1);
+    $statusline['delayed_inserts'] = substr($statusline['flags'], 3, 1);
+    $statusline['downgrade'] = substr($statusline['flags'], 4, 1);
+    $statusline['lock_tables'] = substr($statusline['flags'], 5, 1);
+    $statusline['optimize_tables'] = substr($statusline['flags'], 6, 1);
+    return $statusline;
 }
 
-function NextPart($s, $first=0, $keep_suffix=false)
+function NextPart($s, $first = 0, $keep_suffix = false)
 {
-	$nf=explode('_',$s);
-	$i=array_search('part',$nf)+1;
-	$p=substr($nf[$i],0,strpos($nf[$i],'.'));
-	$ext=substr($nf[$i],strlen($p));
-	if ($first==1)
-	{
-		$nf[$i]='1'.$ext;
-	}
-	else
-	{
-		$nf[$i]=++$p.$ext;
-	}
-	$filename=implode('_',$nf);
-	return $filename;
+    $nf = explode('_', $s);
+    $i = array_search('part', $nf) + 1;
+    $p = substr($nf[$i], 0, strpos($nf[$i], '.'));
+    $ext = substr($nf[$i], strlen($p));
+    if (1 == $first) {
+        $nf[$i] = '1'.$ext;
+    } else {
+        $nf[$i] = ++$p.$ext;
+    }
+    $filename = implode('_', $nf);
+    return $filename;
 }
 
 function zeit_format($t)
 {
-	global $lang;
-	$tt_m=floor($t/60);
-	$tt_s=$t-($tt_m*60);
-	if ($tt_m<1) return floor($tt_s).' '.$lang['L_SECONDS'];
-	elseif ($tt_m==1) return '1 '.$lang['L_MINUTE'].' '.floor($tt_s).' '.$lang['L_SECONDS'];
-	else return $tt_m.' '.$lang['L_MINUTES'].' '.floor($tt_s).' '.$lang['L_SECONDS'];
+    global $lang;
+    $tt_m = floor($t / 60);
+    $tt_s = $t - ($tt_m * 60);
+    if ($tt_m < 1) {
+        return floor($tt_s).' '.$lang['L_SECONDS'];
+    } elseif (1 == $tt_m) {
+        return '1 '.$lang['L_MINUTE'].' '.floor($tt_s).' '.$lang['L_SECONDS'];
+    } else {
+        return $tt_m.' '.$lang['L_MINUTES'].' '.floor($tt_s).' '.$lang['L_SECONDS'];
+    }
 }
 
 function TesteFTP($i)
 {
-	global $lang,$config;
-	if (!isset($config['ftp_timeout'][$i])) $config['ftp_timeout'][$i]=30;
-	$s='';
-	if ($config['ftp_port'][$i]==''||$config['ftp_port'][$i]==0) $config['ftp_port'][$i]=21;
-	$pass=-1;
-	if (!extension_loaded("ftp"))
-	{
-		$s='<br><span class="error">'.$lang['L_NOFTPPOSSIBLE'].'</span>';
-	}
-	else
-		$pass=0;
+    global $lang, $config;
+    if (!isset($config['ftp_timeout'][$i])) {
+        $config['ftp_timeout'][$i] = 30;
+    }
+    $s = '';
+    if ('' == $config['ftp_port'][$i] || 0 == $config['ftp_port'][$i]) {
+        $config['ftp_port'][$i] = 21;
+    }
+    $pass = -1;
+    if (!extension_loaded('ftp')) {
+        $s = '<br><span class="error">'.$lang['L_NOFTPPOSSIBLE'].'</span>';
+    } else {
+        $pass = 0;
+    }
 
-	if ($pass==0)
-	{
-		if ($config['ftp_server'][$i]==''||$config['ftp_user'][$i]=='')
-		{
-			$s='<br><span class="error">'.$lang['L_WRONGCONNECTIONPARS'].'</span>';
-		}
-		else
-			$pass=1;
-	}
+    if (0 == $pass) {
+        if ('' == $config['ftp_server'][$i] || '' == $config['ftp_user'][$i]) {
+            $s = '<br><span class="error">'.$lang['L_WRONGCONNECTIONPARS'].'</span>';
+        } else {
+            $pass = 1;
+        }
+    }
 
-	if ($pass==1)
-	{
-		$s=$lang['L_CONNECT_TO'].' `'.$config['ftp_server'][$i].'` Port '.$config['ftp_port'][$i];
+    if (1 == $pass) {
+        $s = $lang['L_CONNECT_TO'].' `'.$config['ftp_server'][$i].'` Port '.$config['ftp_port'][$i];
 
-		if ($config['ftp_useSSL'][$i]==0)
-		{
-			$conn_id=@ftp_connect($config['ftp_server'][$i],$config['ftp_port'][$i],$config['ftp_timeout'][$i]);
-		}
-		else
-		{
-			$conn_id=@ftp_ssl_connect($config['ftp_server'][$i],$config['ftp_port'][$i],$config['ftp_timeout'][$i]);
-		}
-		if ($conn_id) $login_result=@ftp_login($conn_id,$config['ftp_user'][$i],$config['ftp_pass'][$i]);
-		if (!$conn_id||(!$login_result))
-		{
-			$s.='<br><span class="error">'.$lang['L_CONN_NOT_POSSIBLE'].'</span>';
-		}
-		else
-		{
-			$pass=2;
-			if ($config['ftp_mode'][$i]==1) ftp_pasv($conn_id,true);
-		}
-	}
+        if (0 == $config['ftp_useSSL'][$i]) {
+            $conn_id = @ftp_connect($config['ftp_server'][$i], $config['ftp_port'][$i], $config['ftp_timeout'][$i]);
+        } else {
+            $conn_id = @ftp_ssl_connect($config['ftp_server'][$i], $config['ftp_port'][$i], $config['ftp_timeout'][$i]);
+        }
+        if ($conn_id) {
+            $login_result = @ftp_login($conn_id, $config['ftp_user'][$i], $config['ftp_pass'][$i]);
+        }
+        if (!$conn_id || (!$login_result)) {
+            $s .= '<br><span class="error">'.$lang['L_CONN_NOT_POSSIBLE'].'</span>';
+        } else {
+            $pass = 2;
+            if (1 == $config['ftp_mode'][$i]) {
+                ftp_pasv($conn_id, true);
+            }
+        }
+    }
 
-	if ($pass==2)
-	{
-		$s.='<br><strong>Login ok</strong><br>'.$lang['L_CHANGEDIR'].' `'.$config['ftp_dir'][$i].'` ';
-		$dirc=@ftp_chdir($conn_id,$config['ftp_dir'][$i]);
-		if (!$dirc)
-		{
-			$s.='<br><span class="error">'.$lang['L_CHANGEDIRERROR'].'</span>';
-		}
-		else
-		{
-			$pass=3;
-			$s.='<span class="success">'.$lang['L_OK'].'</span>';
-		}
-		@ftp_close($conn_id);
-	}
+    if (2 == $pass) {
+        $s .= '<br><strong>Login ok</strong><br>'.$lang['L_CHANGEDIR'].' `'.$config['ftp_dir'][$i].'` ';
+        $dirc = @ftp_chdir($conn_id, $config['ftp_dir'][$i]);
+        if (!$dirc) {
+            $s .= '<br><span class="error">'.$lang['L_CHANGEDIRERROR'].'</span>';
+        } else {
+            $pass = 3;
+            $s .= '<span class="success">'.$lang['L_OK'].'</span>';
+        }
+        @ftp_close($conn_id);
+    }
 
-	if ($pass==3) $s.='<br><strong>'.$lang['L_FTP_OK'].'</strong>';
-	return $s;
+    if (3 == $pass) {
+        $s .= '<br><strong>'.$lang['L_FTP_OK'].'</strong>';
+    }
+    return $s;
+}
+
+function TesteSFTP($i)
+{
+    global $lang, $config;
+
+    if ('' == $config['sftp_timeout'][$i] || 0 == $config['sftp_timeout'][$i]) {
+        $config['sftp_timeout'][$i] = 30;
+    }
+    if ('' == $config['sftp_port'][$i] || 0 == $config['sftp_port'][$i]) {
+        $config['sftp_port'][$i] = 22;
+    }
+    if ('' == $config['sftp_path_to_private_key'][$i] || 0 == $config['sftp_path_to_private_key'][$i]) {
+        $config['sftp_path_to_private_key'][$i] = null;
+    }
+    if ('' == $config['sftp_secret_passphrase_for_private_key'][$i] || 0 == $config['sftp_secret_passphrase_for_private_key'][$i]) {
+        $config['sftp_secret_passphrase_for_private_key'][$i] = null;
+    }
+    if ('' == $config['sftp_fingerprint'][$i] || 0 == $config['sftp_fingerprint'][$i]) {
+        $config['sftp_fingerprint'][$i] = null;
+    }
+
+    $s = '';
+    $pass = -1;
+
+    if (!extension_loaded('ftp')) {
+        $s = '<br><span class="error">'.$lang['L_NOSFTPPOSSIBLE'].'</span>';
+    } else {
+        $pass = 0;
+    }
+
+    if (0 == $pass) {
+        if ('' == $config['sftp_server'][$i] || '' == $config['sftp_user'][$i]) {
+            $s = '<br><span class="error">'.$lang['L_WRONGCONNECTIONPARS'].'</span>';
+        } else {
+            $pass = 1;
+        }
+    }
+
+    if (1 == $pass) {
+        $s = $lang['L_CONNECT_TO'].' `'.$config['sftp_server'][$i].'` Port '.$config['sftp_port'][$i];
+
+        // https://flysystem.thephpleague.com/v2/docs/adapter/sftp/
+        $filesystem = new Filesystem(new SftpAdapter(
+            new SftpConnectionProvider(
+                $config['sftp_server'][$i], // host (required)
+                $config['sftp_user'][$i], // username (required)
+                $config['sftp_pass'][$i], // password (optional, default: null) set to null if privateKey is used
+                $config['sftp_path_to_private_key'][$i], // '/path/to/my/private_key', private key (optional, default: null) can be used instead of password, set to null if password is set
+                $config['sftp_secret_passphrase_for_private_key'][$i], // 'my-super-secret-passphrase-for-the-private-key', passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
+                $config['sftp_port'][$i], // port (optional, default: 22)
+                false, // use agent (optional, default: false)
+                intval($config['sftp_timeout'][$i]), // timeout (optional, default: 10)
+                4, // max tries (optional, default: 4)
+                $config['sftp_fingerprint'][$i], // 'fingerprint-string', host fingerprint (optional, default: null),
+                null // connectivity checker (must be an implementation of 'League\Flysystem\PhpseclibV2\ConnectivityChecker' to check if a connection can be established (optional, omit if you don't need some special handling for setting reliable connections)
+            ),
+            $config['sftp_dir'][$i], // root path (required)
+            PortableVisibilityConverter::fromArray([
+                'file' => [
+                    'public' => 0640,
+                    'private' => 0604,
+                ],
+                'dir' => [
+                    'public' => 0740,
+                    'private' => 7604,
+                ],
+            ])
+        ));
+
+        $path = 'path_'.time().'.txt';
+
+        try {
+            $filesystem->write($path, 'contents');
+        } catch (Exception $e) {
+            // handle the error
+            echo 'Exception: ',  $e->getMessage(), "\n";
+            $s .= '<br><span class="error">'.$lang['L_CONN_NOT_POSSIBLE'].'</span>';
+            $pass = 2;
+        }
+
+        // echo $path;
+
+        try {
+            $filesystem->delete($path);
+        } catch (Exception $e) {
+            // handle the error
+            echo 'Exception: ',  $e->getMessage(), "\n";
+            $s .= '<br><span class="error">'.$lang['L_CHANGEDIRERROR'].'</span>';
+            $pass = 2;
+        }
+
+        if (1 == $pass) {
+            $s .= ' <span class="success">'.$lang['L_OK'].'</span>';
+            $s .= '<br><strong>Login ok</strong><br>'.$lang['L_CHANGEDIR'].' `'.$config['sftp_dir'][$i].'` ';
+            $s .= '<br><strong>'.$lang['L_SFTP_OK'].'</strong>';
+        }
+    }
+
+    return $s;
+}
+
+function SendViaSFTP($i, $source_file, $conn_msg = 1)
+{
+    global $config, $out, $lang;
+    flush();
+    if (1 == $conn_msg) {
+        $out .= '<span class="success">'.$lang['L_FILESENDSFTP'].'('.$config['sftp_server'][$i].' - '.$config['sftp_user'][$i].')</span><br>';
+    }
+
+    if ('' == $config['sftp_timeout'][$i] || 0 == $config['sftp_timeout'][$i]) {
+        $config['sftp_timeout'][$i] = 30;
+    }
+    if ('' == $config['sftp_port'][$i] || 0 == $config['sftp_port'][$i]) {
+        $config['sftp_port'][$i] = 22;
+    }
+    if ('' == $config['sftp_path_to_private_key'][$i] || 0 == $config['sftp_path_to_private_key'][$i]) {
+        $config['sftp_path_to_private_key'][$i] = null;
+    }
+    if ('' == $config['sftp_secret_passphrase_for_private_key'][$i] || 0 == $config['sftp_secret_passphrase_for_private_key'][$i]) {
+        $config['sftp_secret_passphrase_for_private_key'][$i] = null;
+    }
+    if ('' == $config['sftp_fingerprint'][$i] || 0 == $config['sftp_fingerprint'][$i]) {
+        $config['sftp_fingerprint'][$i] = null;
+    }
+
+    // https://flysystem.thephpleague.com/v2/docs/adapter/sftp/
+    $filesystem = new Filesystem(new SftpAdapter(
+        new SftpConnectionProvider(
+            $config['sftp_server'][$i], // host (required)
+                $config['sftp_user'][$i], // username (required)
+                $config['sftp_pass'][$i], // password (optional, default: null) set to null if privateKey is used
+                $config['sftp_path_to_private_key'][$i], // '/path/to/my/private_key', private key (optional, default: null) can be used instead of password, set to null if password is set
+                $config['sftp_secret_passphrase_for_private_key'][$i], // 'my-super-secret-passphrase-for-the-private-key', passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
+                $config['sftp_port'][$i], // port (optional, default: 22)
+                false, // use agent (optional, default: false)
+                intval($config['sftp_timeout'][$i]), // timeout (optional, default: 10)
+                4, // max tries (optional, default: 4)
+                $config['sftp_fingerprint'][$i], // 'fingerprint-string', host fingerprint (optional, default: null),
+                null // connectivity checker (must be an implementation of 'League\Flysystem\PhpseclibV2\ConnectivityChecker' to check if a connection can be established (optional, omit if you don't need some special handling for setting reliable connections)
+        ),
+        $config['sftp_dir'][$i], // root path (required)
+        PortableVisibilityConverter::fromArray([
+            'file' => [
+                'public' => 0640,
+                'private' => 0604,
+            ],
+            'dir' => [
+                'public' => 0740,
+                'private' => 7604,
+            ],
+        ])
+    ));
+
+    // Upload the file
+    $path = $source_file;
+    $source = $config['paths']['backup'].$source_file;
+
+    $pass = 1;
+
+    try {
+        $filesystem->write($path, $source);
+    } catch (Exception $e) {
+        // handle the error
+        $out .= '<br>Exception: ' .  $e->getMessage();
+        $out .= '<br><span class="error">'.$lang['L_CONN_NOT_POSSIBLE'].'</span>';
+        $pass = 3;
+    }
+
+    // Check upload status
+    if (3 == $pass) {
+        $out .= '<span class="error">'.$lang['L_FTPCONNERROR3']."<br>($source -> $path)</span><br>";
+    } else {
+        $out .= '<span class="success">'.$lang['L_FILE'].' <a href="'.$config['paths']['backup'].$source_file.'" class="smallblack">'.$source_file.'</a>'.$lang['L_FTPCONNECTED2'].$config['sftp_server'][$i].$lang['L_FTPCONNECTED3'].'</span><br>';
+        WriteLog("'$source_file' sent via sFTP.");
+    }
 }
 
 function Realpfad($p)
 {
-	global $config;
-	$dir=dirname(__FILE__);
-	$dir=str_replace('inc','',$dir);
-	$dir=str_replace('\\','/',$dir);
-	$dir=str_replace('//','/',$dir);
-	if (substr($dir,-1)!='/') $dir.='/';
-	return $dir;
+    $dir = dirname(__FILE__);
+    $dir = str_replace('inc', '', $dir);
+    $dir = str_replace('\\', '/', $dir);
+    $dir = str_replace('//', '/', $dir);
+    if ('/' != substr($dir, -1)) {
+        $dir .= '/';
+    }
+    return $dir;
 }
 
-// liest die Dateiliste aller vorhanden Konfigurationsfiles
+// reads the file list of all existing configuration files
 function get_config_filelist()
 {
-	global $config;
-	$default=$config['config_file'];
-	clearstatcache();
-	$dh=opendir($config['paths']['config']);
-	$r="";
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!="."&&$filename!=".."&&!is_dir($config['paths']['config'].$filename)&&substr($filename,-9)==".conf.php")
-		{
-			$f=substr($filename,0,strlen($filename)-9);
-			$r.='<option value="'.$f.'" ';
-			if ($f==$default) $r.=' selected';
-			$r.='>&nbsp;&nbsp;'.$f.'&nbsp;&nbsp;</option>'."\n";
-		}
-	}
-	return $r;
+    global $config;
+    $default = $config['config_file'];
+    $filters = array('..', '.');
+    $directory = $config['paths']['config'];
+    $dirs = array_diff(scandir($directory), $filters);
+    $r = '';
+    foreach ($dirs as $filename) {
+        if (!is_dir($config['paths']['config'].$filename) && '.conf.php' == substr($filename, -9)) {
+            $f = substr($filename, 0, strlen($filename) - 9);
+            $r .= '<option value="'.$f.'" ';
+            if ($f == $default) {
+                $r .= ' selected';
+            }
+            $r .= '>&nbsp;&nbsp;'.$f.'&nbsp;&nbsp;</option>'."\n";
+        }
+    }
+    return $r;
 }
 
 function GetThemes()
 {
-	global $config;
-	$default=$config['theme'];
-	$dh=opendir($config['paths']['root']."css/");
-	$r="";
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!="."&&$filename!=".."&&is_dir($config['paths']['root']."css/".$filename)&&substr($filename,0,1)!='.'&&substr($filename,0,1)!='_')
-		{
-
-			$r.='<option value="'.$filename.'" ';
-			if ($filename==$default) $r.=' SELECTED';
-			$r.='>&nbsp;&nbsp;'.$filename.'&nbsp;&nbsp;</option>'."\n";
-		}
-	}
-	return $r;
+    global $config;
+    $default = $config['theme'];
+    $dh = opendir($config['paths']['root'].'css/');
+    $r = '';
+    while (false !== ($filename = readdir($dh))) {
+        if ('.' != $filename && '..' != $filename && is_dir($config['paths']['root'].'css/'.$filename) && '.' != substr($filename, 0, 1) && '_' != substr($filename, 0, 1)) {
+            $r .= '<option value="'.$filename.'" ';
+            if ($filename == $default) {
+                $r .= ' selected';
+            }
+            $r .= '>&nbsp;&nbsp;'.$filename.'&nbsp;&nbsp;</option>'."\n";
+        }
+    }
+    return $r;
 }
 
-function GetLanguageCombo($k="op", $class="", $name="", $start="", $end="")
+function GetLanguageCombo($k = 'op', $class = '', $name = '', $start = '', $end = '')
 {
-	global $config,$lang;
-	$default=$config['language'];
-	$dh=opendir($config['paths']['root']."language/");
-	$r="";
-	$lang_files=array();
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!="."&&$filename!='.svn'&&$filename!=".."&&$filename!="flags"&&is_dir($config['paths']['root']."language/".$filename))
-		{
-			$lang_files[$lang[$filename]]=$filename;
-		}
-	}
-	ksort($lang_files);
-	$i=1;
-	foreach ($lang_files as $filename)
-	{
-		if ($k=="op")
-		{
-			$r.=$start.'<option value="'.$filename.'" ';
-			if ($filename==$default) $r.=' SELECTED';
-			$r.=' class="'.$class.'">&nbsp;&nbsp;'.$lang[$filename].'&nbsp;&nbsp;</option>'.$end."\n";
-		}
-		elseif ($k=="radio")
-		{
-			$r.=$start.'<input type="radio" class="'.$class.'" name="'.$name.'" id="l'.$i.'" value="'.$filename.'" ';
-			$r.=(($filename==$default) ? "checked" : "");
-			$r.=' onclick="show_tooldivs(\''.$filename.'\');">';
-			$r.='<label for="l'.$i.'">';
-			$r.='&nbsp;<img src="language/flags/'.$filename.'.gif" alt="" width="25" height="15" border="0">';
-			$r.='&nbsp;&nbsp;&nbsp;'.$lang[$filename].'</label>'.$end."\n";
-		}
-		$i++;
-	}
-	return $r;
+    global $config, $lang;
+    $default = $config['language'];
+    $dh = opendir($config['paths']['root'].'language/');
+    $r = '';
+    $lang_files = [];
+    while (false !== ($filename = readdir($dh))) {
+        if ('.' != $filename && '.svn' != $filename && '..' != $filename && 'flags' != $filename && is_dir($config['paths']['root'].'language/'.$filename)) {
+            $lang_files[$lang[$filename]] = $filename;
+        }
+    }
+    ksort($lang_files);
+    $i = 1;
+    foreach ($lang_files as $filename) {
+        if ('op' == $k) {
+            $r .= $start.'<option value="'.$filename.'" ';
+            if ($filename == $default) {
+                $r .= ' selected';
+            }
+            $r .= ' class="'.$class.'">&nbsp;&nbsp;'.$lang[$filename].'&nbsp;&nbsp;</option>'.$end."\n";
+        } elseif ('radio' == $k) {
+            $r .= $start.'<input type="radio" class="'.$class.'" name="'.$name.'" id="l'.$i.'" value="'.$filename.'" ';
+            $r .= (($filename == $default) ? 'checked' : '');
+            $r .= ' onclick="show_tooldivs(\''.$filename.'\');">';
+            $r .= '<label for="l'.$i.'">';
+            $r .= '&nbsp;<img src="language/flags/'.$filename.'.gif" alt="" width="25" height="15" border="0">';
+            $r .= '&nbsp;&nbsp;&nbsp;'.$lang[$filename].'</label>'.$end."\n";
+        }
+        ++$i;
+    }
+    return $r;
 }
 
 // detect language subdirs and add them to the global definition of $lang
 function GetLanguageArray()
 {
-	global $config,$lang;
-	$dh=opendir($config['paths']['root']."language/");
-	unset($lang['languages']);
-	$lang['languages']=array();
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!="."&&$filename!='.svn'&&$filename!=".."&&$filename!="flags"&&is_dir($config['paths']['root']."language/".$filename))
-		{
-			$lang['languages'][]=$filename;
-		}
-	}
+    global $config, $lang;
+    $dh = opendir($config['paths']['root'].'language/');
+    unset($lang['languages']);
+    $lang['languages'] = [];
+    while (false !== ($filename = readdir($dh))) {
+        if ('.' != $filename && '.svn' != $filename && '..' != $filename && 'flags' != $filename && is_dir($config['paths']['root'].'language/'.$filename)) {
+            $lang['languages'][] = $filename;
+        }
+    }
 }
 
-function headline($title, $mainframe=1)
+function headline($title, $mainframe = 1)
 {
-	global $config,$lang;
-	$s='';
-	if ($config['interface_server_caption']==1)
-	{
-		if ($config['interface_server_caption_position']==$mainframe)
-		{
-			$s.='<div id="server'.$mainframe.'">'.$lang['L_SERVER'].': <a class="server" href="'.getServerProtocol().$_SERVER['SERVER_NAME'].'" target="_blank" title="'.$_SERVER['SERVER_NAME'].'">'.$_SERVER['SERVER_NAME'].'</a></div>';
-		}
-	}
-	if ($mainframe==1)
-	{
-		$s.='<div id="pagetitle">'.$title.'</div>';
-		$s.='<div id="content">';
-	}
-	return $s;
+    global $config, $lang;
+    $s = '';
+    if ((isset($config['interface_server_caption'])) && (1 == $config['interface_server_caption'])) {
+        if ($config['interface_server_caption_position'] == $mainframe) {
+            $s .= '<div id="server'.$mainframe.'">'.$lang['L_SERVER'].': <a class="server" href="'.getServerProtocol().$_SERVER['SERVER_NAME'].'" target="_blank" title="'.$_SERVER['SERVER_NAME'].'">'.$_SERVER['SERVER_NAME'].'</a></div>';
+        }
+    }
+    if (1 == $mainframe) {
+        $s .= '<div id="pagetitle">'.$title.'</div>';
+        $s .= '<div id="content">';
+    }
+    return $s;
 }
 
-function PicCache($rpath='./')
+function PicCache($rpath = './')
 {
-	global $BrowserIcon,$config;
+    global $BrowserIcon, $config;
 
-	$t='<div style="display:none">';
+    $t = '<div style="display:none">';
 
-	$dh=opendir($config['files']['iconpath']);
-	while (false!==($filename=readdir($dh)))
-	{
-		if ($filename!="."&&$filename!=".."&&!is_dir($config['files']['iconpath'].$filename))
-		{
-			$t.='<img src="'.$config['files']['iconpath'].$filename.'" width="16" height="16" alt="">'."\n";
-		}
-	}
-	$t.='</div>';
-	return $t;
+    $dh = opendir($config['files']['iconpath']);
+    while (false !== ($filename = readdir($dh))) {
+        if ('.' != $filename && '..' != $filename && !is_dir($config['files']['iconpath'].$filename)) {
+            $t .= '<img src="'.$config['files']['iconpath'].$filename.'" width="16" height="16" alt="">'."\n";
+        }
+    }
+    $t .= '</div>';
+    return $t;
 }
 
-function MSDHeader($kind=0)
+function MODHeader($kind = 0)
 {
-	global $config;
-	header('Pragma: no-cache');
-	header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
-	header("Expires: -1"); // Datum in der Vergangenheit
-	header('Content-Type: text/html; charset=UTF-8');
+    global $config;
+    header('Pragma: no-cache');
+    header('Cache-Control: no-cache, must-revalidate'); // HTTP/1.1
+    header('Expires: -1'); // Datum in der Vergangenheit
+    header('Content-Type: text/html; charset=UTF-8');
 
-	//kind 0=main 1=menu
-	$r='<!DOCTYPE HTML>'."\n<html>\n<head>\n";
-	$r.='<meta charset="utf-8" />'."\n";
-	$r.='<meta name="robots" content="noindex,nofollow" />'."\n";
-	$r.='<meta http-equiv="X-UA-Compatible" content="IE=Edge">'."\n";
-	$r.='<meta http-equiv="pragma" content="no-cache">'."\n";
-	$r.='<meta http-equiv="expires" content="0">'."\n";
-	$r.='<meta http-equiv="cache-control" content="must-revalidate">'."\n";
-	$r.='<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'."\n";
-	$r.='<title>MyOOS [Dumper]</title>'."\n";
-	$r.='<link rel="stylesheet" type="text/css" href="css/'.$config['theme'].'/style.css">'."\n";
-	$r.='<script language="JavaScript" src="js/script.js" type="text/javascript"></script>'."\n";
-	$r.="</head>\n<body".(($kind==1) ? ' class="menu-frame"' : ' class="content"').'>';
-	return $r;
+    //kind 0=main 1=menu
+    $r = '<!DOCTYPE HTML>'."\n<html>\n<head>\n";
+    $r .= '<meta charset="utf-8" />'."\n";
+    $r .= '<meta name="robots" content="noindex,nofollow" />'."\n";
+    $r .= '<meta http-equiv="X-UA-Compatible" content="IE=Edge">'."\n";
+    $r .= '<meta http-equiv="pragma" content="no-cache">'."\n";
+    $r .= '<meta http-equiv="expires" content="0">'."\n";
+    $r .= '<meta http-equiv="cache-control" content="must-revalidate">'."\n";
+    $r .= '<title>MyOOS [Dumper]</title>'."\n";
+    $r .= '<link rel="stylesheet" type="text/css" href="css/'.$config['theme'].'/style.css">'."\n";
+    $r .= '<script src="js/script.js"></script>'."\n";
+    $r .= "</head>\n<body".((1 == $kind) ? ' class="menu-frame"' : ' class="content"').'>';
+    return $r;
 }
 
-function MSDFooter($rfoot='', $enddiv=1)
+function MODFooter($rfoot = '', $enddiv = 1)
 {
-	/*
-	global $config,$databases,$dump,$restore,$lang;
-	if (isset($config['homepage']))
-	{
-		$f='<p id="footer">Autor: <a href="http://www.mysqldumper.de" target="_blank">
-		Daniel Schlichtholz</a> | Infoboard:
-		<a href="'.$config['homepage'].'" target="_blank">'.$config['homepage'].'</a></p>';
-	}
-	else
-	*/
-		$f='';
-	if ($enddiv==1) $f.='</div>';
+    $f = '';
+    if (1 == $enddiv) {
+        $f .= '</div>';
+    }
 
-	$f.=$rfoot.'</body></html>';
+    $f .= $rfoot.'</body></html>';
 
-	return $f;
+    return $f;
 }
 
 function save_bracket($str)
 {
-	// Wenn Klammer zu am Ende steht, diese behalten
-	$str=trim($str);
-	if (substr($str,-1)==')') $str=')';
-	else
-		$str='';
-	return $str;
+    // Wenn Klammer zu am Ende steht, diese behalten
+    $str = trim($str);
+    if (')' == substr($str, -1)) {
+        $str = ')';
+    } else {
+        $str = '';
+    }
+    return $str;
 }
 
-function DownGrade($s, $show=true)
+function DownGrade($s, $show = true)
 {
-	$tmp=explode(",",$s);
-	//echo "<pre>";print_r($tmp);echo "</pre>";
+    $tmp = explode(',', $s);
+    //echo "<pre>";print_r($tmp);echo "</pre>";
 
+    for ($i = 0; $i < count($tmp); ++$i) {
+        $t = strtolower($tmp[$i]);
 
-	for ($i=0; $i<count($tmp); $i++)
-	{
-		$t=strtolower($tmp[$i]);
+        if (strpos($t, 'collate ')) {
+            $tmp2 = explode(' ', $tmp[$i]);
+            for ($j = 0; $j < count($tmp2); ++$j) {
+                if ('collate' == strtolower($tmp2[$j])) {
+                    $tmp2[$j] = '';
+                    $tmp2[$j + 1] = save_bracket($tmp2[$j + 1]);
+                    ++$j;
+                }
+            }
+            $tmp[$i] = implode(' ', $tmp2);
+        }
 
-		if (strpos($t,"collate "))
-		{
-			$tmp2=explode(" ",$tmp[$i]);
-			for ($j=0; $j<count($tmp2); $j++)
-			{
-				if (strtolower($tmp2[$j])=="collate")
-				{
-					$tmp2[$j]="";
-					$tmp2[$j+1]=save_bracket($tmp2[$j+1]);
-					$j++;
-				}
-			}
-			$tmp[$i]=implode(" ",$tmp2);
-		}
+        if (strpos($t, 'engine=')) {
+            $tmp2 = explode(' ', $tmp[$i]);
+            for ($j = 0; $j < count($tmp2); ++$j) {
+                if ('ENGINE=' == substr(strtoupper($tmp2[$j]), 0, 7)) {
+                    $tmp2[$j] = 'TYPE='.substr($tmp2[$j], 7, strlen($tmp2[$j]) - 7);
+                }
+                if ('CHARSET=' == substr(strtoupper($tmp2[$j]), 0, 8)) {
+                    $tmp2[$j] = '';
+                    $tmp2[$j - 1] = save_bracket($tmp2[$j - 1]);
+                }
+                if ('COLLATE=' == substr(strtoupper($tmp2[$j]), 0, 8)) {
+                    $tmp2[$j] = save_bracket($tmp2[$j]);
+                    $tmp2[$j - 1] = '';
+                }
+            }
+            $tmp[$i] = implode(' ', $tmp2);
+        }
 
-		if (strpos($t,"engine="))
-		{
-			$tmp2=explode(" ",$tmp[$i]);
-			for ($j=0; $j<count($tmp2); $j++)
-			{
-				if (substr(strtoupper($tmp2[$j]),0,7)=="ENGINE=") $tmp2[$j]="TYPE=".substr($tmp2[$j],7,strlen($tmp2[$j])-7);
-				if (substr(strtoupper($tmp2[$j]),0,8)=="CHARSET=")
-				{
-					$tmp2[$j]="";
-					$tmp2[$j-1]=save_bracket($tmp2[$j-1]);
-				}
-				if (substr(strtoupper($tmp2[$j]),0,8)=="COLLATE=")
-				{
-					$tmp2[$j]=save_bracket($tmp2[$j]);
-					$tmp2[$j-1]="";
-				}
-			}
-			$tmp[$i]=implode(" ",$tmp2);
-		}
+        // character Set sprache  entfernen
+        if (strpos($t, 'character set')) {
+            $tmp2 = explode(' ', $tmp[$i]);
+            $end = false;
 
-		// character Set sprache  entfernen
-		if (strpos($t,"character set"))
-		{
-			$tmp2=explode(" ",$tmp[$i]);
-			$end=false;
+            for ($j = 0; $j < count($tmp2); ++$j) {
+                if ('character' == strtolower($tmp2[$j])) {
+                    $tmp2[$j] = '';
+                    $tmp2[$j + 1] = save_bracket($tmp2[$j + 1]);
+                    $tmp2[$j + 2] = save_bracket($tmp2[$j + 2]);
+                }
+            }
+            $tmp[$i] = implode(' ', $tmp2);
+        }
 
-			for ($j=0; $j<count($tmp2); $j++)
-			{
-				if (strtolower($tmp2[$j])=="character")
-				{
-					$tmp2[$j]='';
-					$tmp2[$j+1]=save_bracket($tmp2[$j+1]);
-					$tmp2[$j+2]=save_bracket($tmp2[$j+2]);
-				}
-			}
-			$tmp[$i]=implode(" ",$tmp2);
-		}
+        if (strpos($t, 'timestamp')) {
+            $tmp2 = explode(' ', $tmp[$i]);
+            $end = false;
 
-		if (strpos($t,"timestamp"))
-		{
-			$tmp2=explode(" ",$tmp[$i]);
-			$end=false;
-
-			for ($j=0; $j<count($tmp2); $j++)
-			{
-				if ($end) $tmp2[$j]="";
-				if (strtolower($tmp2[$j])=="timestamp")
-				{
-					$tmp2[$j]="TIMESTAMP(14)";
-					$end=true;
-				}
-			}
-			$tmp[$i]=implode(" ",$tmp2);
-		}
-	}
-	$t=implode(",",$tmp);
-	if (substr(rtrim($t),-1)!=";") $t=rtrim($t).";";
-	return $t;
+            for ($j = 0; $j < count($tmp2); ++$j) {
+                if ($end) {
+                    $tmp2[$j] = '';
+                }
+                if ('timestamp' == strtolower($tmp2[$j])) {
+                    $tmp2[$j] = 'TIMESTAMP(14)';
+                    $end = true;
+                }
+            }
+            $tmp[$i] = implode(' ', $tmp2);
+        }
+    }
+    $t = implode(',', $tmp);
+    if (';' != substr(rtrim($t), -1)) {
+        $t = rtrim($t).';';
+    }
+    return $t;
 }
 
-function MySQL_Ticks($s)
+function MySQLi_Ticks($s)
 {
-	$klammerstart=$lastklammerstart=$end=0;
-	$inner_s_start=strpos($s,'(');
-	$inner_s_end=strrpos($s,')');
-	$inner_s=substr($s,$inner_s_start+1,$inner_s_end-(1+$inner_s_start));
-	$pieces=explode(',',$inner_s);
-	for ($i=0; $i<count($pieces); $i++)
-	{
-		$r=trim($pieces[$i]);
-		$klammerstart+=substr_count($r,"(")-substr_count($r,")");
-		if ($i==count($pieces)-1) $klammerstart+=1;
-		if (substr(strtoupper($r),0,4)=="KEY "||substr(strtoupper($r),0,7)=="UNIQUE "||substr(strtoupper($r),0,12)=="PRIMARY KEY "||substr(strtoupper($r),0,13)=="FULLTEXT KEY ")
-		{
-			//nur ein Key
-			$end=1;
-		}
-		else
-		{
-			if (substr($r,0,1)!='`'&&substr($r,0,1)!='\''&&$klammerstart==0&&$end==0&&$lastklammerstart==0)
-			{
-				$pos=strpos($r,' ');
-				$r='`'.substr($r,0,$pos).'`'.substr($r,$pos);
-			}
-		}
-		$pieces[$i]=$r;
-		$lastklammerstart=$klammerstart;
-	}
-	$back=substr($s,0,$inner_s_start+1).implode(',',$pieces).');';
-	return $back;
+    $klammerstart = $lastklammerstart = $end = 0;
+    $inner_s_start = strpos($s, '(');
+    $inner_s_end = strrpos($s, ')');
+    $inner_s = substr($s, $inner_s_start + 1, $inner_s_end - (1 + $inner_s_start));
+    $pieces = explode(',', $inner_s);
+    for ($i = 0; $i < count($pieces); ++$i) {
+        $r = trim($pieces[$i]);
+        $klammerstart += substr_count($r, '(') - substr_count($r, ')');
+        if ($i == count($pieces) - 1) {
+            ++$klammerstart;
+        }
+        if ('KEY ' == substr(strtoupper($r), 0, 4) || 'UNIQUE ' == substr(strtoupper($r), 0, 7) || 'PRIMARY KEY ' == substr(strtoupper($r), 0, 12) || 'FULLTEXT KEY ' == substr(strtoupper($r), 0, 13)) {
+            //nur ein Key
+            $end = 1;
+        } else {
+            if ('`' != substr($r, 0, 1) && '\'' != substr($r, 0, 1) && 0 == $klammerstart && 0 == $end && 0 == $lastklammerstart) {
+                $pos = strpos($r, ' ');
+                $r = '`'.substr($r, 0, $pos).'`'.substr($r, $pos);
+            }
+        }
+        $pieces[$i] = $r;
+        $lastklammerstart = $klammerstart;
+    }
+    $back = substr($s, 0, $inner_s_start + 1).implode(',', $pieces).');';
+    return $back;
 }
 
 /**
- * Convert all array elements to UTF-8
+ * Convert all array elements to UTF-8.
  *
  * @param $array
+ *
  * @return array
  */
 function convert_to_utf8($obj)
 {
-	global $config;
-	$ret=$obj;
-	// wenn die Verbindung zur Datenbank nicht auf utf8 steht, dann muessen die Rückgaben in utf8 gewandelt werden,
-	// da die Webseite utf8-kodiert ist
-	if (!isset($config['mysql_can_change_encoding'])) get_sql_encodings();
+    global $config;
+    $ret = $obj;
+    // wenn die Verbindung zur Datenbank nicht auf utf8 steht, dann muessen die Rückgaben in utf8 gewandelt werden,
+    // da die Webseite utf8-kodiert ist
+    if (!isset($config['mysql_can_change_encoding'])) {
+        get_sql_encodings();
+    }
 
-	if ($config['mysql_can_change_encoding']==false&&$config['mysql_standard_character_set']!='utf8')
-	{
-		if (is_array($obj))
-		{
-			foreach ($obj as $key=>$val)
-			{
-				//echo "<br> Wandle " . $val . " nach ";
-				$obj[$key]=utf8_encode($val);
-				//echo $obj[$key];
-			}
-		}
-		if (is_string($obj)) $obj=utf8_encode($obj);
-		$ret=$obj;
-	}
-	return $ret;
+    if (false == $config['mysql_can_change_encoding'] && 'utf8' != $config['mysql_standard_character_set']) {
+        if (is_array($obj)) {
+            foreach ($obj as $key => $val) {
+                //echo "<br> Wandle " . $val . " nach ";
+                $obj[$key] = utf8_encode($val);
+                //echo $obj[$key];
+            }
+        }
+        if (is_string($obj)) {
+            $obj = utf8_encode($obj);
+        }
+        $ret = $obj;
+    }
+    return $ret;
 }
 
 /**
- * Convert all array elements to Latin1
+ * Convert all array elements to Latin1.
  *
  * @param $array
+ *
  * @return array
  */
 function convert_to_latin1($obj)
 {
-	global $config;
-	$ret=$obj;
-	// wenn die Verbindung zur Datenbank nicht auf utf8 steht, dann muessen die Rückgaben in utf8 gewandelt werden,
-	// da die Webseite utf8-kodiert ist
-	if ($config['mysql_can_change_encoding']==false&&$config['mysql_standard_character_set']!='utf8')
-	{
-		if (is_array($obj))
-		{
-			foreach ($obj as $key=>$val)
-			{
-				$obj[$key]=utf8_decode($val);
-			}
-		}
-		if (is_string($obj)) $obj=utf8_decode($obj);
-		$ret=$obj;
-	}
-	return $ret;
+    global $config;
+    $ret = $obj;
+    // wenn die Verbindung zur Datenbank nicht auf utf8 steht, dann muessen die Rückgaben in utf8 gewandelt werden,
+    // da die Webseite utf8-kodiert ist
+    if (false == $config['mysql_can_change_encoding'] && 'utf8' != $config['mysql_standard_character_set']) {
+        if (is_array($obj)) {
+            foreach ($obj as $key => $val) {
+                $obj[$key] = utf8_decode($val);
+            }
+        }
+        if (is_string($obj)) {
+            $obj = utf8_decode($obj);
+        }
+        $ret = $obj;
+    }
+    return $ret;
 }
 
 // returns the index of the selected val in an optionlist
 function get_index($arr, $selected)
 {
-	$ret=false; // return false if not found
-	foreach ($arr as $key=>$val)
-	{
-		if (strtolower(substr($val,0,strlen($selected)))==strtolower($selected))
-		{
-			$ret=$key;
-			break;
-		}
-	}
-	return $ret;
+    $ret = false; // return false if not found
+    foreach ($arr as $key => $val) {
+        if (strtolower(substr($val, 0, strlen($selected))) == strtolower($selected)) {
+            $ret = $key;
+            break;
+        }
+    }
+    return $ret;
 }
 
 /**
- * Check if config is readable
+ * Check if config is readable.
  *
  * @param $file
- * @return boolean
+ *
+ * @return bool
  */
-function read_config($file=false)
+function read_config($file = false)
 {
-	global $config,$databases;
-	$ret=false;
-	if (!$file) $file=$config['config_file'];
-	// protect from including external files
-	$search=array(':', 'http', 'ftp', ' ');
-	$replace=array('', '', '', '');
-	$file=str_replace($search,$replace,$file);
+    global $config, $databases;
+    $ret = false;
+    if (!$file) {
+        $file = $config['config_file'];
+    }
+    // protect from including external files
+    $search = [':', 'http', 'ftp', ' '];
+    $replace = ['', '', '', ''];
+    $file = str_replace($search, $replace, $file);
 
-	if (is_readable($config['paths']['config'].$file.'.php'))
-	{
-		// to prevent modern server from caching the new configuration we need to evaluate it this way
-		clearstatcache();
-		$f=implode('',file($config['paths']['config'].$file.'.php'));
-		$f=str_replace('<?php','',$f);
-		$f=str_replace('?>','',$f);
-		eval($f);
-		$config['config_file']=$file;
-		$_SESSION['config_file']=$config['config_file'];
-		$ret=true;
-	}
-	return $ret;
+    if (is_readable($config['paths']['config'].$file.'.php')) {
+        // to prevent modern server from caching the new configuration we need to evaluate it this way
+        clearstatcache();
+        $f = implode('', file($config['paths']['config'].$file.'.php'));
+        $f = str_replace('<?php', '', $f);
+        $f = str_replace('?>', '', $f);
+        eval($f);
+        $config['config_file'] = $file;
+        $_SESSION['config_file'] = $config['config_file'];
+        $ret = true;
+    }
+    return $ret;
 }
 
 /**
- * Get all work configurations from /work/config directory
+ * Get all work configurations from /work/config directory.
  *
  * @return array
  */
 function get_config_filenames()
 {
-	global $config;
-	$configs=array();
-	$dh=opendir($config['paths']['config']."/");
-	while (false!==($filename=readdir($dh)))
-	{
-		if (substr($filename,-4)=='.php'&&substr($filename,-9)!='.conf.php'&&$filename!='dbs_manual.php')
-		{
-			$configs[]=substr($filename,0,-4);
-		}
-	}
-	return $configs;
+    global $config;
+    $configs = [];
+    $dh = opendir($config['paths']['config'].'/');
+    while (false !== ($filename = readdir($dh))) {
+        if ('.php' == substr($filename, -4) && '.conf.php' != substr($filename, -9) && 'dbs_manual.php' != $filename) {
+            $configs[] = substr($filename, 0, -4);
+        }
+    }
+    asort($configs);
+    return $configs;
 }
 
-function table_output($text, $val, $small=false, $colspan=1)
+function table_output($text, $val, $small = false, $colspan = 1)
 {
-	$ret='<tr>';
-	$ret.='<td nowrap="nowrap"';
-	if ($colspan>1) $ret.=' colspan="'.$colspan.'"';
-	$ret.='>'.$text;
-	if ($colspan==1) $ret.=': ';
-	else
-		$ret.='&nbsp;';
-	if ($colspan==1) $ret.='</td><td nowrap="nowrap">';
-	if ($small) $ret.='<span class="small">'.$val.'</span></td></tr>';
-	else
-		$ret.='<strong>'.$val.'</strong></td></tr>';
-	return $ret;
+    $ret = '<tr>';
+    $ret .= '<td nowrap="nowrap"';
+    if ($colspan > 1) {
+        $ret .= ' colspan="'.$colspan.'"';
+    }
+    $ret .= '>'.$text;
+    if (1 == $colspan) {
+        $ret .= ': ';
+    } else {
+        $ret .= '&nbsp;';
+    }
+    if (1 == $colspan) {
+        $ret .= '</td><td nowrap="nowrap">';
+    }
+    if ($small) {
+        $ret .= '<span class="small">'.$val.'</span></td></tr>';
+    } else {
+        $ret .= '<strong>'.$val.'</strong></td></tr>';
+    }
+    return $ret;
 }
 
 /**
- * Receive all possible MySQL character sets and save standard to $config['mysql_standard_charset']
+ * Receive all possible MySQL character sets and save standard to $config['mysql_standard_charset'].
  */
 function get_sql_encodings()
 {
-	global $config;
-	unset($config['mysql_possible_character_sets']);
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$erg=false;
-	$config['mysql_standard_character_set']='';
-	$config['mysql_possible_character_sets']=array();
+    global $config;
 
-	if (!defined('MSD_MYSQL_VERSION')) GetMySQLVersion();
-	$v=explode('.',MSD_MYSQL_VERSION);
-	$config['mysql_can_change_encoding']=false;
-	if (($v[0]<=4&&$v[1]<1)||$v[0]<=3)
-	{
+    unset($config['mysql_possible_character_sets']);
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $erg = false;
+    $config['mysql_standard_character_set'] = '';
+    $config['mysql_possible_character_sets'] = [];
 
-		// MySQL < 4.1
-		$config['mysql_can_change_encoding']=false;
-		$sqlt='SHOW VARIABLES LIKE \'character_set%\'';
-		$res=MSD_query($sqlt) or die(SQLError($sqlt,mysqli_error($config['dbconnection'])));
-		if ($res)
-		{
-			while ($row=mysqli_fetch_row($res))
-			{
-				if ($row[0]=='character_set')
-				{
-					$config['mysql_standard_character_set']=$row[1];
-					if ($v[0]==3) $config['mysql_possible_character_sets'][0]=$row[1];
-				}
+    // MySQL-Version >= 4.1
+    $config['mysql_can_change_encoding'] = true;
+    $sqlt = 'SHOW CHARACTER SET';
+    $res = mod_query($sqlt) or exit(SQLError($sqlt, mysqli_error($config['dbconnection'])));
 
-				if ($row[0]=='character_sets'&&$v[0]>3)
-				{
-					$config['mysql_possible_character_sets']=explode(' ',$row[1]);
-					sort($config['mysql_possible_character_sets']);
-				}
-			}
-		}
-	}
-	else
-	{
-		// MySQL-Version >= 4.1
-		$config['mysql_can_change_encoding']=true;
-		$sqlt='SHOW CHARACTER SET';
-		$res=MSD_query($sqlt) or die(SQLError($sqlt,mysqli_error($config['dbconnection'])));
+    if ($res) {
+        while ($row = mysqli_fetch_row($res)) {
+            $config['mysql_possible_character_sets'][] = $row[0].' - '.$row[1];
+        }
+        sort($config['mysql_possible_character_sets']);
+    }
 
-		if ($res)
-		{
-			while ($row=mysqli_fetch_row($res))
-			{
-				$config['mysql_possible_character_sets'][]=$row[0].' - '.$row[1];
-			}
-			sort($config['mysql_possible_character_sets']);
-		}
-
-		$sqlt='SHOW VARIABLES LIKE \'character_set_connection\'';
-		$res=MSD_query($sqlt) or die(SQLError($sqlt,mysqli_error($config['dbconnection'])));
-
-		if ($res)
-		{
-			while ($row=mysqli_fetch_row($res))
-			{
-				$config['mysql_standard_character_set']=$row[1];
-			}
-		}
-	}
+    $sqlt = 'SHOW VARIABLES LIKE \'character_set_connection\'';
+    $res = mod_query($sqlt) or exit(SQLError($sqlt, mysqli_error($config['dbconnection'])));
 
+    if ($res) {
+        while ($row = mysqli_fetch_row($res)) {
+            $config['mysql_standard_character_set'] = $row[1];
+        }
+    }
 }
 
 /**
- * Un-quotes a quoted string/array
+ * Un-quotes a quoted string/array.
  *
  * @param $value
+ *
  * @return string/array
  */
 function stripslashes_deep($value)
 {
-	$value=is_array($value) ? array_map('stripslashes_deep',$value) : stripslashes($value);
-	return $value;
+    $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
+    return $value;
 }
 
 /**
- * Remove whitespaces before and after an string or array
+ * Remove whitespaces before and after an string or array.
  *
  * @param $value
+ *
  * @return string/array
  */
 function trim_deep($value)
 {
-	$value=is_array($value) ? array_map('trim_deep',$value) : trim($value);
-	return $value;
+    $value = is_array($value) ? array_map('trim_deep', $value) : trim($value);
+    return $value;
 }
 
 /**
- * load external source from given URL and save content locally
+ * load external source from given URL and save content locally.
  *
  * loads content from an external URL and saves it locally in $path with the name $local_file
  * return false on failure or true on success
@@ -1289,57 +1445,63 @@ function trim_deep($value)
  * @param $file
  * @param local_file
  * @param $path
- * @return boolean
+ *
+ * @return bool
  */
-function fetchFileFromURL($url, $file, $local_path='./data/',$local_file)
+function fetchFileFromURL($url, $file, $local_file, $local_path = './data/')
 {
-	$data=fetchFileDataFromURL($url.$file);
-	if ($data)
-	{
-		$d=fopen($local_path.$local_file,"wb");
-		$ret=fwrite($d,$data);
-		fclose($d);
-		return $ret;
-	}
-	return false;
+    $data = fetchFileDataFromURL($url.$file);
+    if ($data) {
+        $d = fopen($local_path.$local_file, 'wb');
+        $ret = fwrite($d, $data);
+        fclose($d);
+        return $ret;
+    }
+    return false;
 }
 
 /**
- * Loads data from an external source via HTTP-socket
+ * Loads data from an external source via HTTP-socket.
  *
  * Loads data from an external source $url given as URL
  * and returns the content as a binary string or an empty string on failure
  *
  * @param $url
+ *
  * @return string file data
  */
 function fetchFileDataFromURL($url)
 {
-	$url_parsed=parse_url($url);
-	$in='';
+    $url_parsed = parse_url($url);
+    $in = '';
 
-	$host=$url_parsed['host'];
-	$port=isset($url_parsed['port']) ? intval($url_parsed['port']) : 80;
-	if ($port==0) $port=80;
-	$path=$url_parsed['path'];
-	if (isset($url_parsed['query'])&&$url_parsed['query']!='') $path.='?'.$url_parsed['query'];
+    $host = $url_parsed['host'];
+    $port = isset($url_parsed['port']) ? intval($url_parsed['port']) : 80;
+    if (0 == $port) {
+        $port = 80;
+    }
+    $path = $url_parsed['path'];
+    if (isset($url_parsed['query']) && '' != $url_parsed['query']) {
+        $path .= '?'.$url_parsed['query'];
+    }
 
-	$fp=fsockopen($host,$port,$errno,$errstr,3);
-	if ($fp)
-	{
-		$out="GET $path HTTP/1.1\r\nHost: $host\r\n";
-		$out.="Connection: close\r\n\r\n";
-		fwrite($fp,$out);
-		$body=false;
-		while (!feof($fp))
-		{
-			$s=fgets($fp,1024);
-			if ($body) $in.=$s;
-			if ($s=="\r\n") $body=true;
-		}
+    $fp = fsockopen($host, $port, $errno, $errstr, 3);
+    if ($fp) {
+        $out = "GET $path HTTP/1.1\r\nHost: $host\r\n";
+        $out .= "Connection: close\r\n\r\n";
+        fwrite($fp, $out);
+        $body = false;
+        while (!feof($fp)) {
+            $s = fgets($fp, 1024);
+            if ($body) {
+                $in .= $s;
+            }
+            if ("\r\n" == $s) {
+                $body = true;
+            }
+        }
 
-		fclose($fp);
-	}
-	return $in;
+        fclose($fp);
+    }
+    return $in;
 }
-
diff --git a/msd/inc/functions_imexport.php b/msd/inc/functions_imexport.php
index 79966d71..a049b136 100644
--- a/msd/inc/functions_imexport.php
+++ b/msd/inc/functions_imexport.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,402 +18,401 @@
 
 function CheckCSVOptions()
 {
-	global $sql;
-	if (!isset($sql['export']['trenn'])) $sql['export']['trenn']=";";
-	if (!isset($sql['export']['enc'])) $sql['export']['enc']="\"";
-	if (!isset($sql['export']['esc'])) $sql['export']['esc']="\\";
-	if (!isset($sql['export']['ztrenn'])) $sql['export']['ztrenn']="\\r\\n";
-	if (!isset($sql['export']['null'])) $sql['export']['null']="NULL";
-	if (!isset($sql['export']['namefirstline'])) $sql['export']['namefirstline']=0;
-	if (!isset($sql['export']['format'])) $sql['export']['format']=0;
-	if (!isset($sql['export']['sendfile'])) $sql['export']['sendfile']=0;
-	if (!isset($sql['export']['tables'])) $sql['export']['tables']=Array();
-	if (!isset($sql['export']['compressed'])) $sql['export']['compressed']=0;
-	if (!isset($sql['export']['htmlstructure'])) $sql['export']['htmlstructure']=0;
-	if (!isset($sql['export']['xmlstructure'])) $sql['export']['xmlstructure']=0;
-
-	if (!isset($sql['import']['trenn'])) $sql['import']['trenn']=";";
-	if (!isset($sql['import']['enc'])) $sql['import']['enc']="\"";
-	if (!isset($sql['import']['esc'])) $sql['import']['esc']="\\";
-	if (!isset($sql['import']['ztrenn'])) $sql['import']['ztrenn']="\\r\\n";
-	if (!isset($sql['import']['null'])) $sql['import']['null']="NULL";
-	if (!isset($sql['import']['namefirstline'])) $sql['import']['namefirstline']=0;
-	if (!isset($sql['import']['format'])) $sql['import']['format']=0;
+    global $sql;
+    if (!isset($sql['export']['trenn'])) {
+        $sql['export']['trenn'] = ';';
+    }
+    if (!isset($sql['export']['enc'])) {
+        $sql['export']['enc'] = '"';
+    }
+    if (!isset($sql['export']['esc'])) {
+        $sql['export']['esc'] = '\\';
+    }
+    if (!isset($sql['export']['ztrenn'])) {
+        $sql['export']['ztrenn'] = '\\r\\n';
+    }
+    if (!isset($sql['export']['null'])) {
+        $sql['export']['null'] = 'NULL';
+    }
+    if (!isset($sql['export']['namefirstline'])) {
+        $sql['export']['namefirstline'] = 0;
+    }
+    if (!isset($sql['export']['format'])) {
+        $sql['export']['format'] = 0;
+    }
+    if (!isset($sql['export']['sendfile'])) {
+        $sql['export']['sendfile'] = 0;
+    }
+    if (!isset($sql['export']['tables'])) {
+        $sql['export']['tables'] = [];
+    }
+    if (!isset($sql['export']['compressed'])) {
+        $sql['export']['compressed'] = 0;
+    }
+    if (!isset($sql['export']['htmlstructure'])) {
+        $sql['export']['htmlstructure'] = 0;
+    }
+    if (!isset($sql['export']['xmlstructure'])) {
+        $sql['export']['xmlstructure'] = 0;
+    }
 
+    if (!isset($sql['import']['trenn'])) {
+        $sql['import']['trenn'] = ';';
+    }
+    if (!isset($sql['import']['enc'])) {
+        $sql['import']['enc'] = '"';
+    }
+    if (!isset($sql['import']['esc'])) {
+        $sql['import']['esc'] = '\\';
+    }
+    if (!isset($sql['import']['ztrenn'])) {
+        $sql['import']['ztrenn'] = '\\r\\n';
+    }
+    if (!isset($sql['import']['null'])) {
+        $sql['import']['null'] = 'NULL';
+    }
+    if (!isset($sql['import']['namefirstline'])) {
+        $sql['import']['namefirstline'] = 0;
+    }
+    if (!isset($sql['import']['format'])) {
+        $sql['import']['format'] = 0;
+    }
 }
 
 function ExportCSV()
 {
-	global $sql,$config;
-	$t="";
-	$time_start=time();
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	for ($table=0; $table < count($sql['export']['tables']); $table++)
-	{
-		$sqlt="SHOW Fields FROM `" . $sql['export']['db'] . "`.`" . $sql['export']['tables'][$table] . "`;";
-		$res=MSD_query($sqlt);
-		if ($res)
-		{
-			$numfields=mysqli_num_rows($res);
-			if ($sql['export']['namefirstline'] == 1)
-			{
-				for ($feld=0; $feld < $numfields; $feld++)
-				{
-					$row=mysqli_fetch_row($res);
-					if ($sql['export']['enc'] != "") $t.=$sql['export']['enc'] . $row[0] . $sql['export']['enc'] . ( ( $feld + 1 < $numfields ) ? $sql['export']['trenn'] : '' );
-					else $t.=$row[0] . ( ( $feld + 1 < $numfields ) ? $sql['export']['trenn'] : '' );
-				}
-				$t.=$sql['export']['endline'];
-				$sql['export']['lines']++;
-			}
-		}
-		$sqlt="SELECT * FROM `" . $sql['export']['db'] . "`.`" . $sql['export']['tables'][$table] . "`;";
-		$res=MSD_query($sqlt);
-		if ($res)
-		{
-			$numrows=mysqli_num_rows($res);
-			for ($data=0; $data < $numrows; $data++)
-			{
-				$row=mysqli_fetch_row($res);
-				for ($feld=0; $feld < $numfields; $feld++)
-				{
-					if (!isset($row[$feld]) || is_null($row[$feld]))
-					{
-						$t.=$sql['export']['null'];
-					}
-					elseif ($row[$feld] == '0' || $row[$feld] != '')
-					{
-						if ($sql['export']['enc'] != "") $t.=$sql['export']['enc'] . str_replace($sql['export']['enc'],$sql['export']['esc'] . $sql['export']['enc'],$row[$feld]) . $sql['export']['enc'];
-						else $t.=$row[$feld];
-					}
-					else
-					{
-						$t.='';
-					}
-					$t.=( $feld + 1 < $numfields ) ? $sql['export']['trenn'] : '';
-				}
-				$t.=$sql['export']['endline'];
-				$sql['export']['lines']++;
-				if (strlen($t) > $config['memory_limit'])
-				{
-					CSVOutput($t);
-					$t="";
-				}
-				$time_now=time();
-				if ($time_start >= $time_now + 30)
-				{
-					$time_start=$time_now;
-					header('X-MSDPing: Pong');
-				}
-			}
-		}
-	}
-	CSVOutput($t,1);
+    global $sql, $config;
+    $t = '';
+    $time_start = time();
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    for ($table = 0; $table < count($sql['export']['tables']); ++$table) {
+        $sqlt = 'SHOW Fields FROM `'.$sql['export']['db'].'`.`'.$sql['export']['tables'][$table].'`;';
+        $res = mod_query($sqlt);
+        if ($res) {
+            $numfields = mysqli_num_rows($res);
+            if (1 == $sql['export']['namefirstline']) {
+                for ($feld = 0; $feld < $numfields; ++$feld) {
+                    $row = mysqli_fetch_row($res);
+                    if ('' != $sql['export']['enc']) {
+                        $t .= $sql['export']['enc'].$row[0].$sql['export']['enc'].(($feld + 1 < $numfields) ? $sql['export']['trenn'] : '');
+                    } else {
+                        $t .= $row[0].(($feld + 1 < $numfields) ? $sql['export']['trenn'] : '');
+                    }
+                }
+                $t .= $sql['export']['endline'];
+                ++$sql['export']['lines'];
+            }
+        }
+        $sqlt = 'SELECT * FROM `'.$sql['export']['db'].'`.`'.$sql['export']['tables'][$table].'`;';
+        $res = mod_query($sqlt);
+        if ($res) {
+            $numrows = mysqli_num_rows($res);
+            for ($data = 0; $data < $numrows; ++$data) {
+                $row = mysqli_fetch_row($res);
+                for ($feld = 0; $feld < $numfields; ++$feld) {
+                    if (!isset($row[$feld]) || is_null($row[$feld])) {
+                        $t .= $sql['export']['null'];
+                    } elseif ('0' == $row[$feld] || '' != $row[$feld]) {
+                        if ('' != $sql['export']['enc']) {
+                            $t .= $sql['export']['enc'].str_replace($sql['export']['enc'], $sql['export']['esc'].$sql['export']['enc'], $row[$feld]).$sql['export']['enc'];
+                        } else {
+                            $t .= $row[$feld];
+                        }
+                    } else {
+                        $t .= '';
+                    }
+                    $t .= ($feld + 1 < $numfields) ? $sql['export']['trenn'] : '';
+                }
+                $t .= $sql['export']['endline'];
+                ++$sql['export']['lines'];
+                if ('' == $config['memory_limit']) {
+                    $config['memory_limit'] = 0;
+                }
+                if (strlen($t) > $config['memory_limit']) {
+                    CSVOutput($t);
+                    $t = '';
+                }
+                $time_now = time();
+                if ($time_start >= $time_now + 30) {
+                    $time_start = $time_now;
+                    header('X-MODPing: Pong');
+                }
+            }
+        }
+    }
+    CSVOutput($t, 1);
 }
 
-function CSVOutput($str, $last=0)
+function CSVOutput($str, $last = 0)
 {
-	global $sql,$config;
-	if ($sql['export']['sendfile'] == 0)
-	{
-		//Display
-		echo $str;
-	}
-	else
-	{
-		if ($sql['export']['header_sent'] == "")
-		{
-			if ($sql['export']['compressed'] == 1 & !function_exists('gzencode')) $sql['export']['compressed']=0;
-			if ($sql['export']['format'] < 4)
-			{
-				$file=$sql['export']['db'] . ( ( $sql['export']['compressed'] == 1 ) ? ".csv.gz" : ".csv" );
-			}
-			elseif ($sql['export']['format'] == 4)
-			{
-				$file=$sql['export']['db'] . ( ( $sql['export']['compressed'] == 1 ) ? ".xml.gz" : ".xml" );
-			}
-			elseif ($sql['export']['format'] == 5)
-			{
-				$file=$sql['export']['db'] . ( ( $sql['export']['compressed'] == 1 ) ? ".html.gz" : ".html" );
-			}
-			$mime=( $sql['export']['compressed'] == 0 ) ? "x-type/subtype" : "application/x-gzip";
+    global $sql, $config;
+    if (0 == $sql['export']['sendfile']) {
+        //Display
+        echo $str;
+    } else {
+        if ('' == $sql['export']['header_sent']) {
+            if (1 == $sql['export']['compressed'] & !function_exists('gzencode')) {
+                $sql['export']['compressed'] = 0;
+            }
+            if ($sql['export']['format'] < 4) {
+                $file = $sql['export']['db'].((1 == $sql['export']['compressed']) ? '.csv.gz' : '.csv');
+            } elseif (4 == $sql['export']['format']) {
+                $file = $sql['export']['db'].((1 == $sql['export']['compressed']) ? '.xml.gz' : '.xml');
+            } elseif (5 == $sql['export']['format']) {
+                $file = $sql['export']['db'].((1 == $sql['export']['compressed']) ? '.html.gz' : '.html');
+            }
+            $mime = (0 == $sql['export']['compressed']) ? 'x-type/subtype' : 'application/x-gzip';
 
-			header('Content-Disposition: attachment; filename="' . $file . '"');
-			header('Pragma: no-cache');
-			header('Content-Type: ' . $mime);
-			header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
-			$sql['export']['header_sent']=1;
-		}
-		if ($sql['export']['compressed'] == 1) echo gzencode($str);
-		else echo $str;
-
-	}
+            header('Content-Disposition: attachment; filename="'.$file.'"');
+            header('Pragma: no-cache');
+            header('Content-Type: '.$mime);
+            header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
+            $sql['export']['header_sent'] = 1;
+        }
+        if (1 == $sql['export']['compressed']) {
+            echo gzencode($str);
+        } else {
+            echo $str;
+        }
+    }
 }
 
 function DoImport()
 {
-	global $sql,$lang;
-	$r='<span class="swarnung">';
-	$zeilen=count($sql['import']['csv']) - $sql['import']['namefirstline'];
-	$sql['import']['first_zeile']=explode($sql['import']['trenn'],$sql['import']['csv'][0]);
-	$importfelder=count($sql['import']['first_zeile']);
+    global $sql, $lang;
+    $r = '<span class="swarnung">';
+    $zeilen = count($sql['import']['csv']) - $sql['import']['namefirstline'];
+    $sql['import']['first_zeile'] = explode($sql['import']['trenn'], $sql['import']['csv'][0]);
+    $importfelder = count($sql['import']['first_zeile']);
 
-	if ($sql['import']['tablecreate'] == 0)
-	{
-		$res=MSD_query("show fields FROM " . $sql['import']['table']);
-		$tabellenfelder=mysqli_num_rows($res);
-		if ($importfelder != $tabellenfelder)
-		{
-			$r.='<br>' . sprintf($lang['L_CSV_FIELDCOUNT_NOMATCH'],$tabellenfelder,$importfelder);
-		}
-		else
-		{
-			$ok=1;
-		}
-	}
-	else
-	{
-		$ok=ImportCreateTable();
-		if ($ok == 0)
-		{
-			$r.='<br>' . sprintf($lang['L_CSV_ERRORCREATETABLE'],$sql['import']['table']);
-		}
-	}
-	if ($ok == 1)
-	{
-		$insert="";
-		if ($sql['import']['emptydb'] == 1 && $sql['import']['tablecreate'] == 0)
-		{
-			MSD_DoSQL("TRUNCATE " . $sql['import']['table'] . ";");
-		}
-		$sql['import']['lines_imported']=0;
-		$enc=( $sql['import']['enc'] == "" ) ? "'" : "";
-		$zc="";
-		for ($i=$sql['import']['namefirstline']; $i < $zeilen + $sql['import']['namefirstline']; $i++)
-		{
-			//Importieren
-			$insert="INSERT INTO " . $sql['import']['table'] . " VALUES(";
-			if ($sql['import']['createindex'] == 1) $insert.="'', ";
-			$zc.=trim(rtrim($sql['import']['csv'][$i]));
-			//echo "Zeile $i: $zc<br>";
-			if ($zc != "")
-			{ // && substr($zc,-1)==$enc) {
-				$zeile=explode($sql['import']['trenn'],$zc);
-				for ($j=0; $j < $importfelder; $j++)
-				{
-					$a=( $zeile[$j] == "" && $enc == "" ) ? "''" : $zeile[$j];
-					$insert.=$enc . $a . $enc . ( ( $j == $importfelder - 1 ) ? ");\n" : "," );
-				}
-				MSD_DoSQL($insert);
-				$sql['import']['lines_imported']++;
-				$zc="";
-			}
-
-		}
-		$r.=sprintf($lang['L_CSV_FIELDSLINES'],$importfelder,$sql['import']['lines_imported']);
-	}
-
-	$r.='</span>';
-	return $r;
+    if (0 == $sql['import']['tablecreate']) {
+        $res = mod_query('show fields FROM '.$sql['import']['table']);
+        $tabellenfelder = mysqli_num_rows($res);
+        if ($importfelder != $tabellenfelder) {
+            $r .= '<br>'.sprintf($lang['L_CSV_FIELDCOUNT_NOMATCH'], $tabellenfelder, $importfelder);
+        } else {
+            $ok = 1;
+        }
+    } else {
+        $ok = ImportCreateTable();
+        if (0 == $ok) {
+            $r .= '<br>'.sprintf($lang['L_CSV_ERRORCREATETABLE'], $sql['import']['table']);
+        }
+    }
+    if (1 == $ok) {
+        $insert = '';
+        if (1 == $sql['import']['emptydb'] && 0 == $sql['import']['tablecreate']) {
+            MOD_DoSQL('TRUNCATE '.$sql['import']['table'].';');
+        }
+        $sql['import']['lines_imported'] = 0;
+        $enc = ('' == $sql['import']['enc']) ? "'" : '';
+        $zc = '';
+        for ($i = $sql['import']['namefirstline']; $i < $zeilen + $sql['import']['namefirstline']; ++$i) {
+            //Importieren
+            $insert = 'INSERT INTO '.$sql['import']['table'].' VALUES(';
+            if (1 == $sql['import']['createindex']) {
+                $insert .= "'', ";
+            }
+            $zc .= trim(rtrim($sql['import']['csv'][$i]));
+            //echo "Zeile $i: $zc<br>";
+            if ('' != $zc) { // && substr($zc,-1)== $enc) {
+                $zeile = explode($sql['import']['trenn'], $zc);
+                for ($j = 0; $j < $importfelder; ++$j) {
+                    $a = ('' == $zeile[$j] && '' == $enc) ? "''" : $zeile[$j];
+                    $insert .= $enc.$a.$enc.(($j == $importfelder - 1) ? ");\n" : ',');
+                }
+                MOD_DoSQL($insert);
+                ++$sql['import']['lines_imported'];
+                $zc = '';
+            }
+        }
+        $r .= sprintf($lang['L_CSV_FIELDSLINES'], $importfelder, $sql['import']['lines_imported']);
+    }
 
+    $r .= '</span>';
+    return $r;
 }
 
 function ImportCreateTable()
 {
-	global $sql,$lang,$db,$config;
-	$tbl=Array();
-	$sql = "SHOW TABLES FROM $db";
-	$tabellen=MSD_query($sql);
-	// while ($row = mysqli_fetch_row($num_tables))
-	while ($row = mysqli_fetch_row($tabellen))
-	{
-		$tbl[]=strtolower($row[0]);
-	}
-	$i=0;
-	$sql['import']['table']=$sql['import']['table'] . $i;
-	while (in_array($sql['import']['table'],$tbl))
-	{
-		$sql['import']['table']=substr($sql['import']['table'],0,strlen($sql['import']['table']) - 1) . ++$i;
-	}
-	$create="CREATE TABLE `" . $sql['import']['table'] . "` (" . ( ( $sql['import']['createindex'] == 1 ) ? '`import_id` int(11) unsigned NOT NULL auto_increment, ' : '' );
-	if ($sql['import']['namefirstline'])
-	{
-		for ($i=0; $i < count($sql['import']['first_zeile']); $i++)
-		{
-			$create.='`' . $sql['import']['first_zeile'][$i] . '` VARCHAR(250) NOT NULL, ';
-		}
-	}
-	else
-	{
-		for ($i=0; $i < count($sql['import']['first_zeile']); $i++)
-		{
-			$create.='`FIELD_' . $i . '` VARCHAR(250) NOT NULL, ';
-		}
-	}
-	if ($sql['import']['createindex'] == 1) $create.='PRIMARY KEY (`import_id`) ';
-	else $create=substr($create,0,strlen($create) - 2);
+    global $sql, $lang, $db, $config;
+    $tbl = [];
+    $sql = "SHOW TABLES FROM $db";
+    $tabellen = mod_query($sql);
+    // while ($row = mysqli_fetch_row($num_tables))
+    while ($row = mysqli_fetch_row($tabellen)) {
+        $tbl[] = strtolower($row[0]);
+    }
+    $i = 0;
+    $sql['import']['table'] = $sql['import']['table'].$i;
+    while (in_array($sql['import']['table'], $tbl)) {
+        $sql['import']['table'] = substr($sql['import']['table'], 0, strlen($sql['import']['table']) - 1).++$i;
+    }
+    $create = 'CREATE TABLE `'.$sql['import']['table'].'` ('.((1 == $sql['import']['createindex']) ? '`import_id` int(11) unsigned NOT NULL auto_increment, ' : '');
+    if ($sql['import']['namefirstline']) {
+        for ($i = 0; $i < count($sql['import']['first_zeile']); ++$i) {
+            $create .= '`'.$sql['import']['first_zeile'][$i].'` VARCHAR(250) NOT NULL, ';
+        }
+    } else {
+        for ($i = 0; $i < count($sql['import']['first_zeile']); ++$i) {
+            $create .= '`FIELD_'.$i.'` VARCHAR(250) NOT NULL, ';
+        }
+    }
+    if (1 == $sql['import']['createindex']) {
+        $create .= 'PRIMARY KEY (`import_id`) ';
+    } else {
+        $create = substr($create, 0, strlen($create) - 2);
+    }
 
-	$create.=') ' . ( ( MSD_NEW_VERSION ) ? 'ENGINE' : 'TYPE' ) . "=MyISAM COMMENT='imported at " . date("l dS of F Y H:i:s A") . "'";
-	$res=mysqli_query($config['dbconnection'], $create) || die(SQLError($create,mysqli_error($config['dbconnection'])));
-	return 1;
+    $create .= ') '.((MOD_NEW_VERSION) ? 'ENGINE' : 'TYPE')."=MyISAM COMMENT='imported at ".date('l dS of F Y H:i:s A')."'";
+    $res = mysqli_query($config['dbconnection'], $create) || exit(SQLError($create, mysqli_error($config['dbconnection'])));
+    return 1;
 }
 
 function ExportXML()
 {
-	global $sql,$config;
-	$tab="\t";
-	$level=0;
-	$t='<?xml version="1.0" encoding="UTF-8" ?>' . "\n" . '<database name="' . $sql['export']['db'] . '">' . "\n";
-	$level++;
-	$time_start=time();
+    global $sql, $config;
+    $tab = "\t";
+    $level = 0;
+    $t = '<?xml version="1.0" encoding="UTF-8" ?>'."\n".'<database name="'.$sql['export']['db'].'">'."\n";
+    ++$level;
+    $time_start = time();
 
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	for ($table=0; $table < count($sql['export']['tables']); $table++)
-	{
-		$t.=str_repeat($tab,$level++) . '<table name="' . $sql['export']['tables'][$table] . '">' . "\n";
-		$sqlt="SHOW Fields FROM `" . $sql['export']['db'] . "`.`" . $sql['export']['tables'][$table] . "`;";
-		$res=MSD_query($sqlt);
-		if ($res)
-		{
-			$numfields=mysqli_num_rows($res);
-			if ($sql['export']['xmlstructure'] == 1)
-			{
-				$t.=str_repeat($tab,$level++) . '<structure>' . "\n";
-				for ($feld=0; $feld < $numfields; $feld++)
-				{
-					$row=mysqli_fetch_array($res);
-					$t.=str_repeat($tab,$level++) . '<field no="' . $feld . '">' . "\n";
-					$t.=str_repeat($tab,$level) . '<name>' . $row['Field'] . '</name>' . "\n";
-					$t.=str_repeat($tab,$level) . '<type>' . $row['Type'] . '</type>' . "\n";
-					$t.=str_repeat($tab,$level) . '<null>' . $row['Null'] . '</null>' . "\n";
-					$t.=str_repeat($tab,$level) . '<key>' . $row['Key'] . '</key>' . "\n";
-					$t.=str_repeat($tab,$level) . '<default>' . $row['Default'] . '</default>' . "\n";
-					$t.=str_repeat($tab,$level) . '<extra>' . $row['Extra'] . '</extra>' . "\n";
-					$t.=str_repeat($tab,--$level) . '</field>' . "\n";
-				}
-				$t.=str_repeat($tab,--$level) . '</structure>' . "\n";
-			}
-		}
-		$t.=str_repeat($tab,$level++) . '<data>' . "\n";
-		$sqlt="SELECT * FROM `" . $sql['export']['db'] . "`.`" . $sql['export']['tables'][$table] . "`;";
-		$res=MSD_query($sqlt);
-		if ($res)
-		{
-			$numrows=mysqli_num_rows($res);
-			for ($data=0; $data < $numrows; $data++)
-			{
-				$t.=str_repeat($tab,$level) . "<row>\n";
-				$level++;
-				$row=mysqli_fetch_row($res);
-				for ($feld=0; $feld < $numfields; $feld++)
-				{
-					$t.=str_repeat($tab,$level) . '<field no="' . $feld . '">' . $row[$feld] . '</field>' . "\n";
-				}
-				$t.=str_repeat($tab,--$level) . "</row>\n";
-				$sql['export']['lines']++;
-				if (strlen($t) > $config['memory_limit'])
-				{
-					CSVOutput($t);
-					$t="";
-				}
-				$time_now=time();
-				if ($time_start >= $time_now + 30)
-				{
-					$time_start=$time_now;
-					header('X-MSDPing: Pong');
-				}
-			}
-		}
-		$t.=str_repeat($tab,--$level) . '</data>' . "\n";
-		$t.=str_repeat($tab,--$level) . '</table>' . "\n";
-	}
-	$t.=str_repeat($tab,--$level) . '</database>' . "\n";
-	CSVOutput($t,1);
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    for ($table = 0; $table < count($sql['export']['tables']); ++$table) {
+        $t .= str_repeat($tab, $level++).'<table name="'.$sql['export']['tables'][$table].'">'."\n";
+        $sqlt = 'SHOW Fields FROM `'.$sql['export']['db'].'`.`'.$sql['export']['tables'][$table].'`;';
+        $res = mod_query($sqlt);
+        if ($res) {
+            $numfields = mysqli_num_rows($res);
+            if (1 == $sql['export']['xmlstructure']) {
+                $t .= str_repeat($tab, $level++).'<structure>'."\n";
+                for ($feld = 0; $feld < $numfields; ++$feld) {
+                    $row = mysqli_fetch_array($res);
+                    $t .= str_repeat($tab, $level++).'<field no="'.$feld.'">'."\n";
+                    $t .= str_repeat($tab, $level).'<name>'.$row['Field'].'</name>'."\n";
+                    $t .= str_repeat($tab, $level).'<type>'.$row['Type'].'</type>'."\n";
+                    $t .= str_repeat($tab, $level).'<null>'.$row['Null'].'</null>'."\n";
+                    $t .= str_repeat($tab, $level).'<key>'.$row['Key'].'</key>'."\n";
+                    $t .= str_repeat($tab, $level).'<default>'.$row['Default'].'</default>'."\n";
+                    $t .= str_repeat($tab, $level).'<extra>'.$row['Extra'].'</extra>'."\n";
+                    $t .= str_repeat($tab, --$level).'</field>'."\n";
+                }
+                $t .= str_repeat($tab, --$level).'</structure>'."\n";
+            }
+        }
+        $t .= str_repeat($tab, $level++).'<data>'."\n";
+        $sqlt = 'SELECT * FROM `'.$sql['export']['db'].'`.`'.$sql['export']['tables'][$table].'`;';
+        $res = mod_query($sqlt);
+        if ($res) {
+            $numrows = mysqli_num_rows($res);
+            for ($data = 0; $data < $numrows; ++$data) {
+                $t .= str_repeat($tab, $level)."<row>\n";
+                ++$level;
+                $row = mysqli_fetch_row($res);
+                for ($feld = 0; $feld < $numfields; ++$feld) {
+                    $t .= str_repeat($tab, $level).'<field no="'.$feld.'">'.$row[$feld].'</field>'."\n";
+                }
+                $t .= str_repeat($tab, --$level)."</row>\n";
+                ++$sql['export']['lines'];
+                if ('' == $config['memory_limit']) {
+                    $config['memory_limit'] = 0;
+                }
+                if (strlen($t) > $config['memory_limit']) {
+                    CSVOutput($t);
+                    $t = '';
+                }
+                $time_now = time();
+                if ($time_start >= $time_now + 30) {
+                    $time_start = $time_now;
+                    header('X-MODPing: Pong');
+                }
+            }
+        }
+        $t .= str_repeat($tab, --$level).'</data>'."\n";
+        $t .= str_repeat($tab, --$level).'</table>'."\n";
+    }
+    $t .= str_repeat($tab, --$level).'</database>'."\n";
+    CSVOutput($t, 1);
 }
 
 function ExportHTML()
 {
-	global $sql,$config,$lang;
-	$header='<html><head><title>MSD Export</title></head>';
-	$footer="\n\n</body>\n</html>";
-	$content="";
-	$content.='<h1>' . $lang['L_DB'] . ' ' . $sql['export']['db'] . '</h1>';
+    global $sql, $config, $lang;
+    $header = '<html><head><title>MOD Export</title></head>';
+    $footer = "\n\n</body>\n</html>";
+    $content = '';
+    $content .= '<h1>'.$lang['L_DB'].' '.$sql['export']['db'].'</h1>';
 
-	$time_start=time();
+    $time_start = time();
 
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	for ($table=0; $table < count($sql['export']['tables']); $table++)
-	{
-		$content.='<h2>Tabelle ' . $sql['export']['tables'][$table] . '</h2>' . "\n";
-		$fsql="show fields from `" . $sql['export']['tables'][$table] . "`";
-		$dsql="select * from `" . $sql['export']['tables'][$table] . "`";
-		//Struktur
-		$res=MSD_query($fsql);
-		if ($res)
-		{
-			$field=$fieldname=$fieldtyp=Array();
-			$structure="<table class=\"Table\">\n";
-			$numfields=mysqli_num_rows($res);
-			for ($feld=0; $feld < $numfields; $feld++)
-			{
-				$row=mysqli_fetch_row($res);
-				$field[$feld]=$row[0];
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    for ($table = 0; $table < count($sql['export']['tables']); ++$table) {
+        $content .= '<h2>Tabelle '.$sql['export']['tables'][$table].'</h2>'."\n";
+        $fsql = 'show fields from `'.$sql['export']['tables'][$table].'`';
+        $dsql = 'select * from `'.$sql['export']['tables'][$table].'`';
+        //Struktur
+        $res = mod_query($fsql);
+        if ($res) {
+            $field = $fieldname = $fieldtyp = [];
+            $structure = "<table class=\"Table\">\n";
+            $numfields = mysqli_num_rows($res);
+            for ($feld = 0; $feld < $numfields; ++$feld) {
+                $row = mysqli_fetch_row($res);
+                $field[$feld] = $row[0];
 
-				if ($feld == 0)
-				{
-					$structure.="<tr class=\"Header\">\n";
-					for ($i=0; $i < count($row); $i++)
-					{
-						$str=mysqli_fetch_field($res,$i);
-						$fieldname[$i]=$str->name;
-						$fieldtyp[$i]=$str->type;
-						$structure.="<th>" . $str->name . "</th>\n";
-					}
-					$structure.="</tr>\n<tr>\n";
-				}
-				for ($i=0; $i < count($row); $i++)
-				{
-					$structure.="<td class=\"Object\">" . ( ( $row[$i] != "" ) ? $row[$i] : "&nbsp;" ) . "</td>\n";
-				}
-				$structure.="</tr>\n";
-			}
-			$structure.="</table>\n";
-		}
-		if ($sql['export']['htmlstructure'] == 1) $content.="<h3>Struktur</h3>\n" . $structure;
-		//Daten
+                if (0 == $feld) {
+                    $structure .= "<tr class=\"Header\">\n";
+                    for ($i = 0; $i < count($row); ++$i) {
+                        $str = mysqli_fetch_field($res, $i);
+                        $fieldname[$i] = $str->name;
+                        $fieldtyp[$i] = $str->type;
+                        $structure .= '<th>'.$str->name."</th>\n";
+                    }
+                    $structure .= "</tr>\n<tr>\n";
+                }
+                for ($i = 0; $i < count($row); ++$i) {
+                    $structure .= '<td class="Object">'.(('' != $row[$i]) ? $row[$i] : '&nbsp;')."</td>\n";
+                }
+                $structure .= "</tr>\n";
+            }
+            $structure .= "</table>\n";
+        }
+        if (1 == $sql['export']['htmlstructure']) {
+            $content .= "<h3>Struktur</h3>\n".$structure;
+        }
+        //Daten
 
-
-		$res=MSD_query($dsql);
-		if ($res)
-		{
-			$anz=mysqli_num_rows($res);
-			$content.="<h3>Daten ($anz Datens&auml;tze)</h3>\n";
-			$content.="<table class=\"Table\">\n";
-			for ($feld=0; $feld < count($field); $feld++)
-			{
-				if ($feld == 0)
-				{
-					$content.="<tr class=\"Header\">\n";
-					for ($i=0; $i < count($field); $i++)
-					{
-						$content.="<th>" . $field[$i] . "</th>\n";
-					}
-					$content.="</tr>\n";
-				}
-			}
-			for ($d=0; $d < $anz; $d++)
-			{
-				$row=mysqli_fetch_row($res);
-				$content.="<tr>\n";
-				for ($i=0; $i < count($row); $i++)
-				{
-
-					$content.='<td class="Object">' . ( ( $row[$i] != "" ) ? $row[$i] : "&nbsp;" ) . "</td>\n";
-				}
-				$content.="</tr>\n";
-			}
-		}
-		$content.="</table>";
-	}
-	CSVOutput($header . $content . $footer);
+        $res = mod_query($dsql);
+        if ($res) {
+            $anz = mysqli_num_rows($res);
+            $content .= "<h3>Daten ($anz Datens&auml;tze)</h3>\n";
+            $content .= "<table class=\"Table\">\n";
+            for ($feld = 0; $feld < count($field); ++$feld) {
+                if (0 == $feld) {
+                    $content .= "<tr class=\"Header\">\n";
+                    for ($i = 0; $i < count($field); ++$i) {
+                        $content .= '<th>'.$field[$i]."</th>\n";
+                    }
+                    $content .= "</tr>\n";
+                }
+            }
+            for ($d = 0; $d < $anz; ++$d) {
+                $row = mysqli_fetch_row($res);
+                $content .= "<tr>\n";
+                for ($i = 0; $i < count($row); ++$i) {
+                    $content .= '<td class="Object">'.(('' != $row[$i]) ? $row[$i] : '&nbsp;')."</td>\n";
+                }
+                $content .= "</tr>\n";
+            }
+        }
+        $content .= '</table>';
+    }
+    CSVOutput($header.$content.$footer);
 }
diff --git a/msd/inc/functions_restore.php b/msd/inc/functions_restore.php
index b852bc21..a6df4cc5 100644
--- a/msd/inc/functions_restore.php
+++ b/msd/inc/functions_restore.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,410 +16,405 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-define('DEBUG',0);
-if (!defined('MSD_VERSION')) die('No direct access.');
+define('DEBUG', 0);
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 function get_sqlbefehl()
 {
-	global $restore,$config,$databases,$lang;
+    global $restore, $config, $databases, $lang;
 
-	//Init
-	$restore['fileEOF']=false;
-	$restore['EOB']=false;
-	$complete_sql='';
-	$sqlparser_status=0;
-	if (!isset($restore['eintraege_ready'])) $restore['eintraege_ready']=0;
+    //Init
+    $restore['fileEOF'] = false;
+    $restore['EOB'] = false;
+    $complete_sql = '';
+    $sqlparser_status = 0;
+    if (!isset($restore['eintraege_ready'])) {
+        $restore['eintraege_ready'] = 0;
+    }
 
-	//Parsen
-	while ($sqlparser_status!=100&&!$restore['fileEOF']&&!$restore['EOB'])
-	{
-		//nächste Zeile lesen
-		$zeile=($restore['compressed']) ? gzgets($restore['filehandle']):fgets($restore['filehandle']);
-		if (DEBUG) echo "<br><br>Zeile: ".htmlspecialchars($zeile);
-		/******************* Setzen des Parserstatus *******************/
-		// herausfinden um was für einen Befehl es sich handelt
-		if ($sqlparser_status==0)
-		{
+    //Parsen
+    while (100 != $sqlparser_status && !$restore['fileEOF'] && !$restore['EOB']) {
+        //nächste Zeile lesen
+        $zeile = ($restore['compressed']) ? gzgets($restore['filehandle']) : fgets($restore['filehandle']);
+        if (DEBUG) {
+            echo '<br><br>Zeile: '.htmlspecialchars($zeile);
+        }
+        /******************* Setzen des Parserstatus *******************/
+        // herausfinden um was für einen Befehl es sich handelt
+        if (0 == $sqlparser_status) {
+            //Vergleichszeile, um nicht bei jedem Vergleich strtoupper ausführen zu müssen
+            $zeile2 = strtoupper(trim($zeile));
+            // pre-built compare strings - so we need the CPU power only once :)
+            $sub9 = substr($zeile2, 0, 9);
+            $sub7 = substr($sub9, 0, 7);
+            $sub6 = substr($sub7, 0, 6);
+            $sub4 = substr($sub6, 0, 4);
+            $sub3 = substr($sub4, 0, 3);
+            $sub2 = substr($sub3, 0, 2);
+            $sub1 = substr($sub2, 0, 1);
 
-			//Vergleichszeile, um nicht bei jedem Vergleich strtoupper ausführen zu müssen
-			$zeile2=strtoupper(trim($zeile));
-			// pre-built compare strings - so we need the CPU power only once :)
-			$sub9=substr($zeile2,0,9);
-			$sub7=substr($sub9,0,7);
-			$sub6=substr($sub7,0,6);
-			$sub4=substr($sub6,0,4);
-			$sub3=substr($sub4,0,3);
-			$sub2=substr($sub3,0,2);
-			$sub1=substr($sub2,0,1);
+            if ('INSERT ' == $sub7) {
+                $sqlparser_status = 3; //Datensatzaktion
+                $restore['actual_table'] = get_tablename($zeile);
+            }
 
-			if ($sub7=='INSERT ')
-			{
-				$sqlparser_status=3; //Datensatzaktion
-				$restore['actual_table']=get_tablename($zeile);
-			}
+            //Einfache Anweisung finden die mit Semikolon beendet werden
+            elseif ('LOCK TA' == $sub7) {
+                $sqlparser_status = 4;
+            } elseif ('COMMIT' == $sub6) {
+                $sqlparser_status = 7;
+            } elseif ('BEGIN' == substr($sub6, 0, 5)) {
+                $sqlparser_status = 7;
+            } elseif ('UNLOCK TA' == $sub9) {
+                $sqlparser_status = 4;
+            } elseif ('SET' == $sub3) {
+                $sqlparser_status = 4;
+            } elseif ('START ' == $sub6) {
+                $sqlparser_status = 4;
+            } elseif ('/*!' == $sub3) {
+                $sqlparser_status = 5;
+            } //MySQL-Condition oder Kommentar
+            elseif ('ALTER TAB' == $sub9) {
+                $sqlparser_status = 4;
+            } // Alter Table
+            elseif ('CREATE TA' == $sub9) {
+                $sqlparser_status = 2;
+            } //Create Table
+            elseif ('CREATE AL' == $sub9) {
+                $sqlparser_status = 2;
+            } //Create View
+            elseif ('CREATE IN' == $sub9) {
+                $sqlparser_status = 4;
+            } //Indexaktion
 
-			//Einfache Anweisung finden die mit Semikolon beendet werden
-			elseif ($sub7=='LOCK TA') $sqlparser_status=4;
-			elseif ($sub6=='COMMIT') $sqlparser_status=7;
-			elseif (substr($sub6,0,5)=='BEGIN') $sqlparser_status=7;
-			elseif ($sub9=='UNLOCK TA') $sqlparser_status=4;
-			elseif ($sub3=='SET') $sqlparser_status=4;
-			elseif ($sub6=='START ') $sqlparser_status=4;
-			elseif ($sub3=='/*!') $sqlparser_status=5; //MySQL-Condition oder Kommentar
-			elseif ($sub9=='ALTER TAB') $sqlparser_status=4; // Alter Table
-			elseif ($sub9=='CREATE TA') $sqlparser_status=2; //Create Table
-			elseif ($sub9=='CREATE AL') $sqlparser_status=2; //Create View
-			elseif ($sub9=='CREATE IN') $sqlparser_status=4; //Indexaktion
+            //Condition?
+            elseif ((5 != $sqlparser_status) && ('/*' == substr($zeile2, 0, 2))) {
+                $sqlparser_status = 6;
+            }
 
+            // Delete actions
+            elseif ('DROP TABL' == $sub9) {
+                $sqlparser_status = 1;
+            } elseif ('DROP VIEW' == $sub9) {
+                $sqlparser_status = 1;
+            }
 
-			//Condition?
-			elseif (($sqlparser_status!=5)&&(substr($zeile2,0,2)=='/*')) $sqlparser_status=6;
+            // Befehle, die nicht ausgeführt werden sollen
+            elseif ('CREATE DA' == $sub9) {
+                $sqlparser_status = 7;
+            } elseif ('DROP DATA ' == $sub9) {
+                $sqlparser_status = 7;
+            } elseif ('USE' == $sub3) {
+                $sqlparser_status = 7;
+            }
 
-			// Delete actions
-			elseif ($sub9=='DROP TABL') $sqlparser_status=1;
-			elseif ($sub9=='DROP VIEW') $sqlparser_status=1;
+            // Am Ende eines MySQLDumper-Backups angelangt?
+            elseif ('-- EOB' == $sub6 || '# EO' == $sub4) {
+                $restore['EOB'] = true;
+                $restore['fileEOF'] = true;
+                $zeile = '';
+                $zeile2 = '';
+                $sqlparser_status = 100;
+            }
 
-			// Befehle, die nicht ausgeführt werden sollen
-			elseif ($sub9=='CREATE DA') $sqlparser_status=7;
-			elseif ($sub9=='DROP DATA ') $sqlparser_status=7;
-			elseif ($sub3=='USE') $sqlparser_status=7;
+            // Kommentar?
+            elseif ('--' == $sub2 || '#' == $sub1) {
+                $zeile = '';
+                $zeile2 = '';
+                $sqlparser_status = 0;
+            }
 
-			// Am Ende eines MySQLDumper-Backups angelangt?
-			elseif ($sub6=='-- EOB'||$sub4=='# EO')
-			{
-				$restore['EOB']=true;
-				$restore['fileEOF']=true;
-				$zeile='';
-				$zeile2='';
-				$sqlparser_status=100;
-			}
+            // Fortsetzung von erweiterten Inserts
+            if (1 == $restore['flag']) {
+                $sqlparser_status = 3;
+            }
 
-			// Kommentar?
-			elseif ($sub2=='--'|| $sub1=='#')
-			{
-				$zeile='';
-				$zeile2='';
-				$sqlparser_status=0;
-			}
+            if ((0 == $sqlparser_status) && (trim($complete_sql) > '') && (-1 == $restore['flag'])) {
+                // Unbekannten Befehl entdeckt
+                v($restore);
+                echo '<br>Sql: '.htmlspecialchars($complete_sql);
+                echo '<br>Erweiterte Inserts: '.$restore['erweiterte_inserts'];
+                exit('<br>'.$lang['L_UNKNOWN_SQLCOMMAND'].': '.$zeile.'<br><br>'.$complete_sql);
+            }
+            /******************* Ende von Setzen des Parserstatus *******************/
+        }
 
-			// Fortsetzung von erweiterten Inserts
-			if ($restore['flag']==1) $sqlparser_status=3;
+        $last_char = substr(rtrim($zeile), -1);
+        // Zeilenumbrüche erhalten - sonst werden Schlüsselwörter zusammengefügt
+        // z.B. 'null' und in der nächsten Zeile 'check' wird zu 'nullcheck'
+        $complete_sql .= $zeile."\n";
 
-			if (($sqlparser_status==0)&&(trim($complete_sql)>'')&&($restore['flag']==-1))
-			{
-				// Unbekannten Befehl entdeckt
-				v($restore);
-				echo "<br>Sql: ".htmlspecialchars($complete_sql);
-				echo "<br>Erweiterte Inserts: ".$restore['erweiterte_inserts'];
-				die('<br>'.$lang['L_UNKNOWN_SQLCOMMAND'].': '.$zeile.'<br><br>'.$complete_sql);
-			}
-		/******************* Ende von Setzen des Parserstatus *******************/
-		}
+        if (3 == $sqlparser_status) {
+            //INSERT
+            if (SQL_Is_Complete($complete_sql)) {
+                $sqlparser_status = 100;
+                $complete_sql = trim($complete_sql);
+                if ('*/' == substr($complete_sql, -2)) {
+                    $complete_sql = remove_comment_at_eol($complete_sql);
+                }
 
-		$last_char=substr(rtrim($zeile),-1);
-		// Zeilenumbrüche erhalten - sonst werden Schlüsselwörter zusammengefügt
-		// z.B. 'null' und in der nächsten Zeile 'check' wird zu 'nullcheck'
-		$complete_sql.=$zeile."\n";
+                // letzter Ausdruck des erweiterten Inserts erreicht?
+                if (');' == substr($complete_sql, -2)) {
+                    $restore['flag'] = -1;
+                }
 
-		if ($sqlparser_status==3)
-		{
-			//INSERT
-			if (SQL_Is_Complete($complete_sql))
-			{
-				$sqlparser_status=100;
-				$complete_sql=trim($complete_sql);
-				if (substr($complete_sql,-2)=='*/')
-				{
-					$complete_sql=remove_comment_at_eol($complete_sql);
-				}
+                // Wenn am Ende der Zeile ein Klammer Komma -> erweiterter Insert-Modus -> Steuerflag setzen
+                elseif ('),' == substr($complete_sql, -2)) {
+                    // letztes Komme gegen Semikolon tauschen
+                    $complete_sql = substr($complete_sql, 0, -1).';';
+                    $restore['erweiterte_inserts'] = 1;
+                    $restore['flag'] = 1;
+                }
 
-				// letzter Ausdruck des erweiterten Inserts erreicht?
-				if (substr($complete_sql,-2)==');')
-				{
-					$restore['flag']=-1;
-				}
+                if ('INSERT ' != substr(strtoupper($complete_sql), 0, 7)) {
+                    // wenn der Syntax aufgrund eines Reloads verloren ging - neu ermitteln
+                    if (!isset($restore['insert_syntax'])) {
+                        $restore['insert_syntax'] = get_insert_syntax($restore['actual_table']);
+                    }
+                    $complete_sql = $restore['insert_syntax'].' VALUES '.$complete_sql.';';
+                } else {
+                    // INSERT Syntax ermitteln und merken
+                    $ipos = strpos(strtoupper($complete_sql), ' VALUES');
+                    if (false === !$ipos) {
+                        $restore['insert_syntax'] = substr($complete_sql, 0, $ipos);
+                    } else {
+                        $restore['insert_syntax'] = 'INSERT INTO `'.$restore['actual_table'].'`';
+                    }
+                }
+            }
+        } elseif (1 == $sqlparser_status) {
+            //Löschaktion
+            if (';' == $last_char) {
+                $sqlparser_status = 100;
+            } //Befehl komplett
+            $restore['actual_table'] = get_tablename($complete_sql);
+        } elseif (2 == $sqlparser_status) {
+            // Createanweisung ist beim Finden eines ; beendet
+            if (';' == $last_char) {
+                if ($config['minspeed'] > 0) {
+                    $restore['anzahl_zeilen'] = $config['minspeed'];
+                }
+                // Soll die Tabelle hergestellt werden?
+                $do_it = true;
+                if (is_array($restore['tables_to_restore'])) {
+                    $do_it = false;
+                    if (in_array($restore['actual_table'], $restore['tables_to_restore'])) {
+                        $do_it = true;
+                    }
+                }
+                if ($do_it) {
+                    $tablename = submit_create_action($complete_sql);
+                    $restore['actual_table'] = $tablename;
+                    ++$restore['table_ready'];
+                }
+                // Zeile verwerfen, da CREATE jetzt bereits ausgefuehrt wurde und naechsten Befehl suchen
+                $complete_sql = '';
+                $sqlparser_status = 0;
+            }
+        }
 
-				// Wenn am Ende der Zeile ein Klammer Komma -> erweiterter Insert-Modus -> Steuerflag setzen
-				else
-					if (substr($complete_sql,-2)=='),')
-					{
-						// letztes Komme gegen Semikolon tauschen
-						$complete_sql=substr($complete_sql,0,-1).';';
-						$restore['erweiterte_inserts']=1;
-						$restore['flag']=1;
-					}
+        // Index
+                elseif (4 == $sqlparser_status) { //Createindex
+                        if (';' == $last_char) {
+                            if ($config['minspeed'] > 0) {
+                                $restore['anzahl_zeilen'] = $config['minspeed'];
+                            }
+                            $complete_sql = del_inline_comments($complete_sql);
+                            $sqlparser_status = 100;
+                        }
+                }
 
-				if (substr(strtoupper($complete_sql),0,7)!='INSERT ')
-				{
-					// wenn der Syntax aufgrund eines Reloads verloren ging - neu ermitteln
-					if (!isset($restore['insert_syntax'])) $restore['insert_syntax']=get_insert_syntax($restore['actual_table']);
-					$complete_sql=$restore['insert_syntax'].' VALUES '.$complete_sql.';';
-				}
-				else
-				{
-					// INSERT Syntax ermitteln und merken
-					$ipos=strpos(strtoupper($complete_sql),' VALUES');
-					if (!$ipos===false) $restore['insert_syntax']=substr($complete_sql,0,$ipos);
-					else
-						$restore['insert_syntax']='INSERT INTO `'.$restore['actual_table'].'`';
-				}
-			}
-		}
+        // Kommentar oder Condition
+                    elseif (5 == $sqlparser_status) { //Anweisung
+                            $t = strrpos($zeile, '*/;');
+                        if (false === !$t) {
+                            $restore['anzahl_zeilen'] = $config['minspeed'];
+                            $sqlparser_status = 100;
+                            if ($config['ignore_enable_keys'] &&
+                                    false !== strrpos($zeile, 'ENABLE KEYS ')) {
+                                $sqlparser_status = 100;
+                                $complete_sql = '';
+                            }
+                        }
+                    }
 
-		else
-			if ($sqlparser_status==1)
-			{
-				//Löschaktion
-				if ($last_char==';') $sqlparser_status=100; //Befehl komplett
-				$restore['actual_table']=get_tablename($complete_sql);
-			}
+        // Mehrzeiliger oder Inline-Kommentar
+        elseif (6 == $sqlparser_status) {
+            $t = strrpos($zeile, '*/');
+            if (false === !$t) {
+                $complete_sql = '';
+                $sqlparser_status = 0;
+            }
+        }
 
-			else
-				if ($sqlparser_status==2)
-				{
-					// Createanweisung ist beim Finden eines ; beendet
-					if ($last_char==';')
-					{
-						if ($config['minspeed']>0) $restore['anzahl_zeilen']=$config['minspeed'];
-						// Soll die Tabelle hergestellt werden?
-						$do_it=true;
-						if (is_array($restore['tables_to_restore']))
-						{
-							$do_it=false;
-							if (in_array($restore['actual_table'],$restore['tables_to_restore']))
-							{
-								$do_it=true;
-							}
-						}
-						if ($do_it)
-						{
-							$tablename=submit_create_action($complete_sql);
-							$restore['actual_table']=$tablename;
-							$restore['table_ready']++;
-						}
-						// Zeile verwerfen, da CREATE jetzt bereits ausgefuehrt wurde und naechsten Befehl suchen
-						$complete_sql='';
-						$sqlparser_status=0;
-					}
-				}
+        // Befehle, die verworfen werden sollen
+                            elseif (7 == $sqlparser_status) { //Anweisung
+                                    if (';' == $last_char) {
+                                        if ($config['minspeed'] > 0) {
+                                            $restore['anzahl_zeilen'] = $config['minspeed'];
+                                        }
+                                        $complete_sql = '';
+                                        $sqlparser_status = 0;
+                                    }
+                            }
 
-				// Index
-				else
-					if ($sqlparser_status==4)
-					{ //Createindex
-						if ($last_char==';')
-						{
-							if ($config['minspeed']>0)
-							{
-								$restore['anzahl_zeilen']=$config['minspeed'];
-							}
-							$complete_sql=del_inline_comments($complete_sql);
-							$sqlparser_status=100;
-						}
-					}
-
-					// Kommentar oder Condition
-					else
-						if ($sqlparser_status==5)
-						{ //Anweisung
-							$t=strrpos($zeile,'*/;');
-							if (!$t===false)
-							{
-								$restore['anzahl_zeilen']=$config['minspeed'];
-								$sqlparser_status=100;
-								if ($config['ignore_enable_keys'] &&
-								    strrpos($zeile, 'ENABLE KEYS ') !== false)
-								{
-                                    $sqlparser_status=100;
-								    $complete_sql = '';
-								}
-							}
-						}
-
-						// Mehrzeiliger oder Inline-Kommentar
-						else
-							if ($sqlparser_status==6)
-							{
-								$t=strrpos($zeile,'*/');
-								if (!$t===false)
-								{
-									$complete_sql='';
-									$sqlparser_status=0;
-								}
-							}
-
-							// Befehle, die verworfen werden sollen
-							else
-								if ($sqlparser_status==7)
-								{ //Anweisung
-									if ($last_char==';')
-									{
-										if ($config['minspeed']>0)
-										{
-											$restore['anzahl_zeilen']=$config['minspeed'];
-										}
-										$complete_sql='';
-										$sqlparser_status=0;
-									}
-								}
-
-		if (($restore['compressed'])&&(gzeof($restore['filehandle']))) $restore['fileEOF']=true;
-		if ((!$restore['compressed'])&&(feof($restore['filehandle']))) $restore['fileEOF']=true;
-	}
-	// wenn bestimmte Tabellen wiederhergestellt werden sollen -> pruefen
-	if (is_array($restore['tables_to_restore'])&&!(in_array($restore['actual_table'],$restore['tables_to_restore'])))
-	{
-		$complete_sql='';
-	}
-	return trim($complete_sql);
+        if (($restore['compressed']) && (gzeof($restore['filehandle']))) {
+            $restore['fileEOF'] = true;
+        }
+        if ((!$restore['compressed']) && (feof($restore['filehandle']))) {
+            $restore['fileEOF'] = true;
+        }
+    }
+    // wenn bestimmte Tabellen wiederhergestellt werden sollen -> pruefen
+    if (is_array($restore['tables_to_restore']) && !(in_array($restore['actual_table'], $restore['tables_to_restore']))) {
+        $complete_sql = '';
+    }
+    return trim($complete_sql);
 }
 
 function submit_create_action($sql)
 {
-	global $config;
+    global $config;
 
-	//executes a create command
-	$tablename=get_tablename($sql);
-	if (strtoupper(substr($sql,0,16))=='CREATE ALGORITHM')
-	{
-		// It`s a VIEW. We need to substitute the original DEFINER with the actual MySQL-User
-		$parts=explode(' ',$sql);
-		for ($i=0,$count=sizeof($parts);$i<$count;$i++)
-		{
-			if (strtoupper(substr($parts[$i],0,8))=='DEFINER=')
-			{
-				$parts[$i]='DEFINER=`'.$config['dbuser'].'`@`'.$config['dbhost'].'`';
-				$sql=implode(' ',$parts);
-				$i=$count;
-			}
-		}
-	}
+    //executes a create command
+    $tablename = get_tablename($sql);
+    if ('CREATE ALGORITHM' == strtoupper(substr($sql, 0, 16))) {
+        // It`s a VIEW. We need to substitute the original DEFINER with the actual MySQL-User
+        $parts = explode(' ', $sql);
+        for ($i = 0, $count = sizeof($parts); $i < $count; ++$i) {
+            if ('DEFINER=' == strtoupper(substr($parts[$i], 0, 8))) {
+                $parts[$i] = 'DEFINER=`'.$config['dbuser'].'`@`'.$config['dbhost'].'`';
+                $sql = implode(' ', $parts);
+                $i = $count;
+            }
+        }
+    }
 
-	$res=@mysqli_query($config['dbconnection'], $sql);
-	if ($res===false)
-	{
-		// erster Versuch fehlgeschlagen -> zweiter Versuch - vielleicht versteht der Server die Inline-Kommentare nicht?
-		$sql=del_inline_comments($sql);
-		$res=@mysqli_query($config['dbconnection'],  downgrade($sql));
-		if ($res===false)
-		{
-			// wieder nichts. Ok, haben wir hier einen alten MySQL-Server 3.x oder 4.0.x?
-			// versuchen wir es mal mit der alten Syntax
-			$res=@mysqli_query($config['dbconnection'], downgrade($sql));
-		}
-	}
-	if ($res===false)
-	{
-		// wenn wir hier angekommen sind hat nichts geklappt -> Fehler ausgeben und abbrechen
-		SQLError($sql,mysqli_error($config['dbconnection']));
-		die("<br>Fatal error: Couldn't create table or view `".$tablename."´");
-	}
-	return $tablename;
+    $res = mysqli_query($config['dbconnection'], $sql);
+    if (false === $res) {
+        // erster Versuch fehlgeschlagen -> zweiter Versuch - vielleicht versteht der Server die Inline-Kommentare nicht?
+        $sql = del_inline_comments($sql);
+        $res = mysqli_query($config['dbconnection'], downgrade($sql));
+    }
+    if (false === $res) {
+        // wenn wir hier angekommen sind hat nichts geklappt -> Fehler ausgeben und abbrechen
+        SQLError($sql, mysqli_error($config['dbconnection']));
+        exit("<br>Fatal error: Couldn't create table or view `".$tablename.'´');
+    }
+    return $tablename;
 }
 
 function get_insert_syntax($table)
 {
-	global $config;
+    global $config;
 
-	$insert='';
-	$sql='SHOW COLUMNS FROM `'.$table.'`';
-	$res=mysqli_query($config['dbconnection'], $sql);
-	if ($res)
-	{
-		$insert='INSERT INTO `'.$table.'` (';
-		while ($row=mysqli_fetch_object($res))
-		{
-			$insert.='`'.$row->Field.'`,';
-		}
-		$insert=substr($insert,0,strlen($insert)-1).') ';
-	}
-	else
-	{
-		global $restore;
-		v($restore);
-		SQLError($sql,mysqli_error($config['dbconnection']));
-	}
-	return $insert;
+    $insert = '';
+    $sql = 'SHOW COLUMNS FROM `'.$table.'`';
+    $res = mysqli_query($config['dbconnection'], $sql);
+    if ($res) {
+        $insert = 'INSERT INTO `'.$table.'` (';
+        while ($row = mysqli_fetch_object($res)) {
+            $insert .= '`'.$row->Field.'`,';
+        }
+        $insert = substr($insert, 0, strlen($insert) - 1).') ';
+    } else {
+        global $restore;
+        v($restore);
+        SQLError($sql, mysqli_error($config['dbconnection']));
+    }
+    return $insert;
 }
 
 function del_inline_comments($sql)
 {
-	//$sql=str_replace("\n",'<br>',$sql);
-	$array=array();
-	preg_match_all("/(\/\*(.+)\*\/)/U",$sql,$array);
-	if (is_array($array[0]))
-	{
-		$sql=str_replace($array[0],'',$sql);
-		if (DEBUG) echo "Nachher: :<br>".$sql."<br><hr>";
-	}
-	//$sql=trim(str_replace('<br>',"\n",$sql));
-	//Wenn nach dem Entfernen nur noch ein ; übrigbleibt -> entfernen
-	if ($sql==';') $sql='';
-	return $sql;
+    //$sql=str_replace("\n",'<br>', $sql);
+    $array = [];
+    preg_match_all("/(\/\*(.+)\*\/)/U", $sql, $array);
+    if (is_array($array[0])) {
+        $sql = str_replace($array[0], '', $sql);
+        if (DEBUG) {
+            echo 'Nachher: :<br>'.$sql.'<br><hr>';
+        }
+    }
+    //$sql=trim(str_replace('<br>',"\n", $sql));
+    //Wenn nach dem Entfernen nur noch ein ; übrigbleibt -> entfernen
+    if (';' == $sql) {
+        $sql = '';
+    }
+    return $sql;
 }
 
 // extrahiert auf einfache Art den Tabellennamen aus dem "Create",Drop"-Befehl
 function get_tablename($t)
 {
-	// alle Schluesselbegriffe entfernen, bis der Tabellenname am Anfang steht
-	$t=substr($t,0,150); // verkuerzen, um Speicher zu sparen - wir brauchenhier nur den Tabellennamen
-	$t=str_ireplace('DROP TABLE','',$t);
-	$t=str_ireplace('DROP VIEW','',$t);
-	$t=str_ireplace('CREATE TABLE','',$t);
-	$t=str_ireplace('INSERT INTO','',$t);
-	$t=str_ireplace('REPLACE INTO','',$t);
-	$t=str_ireplace('IF NOT EXISTS','',$t);
-	$t=str_ireplace('IF EXISTS','',$t);
-	if (substr(strtoupper($t),0,16)=='CREATE ALGORITHM')
-	{
-		$pos=strpos($t,'DEFINER VIEW ');
-		$t=substr($t,$pos,strlen($t)-$pos);
-	}
-	$t=str_ireplace(';',' ;',$t); // tricky -> insert space as delimiter
-	$t=trim($t);
+    // alle Schluesselbegriffe entfernen, bis der Tabellenname am Anfang steht
+    $t = substr($t, 0, 150); // verkuerzen, um Speicher zu sparen - wir brauchenhier nur den Tabellennamen
+    $t = str_ireplace('DROP TABLE', '', $t);
+    $t = str_ireplace('DROP VIEW', '', $t);
+    $t = str_ireplace('CREATE TABLE', '', $t);
+    $t = str_ireplace('INSERT INTO', '', $t);
+    $t = str_ireplace('REPLACE INTO', '', $t);
+    $t = str_ireplace('IF NOT EXISTS', '', $t);
+    $t = str_ireplace('IF EXISTS', '', $t);
+    if ('CREATE ALGORITHM' == substr(strtoupper($t), 0, 16)) {
+        $pos = strpos($t, 'DEFINER VIEW ');
+        $t = substr($t, $pos, strlen($t) - $pos);
+    }
+    $t = str_ireplace(';', ' ;', $t); // tricky -> insert space as delimiter
+    $t = trim($t);
 
-	// jetzt einfach nach dem ersten Leerzeichen suchen
-	$delimiter=substr($t,0,1);
-	if ($delimiter!='`') $delimiter=' ';
-	$found=false;
-	$position=1;
-	while (!$found)
-	{
-		if (substr($t,$position,1)==$delimiter) $found=true;
-		if ($position>=strlen($t)) $found=true;
-		$position++;
-	}
-	$t=substr($t,0,$position);
-	$t=trim(str_replace('`','',$t));
-	return $t;
+    // jetzt einfach nach dem ersten Leerzeichen suchen
+    $delimiter = substr($t, 0, 1);
+    if ('`' != $delimiter) {
+        $delimiter = ' ';
+    }
+    $found = false;
+    $position = 1;
+    while (!$found) {
+        if (substr($t, $position, 1) == $delimiter) {
+            $found = true;
+        }
+        if ($position >= strlen($t)) {
+            $found = true;
+        }
+        ++$position;
+    }
+    $t = substr($t, 0, $position);
+    $t = trim(str_replace('`', '', $t));
+    return $t;
 }
 
 // decide if an INSERT-Command is complete - simply count quotes and look for ); at the end of line
 function SQL_Is_Complete($string)
 {
-	$string=str_replace('\\\\','',trim($string)); // trim and remove escaped backslashes
-	$string=trim($string);
-	$quotes=substr_count($string,'\'');
-	$escaped_quotes=substr_count($string,'\\\'');
-	if (($quotes-$escaped_quotes)%2==0)
-	{
-		$compare=substr($string,-2);
-		if ($compare=='*/') $compare=substr(trim(remove_comment_at_eol($string)),-2);
-		if ($compare==');') return true;
-		if ($compare=='),') return true;
-	}
-	return false;
+    $string = str_replace('\\\\', '', trim($string)); // trim and remove escaped backslashes
+    $string = trim($string);
+    $quotes = substr_count($string, '\'');
+    $escaped_quotes = substr_count($string, '\\\'');
+    if (($quotes - $escaped_quotes) % 2 == 0) {
+        $compare = substr($string, -2);
+        if ('*/' == $compare) {
+            $compare = substr(trim(remove_comment_at_eol($string)), -2);
+        }
+        if (');' == $compare) {
+            return true;
+        }
+        if ('),' == $compare) {
+            return true;
+        }
+    }
+    return false;
 }
 
 function remove_comment_at_eol($string)
 {
-	// check for Inline-Comments at the end of the line
-	if (substr(trim($string),-2)=='*/')
-	{
-		$pos=strrpos($string,'/*');
-		if ($pos>0)
-		{
-			$string=trim(substr($string,0,$pos));
-		}
-	}
-	return $string;
+    // check for Inline-Comments at the end of the line
+    if ('*/' == substr(trim($string), -2)) {
+        $pos = strrpos($string, '/*');
+        if ($pos > 0) {
+            $string = trim(substr($string, 0, $pos));
+        }
+    }
+    return $string;
 }
diff --git a/msd/inc/functions_sql.php b/msd/inc/functions_sql.php
index 1233b896..d83364f2 100644
--- a/msd/inc/functions_sql.php
+++ b/msd/inc/functions_sql.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2017 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,1078 +16,1107 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 
 //SQL-Library laden
-include ( './inc/sqllib.php' );
+include './inc/sqllib.php';
 
-if (!isset($config['sql_limit'])) $config['sql_limit']=30;
-if (!isset($config['bb_width'])) $config['bb_width']=300;
-if (!isset($config['bb_textcolor'])) $config['bb_textcolor']="#990033";
+if (!isset($config['sql_limit'])) {
+    $config['sql_limit'] = 30;
+}
+if (!isset($config['bb_width'])) {
+    $config['bb_width'] = 300;
+}
+if (!isset($config['bb_textcolor'])) {
+    $config['bb_textcolor'] = '#990033';
+}
 
 function ReadSQL()
 {
-	global $SQL_ARRAY,$config;
-	$sf=$config['paths']['config'] . 'sql_statements';
-	if (!is_file($sf))
-	{
-		$fp=fopen($sf,"w+");
-		fclose($fp);
-		@chmod($sf,0777);
-	}
-	if (count($SQL_ARRAY) == 0 && filesize($sf) > 0)
-	{
-		$SQL_ARRAY=file($sf);
-	}
+    global $SQL_ARRAY, $config;
+    $sf = $config['paths']['config'].'sql_statements';
+    if (!is_file($sf)) {
+        $fp = fopen($sf, 'w+');
+        fclose($fp);
+        @chmod($sf, 0777);
+    }
+
+    if ((is_array($SQL_ARRAY) && 0 == count($SQL_ARRAY)) && filesize($sf) > 0) {
+        $SQL_ARRAY = file($sf);
+    }
 }
 
 function WriteSQL()
 {
-	global $SQL_ARRAY,$config;
-	$sf=$config['paths']['config'] . 'sql_statements';
-	$str="";
-	for ($i=0; $i < count($SQL_ARRAY); $i++)
-	{
-		$str.=$SQL_ARRAY[$i];
-		if (substr($str,-1) != "\n" && $i != ( count($SQL_ARRAY) - 1 )) $str.="\n";
-
-	}
-	if ($config['magic_quotes_gpc']) $str=stripslashes($str);
-	$fp=fopen($sf,"wb");
-	fwrite($fp,$str);
-	fclose($fp);
+    global $SQL_ARRAY, $config;
+    $sf = $config['paths']['config'].'sql_statements';
+    $str = '';
+    for ($i = 0; $i < count($SQL_ARRAY); ++$i) {
+        $str .= $SQL_ARRAY[$i];
+        if ("\n" != substr($str, -1) && $i != (count($SQL_ARRAY) - 1)) {
+            $str .= "\n";
+        }
+    }
 
+    $fp = fopen($sf, 'wb');
+    fwrite($fp, $str);
+    fclose($fp);
 }
 
 function SQL_Name($index)
 {
-	global $SQL_ARRAY;
-	$s=explode('|',$SQL_ARRAY[$index]);
-	return $s[0];
+    global $SQL_ARRAY;
+    $s = explode('|', $SQL_ARRAY[$index]);
+    return $s[0];
 }
 
 function SQL_String($index)
 {
-	global $SQL_ARRAY;
-	if (isset($SQL_ARRAY[$index]) && !empty($SQL_ARRAY[$index]))
-	{
-		$s=explode('|',$SQL_ARRAY[$index],2);
-		return ( isset($s[1]) ) ? $s[1] : '';
-	}
+    global $SQL_ARRAY;
+    if (isset($SQL_ARRAY[$index]) && !empty($SQL_ARRAY[$index])) {
+        $s = explode('|', $SQL_ARRAY[$index], 2);
+        return (isset($s[1])) ? $s[1] : '';
+    }
 }
 
 function SQL_ComboBox()
 {
-	global $SQL_ARRAY,$tablename,$nl;
-	$s='';
-	if (count($SQL_ARRAY) > 0)
-	{
-		$s=$nl . $nl . '<select class="SQLCombo" name="sqlcombo" onchange="this.form.sqltextarea.value=this.options[this.selectedIndex].value;">' . $nl;
-		$s.='<option value="" selected>---</option>' . $nl;
-		for ($i=0; $i < count($SQL_ARRAY); $i++)
-		{
-			$s.='<option value="' . htmlspecialchars(stripslashes(SQL_String($i))) . '">' . SQL_Name($i) . '</option>' . $nl;
-		}
-		$s.='</select>' . $nl . $nl;
-	}
-	return $s;
+    global $SQL_ARRAY, $tablename, $nl;
+    $s = '';
+    if (is_array($SQL_ARRAY) && count($SQL_ARRAY) > 0) {
+        $s = $nl.$nl.'<select class="SQLCombo" name="sqlcombo" onchange="this.form.sqltextarea.value=this.options[this.selectedIndex].value;">'.$nl;
+        $s .= '<option value="" selected>---</option>'.$nl;
+        for ($i = 0; $i < count($SQL_ARRAY); ++$i) {
+            $s .= '<option value="'.htmlspecialchars(stripslashes(SQL_String($i))).'">'.SQL_Name($i).'</option>'.$nl;
+        }
+        $s .= '</select>'.$nl.$nl;
+    }
+    return $s;
 }
 
 function Table_ComboBox()
 {
-	global $db,$config,$lang,$nl;
-	$tabellen=mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `' . $db . '`');
-	$num_tables = 0;
-	if (is_resource($tabellen)) {
-    	$num_tables=mysqli_num_rows($tabellen);
-	}
-	$s=$nl . $nl . '<select class="SQLCombo" name="tablecombo" onchange="this.form.sqltextarea.value=this.options[this.selectedIndex].value;this.form.execsql.click();">' . $nl . '<option value="" selected> ---  </option>' . $nl;
-	for ($i=0; $i < $num_tables; $i++)
-	{
-		$t=mysqli_fetch_row($tabellen);
-		$s.='<option value="SELECT * FROM `' . $db . '`.`' . $t[0] . '`">' . $lang['L_TABLE'] . ' `' . $t[0] . '`</option>' . $nl;
-	}
-	$s.='</select>' . $nl . $nl;
-	return $s;
+    global $db, $config, $lang, $nl;
+    $tabellen = mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `'.$db.'`');
+    $num_tables = 0;
+    if (is_resource($tabellen)) {
+        $num_tables = mysqli_num_rows($tabellen);
+    }
+    $s = $nl.$nl.'<select class="SQLCombo" name="tablecombo" onchange="this.form.sqltextarea.value=this.options[this.selectedIndex].value;this.form.execsql.click();">'.$nl.'<option value="" selected> ---  </option>'.$nl;
+    for ($i = 0; $i < $num_tables; ++$i) {
+        $t = mysqli_fetch_row($tabellen);
+        $s .= '<option value="SELECT * FROM `'.$db.'`.`'.$t[0].'`">'.$lang['L_TABLE'].' `'.$t[0].'`</option>'.$nl;
+    }
+    $s .= '</select>'.$nl.$nl;
+    return $s;
 }
 
-function TableComboBox($default='')
+function TableComboBox($default = '')
 {
-	global $db,$config,$lang,$nl;
+    global $db, $config, $lang, $nl;
 
-	$sql="SHOW TABLES FROM $db";
-	$tabellen=MSD_query($sql);
-	$s='<option value="" ' . ( ( $default == '' ) ? ' selected="selected"' : '' ) . '>                 </option>' . $nl;
-	while ($row = mysqli_fetch_row($tabellen))
-	{
-		$t= $row[0];
-		$s.='<option value="`' . $t . '`"' . ( ( $default == '`' . $t . '`' ) ? ' selected="selected"' : '' ) . '>`' . $t . '`</option>' . $nl;
-	}
-	return $s;
+    $sql = "SHOW TABLES FROM $db";
+    $tabellen = mod_query($sql);
+    $s = '<option value="" '.(('' == $default) ? ' selected="selected"' : '').'>                 </option>'.$nl;
+    while ($row = mysqli_fetch_row($tabellen)) {
+        $t = $row[0];
+        $s .= '<option value="`'.$t.'`"'.(($default == '`'.$t.'`') ? ' selected="selected"' : '').'>`'.$t.'`</option>'.$nl;
+    }
+    return $s;
 }
 
 function DB_Exists($db)
 {
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$erg=false;
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $erg = false;
 
-	$dbs=MSD_query("SHOW DATABASES");
-	while ($row=mysqli_fetch_assoc($dbs))
-	{
-		if (strtolower($row['Database']) == strtolower($db))
-		{
-			$erg=true;
-			break;
-		}
-	}
-	return $erg;
+    $dbs = mod_query('SHOW DATABASES');
+    while ($row = mysqli_fetch_assoc($dbs)) {
+        if (strtolower($row['Database']) == strtolower($db)) {
+            $erg = true;
+            break;
+        }
+    }
+    return $erg;
 }
 
 function Table_Exists($db, $table)
 {
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$sqlt="SHOW TABLES FROM `$db`";
-	$res=MSD_query($sqlt);
-	if ($res)
-	{
-		$tables=array();
-		while ($row=mysqli_fetch_row($res))
-		{
-			$tables[]=$row[0];
-		}
-		if (in_array($table,$tables)) return true;
-	}
-	return false;
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $sqlt = "SHOW TABLES FROM `$db`";
+    $res = mod_query($sqlt);
+    if ($res) {
+        $tables = [];
+        while ($row = mysqli_fetch_row($res)) {
+            $tables[] = $row[0];
+        }
+        if (in_array($table, $tables)) {
+            return true;
+        }
+    }
+    return false;
 }
 
 function DB_Empty($dbn)
 {
-	$r="DROP DATABASE `$dbn`;\nCREATE DATABASE `$dbn`;";
-	return MSD_DoSQL($r);
-
+    $r = "DROP DATABASE `$dbn`;\nCREATE DATABASE `$dbn`;";
+    return MOD_DoSQL($r);
 }
 
 function sqlReturnsRecords($sql)
 {
-	global $mysql_SQLhasRecords;
-	$s=explode(' ',$sql);
-	return in_array(strtoupper($s[0]),$mysql_SQLhasRecords) ? 1 : 0;
+    global $mysql_SQLhasRecords;
+    $s = explode(' ', $sql);
+    return in_array(strtoupper($s[0]), $mysql_SQLhasRecords) ? 1 : 0;
 }
 
 function getCountSQLStatements($sql)
 {
-	$z=0;
-	$l=strlen($sql);
-	$inQuotes=false;
-	for ($i=0; $i < $l; $i++)
-	{
-		if ($sql[$i] == "'" || $sql[$i] == '"') $inQuotes=!$inQuotes;
-		if (( $sql[$i] == ';' && $inQuotes == false ) || $i == $l - 1) $z++;
-	}
-	return $z;
+    $z = 0;
+    $l = strlen($sql);
+    $inQuotes = false;
+    for ($i = 0; $i < $l; ++$i) {
+        if ("'" == $sql[$i] || '"' == $sql[$i]) {
+            $inQuotes = !$inQuotes;
+        }
+        if ((';' == $sql[$i] && false == $inQuotes) || $i == $l - 1) {
+            ++$z;
+        }
+    }
+    return $z;
 }
 
 function splitSQLStatements2Array($sql)
 {
-	$z=0;
-	$sqlArr=array();
-	$tmp='';
-	$sql=str_replace("\n",'',$sql);
-	$l=strlen($sql);
-	$inQuotes=false;
-	for ($i=0; $i < $l; $i++)
-	{
-		$tmp.=$sql[$i];
-		if ($sql[$i] == "'" || $sql[$i] == '"') $inQuotes=!$inQuotes;
-		if ($sql[$i] == ';' && $inQuotes == false)
-		{
-			$z++;
-			$sqlArr[]=$tmp;
-			$tmp='';
-		}
-	}
-	if (trim($tmp) != '') $sqlArr[]=$tmp;
-	return $sqlArr;
+    $z = 0;
+    $sqlArr = [];
+    $tmp = '';
+    $sql = str_replace("\n", '', $sql);
+    $l = strlen($sql);
+    $inQuotes = false;
+    for ($i = 0; $i < $l; ++$i) {
+        $tmp .= $sql[$i];
+        if ("'" == $sql[$i] || '"' == $sql[$i]) {
+            $inQuotes = !$inQuotes;
+        }
+        if (';' == $sql[$i] && false == $inQuotes) {
+            ++$z;
+            $sqlArr[] = $tmp;
+            $tmp = '';
+        }
+    }
+    if ('' != trim($tmp)) {
+        $sqlArr[] = $tmp;
+    }
+    return $sqlArr;
 }
 
-function DB_Copy($source, $destination, $drop_source=0, $insert_data=1)
+function DB_Copy($source, $destination, $drop_source = 0, $insert_data = 1)
 {
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$SQL_Array=$t="";
-    if (!DB_Exists($destination))
-    {
-        $res = MSD_DoSQL("CREATE DATABASE `$destination`;");
-        if (!$res)
-        {
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $SQL_Array = $t = '';
+    if (!DB_Exists($destination)) {
+        $res = MOD_DoSQL("CREATE DATABASE `$destination`;");
+        if (!$res) {
             return false;
         }
     }
-	$SQL_Array.="USE `$destination` ;\n";
-	$sql="SHOW TABLES FROM $source";
-	$tabellen=MSD_query($sql);
-	while ($row = mysqli_fetch_row($tabellen))
-	{
-
-		$table=strtolower($row[0]);
-		$table.='xxxxxxxxxxxxxxxxralf';
-		$sqlt="SHOW CREATE TABLE `$source`.`$table`";
-		$res=MSD_query($sqlt);
-		if ($res)
-        {
-            $row=mysqli_fetch_row($res);
-            $c=$row[1];
-            if (substr($c,-1) == ";") $c=substr($c,0,strlen($c) - 1);
-            $SQL_Array.=( $insert_data == 1 ) ? "$c SELECT * FROM `$source`.`$table` ;\n" : "$c ;\n";
-        }
-        else
-        {
+    $SQL_Array .= "USE `$destination` ;\n";
+    $sql = "SHOW TABLES FROM $source";
+    $tabellen = mod_query($sql);
+    while ($row = mysqli_fetch_row($tabellen)) {
+        $table = strtolower($row[0]);
+        $sqlt = "SHOW CREATE TABLE `$source`.`$table`";
+        $res = mod_query($sqlt);
+        if ($res) {
+            $row = mysqli_fetch_row($res);
+            $c = $row[1];
+            if (';' == substr($c, -1)) {
+                $c = substr($c, 0, strlen($c) - 1);
+            }
+            $SQL_Array .= (1 == $insert_data) ? "$c SELECT * FROM `$source`.`$table` ;\n" : "$c ;\n";
+        } else {
             return false;
         }
-	}
+    }
     mysqli_select_db($config['dbconnection'], $destination);
-    $res=MSD_DoSQL($SQL_Array);
-    if ($drop_source == 1 && $res) MSD_query("DROP DATABASE `$source`;");
+    $res = MOD_DoSQL($SQL_Array);
+    if (1 == $drop_source && $res) {
+        mod_query("DROP DATABASE `$source`;");
+    }
     return $res;
 }
 
-function Table_Copy($source, $destination, $insert_data, $destinationdb="")
+function Table_Copy($source, $destination, $insert_data, $destinationdb = '')
 {
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$SQL_Array=$t="";
-	$sqlc="SHOW CREATE TABLE $source";
-	$res=MSD_query($sqlc);
-	$row=mysqli_fetch_row($res);
-	$c=$row[1];
-	$a1=strpos($c,"`");
-	$a2=strpos($c,"`",$a1 + 1);
-	$c=substr($c,0,$a1 + 1) . $destination . substr($c,$a2);
-	if (substr($c,-1) == ";") $c=substr($c,0,strlen($c) - 1);
-	$SQL_Array.=( $insert_data == 1 ) ? "$c SELECT * FROM $source ;\n" : "$c ;\n";
-	//echo "<h5>$SQL_Array</h5>";
-	MSD_DoSQL($SQL_Array);
-
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $SQL_Array = $t = '';
+    $sqlc = "SHOW CREATE TABLE $source";
+    $res = mod_query($sqlc);
+    $row = mysqli_fetch_row($res);
+    $c = $row[1];
+    $a1 = strpos($c, '`');
+    $a2 = strpos($c, '`', $a1 + 1);
+    $c = substr($c, 0, $a1 + 1).$destination.substr($c, $a2);
+    if (';' == substr($c, -1)) {
+        $c = substr($c, 0, strlen($c) - 1);
+    }
+    $SQL_Array .= (1 == $insert_data) ? "$c SELECT * FROM $source ;\n" : "$c ;\n";
+    //echo "<h5>$SQL_Array</h5>";
+    MOD_DoSQL($SQL_Array);
 }
 
-function MSD_DoSQL($sqlcommands, $limit="")
+function MOD_DoSQL($sqlcommands, $limit = '')
 {
-	global $config,$out,$numrowsabs,$numrows,$num_befehle,$time_used,$sql;
+    global $config, $out, $numrowsabs, $numrows, $num_befehle, $time_used, $sql;
 
-	if (!isset($sql['parser']['sql_commands'])) $sql['parser']['sql_commands']=0;
-	if (!isset($sql['parser']['sql_errors'])) $sql['parser']['sql_errors']=0;
+    if (!isset($sql['parser']['sql_commands'])) {
+        $sql['parser']['sql_commands'] = 0;
+    }
+    if (!isset($sql['parser']['sql_errors'])) {
+        $sql['parser']['sql_errors'] = 0;
+    }
 
-	$sql['parser']['time_used']=getmicrotime();
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$out=$sqlcommand='';
-	$allSQL=splitSQLStatements2Array($sqlcommands); #explode(';',preg_replace('/\r\n|\n/', '', $sqlcommands));
-	$sql_queries=count($allSQL);
+    $sql['parser']['time_used'] = getmicrotime();
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $out = $sqlcommand = '';
+    $allSQL = splitSQLStatements2Array($sqlcommands); //explode(';',preg_replace('/\r\n|\n/', '', $sqlcommands));
+    $sql_queries = count($allSQL);
 
-	if (!isset($allSQL[$sql_queries - 1])) $sql_queries--;
-	if ($sql_queries == 1)
-	{
-		SQLParser($allSQL[0]);
-		$sql['parser']['sql_commands']++;
-		$out.=Stringformat(( $sql['parser']['sql_commands'] ),4) . ': ' . $allSQL[0] . "\n";
-		$result=MSD_query($allSQL[0]);
-	}
-	else
-	{
-	    $result = true;
-		for ($i=0; $i < $sql_queries; $i++)
-		{
-			$allSQL[$i]=trim(rtrim($allSQL[$i]));
+    if (!isset($allSQL[$sql_queries - 1])) {
+        --$sql_queries;
+    }
+    if (1 == $sql_queries) {
+        SQLParser($allSQL[0]);
+        ++$sql['parser']['sql_commands'];
+        $out .= Stringformat(($sql['parser']['sql_commands']), 4).': '.$allSQL[0]."\n";
+        $result = mod_query($allSQL[0]);
+    } else {
+        $result = true;
+        for ($i = 0; $i < $sql_queries; ++$i) {
+            $allSQL[$i] = trim(rtrim($allSQL[$i]));
 
-			if ($allSQL[$i] != "")
-			{
-				$sqlcommand.=$allSQL[$i];
-				$sqlcommand=SQLParser($sqlcommand);
-				if ($sql['parser']['start'] == 0 && $sql['parser']['end'] == 0 && $sqlcommand != '')
-				{
-					//sql complete
-					$sql['parser']['sql_commands']++;
-					$out.=Stringformat(( $sql['parser']['sql_commands'] ),4) . ': ' . $sqlcommand . "\n";
-					$result=$result && MSD_query($sqlcommand);
-					$sqlcommand="";
-				}
-			}
-		}
-	}
-	$sql['parser']['time_used']=getmicrotime() - $sql['parser']['time_used'];
-	return $result;
+            if ('' != $allSQL[$i]) {
+                $sqlcommand .= $allSQL[$i];
+                $sqlcommand = SQLParser($sqlcommand);
+                if (0 == $sql['parser']['start'] && 0 == $sql['parser']['end'] && '' != $sqlcommand) {
+                    //sql complete
+                    ++$sql['parser']['sql_commands'];
+                    $out .= Stringformat(($sql['parser']['sql_commands']), 4).': '.$sqlcommand."\n";
+                    $result = $result && mod_query($sqlcommand);
+                    $sqlcommand = '';
+                }
+            }
+        }
+    }
+    $sql['parser']['time_used'] = getmicrotime() - $sql['parser']['time_used'];
+    return $result;
 }
 
-function SQLParser($command, $debug=0)
+function SQLParser($command, $debug = 0)
 {
-	global $sql;
-	$sql['parser']['start']=$sql['parser']['end']=0;
-	$sql['parser']['sqlparts']=0;
-	if (!isset($sql['parser']['drop'])) $sql['parser']['drop']=0;
-	if (!isset($sql['parser']['create'])) $sql['parser']['create']=0;
-	if (!isset($sql['parser']['insert'])) $sql['parser']['insert']=0;
-	if (!isset($sql['parser']['update'])) $sql['parser']['update']=0;
-	if (!isset($sql['parser']['comment'])) $sql['parser']['comment']=0;
-	$Backslash=chr(92);
-	$s=rtrim(trim(( $command )));
+    global $sql;
+    $sql['parser']['start'] = $sql['parser']['end'] = 0;
+    $sql['parser']['sqlparts'] = 0;
+    if (!isset($sql['parser']['drop'])) {
+        $sql['parser']['drop'] = 0;
+    }
+    if (!isset($sql['parser']['create'])) {
+        $sql['parser']['create'] = 0;
+    }
+    if (!isset($sql['parser']['insert'])) {
+        $sql['parser']['insert'] = 0;
+    }
+    if (!isset($sql['parser']['update'])) {
+        $sql['parser']['update'] = 0;
+    }
+    if (!isset($sql['parser']['comment'])) {
+        $sql['parser']['comment'] = 0;
+    }
+    $Backslash = chr(92);
+    $s = rtrim(trim(($command)));
 
-	//Was ist das für eine Anfrage ?
-	if (substr($s,0,1) == "#" || substr($s,0,2) == "--")
-	{
-		$sql['parser']['comment']++;
-		$s="";
-	}
-	elseif (strtoupper(substr($s,0,5)) == "DROP ")
-	{
-		$sql['parser']['drop']++;
-	}
-	elseif (strtoupper(substr($s,0,7)) == "CREATE ")
-	{
-		//Hier nur die Anzahl der Klammern zählen
-		$sql['parser']['start']=1;
-		$kl1=substr_count($s,"(");
-		$kl2=substr_count($s,")");
-		if ($kl2 - $kl1 == 0)
-		{
-			$sql['parser']['start']=0;
-			$sql['parser']['create']++;
-		}
-	}
-	elseif (strtoupper(substr($s,0,7)) == "INSERT " || strtoupper(substr($s,0,7)) == "UPDATE ")
-	{
+    //Was ist das für eine Anfrage ?
+    if ('#' == substr($s, 0, 1) || '--' == substr($s, 0, 2)) {
+        ++$sql['parser']['comment'];
+        $s = '';
+    } elseif ('DROP ' == strtoupper(substr($s, 0, 5))) {
+        ++$sql['parser']['drop'];
+    } elseif ('CREATE ' == strtoupper(substr($s, 0, 7))) {
+        //Hier nur die Anzahl der Klammern zählen
+        $sql['parser']['start'] = 1;
+        $kl1 = substr_count($s, '(');
+        $kl2 = substr_count($s, ')');
+        if (0 == $kl2 - $kl1) {
+            $sql['parser']['start'] = 0;
+            ++$sql['parser']['create'];
+        }
+    } elseif ('INSERT ' == strtoupper(substr($s, 0, 7)) || 'UPDATE ' == strtoupper(substr($s, 0, 7))) {
+        if ('INSERT ' == strtoupper(substr($s, 0, 7))) {
+            ++$sql['parser']['insert'];
+        } else {
+            ++$sql['parser']['update'];
+        }
+        $i = strpos(strtoupper($s), ' VALUES') + 7;
+        $st = substr($s, $i);
+        $i = strpos($st, '(') + 1;
+        $st = substr($st, $i);
+        $st = substr($st, 0, strlen($st) - 2);
 
-		if (strtoupper(substr($s,0,7)) == "INSERT ") $sql['parser']['insert']++;
-		else $sql['parser']['update']++;
-		$i=strpos(strtoupper($s)," VALUES") + 7;
-		$st=substr($s,$i);
-		$i=strpos($st,"(") + 1;
-		$st=substr($st,$i);
-		$st=substr($st,0,strlen($st) - 2);
+        $tb = explode(',', $st);
+        for ($i = 0; $i < count($tb); ++$i) {
+            $first = $B_Esc = $B_Ticks = $B_Dashes = 0;
+            $v = trim($tb[$i]);
+            //Ticks + Dashes zählen
+            for ($cpos = 2; $cpos <= strlen($v); ++$cpos) {
+                if ("'" == substr($v, (-1 * $cpos), 1)) {
+                    ++$B_Ticks;
+                } else {
+                    break;
+                }
+            }
+            for ($cpos = 2; $cpos <= strlen($v); ++$cpos) {
+                if ('"' == substr($v, (-1 * $cpos), 1)) {
+                    ++$B_Dashes;
+                } else {
+                    break;
+                }
+            }
 
-		$tb=explode(",",$st);
-		for ($i=0; $i < count($tb); $i++)
-		{
-			$first=$B_Esc=$B_Ticks=$B_Dashes=0;
-			$v=trim($tb[$i]);
-			//Ticks + Dashes zählen
-			for ($cpos=2; $cpos <= strlen($v); $cpos++)
-			{
-				if (substr($v,( -1 * $cpos ),1) == "'")
-				{
-					$B_Ticks++;
-				}
-				else
-				{
-					break;
-				}
-			}
-			for ($cpos=2; $cpos <= strlen($v); $cpos++)
-			{
-				if (substr($v,( -1 * $cpos ),1) == '"')
-				{
-					$B_Dashes++;
-				}
-				else
-				{
-					break;
-				}
-			}
+            //Backslashes zählen
+            for ($cpos = 2 + $B_Ticks; $cpos <= strlen($v); ++$cpos) {
+                if ('\\' == substr($v, (-1 * $cpos), 1)) {
+                    ++$B_Esc;
+                } else {
+                    break;
+                }
+            }
 
-			//Backslashes zählen
-			for ($cpos=2 + $B_Ticks; $cpos <= strlen($v); $cpos++)
-			{
-				if (substr($v,( -1 * $cpos ),1) == "\\")
-				{
-					$B_Esc++;
-				}
-				else
-				{
-					break;
-				}
-			}
+            if ('NULL' == $v && 0 == $sql['parser']['start']) {
+                $sql['parser']['start'] = 1;
+                $sql['parser']['end'] = 1;
+            }
+            if (0 == $sql['parser']['start'] && is_numeric($v)) {
+                $sql['parser']['start'] = 1;
+                $sql['parser']['end'] = 1;
+            }
+            if (0 == $sql['parser']['start'] && '0X' == substr($v, 0, 2) && false == strpos($v, ' ')) {
+                $sql['parser']['start'] = 1;
+                $sql['parser']['end'] = 1;
+            }
+            if (0 == $sql['parser']['start'] && is_object($v)) {
+                $sql['parser']['start'] = 1;
+                $sql['parser']['end'] = 1;
+            }
 
-			if ($v == "NULL" && $sql['parser']['start'] == 0)
-			{
-				$sql['parser']['start']=1;
-				$sql['parser']['end']=1;
-			}
-			if ($sql['parser']['start'] == 0 && is_numeric($v))
-			{
-				$sql['parser']['start']=1;
-				$sql['parser']['end']=1;
-			}
-			if ($sql['parser']['start'] == 0 && substr($v,0,2) == "0X" && strpos($v," ") == false)
-			{
-				$sql['parser']['start']=1;
-				$sql['parser']['end']=1;
-			}
-			if ($sql['parser']['start'] == 0 && is_object($v))
-			{
-				$sql['parser']['start']=1;
-				$sql['parser']['end']=1;
-			}
-
-			if (substr($v,0,1) == "'" && $sql['parser']['start'] == 0)
-			{
-				$sql['parser']['start']=1;
-				if (strlen($v) == 1) $first=1;
-				$DELIMITER="'";
-			}
-			if (substr($v,0,1) == '"' && $sql['parser']['start'] == 0)
-			{
-				$sql['parser']['start']=1;
-				if (strlen($v) == 1) $first=1;
-				$DELIMITER='"';
-			}
-			if ($sql['parser']['start'] == 1 && $sql['parser']['end'] != 1 && $first == 0)
-			{
-				if (substr($v,-1) == $DELIMITER)
-				{
-					$B_Delimiter=( $DELIMITER == "'" ) ? $B_Ticks : $B_Dashes;
-					//ist Delimiter maskiert?
-					if (( $B_Esc % 2 ) == 1 && ( $B_Delimiter % 2 ) == 1 && strlen($v) > 2)
-					{
-
-						$sql['parser']['end']=1;
-					}
-					elseif (( $B_Delimiter % 2 ) == 1 && strlen($v) > 2)
-					{
-						//ist mit `'` maskiert
-						$sql['parser']['end']=0;
-					}
-					elseif (( $B_Esc % 2 ) == 1)
-					{
-						//ist mit Backslash maskiert
-						$sql['parser']['end']=0;
-					}
-					else
-					{
-
-						$sql['parser']['end']=1;
-					}
-				}
-			}
-			if ($debug == 1) echo "<font color='#0000FF'>" . $sql['parser']['start'] . "/" . $sql['parser']['end'] . "</font> Feld $i: " . htmlspecialchars($tb[$i]) . "<font color=#008000>- " . $sql['parser']['sqlparts'] . "  ($B_Ticks / $B_Esc)</font><br>";
-			if ($sql['parser']['start'] == 1 && $sql['parser']['end'] == 1)
-			{
-				$sql['parser']['sqlparts']++;
-				$sql['parser']['start']=$sql['parser']['end']=0;
-			}
-		}
-	}
-	return $s;
+            if ("'" == substr($v, 0, 1) && 0 == $sql['parser']['start']) {
+                $sql['parser']['start'] = 1;
+                if (1 == strlen($v)) {
+                    $first = 1;
+                }
+                $DELIMITER = "'";
+            }
+            if ('"' == substr($v, 0, 1) && 0 == $sql['parser']['start']) {
+                $sql['parser']['start'] = 1;
+                if (1 == strlen($v)) {
+                    $first = 1;
+                }
+                $DELIMITER = '"';
+            }
+            if (1 == $sql['parser']['start'] && 1 != $sql['parser']['end'] && 0 == $first) {
+                if (substr($v, -1) == $DELIMITER) {
+                    $B_Delimiter = ("'" == $DELIMITER) ? $B_Ticks : $B_Dashes;
+                    //ist Delimiter maskiert?
+                    if (($B_Esc % 2) == 1 && ($B_Delimiter % 2) == 1 && strlen($v) > 2) {
+                        $sql['parser']['end'] = 1;
+                    } elseif (($B_Delimiter % 2) == 1 && strlen($v) > 2) {
+                        //ist mit `'` maskiert
+                        $sql['parser']['end'] = 0;
+                    } elseif (($B_Esc % 2) == 1) {
+                        //ist mit Backslash maskiert
+                        $sql['parser']['end'] = 0;
+                    } else {
+                        $sql['parser']['end'] = 1;
+                    }
+                }
+            }
+            if (1 == $debug) {
+                echo "<font color='#0000FF'>".$sql['parser']['start'].'/'.$sql['parser']['end']."</font> Feld $i: ".htmlspecialchars($tb[$i]).'<font color=#008000>- '.$sql['parser']['sqlparts']."  ($B_Ticks / $B_Esc)</font><br>";
+            }
+            if (1 == $sql['parser']['start'] && 1 == $sql['parser']['end']) {
+                ++$sql['parser']['sqlparts'];
+                $sql['parser']['start'] = $sql['parser']['end'] = 0;
+            }
+        }
+    }
+    return $s;
 }
 
-function SQLOutput($sqlcommand, $meldung='')
+function SQLOutput($sqlcommand, $meldung = '')
 {
-	global $sql,$lang;
-	$s='<h6 align="center">' . $lang['L_SQL_OUTPUT'] . '</h6><div id="sqloutbox"><strong>';
-	if ($meldung != '') $s.=trim($meldung);
+    global $sql, $lang;
+    $s = '<h6 align="center">'.$lang['L_SQL_OUTPUT'].'</h6><div id="sqloutbox"><strong>';
+    if ('' != $meldung) {
+        $s .= trim($meldung);
+    }
 
-	if (isset($sql['parser']['sql_commands']))
-	{
-		$s.=' ' . $sql['parser']['sql_commands'] . '</strong>' . $lang['L_SQL_COMMANDS_IN'] . round($sql['parser']['time_used'],4) . $lang['L_SQL_COMMANDS_IN2'] . '<br><br>';
-		$s.=$lang['L_SQL_OUT1'] . '<strong>' . $sql['parser']['drop'] . '</strong> <span style="color:#990099;font-weight:bold;">DROP</span>-, ';
-		$s.='<strong>' . $sql['parser']['create'] . '</strong> <span style="color:#990099;font-weight:bold;">CREATE</span>-, ';
-		$s.='<strong>' . $sql['parser']['insert'] . '</strong> <span style="color:#990099;font-weight:bold;">INSERT</span>-, ';
-		$s.='<strong>' . $sql['parser']['update'] . '</strong> <span style="color:#990099;font-weight:bold;">UPDATE</span>-' . $lang['L_SQL_OUT2'] . '<br>';
-		$s.=$lang['L_SQL_OUT3'] . '<strong>' . $sql['parser']['comment'] . '</strong> ' . $lang['L_SQL_OUT4'] . '<br>';
-		if ($sql['parser']['sql_commands'] < 50) $s.='<pre>' . Highlight_SQL($sqlcommand) . '</pre>';
-		else $s.=$lang['L_SQL_OUT5'];
-	}
-	elseif ($sqlcommand != '') $s.='<h5 align="center">' . $lang['L_SQL_OUTPUT'] . '</h5><pre>' . Highlight_SQL($sqlcommand) . '</pre>';
-	return $s . '</div>';
+    if (isset($sql['parser']['sql_commands'])) {
+        $s .= ' '.$sql['parser']['sql_commands'].'</strong>'.$lang['L_SQL_COMMANDS_IN'].round($sql['parser']['time_used'], 4).$lang['L_SQL_COMMANDS_IN2'].'<br><br>';
+        $s .= $lang['L_SQL_OUT1'].'<strong>'.$sql['parser']['drop'].'</strong> <span style="color:#990099;font-weight:bold;">DROP</span>-, ';
+        $s .= '<strong>'.$sql['parser']['create'].'</strong> <span style="color:#990099;font-weight:bold;">CREATE</span>-, ';
+        $s .= '<strong>'.$sql['parser']['insert'].'</strong> <span style="color:#990099;font-weight:bold;">INSERT</span>-, ';
+        $s .= '<strong>'.$sql['parser']['update'].'</strong> <span style="color:#990099;font-weight:bold;">UPDATE</span>-'.$lang['L_SQL_OUT2'].'<br>';
+        $s .= $lang['L_SQL_OUT3'].'<strong>'.$sql['parser']['comment'].'</strong> '.$lang['L_SQL_OUT4'].'<br>';
+        if ($sql['parser']['sql_commands'] < 50) {
+            $s .= '<pre>'.Highlight_SQL($sqlcommand).'</pre>';
+        } else {
+            $s .= $lang['L_SQL_OUT5'];
+        }
+    } elseif ('' != $sqlcommand) {
+        $s .= '<h5 align="center">'.$lang['L_SQL_OUTPUT'].'</h5><pre>'.Highlight_SQL($sqlcommand).'</pre>';
+    }
+    return $s.'</div>';
 }
 
 function GetCreateTable($db, $tabelle)
 {
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-	$res=mysqli_query($config['dbconnection'], "SHOW CREATE TABLE `$db`.`$tabelle`");
-	if ($res)
-	{
-		$row=mysqli_fetch_array($res);
-		if (isset($row['Create Table'])) return $row['Create Table'];
-		elseif (isset($row['Create View'])) return $row['Create View'];
-		else return false;
-	}
-	else
-		return mysqli_error($config['dbconnection']);
-
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    $res = mysqli_query($config['dbconnection'], "SHOW CREATE TABLE `$db`.`$tabelle`");
+    if ($res) {
+        $row = mysqli_fetch_array($res);
+        if (isset($row['Create Table'])) {
+            return $row['Create Table'];
+        } elseif (isset($row['Create View'])) {
+            return $row['Create View'];
+        } else {
+            return false;
+        }
+    } else {
+        return mysqli_error($config['dbconnection']);
+    }
 }
 
 function KindSQL($sql)
 {
-	if (preg_match('@^((-- |#)[^\n]*\n|/\*.*?\*/)*(DROP|CREATE)[[:space:]]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im',$sql))
-	{
-		return 2;
-	}
-	elseif (preg_match('@^((-- |#)[^\n]*\n|/\*.*?\*/)*(DROP|CREATE)[[:space:]]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im',$sql))
-	{
-		return 1;
-	}
+    if (preg_match('@^((-- |#)[^\n]*\n|/\*.*?\*/)*(DROP|CREATE)[[:space:]]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $sql)) {
+        return 2;
+    } elseif (preg_match('@^((-- |#)[^\n]*\n|/\*.*?\*/)*(DROP|CREATE)[[:space:]]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $sql)) {
+        return 1;
+    }
 }
 
 function GetPostParams()
 {
-	global $db,$dbid,$tablename,$context,$limitstart,$order,$orderdir,$sql;
-	$db=$_POST['db'];
-	$dbid=$_POST['dbid'];
-	$tablename=$_POST['tablename'];
-	$context=$_POST['context'];
-	$limitstart=$_POST['limitstart'];
-	$order=$_POST['order'];
-	$orderdir=$_POST['orderdir'];
-	$sql['sql_statement']=( isset($_POST['sql_statement']) ) ? $_POST['sql_statement'] : "SELECT * FROM `$tablename`";
-
+    global $db, $dbid, $tablename, $context, $limitstart, $order, $orderdir, $sql;
+    $db = $_POST['db'];
+    $dbid = $_POST['dbid'];
+    $tablename = $_POST['tablename'];
+    $context = $_POST['context'];
+    $limitstart = $_POST['limitstart'];
+    $order = $_POST['order'];
+    $orderdir = $_POST['orderdir'];
+    $sql['sql_statement'] = (isset($_POST['sql_statement'])) ? $_POST['sql_statement'] : "SELECT * FROM `$tablename`";
 }
 
 // when fieldnames contain spaces or dots they are replaced with underscores
 // we need to built the same index to get the postet values for inserts and updates
 function correct_post_index($index)
 {
-	$index=str_replace(' ','_',$index);
-	$index=str_replace('.','_',$index);
-	return $index;
+    $index = str_replace(' ', '_', $index);
+    $index = str_replace('.', '_', $index);
+    return $index;
 }
 function ComboCommandDump($when, $index, $disabled = '')
 {
-	global $SQL_ARRAY,$nl,$databases,$lang;
-	if (count($SQL_ARRAY) == 0)
-	{
-		$r='<a href="sql.php?context=1" class="uls">' . $lang['L_SQL_BEFEHLE'] . '</a>';
-		if ($when == 0) $r.='<input type="hidden" name="command_before_' . $index . '" value="">';
-		else $r.='<input type="hidden" name="command_after_' . $index . '" value="">';
-	}
-	else
-	{
-		if ($when == 0)
-		{
-			$r='<select class="SQLCombo" name="command_before_' . $index . '"'
-			 . $disabled.'>';
-			$csql=$databases['command_before_dump'][$index];
-		}
-		else
-		{
-			$r='<select class="SQLCombo" name="command_after_' . $index . '"'
-			          . $disabled.'>';
-			$csql=$databases['command_after_dump'][$index];
-		}
+    global $SQL_ARRAY, $nl, $databases, $lang;
+    if ((is_array($SQL_ARRAY) && 0 == count($SQL_ARRAY)) || !is_array($SQL_ARRAY)) {
+        $r = '<a href="sql.php?context=1" class="uls">'.$lang['L_SQL_BEFEHLE'].'</a>';
+        if (0 == $when) {
+            $r .= '<input type="hidden" name="command_before_'.$index.'" value="">';
+        } else {
+            $r .= '<input type="hidden" name="command_after_'.$index.'" value="">';
+        }
+    } else {
+        if (0 == $when) {
+            $r = '<select class="SQLCombo" name="command_before_'.$index.'"'
+             .$disabled.'>';
+            $csql = $databases['command_before_dump'][$index];
+        } else {
+            $r = '<select class="SQLCombo" name="command_after_'.$index.'"'
+                      .$disabled.'>';
+            $csql = $databases['command_after_dump'][$index];
+        }
 
-		$r.='<option value="" ' . ( ( $csql == '' ) ? ' selected="selected"' : '' ) . '>&nbsp;</option>' . "\n";
-		if (count($SQL_ARRAY) > 0)
-		{
-			for ($i=0; $i < count($SQL_ARRAY); $i++)
-			{
-				$s=trim(SQL_String($i));
-				$r.='<option value="' . htmlspecialchars($s) . '" ' . ( ( $csql == $s ) ? ' selected="selected"' : '' ) . '>' . SQL_Name($i) . '</option>' . "\n";
-			}
-		}
-		$r.='</select>';
-	}
-	return $r;
+        $r .= '<option value="" '.(('' == $csql) ? ' selected="selected"' : '').'>&nbsp;</option>'."\n";
+        if (is_array($SQL_ARRAY) && count($SQL_ARRAY) > 0) {
+            for ($i = 0; $i < count($SQL_ARRAY); ++$i) {
+                $s = trim(SQL_String($i));
+                $r .= '<option value="'.htmlspecialchars($s).'" '.(($csql == $s) ? ' selected="selected"' : '').'>'.SQL_Name($i).'</option>'."\n";
+            }
+        }
+        $r .= '</select>';
+    }
+    return $r;
 }
 
-function EngineCombo($default="")
+function EngineCombo($default = '')
 {
-	global $config;
-	if (!$config['dbconnection']) MSD_mysql_connect();
+    global $config;
+    if (!$config['dbconnection']) {
+        mod_mysqli_connect();
+    }
 
-	$r='<option value="" ' . ( ( $default == "" ) ? ' selected="selected"' : "" ) . '></option>';
-	if (!MSD_NEW_VERSION)
-	{
-		//BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM
-		$r.='<option value="BDB" ' . ( ( "BDB" == $default ) ? ' selected="selected"' : "" ) . '>BDB</option>';
-		$r.='<option value="HEAP" ' . ( ( "HEAP" == $default ) ? ' selected="selected"' : "" ) . '>HEAP</option>';
-		$r.='<option value="ISAM" ' . ( ( "ISAM" == $default ) ? ' selected="selected"' : "" ) . '>ISAM</option>';
-		$r.='<option value="InnoDB" ' . ( ( "InnoDB" == $default ) ? ' selected="selected"' : "" ) . '>InnoDB</option>';
-		$r.='<option value="MERGE" ' . ( ( "MERGE" == $default ) ? ' selected="selected"' : "" ) . '>MERGE</option>';
-		$r.='<option value="MRG_MYISAM" ' . ( ( "MRG_MYISAM" == $default ) ? ' selected="selected"' : "" ) . '>MRG_MYISAM</option>';
-		$r.='<option value="MYISAM" ' . ( ( "MyISAM" == $default ) ? ' selected="selected"' : "" ) . '>MyISAM</option>';
-	}
-	else
-	{
-		$res=mysqli_query($config['dbconnection'], "SHOW ENGINES");
-		$num=mysqli_num_rows($res);
-		for ($i=0; $i < $num; $i++)
-		{
-			$row=mysqli_fetch_array($res);
-			$r.='<option value="' . $row['Engine'] . '" ' . ( ( $row['Engine'] == $default ) ? ' selected="selected"' : "" ) . '>' . $row['Engine'] . '</option>';
-		}
-	}
-	return $r;
+    $r = '<option value="" '.(('' == $default) ? ' selected="selected"' : '').'></option>';
+    if (!MOD_NEW_VERSION) {
+        //BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM
+        $r .= '<option value="BDB" '.(('BDB' == $default) ? ' selected="selected"' : '').'>BDB</option>';
+        $r .= '<option value="HEAP" '.(('HEAP' == $default) ? ' selected="selected"' : '').'>HEAP</option>';
+        $r .= '<option value="ISAM" '.(('ISAM' == $default) ? ' selected="selected"' : '').'>ISAM</option>';
+        $r .= '<option value="InnoDB" '.(('InnoDB' == $default) ? ' selected="selected"' : '').'>InnoDB</option>';
+        $r .= '<option value="MERGE" '.(('MERGE' == $default) ? ' selected="selected"' : '').'>MERGE</option>';
+        $r .= '<option value="MRG_MYISAM" '.(('MRG_MYISAM' == $default) ? ' selected="selected"' : '').'>MRG_MYISAM</option>';
+        $r .= '<option value="MYISAM" '.(('MyISAM' == $default) ? ' selected="selected"' : '').'>MyISAM</option>';
+    } else {
+        $res = mysqli_query($config['dbconnection'], 'SHOW ENGINES');
+        $num = mysqli_num_rows($res);
+        for ($i = 0; $i < $num; ++$i) {
+            $row = mysqli_fetch_array($res);
+            $r .= '<option value="'.$row['Engine'].'" '.(($row['Engine'] == $default) ? ' selected="selected"' : '').'>'.$row['Engine'].'</option>';
+        }
+    }
+    return $r;
 }
 
-function CharsetCombo($default="")
+function CharsetCombo($default = '')
 {
-	global $config;
-	if (!MSD_NEW_VERSION)
-	{
-		return "";
-	}
-	else
-	{
-		if (!isset($config['dbconnection'])) MSD_mysql_connect();
-		$res=mysqli_query($config['dbconnection'], "SHOW Charset");
-		$num=mysqli_num_rows($res);
-		$r='<option value="" ' . ( ( $default == "" ) ? ' selected="selected"' : "" ) . '></option>';
-		$charsets=array();
-		for ($i=0; $i < $num; $i++)
-		{
-			$charsets[]=mysqli_fetch_array($res);
-		}
+    global $config;
+    if (!MOD_NEW_VERSION) {
+        return '';
+    } else {
+        if (!isset($config['dbconnection'])) {
+            mod_mysqli_connect();
+        }
+        $res = mysqli_query($config['dbconnection'], 'SHOW Charset');
+        $num = mysqli_num_rows($res);
+        $r = '<option value="" '.(('' == $default) ? ' selected="selected"' : '').'></option>';
+        $charsets = [];
+        for ($i = 0; $i < $num; ++$i) {
+            $charsets[] = mysqli_fetch_array($res);
+        }
 
-		if (is_array($charsets))
-		{
-			$charsets=mu_sort($charsets,'Charset');
-			foreach ($charsets as $row)
-			{
-				$r.='<option value="' . $row['Charset'] . '" ' . ( ( $row['Charset'] == $default ) ? ' selected="selected"' : "" ) . '>' . $row['Charset'] . '</option>';
-			}
-		}
-		return $r;
-	}
+        if (is_array($charsets)) {
+            $charsets = mu_sort($charsets, 'Charset');
+            foreach ($charsets as $row) {
+                $r .= '<option value="'.$row['Charset'].'" '.(($row['Charset'] == $default) ? ' selected="selected"' : '').'>'.$row['Charset'].'</option>';
+            }
+        }
+        return $r;
+    }
 }
 
 function GetCollationArray()
 {
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
 
-	$res=mysqli_query($config['dbconnection'], "SHOW Collation");
-	$num=@mysqli_num_rows($res);
-	$r=Array();
-	if (is_array($r))
-	{
-		for ($i=0; $i < $num; $i++)
-		{
-			$row=mysqli_fetch_array($res);
-			$r[$i]['Collation']=isset($row['Collation']) ? $row['Collation'] : '';
-			$r[$i]['Charset']=isset($row['Charset']) ? $row['Charset'] : '';
-			$r[$i]['Id']=isset($row['Id']) ? $row['Id'] : '';
-			$r[$i]['Default']=isset($row['Default']) ? $row['Default'] : '';
-			$r[$i]['Compiled']=isset($row['Compiled']) ? $row['Compiled'] : '';
-			$r[$i]['Sortlen']=isset($row['Sortlen']) ? $row['Sortlen'] : '';
-		}
-	}
-	return $r;
+    $res = mysqli_query($config['dbconnection'], 'SHOW Collation');
+    $num = mysqli_num_rows($res);
+    $r = [];
+    if (is_array($r)) {
+        for ($i = 0; $i < $num; ++$i) {
+            $row = mysqli_fetch_array($res);
+            $r[$i]['Collation'] = isset($row['Collation']) ? $row['Collation'] : '';
+            $r[$i]['Charset'] = isset($row['Charset']) ? $row['Charset'] : '';
+            $r[$i]['Id'] = isset($row['Id']) ? $row['Id'] : '';
+            $r[$i]['Default'] = isset($row['Default']) ? $row['Default'] : '';
+            $r[$i]['Compiled'] = isset($row['Compiled']) ? $row['Compiled'] : '';
+            $r[$i]['Sortlen'] = isset($row['Sortlen']) ? $row['Sortlen'] : '';
+        }
+    }
+    return $r;
 }
 
-function CollationCombo($default="", $withcharset=0)
+function CollationCombo($default = '', $withcharset = 0)
 {
-	if (!MSD_NEW_VERSION)
-	{
-		return "";
-	}
-	else
-	{
-		$r=GetCollationArray();
-		sort($r);
-		$s='';
-		$s='<option value=""' . ( ( $default == '' ) ? ' selected="selected"' : '' ) . '></option>';
-		$group='';
-		for ($i=0; $i < count($r); $i++)
-		{
-			$gc=$r[$i]['Charset'];
-			if ($gc != $group)
-			{
-				$group=$gc;
-				if ($i > 0) $s.='</optgroup>';
-				$s.='<optgroup label="' . $group . '">';
-			}
-			$s.='<option value="' . ( ( $withcharset == 1 ) ? $group . '|' : '' ) . $r[$i]['Collation'] . '" ' . ( ( $r[$i]['Collation'] == $default ) ? "selected" : "" ) . '>' . $r[$i]['Collation'] . '</option>';
-		}
-		return $s . '</optgroup>';
-	}
+    if (!MOD_NEW_VERSION) {
+        return '';
+    } else {
+        $r = GetCollationArray();
+        sort($r);
+        $s = '';
+        $s = '<option value=""'.(('' == $default) ? ' selected="selected"' : '').'></option>';
+        $group = '';
+        for ($i = 0; $i < count($r); ++$i) {
+            $gc = $r[$i]['Charset'];
+            if ($gc != $group) {
+                $group = $gc;
+                if ($i > 0) {
+                    $s .= '</optgroup>';
+                }
+                $s .= '<optgroup label="'.$group.'">';
+            }
+            $s .= '<option value="'.((1 == $withcharset) ? $group.'|' : '').$r[$i]['Collation'].'" '.(($r[$i]['Collation'] == $default) ? 'selected' : '').'>'.$r[$i]['Collation'].'</option>';
+        }
+        return $s.'</optgroup>';
+    }
 }
 
-function AttributeCombo($default='')
+function AttributeCombo($default = '')
 {
-	$s='<option value=""' . ( ( $default == '' ) ? ' selected="selected"' : '' ) . '></option>';
-	$s.='<option value="unsigned" ' . ( ( $default == 'unsigned' ) ? ' selected="selected"' : '' ) . '>unsigned</option>';
-	$s.='<option value="unsigned zerofill"' . ( ( $default == 'unsigned zerofill' ) ? ' selected="selected"' : '' ) . '>unsigned zerofill</option>';
-	return $s;
-
+    $s = '<option value=""'.(('' == $default) ? ' selected="selected"' : '').'></option>';
+    $s .= '<option value="unsigned" '.(('unsigned' == $default) ? ' selected="selected"' : '').'>unsigned</option>';
+    $s .= '<option value="unsigned zerofill"'.(('unsigned zerofill' == $default) ? ' selected="selected"' : '').'>unsigned zerofill</option>';
+    return $s;
 }
 
 function simple_bbcode_conversion($a)
 {
-	global $config;
-	$tag_start='';
-	$tag_end='';
+    global $config;
+    $tag_start = '';
+    $tag_end = '';
 
-	//replacements
-	$a=nl2br($a);
-	$a=str_replace('<br>',' <br>',$a);
-	$a=str_replace('<br />',' <br>',$a);
+    //replacements
+    $a = nl2br($a);
+    $a = str_replace('<br>', ' <br>', $a);
+    $a = str_replace('<br />', ' <br>', $a);
 
-	$a=preg_replace("/\[url=(.*?)\](.*?)\[\/url\]/si","<a class=\"small\"  href=\"$1\" target=\"blank\">$2</a>",$a);
-	$a=preg_replace("/\[urltargetself=(.*?)\](.*?)\[\/urltargetself\]/si","<a class=\"small\"  href=\"$1\" target=\"blank\">$2</a>",$a);
-	$a=preg_replace("/\[url\](.*?)\[\/url\]/si","<a class=\"small\"  href=\"$1\" target=\"blank\">$1</a>",$a);
-	$a=preg_replace("/\[ed2k=\+(.*?)\](.*?)\[\/ed2k\]/si","<a class=\"small\"  href=\"$1\" target=\"blank\">$2</a>",$a);
-	$a=preg_replace("/\[ed2k=(.*?)\](.*?)\[\/ed2k\]/si","<a class=\"small\"  href=\"$1\" target=\"blank\">$2</a>",$a);
+    $a = preg_replace("/\[url=(.*?)\](.*?)\[\/url\]/si", '<a class="small"  href="$1" target="blank">$2</a>', $a);
+    $a = preg_replace("/\[urltargetself=(.*?)\](.*?)\[\/urltargetself\]/si", '<a class="small"  href="$1" target="blank">$2</a>', $a);
+    $a = preg_replace("/\[url\](.*?)\[\/url\]/si", '<a class="small"  href="$1" target="blank">$1</a>', $a);
+    $a = preg_replace("/\[ed2k=\+(.*?)\](.*?)\[\/ed2k\]/si", '<a class="small"  href="$1" target="blank">$2</a>', $a);
+    $a = preg_replace("/\[ed2k=(.*?)\](.*?)\[\/ed2k\]/si", '<a class="small"  href="$1" target="blank">$2</a>', $a);
 
-	$a=preg_replace("/\[center\](.*?)\[\/center\]/si","<div align=\"center\">$1</div>",$a);
-	$a=preg_replace("/\[size=([1-2]?[0-9])\](.*?)\[\/size\]/si","<span style=\"font-size=$1px;\">$2</span>",$a);
-	$a=preg_replace("/\[size=([1-2]?[0-9]):(.*?)\](.*?)\[\/size(.*?)\]/si","<span style=\"font-size=$1px;\">$3</span>",$a);
-	$a=preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/si","<span style=\"font-family:$1;\">$2</span>",$a);
-	$a=preg_replace("/\[color=(.*?)\](.*?)\[\/color\]/si","<span style=\"color=$1;\">$2</span>",$a);
-	$a=preg_replace("/\[color=(.*?):(.*?)\](.*?)\[\/color(.*?)\]/si","<span style=\"color=$1;\">$3</span>",$a);
-	$a=preg_replace("/\[img\](.*?)\[\/img\]/si","<img src=\"$1\" vspace=4 hspace=4>",$a);
-	//$a=preg_replace("/\[b\](.*?)\[\/b\]/si", "<strong>$1</strong>", $a);
-	$a=preg_replace("/\[b(.*?)\](.*?)\[\/b(.*?)\]/si","<strong>$2</strong>",$a);
-	//$a=preg_replace("/\[u\](.*?)\[\/u\]/si", "<u>$1</u>", $a);
-	$a=preg_replace("/\[u(.*?)\](.*?)\[\/u(.*?)\]/si","<u>$2</u>",$a);
-	//$a=preg_replace("/\[i\](.*?)\[\/i\]/si", "<em>$1</em>", $a);
-	$a=preg_replace("/\[i(.*?)\](.*?)\[\/i(.*?)\]/si","<em>$2</em>",$a);
-	//$a=preg_replace("/\[quote\](.*?)\[\/quote\]/si", "<p align=\"left\" style=\"border: 2px solid silver;padding:4px;\">$1</p>", $a);
-	$a=preg_replace("/\[quote(.*?)\](.*?)\[\/quote(.*?)\]/si","<p align=\"left\" style=\"border: 2px solid silver;padding:4px;\">$2</p>",$a);
-	$a=preg_replace("/\[code(.*?)\](.*?)\[\/code(.*?)\]/si","<p align=\"left\" style=\"border: 2px solid red;color:green;padding:4px;\">$2</p>",$a);
-	$a=preg_replace("/\[hide\](.*?)\[\/hide\]/si","<div style=\"background-color:#ccffcc;\">$1</div>",$a);
-	$a=preg_replace("/(^|\s)+((http:\/\/)|(www.))(.+)(\s|$)+/Uis"," <a href=\"http://$4$5\" target=\"_blank\">http://$4$5</a> ",$a);
-	return $tag_start . $a . $tag_end;
+    $a = preg_replace("/\[center\](.*?)\[\/center\]/si", '<div align="center">$1</div>', $a);
+    $a = preg_replace("/\[size=([1-2]?[0-9])\](.*?)\[\/size\]/si", '<span style="font-size= $1px;">$2</span>', $a);
+    $a = preg_replace("/\[size=([1-2]?[0-9]):(.*?)\](.*?)\[\/size(.*?)\]/si", '<span style="font-size= $1px;">$3</span>', $a);
+    $a = preg_replace("/\[font=(.*?)\](.*?)\[\/font\]/si", '<span style="font-family:$1;">$2</span>', $a);
+    $a = preg_replace("/\[color=(.*?)\](.*?)\[\/color\]/si", '<span style="color= $1;">$2</span>', $a);
+    $a = preg_replace("/\[color=(.*?):(.*?)\](.*?)\[\/color(.*?)\]/si", '<span style="color= $1;">$3</span>', $a);
+    $a = preg_replace("/\[img\](.*?)\[\/img\]/si", '<img src="$1" vspace=4 hspace=4>', $a);
+    //$a=preg_replace("/\[b\](.*?)\[\/b\]/si", "<strong>$1</strong>", $a);
+    $a = preg_replace("/\[b(.*?)\](.*?)\[\/b(.*?)\]/si", '<strong>$2</strong>', $a);
+    //$a=preg_replace("/\[u\](.*?)\[\/u\]/si", "<u>$1</u>", $a);
+    $a = preg_replace("/\[u(.*?)\](.*?)\[\/u(.*?)\]/si", '<u>$2</u>', $a);
+    //$a=preg_replace("/\[i\](.*?)\[\/i\]/si", "<em>$1</em>", $a);
+    $a = preg_replace("/\[i(.*?)\](.*?)\[\/i(.*?)\]/si", '<em>$2</em>', $a);
+    //$a=preg_replace("/\[quote\](.*?)\[\/quote\]/si", "<p align=\"left\" style=\"border: 2px solid silver;padding:4px;\">$1</p>", $a);
+    $a = preg_replace("/\[quote(.*?)\](.*?)\[\/quote(.*?)\]/si", '<p align="left" style="border: 2px solid silver;padding:4px;">$2</p>', $a);
+    $a = preg_replace("/\[code(.*?)\](.*?)\[\/code(.*?)\]/si", '<p align="left" style="border: 2px solid red;color:green;padding:4px;">$2</p>', $a);
+    $a = preg_replace("/\[hide\](.*?)\[\/hide\]/si", '<div style="background-color:#ccffcc;">$1</div>', $a);
+    $a = preg_replace("/(^|\s)+((http:\/\/)|(www.))(.+)(\s|$)+/Uis", ' <a href="http://$4$5" target="_blank">http://$4$5</a> ', $a);
+    return $tag_start.$a.$tag_end;
 }
 
 function ExtractTablenameFromSQL($q)
 {
-	global $databases,$db,$dbid;
-	$tablename='';
-	if (strlen($q) > 100) $q=substr($q,0,100);
-	$p=trim($q);
-	// if we get a list of tables - no current table is selected -> return ''
-	if (strtoupper(substr($p,0,17)) == 'SHOW TABLE STATUS') return '';
-	// check for SELECT-Statement to extract tablename after FROM
-	if (strtoupper(substr($p,0,7)) == 'SELECT ')
-	{
-		$parts=array();
-		$p=substr($p,strpos(strtoupper($p),'FROM') + 5);
-		$parts=explode(' ',$p);
-		$p=$parts[0];
-	}
+    global $databases, $db, $dbid;
+    $tablename = '';
+    if (strlen($q) > 100) {
+        $q = substr($q, 0, 100);
+    }
+    $p = trim($q);
+    // if we get a list of tables - no current table is selected -> return ''
+    if ('SHOW TABLE STATUS' == strtoupper(substr($p, 0, 17))) {
+        return '';
+    }
+    // check for SELECT-Statement to extract tablename after FROM
+    if ('SELECT ' == strtoupper(substr($p, 0, 7))) {
+        $parts = [];
+        $p = substr($p, strpos(strtoupper($p), 'FROM') + 5);
+        $parts = explode(' ', $p);
+        $p = $parts[0];
+    }
     // remove keyword DATABASES and the database name after that
     $p = preg_replace('/DATABASE [`]*\w+[`]*/i', '', $p);
     // remove other keywords
-	$suchen=array(
+    $suchen = [
                'SHOW DATABASES',
-				'SHOW ',
-				'SELECT',
-				'DROP',
-				'INSERT',
-				'UPDATE',
-				'DELETE',
-				'CREATE',
-				'TABLE',
-				'STATUS',
-				'FROM',
-				'*'
-	);
-	$ersetzen=array(
+                'SHOW ',
+                'SELECT',
+                'DROP',
+                'INSERT',
+                'UPDATE',
+                'DELETE',
+                'CREATE',
+                'TABLE',
+                'STATUS',
+                'FROM',
+                '*',
+    ];
+    $ersetzen = [
                     '',
-					'',
-					'',
-					'',
-					'',
-					'',
-					'',
-					'',
-					'',
-					'',
-					'',
-					''
-	);
-	$cleaned=trim(str_ireplace($suchen,$ersetzen,$p));
-	$tablename=$cleaned;
-	if (strpos($cleaned,' ')) $tablename=substr($cleaned,0,strpos($cleaned,' '));
-	$tablename=str_replace('`','',$tablename); // remove backticks
-	// take care of db-name.tablename
-	if (strpos($tablename,'.'))
-	{
-		$p=explode('.',$tablename);
-		$databases['db_actual']=$p[0];
-		// if database is changed in Query we need to get the index of the actual db
-		$db_temp=array_flip($databases['Name']);
-		if (isset($db_temp[$databases['db_actual']]))
-		{
-			$databases['db_selected_index']=$db_temp[$databases['db_actual']];
-			$dbid=$databases['db_selected_index'];
-		}
-		if (isset($_GET['tablename'])) unset($_GET['tablename']);
-		//echo "<br>" . $db;
-		$tablename=$p[1];
-	}
-	//	if (Table_Exists($databases['db_actual'],$tablename)) return $tablename;
-	//	else return '';
-	return $tablename;
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+                    '',
+    ];
+    $cleaned = trim(str_ireplace($suchen, $ersetzen, $p));
+    $tablename = $cleaned;
+    if (strpos($cleaned, ' ')) {
+        $tablename = substr($cleaned, 0, strpos($cleaned, ' '));
+    }
+    $tablename = str_replace('`', '', $tablename); // remove backticks
+    // take care of db-name.tablename
+    if (strpos($tablename, '.')) {
+        $p = explode('.', $tablename);
+        $databases['db_actual'] = $p[0];
+        // if database is changed in Query we need to get the index of the actual db
+        $db_temp = array_flip($databases['Name']);
+        if (isset($db_temp[$databases['db_actual']])) {
+            $databases['db_selected_index'] = $db_temp[$databases['db_actual']];
+            $dbid = $databases['db_selected_index'];
+        }
+        if (isset($_GET['tablename'])) {
+            unset($_GET['tablename']);
+        }
+        //echo "<br>" . $db;
+        $tablename = $p[1];
+    }
+    //	if (Table_Exists($databases['db_actual'], $tablename)) return $tablename;
+    //	else return '';
+    return $tablename;
 }
 
 function GetOptionsCombo($arr, $default)
 {
-	global $feldtypen,$feldattribute,$feldnull,$feldextras,$feldkeys,$feldrowformat;
-	$r='';
-	foreach ($arr as $s)
-	{
-		$r.='<option value="' . $s . '" ' . ( ( strtoupper($default) == strtoupper($s) ) ? ' selected="selected"' : "" ) . '>' . $s . '</option>' . "\n";
-	}
-	return $r;
+    global $feldtypen, $feldattribute, $feldnull, $feldextras, $feldkeys, $feldrowformat;
+    $r = '';
+    foreach ($arr as $s) {
+        $r .= '<option value="'.$s.'" '.((strtoupper($default) == strtoupper($s)) ? ' selected="selected"' : '').'>'.$s.'</option>'."\n";
+    }
+    return $r;
 }
 
 function make_options($arr, $selected)
 {
-	$r='';
-	foreach ($arr as $key=>$val)
-	{
-		$r.='<option value="' . $key . '"';
-		if ($key == $selected) $r.=' selected';
-		$r.='>' . $val . '</option>' . "\n";
-	}
-	return $r;
+    $r = '';
+    foreach ($arr as $key => $val) {
+        $r .= '<option value="'.$key.'"';
+        if ($key == $selected) {
+            $r .= ' selected';
+        }
+        $r .= '>'.$val.'</option>'."\n";
+    }
+    return $r;
 }
 
 /**
- * Reads MySQL field information (depricated: will be substituted by function getExtendedFieldInfos)
+ * Reads MySQL field information (depricated: will be substituted by function getExtendedFieldInfos).
  *
  * Reads field information for each field of a MySQL table
  * and fills an array with the keys detected
  *
- * @param $db Database
- * @param $tabelle Table
+ * @param $db
+ * @param $tabelle
+ *
  * @return array
  */
 function getFieldinfos($db, $tabelle)
 {
-	global $config;
-	$fields_infos=Array();
-	$t=GetCreateTable($db,$tabelle);
-	$sqlf="SHOW FULL FIELDS FROM `$db`.`$tabelle`;";
-	$res=MSD_query($sqlf);
-	$anz_fields=mysqli_num_rows($res);
+    global $config;
+    $fields_infos = [];
+    $t = GetCreateTable($db, $tabelle);
+    $sqlf = "SHOW FULL FIELDS FROM `$db`.`$tabelle`;";
+    $res = mod_query($sqlf);
+    $anz_fields = mysqli_num_rows($res);
 
-	$fields_infos['_primarykeys_']=array();
-	$fields_infos['_key_']=array();
-	$fields_infos['_uniquekey_']=array();
-	$fields_infos['_fulltextkey_']=array();
+    $fields_infos['_primarykeys_'] = [];
+    $fields_infos['_key_'] = [];
+    $fields_infos['_uniquekey_'] = [];
+    $fields_infos['_fulltextkey_'] = [];
 
-	$fields_infos['_tableinfo_']=array(
-										'ENGINE' => 'MyISAM',
-										'AUTO_INCREMENT' => '',
-										'DEFAULT CHARSET' => ''
-	);
+    $fields_infos['_tableinfo_'] = [
+                                        'ENGINE' => 'MyISAM',
+                                        'AUTO_INCREMENT' => '',
+                                        'DEFAULT CHARSET' => '',
+    ];
 
-	for ($i=0; $i < $anz_fields; $i++)
-	{
-		// define defaults
-		$fields_infos[$i]['name']='';
-		$fields_infos[$i]['size']='';
-		$fields_infos[$i]['default']='';
-		$fields_infos[$i]['extra']='';
-		$fields_infos[$i]['attributes']='';
-		$fields_infos[$i]['null']='';
-		$fields_infos[$i]['collate']='';
-		$fields_infos[$i]['comment']='';
-		$fields_infos[$i]['type']='';
-		$fields_infos[$i]['privileges']='';
+    for ($i = 0; $i < $anz_fields; ++$i) {
+        // define defaults
+        $fields_infos[$i]['name'] = '';
+        $fields_infos[$i]['size'] = '';
+        $fields_infos[$i]['default'] = '';
+        $fields_infos[$i]['extra'] = '';
+        $fields_infos[$i]['attributes'] = '';
+        $fields_infos[$i]['null'] = '';
+        $fields_infos[$i]['collate'] = '';
+        $fields_infos[$i]['comment'] = '';
+        $fields_infos[$i]['type'] = '';
+        $fields_infos[$i]['privileges'] = '';
 
-		$row=mysqli_fetch_array($res,MYSQLI_ASSOC);
-		//v($row);
-		if (isset($row['Collation'])) $fields_infos[$i]['collate']=$row['Collation'];
-		if (isset($row['COLLATE'])) $fields_infos[$i]['collate']=$row['COLLATE']; // MySQL <4.1
-		if (isset($row['Comment'])) $fields_infos[$i]['comment']=$row['Comment'];
-		if (isset($row['Type'])) $fields_infos[$i]['type']=$row['Type'];
-		if (isset($row['Field'])) $fields_infos[$i]['name']=$row['Field'];
-		$fields_infos[$i]['size']=get_attribut_size_from_type($fields_infos[$i]['type']);
-		// remove size from type for readability in output
-		$fields_infos[$i]['type']=str_replace('(' . $fields_infos[$i]['size'] . ')','',$fields_infos[$i]['type']);
-		// look for attributes, everthing behind the first space is an atribut
-		$attributes=explode(' ',$fields_infos[$i]['type'],2);
-		if (isset($attributes[1]))
-		{
-			// we found attributes
-			unset($attributes[0]); // delete type
-			$fields_infos[$i]['attributes']=trim(implode(' ',$attributes)); //merge all other attributes
-			// remove attributes from type
-			$fields_infos[$i]['type']=trim(str_replace($fields_infos[$i]['attributes'],'',$fields_infos[$i]['type']));
-		}
-		if (isset($row['NULL'])) $fields_infos[$i]['null']=$row['NULL'];
-		if (isset($row['Null'])) $fields_infos[$i]['null']=$row['Null'];
-		if (isset($row['Default'])) $fields_infos[$i]['default']=$row['Default'];
-		if (isset($row['Extra'])) $fields_infos[$i]['extra']=$row['Extra'];
-		if (isset($row['Privileges'])) $fields_infos[$i]['privileges']=$row['Privileges'];
-		if (isset($row['privileges'])) $fields_infos[$i]['privileges']=$row['privileges'];
-	}
+        $row = mysqli_fetch_array($res, MYSQLI_ASSOC);
+        //v($row);
+        if (isset($row['Collation'])) {
+            $fields_infos[$i]['collate'] = $row['Collation'];
+        }
+        if (isset($row['COLLATE'])) {
+            $fields_infos[$i]['collate'] = $row['COLLATE'];
+        } // MySQL <4.1
+        if (isset($row['Comment'])) {
+            $fields_infos[$i]['comment'] = $row['Comment'];
+        }
+        if (isset($row['Type'])) {
+            $fields_infos[$i]['type'] = $row['Type'];
+        }
+        if (isset($row['Field'])) {
+            $fields_infos[$i]['name'] = $row['Field'];
+        }
+        $fields_infos[$i]['size'] = get_attribut_size_from_type($fields_infos[$i]['type']);
+        // remove size from type for readability in output
+        $fields_infos[$i]['type'] = str_replace('('.$fields_infos[$i]['size'].')', '', $fields_infos[$i]['type']);
+        // look for attributes, everthing behind the first space is an atribut
+        $attributes = explode(' ', $fields_infos[$i]['type'], 2);
+        if (isset($attributes[1])) {
+            // we found attributes
+            unset($attributes[0]); // delete type
+            $fields_infos[$i]['attributes'] = trim(implode(' ', $attributes)); //merge all other attributes
+            // remove attributes from type
+            $fields_infos[$i]['type'] = trim(str_replace($fields_infos[$i]['attributes'], '', $fields_infos[$i]['type']));
+        }
+        if (isset($row['NULL'])) {
+            $fields_infos[$i]['null'] = $row['NULL'];
+        }
+        if (isset($row['Null'])) {
+            $fields_infos[$i]['null'] = $row['Null'];
+        }
+        if (isset($row['Default'])) {
+            $fields_infos[$i]['default'] = $row['Default'];
+        }
+        if (isset($row['Extra'])) {
+            $fields_infos[$i]['extra'] = $row['Extra'];
+        }
+        if (isset($row['Privileges'])) {
+            $fields_infos[$i]['privileges'] = $row['Privileges'];
+        }
+        if (isset($row['privileges'])) {
+            $fields_infos[$i]['privileges'] = $row['privileges'];
+        }
+    }
 
-	// now get key definitions of the table and add info to fields
-	$sql='SHOW KEYS FROM `' . $db . '`.`' . $tabelle . '`';
-	$res=MSD_query($sql);
-	while ($row=mysqli_fetch_array($res,MYSQLI_ASSOC))
-	{
-		//v($row);
-		$key_name=isset($row['Key_name']) ? $row['Key_name'] : '';
-		$index_type=isset($row['Index_type']) ? $row['Index_type'] : '';
-		$column_name=isset($row['Column_name']) ? $row['Column_name'] : '';
-		$non_unique=isset($row['Non_unique']) ? $row['Non_unique'] : '';
-		if ($column_name > '')
-		{
-			// first find indexnr of field
-			for ($index=0, $count=sizeof($fields_infos); $index < $count; $index++)
-			{
-				if ($fields_infos[$index]['name'] == $column_name) break;
-			}
-			if ($key_name == 'PRIMARY')
-				$fields_infos['_primarykeys_'][]=$column_name;
-			elseif ($index_type == 'FULLTEXT')
-				$fields_infos['_fulltextkey_'][]=$column_name;
-			elseif ($non_unique == 0)
-				$fields_infos['_uniquekey_'][]=$column_name;
-			else
-				$fields_infos['_key_'][]=$column_name;
-		}
-	}
-	//v($fields_infos);
-	return $fields_infos;
+    // now get key definitions of the table and add info to fields
+    $sql = 'SHOW KEYS FROM `'.$db.'`.`'.$tabelle.'`';
+    $res = mod_query($sql);
+    while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+        //v($row);
+        $key_name = isset($row['Key_name']) ? $row['Key_name'] : '';
+        $index_type = isset($row['Index_type']) ? $row['Index_type'] : '';
+        $column_name = isset($row['Column_name']) ? $row['Column_name'] : '';
+        $non_unique = isset($row['Non_unique']) ? $row['Non_unique'] : '';
+        if ($column_name > '') {
+            // first find indexnr of field
+            for ($index = 0, $count = sizeof($fields_infos); $index < $count; ++$index) {
+                if ($fields_infos[$index]['name'] == $column_name) {
+                    break;
+                }
+            }
+            if ('PRIMARY' == $key_name) {
+                $fields_infos['_primarykeys_'][] = $column_name;
+            } elseif ('FULLTEXT' == $index_type) {
+                $fields_infos['_fulltextkey_'][] = $column_name;
+            } elseif (0 == $non_unique) {
+                $fields_infos['_uniquekey_'][] = $column_name;
+            } else {
+                $fields_infos['_key_'][] = $column_name;
+            }
+        }
+    }
+    //v($fields_infos);
+    return $fields_infos;
 }
 
 /**
- * Reads extened MySQL field information
+ * Reads extened MySQL field information.
  *
  * Reads extened field information for each field of a MySQL table
  * and fills an array like
  * array(
- *  [Fieldname][attribut]=value,
- *  ['primary_key']=keys
+ *  [Fieldname][attribut] =value,
+ *  ['primary_key'] =keys
  * )
  *
- * @param $db Database
- * @param $table Table
+ * @param $db
+ * @param $table
+ *
  * @return array Field infos
  */
 function getExtendedFieldInfo($db, $table)
 {
-	global $config;
-	$fields_infos=Array();
-	$t=GetCreateTable($db,$table);
-	$sqlf="SHOW FULL FIELDS FROM `$db`.`$table`;";
-	$res=MSD_query($sqlf);
-	$num_fields=mysqli_num_rows($res);
+    global $config;
+    $fields_infos = [];
+    $t = GetCreateTable($db, $table);
+    $sqlf = "SHOW FULL FIELDS FROM `$db`.`$table`;";
+    $res = mod_query($sqlf);
+    $num_fields = mysqli_num_rows($res);
 
-	$f=array(); //will hold all info
-	for ($x=0; $x < $num_fields; $x++)
-	{
-		$row=mysqli_fetch_array($res,MYSQLI_ASSOC);
-		//v($row);
-		$i=$row['Field']; // define name of field as index of array
-		//define field defaults - this way the index of the array is defined anyway
-		$f[$i]['field']='';
-		$f[$i]['collation']='';
-		$f[$i]['comment']='';
-		$f[$i]['type']='';
-		$f[$i]['size']='';
-		$f[$i]['attributes']='';
-		$f[$i]['null']='';
-		$f[$i]['default']='';
-		$f[$i]['extra']='';
-		$f[$i]['privileges']='';
-		$f[$i]['primary_keys']=array();
+    $f = []; //will hold all info
+    for ($x = 0; $x < $num_fields; ++$x) {
+        $row = mysqli_fetch_array($res, MYSQLI_ASSOC);
+        //v($row);
+        $i = $row['Field']; // define name of field as index of array
+        //define field defaults - this way the index of the array is defined anyway
+        $f[$i]['field'] = '';
+        $f[$i]['collation'] = '';
+        $f[$i]['comment'] = '';
+        $f[$i]['type'] = '';
+        $f[$i]['size'] = '';
+        $f[$i]['attributes'] = '';
+        $f[$i]['null'] = '';
+        $f[$i]['default'] = '';
+        $f[$i]['extra'] = '';
+        $f[$i]['privileges'] = '';
+        $f[$i]['primary_keys'] = [];
 
-		if (isset($row['Collation'])) $f[$i]['collate']=$row['Collation'];
-		if (isset($row['COLLATE'])) $f[$i]['collate']=$row['COLLATE']; // MySQL <4.1
-		if (isset($row['Comment'])) $f[$i]['comment']=$row['Comment'];
-		if (isset($row['Type'])) $f[$i]['type']=$row['Type'];
-		if (isset($row['Field'])) $f[$i]['field']=$row['Field'];
-		$f[$i]['size']=get_attribut_size_from_type($f[$i]['type']);
-		// remove size from type for readability in output
-		$f[$i]['type']=str_replace('(' . $f[$i]['size'] . ')','',$f[$i]['type']);
-		// look for attributes, everthing behind the first space is an atribut
-		$attributes=explode(' ',$f[$i]['type'],2);
-		if (isset($attributes[1]))
-		{
-			// we found attributes
-			unset($attributes[0]); // delete type
-			$f[$i]['attributes']=trim(implode(' ',$attributes)); //merge all other attributes
-			// remove attributes from type
-			$f[$i]['type']=trim(str_replace($f[$i]['attributes'],'',$f[$i]['type']));
-		}
-		if (isset($row['NULL'])) $f[$i]['null']=$row['NULL'];
-		if (isset($row['Null'])) $f[$i]['null']=$row['Null'];
-		if (isset($row['Default'])) $f[$i]['default']=$row['Default'];
-		if (isset($row['Extra'])) $f[$i]['extra']=$row['Extra'];
-		if (isset($row['Privileges'])) $f[$i]['privileges']=$row['Privileges'];
-		if (isset($row['privileges'])) $f[$i]['privileges']=$row['privileges'];
-	}
+        if (isset($row['Collation'])) {
+            $f[$i]['collate'] = $row['Collation'];
+        }
+        if (isset($row['COLLATE'])) {
+            $f[$i]['collate'] = $row['COLLATE'];
+        } // MySQL <4.1
+        if (isset($row['Comment'])) {
+            $f[$i]['comment'] = $row['Comment'];
+        }
+        if (isset($row['Type'])) {
+            $f[$i]['type'] = $row['Type'];
+        }
+        if (isset($row['Field'])) {
+            $f[$i]['field'] = $row['Field'];
+        }
+        $f[$i]['size'] = get_attribut_size_from_type($f[$i]['type']);
+        // remove size from type for readability in output
+        $f[$i]['type'] = str_replace('('.$f[$i]['size'].')', '', $f[$i]['type']);
+        // look for attributes, everthing behind the first space is an atribut
+        $attributes = explode(' ', $f[$i]['type'], 2);
+        if (isset($attributes[1])) {
+            // we found attributes
+            unset($attributes[0]); // delete type
+            $f[$i]['attributes'] = trim(implode(' ', $attributes)); //merge all other attributes
+            // remove attributes from type
+            $f[$i]['type'] = trim(str_replace($f[$i]['attributes'], '', $f[$i]['type']));
+        }
+        if (isset($row['NULL'])) {
+            $f[$i]['null'] = $row['NULL'];
+        }
+        if (isset($row['Null'])) {
+            $f[$i]['null'] = $row['Null'];
+        }
+        if (isset($row['Default'])) {
+            $f[$i]['default'] = $row['Default'];
+        }
+        if (isset($row['Extra'])) {
+            $f[$i]['extra'] = $row['Extra'];
+        }
+        if (isset($row['Privileges'])) {
+            $f[$i]['privileges'] = $row['Privileges'];
+        }
+        if (isset($row['privileges'])) {
+            $f[$i]['privileges'] = $row['privileges'];
+        }
+    }
 
-	// now get key definitions of the table and add info to field-array
-	$sql='SHOW KEYS FROM `' . $db . '`.`' . $table . '`';
-	$res=MSD_query($sql);
-	while ($row=mysqli_fetch_array($res,MYSQLI_ASSOC))
-	{
-		//echo "<br>Keys of $table: ";v($row);
-		$key_name=isset($row['Key_name']) ? $row['Key_name'] : '';
-		$index_type=isset($row['Index_type']) ? $row['Index_type'] : '';
-		$column_name=isset($row['Column_name']) ? $row['Column_name'] : '';
-		// to do: add other info about index etc.
-		if ($key_name == 'PRIMARY') $f['primary_keys'][]=$column_name;
-	}
-	return $f;
+    // now get key definitions of the table and add info to field-array
+    $sql = 'SHOW KEYS FROM `'.$db.'`.`'.$table.'`';
+    $res = mod_query($sql);
+    while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+        //echo "<br>Keys of $table: ";v($row);
+        $key_name = isset($row['Key_name']) ? $row['Key_name'] : '';
+        $index_type = isset($row['Index_type']) ? $row['Index_type'] : '';
+        $column_name = isset($row['Column_name']) ? $row['Column_name'] : '';
+        // to do: add other info about index etc.
+        if ('PRIMARY' == $key_name) {
+            $f['primary_keys'][] = $column_name;
+        }
+    }
+    return $f;
 }
 
-function ChangeKeys($ok, $nk, $fld, $size, $restriction='')
+function ChangeKeys($ok, $nk, $fld, $size, $restriction = '')
 {
-	if ($ok[0] == $nk[0] && $ok[1] == $nk[1] && $ok[2] == $nk[2] && $ok[3] == $nk[3]) return '';
-	else
-	{
-		$s='';
-		if ($ok[0] == 0 && $nk[0] == 1)
-		{
-			if ($restriction != 'drop_only') $s.="ADD PRIMARY KEY (`$fld`), ";
-		}
-		elseif ($ok[0] == 1 && $nk[0] == 0)
-		{
-			$s.='DROP PRIMARY KEY, ';
-		}
-		if ($ok[1] == 0 && $nk[1] == 1)
-		{
-			if ($restriction != 'drop_only') $s.="ADD UNIQUE INDEX `$fld` (`$fld`), ";
-		}
-		elseif ($ok[1] == 1 && $nk[1] == 0)
-		{
-			$s.="DROP INDEX `$fld`, ";
-		}
-		if ($ok[2] == 0 && $nk[2] == 1)
-		{
-			if ($restriction != 'drop_only') $s.="ADD INDEX `$fld` (`$fld`), ";
-		}
-		elseif ($ok[2] == 1 && $nk[2] == 0)
-		{
-			$s.="DROP INDEX `$fld`, ";
-		}
-		if ($ok[3] == 0 && $nk[3] == 1)
-		{
-			if ($restriction != 'drop_only') $s.="ADD FULLTEXT INDEX `$fld` (`$fld`($size)), ";
-		}
-		elseif ($ok[3] == 1 && $nk[3] == 0)
-		{
-			$s.="DROP FULLTEXT INDEX `$fld`, ";
-		}
-	}
-	if ($s != '') $s=substr($s,0,strlen($s) - 2);
-	return $s;
+    if ($ok[0] == $nk[0] && $ok[1] == $nk[1] && $ok[2] == $nk[2] && $ok[3] == $nk[3]) {
+        return '';
+    } else {
+        $s = '';
+        if (0 == $ok[0] && 1 == $nk[0]) {
+            if ('drop_only' != $restriction) {
+                $s .= "ADD PRIMARY KEY (`$fld`), ";
+            }
+        } elseif (1 == $ok[0] && 0 == $nk[0]) {
+            $s .= 'DROP PRIMARY KEY, ';
+        }
+        if (0 == $ok[1] && 1 == $nk[1]) {
+            if ('drop_only' != $restriction) {
+                $s .= "ADD UNIQUE INDEX `$fld` (`$fld`), ";
+            }
+        } elseif (1 == $ok[1] && 0 == $nk[1]) {
+            $s .= "DROP INDEX `$fld`, ";
+        }
+        if (0 == $ok[2] && 1 == $nk[2]) {
+            if ('drop_only' != $restriction) {
+                $s .= "ADD INDEX `$fld` (`$fld`), ";
+            }
+        } elseif (1 == $ok[2] && 0 == $nk[2]) {
+            $s .= "DROP INDEX `$fld`, ";
+        }
+        if (0 == $ok[3] && 1 == $nk[3]) {
+            if ('drop_only' != $restriction) {
+                $s .= "ADD FULLTEXT INDEX `$fld` (`$fld`($size)), ";
+            }
+        } elseif (1 == $ok[3] && 0 == $nk[3]) {
+            $s .= "DROP FULLTEXT INDEX `$fld`, ";
+        }
+    }
+    if ('' != $s) {
+        $s = substr($s, 0, strlen($s) - 2);
+    }
+    return $s;
 }
 
 function build_where_from_record($data)
 {
-	if (!is_array($data)) return false;
-	$ret='';
-	foreach ($data as $key=>$val)
-	{
-		$val=str_replace('<span class="treffer">','',$val);
-		$val=str_replace('</span>','',$val);
-		if (!empty($val)){
-			$ret.='`' . $key . '`="' . addslashes($val) . '" AND ';
-		}
-	}
-	$ret=substr($ret,0,-5);
-	return $ret;
+    if (!is_array($data)) {
+        return false;
+    }
+    $ret = '';
+    foreach ($data as $key => $val) {
+        if (is_string($val)) {
+            $val = str_replace('<span class="treffer">', '', $val);
+            $val = str_replace('</span>', '', $val);
+        }
+        $nLen = strlen($val);
+        if (!empty($val) && ($nLen < 200)) {
+            $ret .= '`'.$key.'`="'.addslashes($val).'" AND ';
+        }
+    }
+    $ret = substr($ret, 0, -5);
+
+    return $ret;
 }
 
 /*
@@ -1098,24 +1127,22 @@ function build_where_from_record($data)
  */
 function getPrimaryKeys($db, $table)
 {
-	$keys=Array();
-	$sqlk="SHOW KEYS FROM `" . $db . "`.`" . $table . "`;";
-	$res=MSD_query($sqlk);
-	while ($row=mysqli_fetch_array($res))
-	{
-		//wenn Primaerschluessel
-		if ($row['Key_name'] == "PRIMARY") $keys['name'][]=$row['Column_name'];
-		if ($row['Sub_part'] != null)
-		{
-			$keys['size'][]=$row['Sub_part'];
-		}
-		else
-		{
-			$keys['size'][]='';
-		}
-	}
+    $keys = [];
+    $sqlk = 'SHOW KEYS FROM `'.$db.'`.`'.$table.'`;';
+    $res = mod_query($sqlk);
+    while ($row = mysqli_fetch_array($res)) {
+        //wenn Primaerschluessel
+        if ('PRIMARY' == $row['Key_name']) {
+            $keys['name'][] = $row['Column_name'];
+        }
+        if (null != $row['Sub_part']) {
+            $keys['size'][] = $row['Sub_part'];
+        } else {
+            $keys['size'][] = '';
+        }
+    }
 
-	return $keys;
+    return $keys;
 }
 
 /*
@@ -1126,14 +1153,13 @@ function getPrimaryKeys($db, $table)
  */
 function getAllFields($db, $table)
 {
-	$fields=Array();
-	$sqlk="DESCRIBE `" . $db . "`.`" . $table . "`;";
-	$res=MSD_query($sqlk);
-	while ($row=mysqli_fetch_array($res))
-	{
-		$fields[]=$row['Field'];
-	}
-	return $fields;
+    $fields = [];
+    $sqlk = 'DESCRIBE `'.$db.'`.`'.$table.'`;';
+    $res = mod_query($sqlk);
+    while ($row = mysqli_fetch_array($res)) {
+        $fields[] = $row['Field'];
+    }
+    return $fields;
 }
 
 /*
@@ -1144,94 +1170,99 @@ function getAllFields($db, $table)
  */
 function setNewPrimaryKeys($db, $table, $newKeys, $indexSizes)
 {
-    $sqlSetNewPrimaryKeys="ALTER TABLE `" . $db . "`.`" . $table . "`";
+    $sqlSetNewPrimaryKeys = 'ALTER TABLE `'.$db.'`.`'.$table.'`';
     //wenn es Primaerschluessel gibt, diese loeschen
     $existingKeys = getPrimaryKeys($db, $table);
-    if (count($existingKeys) > 0)
-    {
-        $sqlSetNewPrimaryKeys.=" DROP PRIMARY KEY";
+    if (count($existingKeys) > 0) {
+        $sqlSetNewPrimaryKeys .= ' DROP PRIMARY KEY';
     }
     //wenn min. 1 Schluessel im Array, sonst nur loeschen
-	if (count($newKeys) > 0)
-	{
-        if (count($existingKeys) > 0)
-        {
-            $sqlSetNewPrimaryKeys.=", ";
+    if (count($newKeys) > 0) {
+        if (count($existingKeys) > 0) {
+            $sqlSetNewPrimaryKeys .= ', ';
         }
-        $sqlSetNewPrimaryKeys.=" ADD PRIMARY KEY (";
-		foreach ($newKeys as $id => $name)
-		{
-			if ($id > 0) $sqlSetNewPrimaryKeys.=", ";
-			$sqlSetNewPrimaryKeys.="`" . $name . "`";
-			if ($indexSizes[$id]) {
-				$sqlSetNewPrimaryKeys.=" (" . $indexSizes[$id] . ")";
-			}
-		}
-		$sqlSetNewPrimaryKeys.=")";
-	}
-	$sqlSetNewPrimaryKeys.=";";
-	$res=MSD_query($sqlSetNewPrimaryKeys);
-	return $res;
+        $sqlSetNewPrimaryKeys .= ' ADD PRIMARY KEY (';
+        foreach ($newKeys as $id => $name) {
+            if ($id > 0) {
+                $sqlSetNewPrimaryKeys .= ', ';
+            }
+            $sqlSetNewPrimaryKeys .= '`'.$name.'`';
+            if ($indexSizes[$id]) {
+                $sqlSetNewPrimaryKeys .= ' ('.$indexSizes[$id].')';
+            }
+        }
+        $sqlSetNewPrimaryKeys .= ')';
+    }
+    $sqlSetNewPrimaryKeys .= ';';
+    $res = mod_query($sqlSetNewPrimaryKeys);
+    return $res;
 }
 
 function setNewKeys($db, $table, $newKeys, $indexType, $indexName, $indexSizes)
 {
-    $sqlSetNewKeys="ALTER TABLE `" . $db . "`.`" . $table . "` ";
-    $sqlSetNewKeys.="ADD ".$indexType." ";
-	if ($indexName)
-	{
-		 $sqlSetNewKeys.="`" . $indexName ."` ";
-	}
-	$sqlSetNewKeys.="(";
-	foreach ($newKeys as $id => $name)
-    {
-		if ($id > 0) $sqlSetNewKeys.=", ";
-		$sqlSetNewKeys.="`" . $name . "`";
-		if ($indexSizes[$id]) {
-			$sqlSetNewKeys.=" (" . $indexSizes[$id] . ")";
-		}
-	}
-	$sqlSetNewKeys.=");";
-	$res=MSD_query($sqlSetNewKeys);
-	return $res;
+    $sqlSetNewKeys = 'ALTER TABLE `'.$db.'`.`'.$table.'` ';
+    $sqlSetNewKeys .= 'ADD '.$indexType.' ';
+    if ($indexName) {
+        $sqlSetNewKeys .= '`'.$indexName.'` ';
+    }
+    $sqlSetNewKeys .= '(';
+    foreach ($newKeys as $id => $name) {
+        if ($id > 0) {
+            $sqlSetNewKeys .= ', ';
+        }
+        $sqlSetNewKeys .= '`'.$name.'`';
+        if ($indexSizes[$id]) {
+            $sqlSetNewKeys .= ' ('.$indexSizes[$id].')';
+        }
+    }
+    $sqlSetNewKeys .= ');';
+    $res = mod_query($sqlSetNewKeys);
+    return $res;
 }
 
 function killKey($db, $table, $indexName)
 {
-	$sqlKillKey = "ALTER TABLE `".$db."`.`".$table."` DROP INDEX `".$indexName."`";
-	$res=MSD_query($sqlKillKey);
-	return $res;
+    $sqlKillKey = 'ALTER TABLE `'.$db.'`.`'.$table.'` DROP INDEX `'.$indexName.'`';
+    $res = mod_query($sqlKillKey);
+    return $res;
 }
 
 function get_output_attribut_null($null)
 {
-	global $lang;
-	if ($null == '') return $lang['L_YES'];
-	$not_null=array(
-					'NO',
-					'NOT NULL'
-	);
-	if (in_array($null,$not_null)) return $lang['L_NO'];
-	else return $lang['L_YES'];
+    global $lang;
+    if ('' == $null) {
+        return $lang['L_YES'];
+    }
+    $not_null = [
+                    'NO',
+                    'NOT NULL',
+    ];
+    if (in_array($null, $not_null)) {
+        return $lang['L_NO'];
+    } else {
+        return $lang['L_YES'];
+    }
 }
 
 function get_attribut_size_from_type($type)
 {
-	$size='';
-	$matches=array();
-	$pattern='/\((\d.*?)\)/msi';
-	preg_match($pattern,$type,$matches);
-	if (isset($matches[1])) $size=$matches[1];
-	return $size;
+    $size = '';
+    $matches = [];
+    $pattern = '/\((\d.*?)\)/msi';
+    preg_match($pattern, $type, $matches);
+    if (isset($matches[1])) {
+        $size = $matches[1];
+    }
+    return $size;
 }
 
-
 // Bildet die WHERE-Bedingung zur eindeutigen Identifizierung wenn kein Primaerschluessel vorhanden ist
-// erwartet ein Array mit $data[feldname]=wert
+// erwartet ein Array mit $data[feldname] =wert
 function build_recordkey($data)
 {
-	if (!is_array($data)) return urlencode($data);
-	else return urlencode(serialize($data));
+    if (!is_array($data)) {
+        return urlencode($data);
+    } else {
+        return urlencode(serialize($data));
+    }
 }
-
-
diff --git a/msd/inc/header.php b/msd/inc/header.php
index 07ea8ed6..9a517e38 100644
--- a/msd/inc/header.php
+++ b/msd/inc/header.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,25 +16,35 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-$msd_path=realpath(dirname(__FILE__) . '/../') . '/';
-if (!defined('MSD_PATH')) define('MSD_PATH',$msd_path);
+$mod_path = realpath(dirname(__FILE__).'/../').'/';
+if (!defined('MOD_PATH')) {
+    define('MOD_PATH', $mod_path);
+}
 session_name('MyOOSDumperID');
 session_start();
-if (!isset($download))
-{
-	header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
-	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
-	header("Cache-Control: no-store, no-cache, must-revalidate");
-	header("Cache-Control: post-check=0, pre-check=0",false);
-	header("Pragma: no-cache");
+if (!isset($download)) {
+    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
+    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+    header('Cache-Control: no-store, no-cache, must-revalidate');
+    header('Cache-Control: post-check=0, pre-check=0', false);
+    header('Pragma: no-cache');
+}
+include MOD_PATH.'inc/functions.php';
+include MOD_PATH.'inc/mysqli.php';
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+if (!file_exists($config['files']['parameter'])) {
+    $error = TestWorkDir();
 }
-include ( MSD_PATH . 'inc/functions.php' );
-include ( MSD_PATH . 'inc/mysql.php' );
-if (!defined('MSD_VERSION')) die('No direct access.');
-if (!file_exists($config['files']['parameter'])) $error=TestWorkDir();
 read_config($config['config_file']);
-include ( MSD_PATH . 'language/lang_list.php' );
-if (!isset($databases['db_selected_index'])) $databases['db_selected_index']=0;
+include MOD_PATH.'language/lang_list.php';
+if (!isset($databases['db_selected_index'])) {
+    $databases['db_selected_index'] = 0;
+}
 SelectDB($databases['db_selected_index']);
-$config['files']['iconpath']='./css/' . $config['theme'] . '/icons/';
-if (isset($error)) echo $error;
+$config['theme'] = isset($config['theme']) ? $config['theme'] : 'mod';
+$config['files']['iconpath'] = './css/'.$config['theme'].'/icons/';
+if (isset($error)) {
+    echo $error;
+}
diff --git a/msd/inc/home/apr1_md5/apr1_md5.php b/msd/inc/home/apr1_md5/apr1_md5.php
new file mode 100644
index 00000000..4df10ae9
--- /dev/null
+++ b/msd/inc/home/apr1_md5/apr1_md5.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace WhiteHat101\Crypt;
+
+class APR1_MD5
+{
+    public const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+    public const APRMD5_ALPHABET = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+
+    // Source/References for core algorithm:
+    // http://www.cryptologie.net/article/126/bruteforce-apr1-hashes/
+    // http://svn.apache.org/viewvc/apr/apr-util/branches/1.3.x/crypto/apr_md5.c?view=co
+    // http://www.php.net/manual/en/function.crypt.php#73619
+    // http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
+    // Wikipedia
+
+    public static function hash($mdp, $salt = null)
+    {
+        if (is_null($salt)) {
+            $salt = self::salt();
+        }
+        $salt = substr($salt, 0, 8);
+        $max = strlen($mdp);
+        $context = $mdp.'$apr1$'.$salt;
+        $binary = pack('H32', md5($mdp.$salt.$mdp));
+        for ($i = $max; $i > 0; $i -= 16) {
+            $context .= substr($binary, 0, min(16, $i));
+        }
+        for ($i = $max; $i > 0; $i >>= 1) {
+            $context .= ($i & 1) ? chr(0) : $mdp[0];
+        }
+        $binary = pack('H32', md5($context));
+        for ($i = 0; $i < 1000; ++$i) {
+            $new = ($i & 1) ? $mdp : $binary;
+            if ($i % 3) {
+                $new .= $salt;
+            }
+            if ($i % 7) {
+                $new .= $mdp;
+            }
+            $new .= ($i & 1) ? $binary : $mdp;
+            $binary = pack('H32', md5($new));
+        }
+        $hash = '';
+        for ($i = 0; $i < 5; ++$i) {
+            $k = $i + 6;
+            $j = $i + 12;
+            if (16 == $j) {
+                $j = 5;
+            }
+            $hash = $binary[$i].$binary[$k].$binary[$j].$hash;
+        }
+        $hash = chr(0).chr(0).$binary[11].$hash;
+        $hash = strtr(
+            strrev(substr(base64_encode($hash), 2)),
+            self::BASE64_ALPHABET,
+            self::APRMD5_ALPHABET
+        );
+        return '$apr1$'.$salt.'$'.$hash;
+    }
+
+    // 8 character salts are the best. Don't encourage anything but the best.
+    public static function salt()
+    {
+        $alphabet = self::APRMD5_ALPHABET;
+        $salt = '';
+        for ($i = 0; $i < 8; ++$i) {
+            $offset = hexdec(bin2hex(openssl_random_pseudo_bytes(1))) % 64;
+            $salt .= $alphabet[$offset];
+        }
+        return $salt;
+    }
+
+    public static function check($plain, $hash)
+    {
+        $parts = explode('$', $hash);
+        return self::hash($plain, $parts[2]) === $hash;
+    }
+}
diff --git a/msd/inc/home/apr1_md5/license.txt b/msd/inc/home/apr1_md5/license.txt
new file mode 100644
index 00000000..3e0c9c76
--- /dev/null
+++ b/msd/inc/home/apr1_md5/license.txt
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Jeremy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/msd/inc/home/apr1_md5/origin_url.txt b/msd/inc/home/apr1_md5/origin_url.txt
new file mode 100644
index 00000000..65734146
--- /dev/null
+++ b/msd/inc/home/apr1_md5/origin_url.txt
@@ -0,0 +1 @@
+https://github.com/whitehat101/apr1-md5
diff --git a/msd/inc/home/databases.php b/msd/inc/home/databases.php
index 28cab1e4..9863a14e 100644
--- a/msd/inc/home/databases.php
+++ b/msd/inc/home/databases.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,215 +16,215 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
-include('./language/'.$config['language'].'/lang_sql.php');
-$checkit=(isset($_GET['checkit'])) ? urldecode($_GET['checkit']) : '';
-$repair=(isset($_GET['repair'])) ? $_GET['repair'] : 0;
-$enableKeys=(isset($_GET['enableKeys'])) ? $_GET['enableKeys'] : '';
-for ($i=0; $i<count($databases['Name']); $i++)
-{
-	if (isset($_POST['empty'.$i]))
-	{
-		EmptyDB($databases['Name'][$i]);
-		$dba='<p class="green">'.$lang['L_DB']." ".$databases['Name'][$i]." ".$lang['L_INFO_CLEARED']."</p>";
-		break;
-	}
-	if (isset($_POST['kill'.$i]))
-	{
-		$res=mysqli_query($config['dbconnection'], 'DROP DATABASE `'.$databases['Name'][$i].'`') or die(mysqli_error($config['dbconnection']));
-		$dba='<p class="green">'.$lang['L_DB'].' '.$databases['Name'][$i].' '.$lang['L_INFO_DELETED'].'</p>';
-		SetDefault();
-		include ($config['files']['parameter']);
-		echo '<script language="JavaScript">parent.MyOOS_Dumper_menu.location.href="menu.php?action=dbrefresh";</script>';
-		break;
-	}
-	if (isset($_POST['optimize'.$i]))
-	{
-	    mysqli_select_db($config['dbconnection'], $databases['Name'][$i]);
-        $res=mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `'.$databases['Name'][$i].'`');
-		$tabellen='';
-		while ($row=mysqli_fetch_row($res))
-			$tabellen.='`'.$row[0].'`,';
-		$tabellen=substr($tabellen,0,(strlen($tabellen)-1));
-		if ($tabellen>"")
-		{
-			$query="OPTIMIZE TABLE ".$tabellen;
-			$res=mysqli_query($config['dbconnection'], $query) or die(mysqli_error($config['dbconnection'])."");
-		}
-		$_GET['dbid']=$i;
-		$dba='<p class="green">'.$lang['L_DB'].' <b>'.$databases['Name'][$i].'</b> '.$lang['L_INFO_OPTIMIZED'].'.</p>';
-		break;
-	}
-	if (isset($_POST['check'.$i]))
-	{
-		$checkit="ALL";
-		$_GET['dbid']=$i;
-	}
-	if (isset($_POST['enableKeys'.$i])) {
-	    $enableKeys="ALL";
-        $_GET['dbid']=$i;
-	}
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+include './language/'.$config['language'].'/lang_sql.php';
+$checkit = (isset($_GET['checkit'])) ? urldecode($_GET['checkit']) : '';
+$repair = (isset($_GET['repair'])) ? $_GET['repair'] : 0;
+$enableKeys = (isset($_GET['enableKeys'])) ? $_GET['enableKeys'] : '';
+for ($i = 0; $i < count($databases['Name']); ++$i) {
+    if (isset($_POST['empty'.$i])) {
+        EmptyDB($databases['Name'][$i]);
+        $dba = '<p class="green">'.$lang['L_DB'].' '.$databases['Name'][$i].' '.$lang['L_INFO_CLEARED'].'</p>';
+        break;
+    }
+    if (isset($_POST['kill'.$i])) {
+        $res = mysqli_query($config['dbconnection'], 'DROP DATABASE `'.$databases['Name'][$i].'`') or exit(mysqli_error($config['dbconnection']));
+        $dba = '<p class="green">'.$lang['L_DB'].' '.$databases['Name'][$i].' '.$lang['L_INFO_DELETED'].'</p>';
+        SetDefault();
+        include $config['files']['parameter'];
+        echo '<script>parent.MyOOS_Dumper_menu.location.href="menu.php?action=dbrefresh";</script>';
+        break;
+    }
+    if (isset($_POST['optimize'.$i])) {
+        mysqli_select_db($config['dbconnection'], $databases['Name'][$i]);
+        $res = mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `'.$databases['Name'][$i].'`');
+        $tabellen = '';
+        while ($row = mysqli_fetch_row($res)) {
+            $tabellen .= '`'.$row[0].'`,';
+        }
+        $tabellen = substr($tabellen, 0, (strlen($tabellen) - 1));
+        if ($tabellen > '') {
+            $query = 'OPTIMIZE TABLE '.$tabellen;
+            $res = mysqli_query($config['dbconnection'], $query) or exit(mysqli_error($config['dbconnection']).'');
+        }
+        $_GET['dbid'] = $i;
+        $dba = '<p class="green">'.$lang['L_DB'].' <b>'.$databases['Name'][$i].'</b> '.$lang['L_INFO_OPTIMIZED'].'.</p>';
+        break;
+    }
+    if (isset($_POST['check'.$i])) {
+        $checkit = 'ALL';
+        $_GET['dbid'] = $i;
+    }
+    if (isset($_POST['enableKeys'.$i])) {
+        $enableKeys = 'ALL';
+        $_GET['dbid'] = $i;
+    }
 }
 
 //list databases
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => './tpl/home/databases_list_dbs.tpl'));
-$tpl->assign_vars(array(
-	'ICONPATH' => $config['files']['iconpath']));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => './tpl/home/databases_list_dbs.tpl', ]);
+$tpl->assign_vars([
+    'ICONPATH' => $config['files']['iconpath'], ]);
 
-if (!isset($config['dbconnection'])) MSD_mysql_connect();
-for ($i=0; $i<count($databases['Name']); $i++)
-{
-	$rowclass=($i%2) ? 'dbrow' : 'dbrow1';
-	if ($i==$databases['db_selected_index']) $rowclass="dbrowsel";
+if (!isset($config['dbconnection'])) {
+    mod_mysqli_connect();
+}
+for ($i = 0; $i < count($databases['Name']); ++$i) {
+    $rowclass = ($i % 2) ? 'dbrow' : 'dbrow1';
+    if ($i == $databases['db_selected_index']) {
+        $rowclass = 'dbrowsel';
+    }
 
-	//gibts die Datenbank überhaupt?
-	if (!mysqli_select_db($config['dbconnection'], $databases['Name'][$i]))
-	{
-		$tpl->assign_block_vars('DB_NOT_FOUND',array(
-			'ROWCLASS' => $rowclass,
-			'NR' => ($i+1),
-			'DB_NAME' => $databases['Name'][$i],
-			'DB_ID' => $i));
-	}
-	else
-	{
-		mysqli_select_db($config['dbconnection'], $databases['Name'][$i]);
-		$tabellen=mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `'.$databases['Name'][$i].'`');
-		$num_tables=mysqli_num_rows($tabellen);
-		$tpl->assign_block_vars('ROW',array(
-			'ROWCLASS' => $rowclass,
-			'NR' => ($i+1),
-			'DB_NAME' => $databases['Name'][$i],
-			'DB_ID' => $i,
-			'TABLE_COUNT' => $num_tables));
-		if ($num_tables==1) $tpl->assign_block_vars('ROW.TABLE',array());
-		else
-			$tpl->assign_block_vars('ROW.TABLES',array());
-	}
+    //gibts die Datenbank überhaupt?
+    if (!mysqli_select_db($config['dbconnection'], $databases['Name'][$i])) {
+        $tpl->assign_block_vars('DB_NOT_FOUND', [
+            'ROWCLASS' => $rowclass,
+            'NR' => ($i + 1),
+            'DB_NAME' => $databases['Name'][$i],
+            'DB_ID' => $i, ]);
+    } else {
+        mysqli_select_db($config['dbconnection'], $databases['Name'][$i]);
+        $tabellen = mysqli_query($config['dbconnection'], 'SHOW TABLES FROM `'.$databases['Name'][$i].'`');
+        $num_tables = mysqli_num_rows($tabellen);
+        $tpl->assign_block_vars('ROW', [
+            'ROWCLASS' => $rowclass,
+            'NR' => ($i + 1),
+            'DB_NAME' => $databases['Name'][$i],
+            'DB_ID' => $i,
+            'TABLE_COUNT' => $num_tables, ]);
+        if (1 == $num_tables) {
+            $tpl->assign_block_vars('ROW.TABLE', []);
+        } else {
+            $tpl->assign_block_vars('ROW.TABLES', []);
+        }
+    }
 }
 $tpl->pparse('show');
 
 //list tables of selected database
-if (isset($_GET['dbid']))
-{
+if (isset($_GET['dbid'])) {
     $disabled_keys_found = false;
 
     // Output list of tables of the selected database
-	$tpl=new MSDTemplate();
-	$tpl->set_filenames(array(
-		'show' => 'tpl/home/databases_list_tables.tpl'));
-	$dbid=$_GET['dbid'];
+    $tpl = new MODTemplate();
+    $tpl->set_filenames([
+        'show' => 'tpl/home/databases_list_tables.tpl', ]);
+    $dbid = $_GET['dbid'];
 
-	$numrows=0;
-	$res=@mysqli_query($config['dbconnection'], "SHOW TABLE STATUS FROM `".$databases['Name'][$dbid]."`");
-	mysqli_select_db($config['dbconnection'], $databases['Name'][$dbid]);
-	if ($res) $numrows=mysqli_num_rows($res);
-	$tpl->assign_vars(array(
-		'DB_NAME' => $databases['Name'][$dbid],
-		'DB_NAME_URLENCODED' => urlencode($databases['Name'][$dbid]),
-		'DB_ID' => $dbid,
-		'TABLE_COUNT' => $numrows,
-		'ICONPATH' => $config['files']['iconpath']));
-	$numrows=intval($numrows);
-	if ($numrows>1) $tpl->assign_block_vars('MORE_TABLES',array());
-	elseif ($numrows==1) $tpl->assign_block_vars('1_TABLE',array());
-	elseif ($numrows==0) $tpl->assign_block_vars('NO_TABLE',array());
-	if ($numrows>0)
-	{
-		$last_update="2000-01-01 00:00:00";
-		$sum_records=$sum_data_length='';
-		for ($i=0; $i<$numrows; $i++)
-		{
-			$row=mysqli_fetch_array($res,MYSQLI_ASSOC);
-			// Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
-			$sql_2="SELECT count(*) as `count_records` FROM `".$databases['Name'][$dbid]."`.`".$row['Name']."`";
-			$res2=@mysqli_query($config['dbconnection'], $sql_2);
-			if ($res2===false)
-			{
-				$row['Rows']=0;
-				$rowclass='dbrowsel';
-			}
-			else
-			{
-				$row2=mysqli_fetch_array($res2);
-				$row['Rows']=$row2['count_records'];
-				$rowclass=($i%2) ? 'dbrow' : 'dbrow1';
-			}
+    $numrows = 0;
+    $res = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['Name'][$dbid].'`');
+    mysqli_select_db($config['dbconnection'], $databases['Name'][$dbid]);
+    if ($res) {
+        $numrows = mysqli_num_rows($res);
+    }
+    $tpl->assign_vars([
+        'DB_NAME' => $databases['Name'][$dbid],
+        'DB_NAME_URLENCODED' => urlencode($databases['Name'][$dbid]),
+        'DB_ID' => $dbid,
+        'TABLE_COUNT' => $numrows,
+        'ICONPATH' => $config['files']['iconpath'], ]);
+    $numrows = intval($numrows);
+    if ($numrows > 1) {
+        $tpl->assign_block_vars('MORE_TABLES', []);
+    } elseif (1 == $numrows) {
+        $tpl->assign_block_vars('1_TABLE', []);
+    } elseif (0 == $numrows) {
+        $tpl->assign_block_vars('NO_TABLE', []);
+    }
+    if ($numrows > 0) {
+        $last_update = '2000-01-01 00:00:00';
+        $sum_records = $sum_data_length = 0;
+        for ($i = 0; $i < $numrows; ++$i) {
+            $row = mysqli_fetch_array($res, MYSQLI_ASSOC);
+            // Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
+            $sql_2 = 'SELECT count(*) as `count_records` FROM `'.$databases['Name'][$dbid].'`.`'.$row['Name'].'`';
+            $res2 = mysqli_query($config['dbconnection'], $sql_2);
+            if (false === $res2) {
+                $row['Rows'] = 0;
+                $rowclass = 'dbrowsel';
+            } else {
+                $row2 = mysqli_fetch_array($res2);
+                $row['Rows'] = $row2['count_records'];
+                $rowclass = ($i % 2) ? 'dbrow' : 'dbrow1';
+            }
 
-			if (isset($row['Update_time'])&&strtotime($row['Update_time'])>strtotime($last_update)) $last_update=$row['Update_time'];
-			$sum_records+=$row['Rows'];
-			$sum_data_length+=$row['Data_length']+$row['Index_length'];
+            if (isset($row['Update_time']) && strtotime($row['Update_time']) > strtotime($last_update)) {
+                $last_update = $row['Update_time'];
+            }
+            $sum_records += $row['Rows'];
+            $sum_data_length += $row['Data_length'] + $row['Index_length'];
 
-			$keys_disabled = false;
-			if ($row['Engine'] == "MyIsam") {
-			}
-            $tpl->assign_block_vars('ROW',array(
-				'ROWCLASS' => $rowclass,
-				'NR' => ($i+1),
-				'TABLE_NAME' => $row['Name'],
-				'TABLE_NAME_URLENCODED' => urlencode($row['Name']),
-				'RECORDS' => $row['Rows'],
-				'SIZE' => byte_output($row['Data_length']+$row['Index_length']),
-				'LAST_UPDATE' => $row['Update_time'],
-				'ENGINE' => $row['Engine'],
-			));
+            $keys_disabled = false;
+            if ('MyIsam' == $row['Engine']) {
+            }
+            $tpl->assign_block_vars('ROW', [
+                'ROWCLASS' => $rowclass,
+                'NR' => ($i + 1),
+                'TABLE_NAME' => $row['Name'],
+                'TABLE_NAME_URLENCODED' => urlencode($row['Name']),
+                'RECORDS' => $row['Rows'],
+                'SIZE' => byte_output($row['Data_length'] + $row['Index_length']),
+                'LAST_UPDATE' => $row['Update_time'],
+                'ENGINE' => $row['Engine'],
+            ]);
 
-			// Otimize & Repair - only for MyISAM-Tables
-			if ($row['Engine']=='MyISAM')
-			{
-				if ($row['Data_free']==0) $tpl->assign_block_vars('ROW.OPTIMIZED',array());
-				else
-					$tpl->assign_block_vars('ROW.NOT_OPTIMIZED',array());
-
-				if ($checkit==$row['Name']||$repair==1)
-				{
-					$tmp_res=mysqli_query($config['dbconnection'], "REPAIR TABLE `".$row['Name']."`");
-				}
-
-				if (($checkit==$row['Name']||$checkit=='ALL'))
-				{
-					// table needs to be checked
-					$tmp_res=mysqli_query($config['dbconnection'], 'CHECK TABLE `'.$row['Name'].'`');
-					if ($tmp_res)
-					{
-						$tmp_row=mysqli_fetch_row($tmp_res);
-						if ($tmp_row[3]=='OK') $tpl->assign_block_vars('ROW.CHECK_TABLE_OK',array());
-						else
-							$tpl->assign_block_vars('ROW.CHECK_TABLE_NOT_OK',array());
-					}
-				}
-				else
-				{
-					// Show Check table link
-					$tpl->assign_block_vars('ROW.CHECK_TABLE',array());
-				}
-                if ($enableKeys==$row['Name'] || $enableKeys=="ALL")
-                {
-                    $sSql= "ALTER TABLE `".$databases['Name'][$dbid]."`.`".$row['Name']."` ENABLE KEYS";
-                    $tmp_res=mysqli_query($config['dbconnection'], $sSql);
+            // Otimize & Repair - only for MyISAM-Tables
+            if ('MyISAM' == $row['Engine']) {
+                if (0 == $row['Data_free']) {
+                    $tpl->assign_block_vars('ROW.OPTIMIZED', []);
+                } else {
+                    $tpl->assign_block_vars('ROW.NOT_OPTIMIZED', []);
                 }
-                $res3=mysqli_query($config['dbconnection'], 'SHOW INDEX FROM `'.$databases['Name'][$dbid]."`.`".$row['Name']."`");
-                while ($row3 = mysqli_fetch_array($res3, MYSQLI_ASSOC))
-                {
-                    if ($row3['Comment']=="disabled") {
+
+                if ($checkit == $row['Name'] || 1 == $repair) {
+                    $tmp_res = mysqli_query($config['dbconnection'], 'REPAIR TABLE `'.$row['Name'].'`');
+                }
+
+                if (($checkit == $row['Name'] || 'ALL' == $checkit)) {
+                    // table needs to be checked
+                    $tmp_res = mysqli_query($config['dbconnection'], 'CHECK TABLE `'.$row['Name'].'`');
+                    if ($tmp_res) {
+                        $tmp_row = mysqli_fetch_row($tmp_res);
+                        if ('OK' == $tmp_row[3]) {
+                            $tpl->assign_block_vars('ROW.CHECK_TABLE_OK', []);
+                        } else {
+                            $tpl->assign_block_vars('ROW.CHECK_TABLE_NOT_OK', []);
+                        }
+                    }
+                } else {
+                    // Show Check table link
+                    $tpl->assign_block_vars('ROW.CHECK_TABLE', []);
+                }
+                if ($enableKeys == $row['Name'] || 'ALL' == $enableKeys) {
+                    $sSql = 'ALTER TABLE `'.$databases['Name'][$dbid].'`.`'.$row['Name'].'` ENABLE KEYS';
+                    $tmp_res = mysqli_query($config['dbconnection'], $sSql);
+                }
+                $res3 = mysqli_query($config['dbconnection'], 'SHOW INDEX FROM `'.$databases['Name'][$dbid].'`.`'.$row['Name'].'`');
+                while ($row3 = mysqli_fetch_array($res3, MYSQLI_ASSOC)) {
+                    if ('disabled' == $row3['Comment']) {
                         $keys_disabled = true;
                         $disabled_keys_found = true;
                     }
                 }
-                if ($keys_disabled) $tpl->assign_block_vars('ROW.KEYS_DISABLED', array());
-                else $tpl->assign_block_vars('ROW.KEYS_ENABLED', array());
-			}
-
-		}
-		// Output sum-row
-		$tpl->assign_block_vars('SUM',array(
-			'RECORDS' => number_format($sum_records,0,",","."),
-			'SIZE' => byte_output($sum_data_length),
-			'LAST_UPDATE' => $last_update));
-		if ($disabled_keys_found) $tpl->assign_block_vars('DISABLED_KEYS_FOUND', array());
-
-	}
-	$tpl->pparse('show');
+                if ($keys_disabled) {
+                    $tpl->assign_block_vars('ROW.KEYS_DISABLED', []);
+                } else {
+                    $tpl->assign_block_vars('ROW.KEYS_ENABLED', []);
+                }
+            }
+        }
+        // Output sum-row
+        $tpl->assign_block_vars('SUM', [
+            'RECORDS' => number_format($sum_records, 0, ',', '.'),
+            'SIZE' => byte_output($sum_data_length),
+            'LAST_UPDATE' => $last_update, ]);
+        if ($disabled_keys_found) {
+            $tpl->assign_block_vars('DISABLED_KEYS_FOUND', []);
+        }
+    }
+    $tpl->pparse('show');
 }
diff --git a/msd/inc/home/home.php b/msd/inc/home/home.php
index d3db7556..d9e562ce 100644
--- a/msd/inc/home/home.php
+++ b/msd/inc/home/home.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,66 +16,129 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
-if (!defined('MSD_VERSION')) die('No direct access.');
-$Sum_Files=$Sum_Size=0;
-$Last_BU=Array();
-$is_htaccess=(file_exists('./.htaccess'));
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+$Sum_Files = $Sum_Size = 0;
+$Last_BU = [];
+$is_htaccess = (file_exists('./.htaccess'));
+$is_protected = IsAccessProtected();
+$is_new_version_available = (isset($update) && is_object($update) && $check_update === true) ? $update->newVersionAvailable() : false;
 
 // find latest backup file
-$dh=opendir($config['paths']['backup']);
-while (false!==($filename=readdir($dh)))
-{
-	if ($filename!='.'&&$filename!='..'&&!is_dir($config['paths']['backup'].$filename))
-	{
-		$files[]=$filename;
-		$Sum_Files++;
-		$Sum_Size+=filesize($config['paths']['backup'].$filename);
-		$ft=filectime($config['paths']['backup'].$filename);
-		if (!isset($Last_BU[2])||(isset($Last_BU[2])&&$ft>$Last_BU[2]))
-		{
-			$Last_BU[0]=$filename;
-			$Last_BU[1]=date("d.m.Y H:i",$ft);
-			$Last_BU[2]=$ft;
-		}
-	}
+$available = [];
+if ('' == $databases['multisetting']) {
+    $available[0] = $databases['db_actual'];
+} else {
+    $available = explode(';', $databases['multisetting']);
+}
+$dh = opendir($config['paths']['backup']);
+while (false !== ($filename = readdir($dh))) {
+    if ('.' != $filename && '..' != $filename && !is_dir($config['paths']['backup'].$filename)) {
+        foreach ($available as $item) {
+            $pos = strpos($filename, $item);
+            if ($pos === false) {
+                // Der Datenbankname wurde nicht in der Konfiguration gefunden;
+            } else {
+                $files[] = $filename;
+                ++$Sum_Files;
+                $Sum_Size += filesize($config['paths']['backup'].$filename);
+                $ft = filectime($config['paths']['backup'].$filename);
+                if (!isset($Last_BU[2]) || (isset($Last_BU[2]) && $ft > $Last_BU[2])) {
+                    $Last_BU[0] = $filename;
+                    $Last_BU[1] = date('d.m.Y H:i', $ft);
+                    $Last_BU[2] = $ft;
+                }
+            }
+        }
+    }
 }
-$directory_warnings=DirectoryWarnings();
 
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => 'tpl/home/home.tpl'));
-$tpl->assign_vars(array(
-	'THEME' => $config['theme'],
-	'MSD_VERSION' => MSD_VERSION,
-	'OS' => MSD_OS,
-	'OS_EXT' => MSD_OS_EXT,
-	'MYSQL_VERSION' => MSD_MYSQL_VERSION,
-	'PHP_VERSION' => PHP_VERSION,
-	'MEMORY' => byte_output($config['php_ram']*1024*1024),
-	'MAX_EXECUTION_TIME' => $config['max_execution_time'],
-	'PHP_EXTENSIONS' => $config['phpextensions'],
-	'SERVER_NAME' => $_SERVER['SERVER_NAME'],
-	'MSD_PATH' => $config['paths']['root'],
-	'DB' => $databases['db_actual'],
-	'NR_OF_BACKUP_FILES' => $Sum_Files,
-	'SIZE_BACKUPS' => byte_output($Sum_Size),
-	'FREE_DISKSPACE' => MD_FreeDiskSpace()));
-if ($directory_warnings>'') $tpl->assign_block_vars('DIRECTORY_WARNINGS',array(
-	'MSG' => $directory_warnings));
 
-if ($config['disabled']>'') $tpl->assign_block_vars('DISABLED_FUNCTIONS',array(
-	'PHP_DISABLED_FUNCTIONS' => str_replace(',',', ',$config['disabled'])));
+if (!is_writable($config['paths']['temp'])) {
+    $ret = SetFileRechte($config['paths']['temp'], 1, 0777);
+}
+if (!is_writable($config['paths']['cache'])) {
+    $ret = SetFileRechte($config['paths']['cache'], 1, 0777);
+}
+$directory_warnings = DirectoryWarnings();
 
-// Zlib is buggy from version 4.3.0 upto 4.3.2, so lets check for these versions
-if (version_compare(PHP_VERSION,'4.3.0','>=')&&version_compare(PHP_VERSION,'4.3.2','<=')) $tpl->assign_block_vars('ZLIBBUG',array());
-if (!extension_loaded('ftp')) $tpl->assign_block_vars('NO_FTP',array());
-if (!$config['zlib']) $tpl->assign_block_vars('NO_ZLIB',array());
-if ($is_htaccess) $tpl->assign_block_vars('HTACCESS_EXISTS',array());
-else
-	$tpl->assign_block_vars('HTACCESS_DOESNT_EXISTS',array());
-if ($Sum_Files>0&&isset($Last_BU[1])) $tpl->assign_block_vars('LAST_BACKUP',array(
-	'LAST_BACKUP_INFO' => $Last_BU[1],
-	'LAST_BACKUP_LINK' => $config['paths']['backup'].urlencode($Last_BU[0]),
-	'LAST_BACKUP_NAME' => $Last_BU[0]));
+if ($is_new_version_available) {
+    $update_info = $lang['L_NEW_MOD_VERSION'] . ': ' . $update->getLatestVersion();
+}
+
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => 'tpl/home/home.tpl', ]);
+$tpl->assign_vars([
+    'THEME' => $config['theme'],
+    'MOD_VERSION' => MOD_VERSION,
+    'OS' => MOD_OS,
+    'OS_EXT' => MOD_OS_EXT,
+    'MYSQL_VERSION' => MOD_MYSQL_VERSION,
+    'PHP_VERSION' => PHP_VERSION,
+    'MEMORY' => byte_output($config['php_ram'] * 1024 * 1024),
+    'MAX_EXECUTION_TIME' => $config['max_execution_time'],
+    'PHP_EXTENSIONS' => $config['phpextensions'],
+    'SERVER_NAME' => $_SERVER['SERVER_NAME'],
+    'MOD_PATH' => $config['paths']['root'],
+    'DB' => $databases['db_actual'],
+    'NR_OF_BACKUP_FILES' => $Sum_Files,
+    'SIZE_BACKUPS' => byte_output($Sum_Size),
+    'FREE_DISKSPACE' => MD_FreeDiskSpace(),
+]);
+
+
+
+if ($is_new_version_available) {
+    $tpl->assign_block_vars('NEW_VERSION_EXISTS', []);
+}
+
+if (isset($update_info)) {
+    $tpl->assign_block_vars('UPDATE_INFO', [
+    'MSG' => $update_info, ]);
+}
+
+
+if ($directory_warnings > '') {
+    $tpl->assign_block_vars('DIRECTORY_WARNINGS', [
+    'MSG' => $directory_warnings, ]);
+}
+
+if ($config['disabled'] > '') {
+    $tpl->assign_block_vars('DISABLED_FUNCTIONS', [
+    'PHP_DISABLED_FUNCTIONS' => str_replace(',', ', ', $config['disabled']), ]);
+}
+
+if (!extension_loaded('ftp')) {
+    $tpl->assign_block_vars('NO_FTP', []);
+}
+if (!$config['zlib']) {
+    $tpl->assign_block_vars('NO_ZLIB', []);
+}
+
+if (false === $is_protected) {
+    $tpl->assign_block_vars('DIRECTORY_PROTECTION_STATUS_ERROR', ['MSG' => $lang['L_HTACC_CHECK_ERROR']]);
+} elseif (1 === $is_protected && !$is_htaccess) {
+    $tpl->assign_block_vars('DIRECTORY_PROTECTION_STATUS', ['MSG' => $lang['L_HTACC_NOT_NEEDED']]);
+} elseif (1 === $is_protected && $is_htaccess) {
+    $tpl->assign_block_vars('DIRECTORY_PROTECTION_STATUS', ['MSG' => $lang['L_HTACC_COMPLETE']]);
+} elseif (0 === $is_protected && $is_htaccess) {
+    $tpl->assign_block_vars('DIRECTORY_PROTECTION_STATUS_ERROR', ['MSG' => $lang['L_HTACC_INCOMPLETE']]);
+} else {
+    $tpl->assign_block_vars('DIRECTORY_PROTECTION_STATUS_ERROR', ['MSG' => $lang['L_HTACC_PROPOSED']]);
+}
+
+if ($is_htaccess) {
+    $tpl->assign_block_vars('HTACCESS_EXISTS', []);
+} else {
+    $tpl->assign_block_vars('HTACCESS_DOESNT_EXISTS', []);
+}
+
+if ($Sum_Files > 0 && isset($Last_BU[1])) {
+    $tpl->assign_block_vars('LAST_BACKUP', [
+    'LAST_BACKUP_INFO' => $Last_BU[1],
+    'LAST_BACKUP_LINK' => $config['paths']['backup'].urlencode($Last_BU[0]),
+    'LAST_BACKUP_NAME' => $Last_BU[0], ]);
+}
 $tpl->pparse('show');
diff --git a/msd/inc/home/mysql_variables.php b/msd/inc/home/mysql_variables.php
index 4b3f45f9..7c0b7f92 100644
--- a/msd/inc/home/mysql_variables.php
+++ b/msd/inc/home/mysql_variables.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,11 +16,12 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
-$var=(isset($_GET['var'])) ? $_GET['var'] : "prozesse";
-$Titelausgabe=array(
-
-"variables" => $lang['L_VARIABELN'], "status" => $lang['L_STATUS'], "prozesse" => $lang['L_PROZESSE']);
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+$var = (isset($_GET['var'])) ? $_GET['var'] : 'prozesse';
+$Titelausgabe = [
+'variables' => $lang['L_VARIABELN'], 'status' => $lang['L_STATUS'], 'prozesse' => $lang['L_PROZESSE'], ];
 echo '<h5>'.$lang['L_MYSQLVARS'].'</h5><strong>'.$Titelausgabe[$var].'</strong>&nbsp;&nbsp;&nbsp;&nbsp;';
 echo '<a href="main.php?action=vars&amp;var=prozesse">'.$lang['L_PROZESSE'].'</a>&nbsp;&nbsp;&nbsp;';
 echo '<a href="main.php?action=vars&amp;var=status">'.$lang['L_STATUS'].'</a>&nbsp;&nbsp;&nbsp;';
@@ -28,102 +29,90 @@ echo '<a href="main.php?action=vars&amp;var=variables">'.$lang['L_VARIABELN'].'<
 
 echo '<p>&nbsp;</p>';
 //Variabeln
-switch ($var)
-{
-	case "variables":
-		$res=@mysqli_query($config['dbconnection'], "SHOW variables");
-		if ($res) $numrows=mysqli_num_rows($res);
-		if ($numrows==0)
-		{
-			echo $lang['L_INFO_NOVARS'];
-		}
-		else
-		{
-			echo '<table class="bdr"><tr class="thead"><th><strong>Name</strong></th><th><strong>'.$lang['L_INHALT'].'</strong></th></tr>';
-			for ($i=0; $i<$numrows; $i++)
-			{
-				$row=mysqli_fetch_array($res);
-				$cl=($i%2) ? "dbrow" : "dbrow1";
-				echo '<tr class="'.$cl.'"><td align="left">'.$row[0].'</td><td  align="left">'.$row[1].'</td></tr>';
-			}
-		}
-		echo '</table>';
-		break;
-	case "status":
-		$res=@mysqli_query($config['dbconnection'], "SHOW STATUS");
-		if ($res) $numrows=mysqli_num_rows($res);
-		if ($numrows==0)
-		{
-			echo $lang['L_INFO_NOSTATUS'];
-		}
-		else
-		{
-			echo '<table class="bdr"><tr class="thead"><th>Name</th><th>'.$lang['L_INHALT'].'</th></tr>';
-			for ($i=0; $i<$numrows; $i++)
-			{
-				$cl=($i%2) ? "dbrow" : "dbrow1";
-				$row=mysqli_fetch_array($res);
-				echo '<tr class="'.$cl.'"><td align="left" valign="top">'.$row[0].'</td><td align="left" valign="top">'.$row[1].'</td></tr>';
-			}
-		}
-		echo '</table>';
-		break;
-	case "prozesse":
-		if ($config['processlist_refresh']<1000) $config['processlist_refresh']=2000;
-		if (isset($_GET['killid'])&&$_GET['killid']>0)
-		{
-			$killid=(isset($_GET['killid'])) ? $_GET['killid'] : 0;
-			$wait=(isset($_GET['wait'])) ? $_GET['wait'] : 0;
-			if ($wait==0)
-			{
-				$ret=mysqli_query($config['dbconnection'], "KILL ".$_GET['killid']);
-				$wait=2;
-			}
-			else
-				$wait+=2;
+switch ($var) {
+    case 'variables':
+        $res = mysqli_query($config['dbconnection'], 'SHOW variables');
+        if ($res) {
+            $numrows = mysqli_num_rows($res);
+        }
+        if (0 == $numrows) {
+            echo $lang['L_INFO_NOVARS'];
+        } else {
+            echo '<table class="bdr"><tr class="thead"><th><strong>Name</strong></th><th><strong>'.$lang['L_INHALT'].'</strong></th></tr>';
+            for ($i = 0; $i < $numrows; ++$i) {
+                $row = mysqli_fetch_array($res);
+                $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+                echo '<tr class="'.$cl.'"><td align="left">'.$row[0].'</td><td  align="left">'.$row[1].'</td></tr>';
+            }
+        }
+        echo '</table>';
+        break;
+    case 'status':
+        $res = mysqli_query($config['dbconnection'], 'SHOW STATUS');
+        if ($res) {
+            $numrows = mysqli_num_rows($res);
+        }
+        if (0 == $numrows) {
+            echo $lang['L_INFO_NOSTATUS'];
+        } else {
+            echo '<table class="bdr"><tr class="thead"><th>Name</th><th>'.$lang['L_INHALT'].'</th></tr>';
+            for ($i = 0; $i < $numrows; ++$i) {
+                $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+                $row = mysqli_fetch_array($res);
+                echo '<tr class="'.$cl.'"><td align="left" valign="top">'.$row[0].'</td><td align="left" valign="top">'.$row[1].'</td></tr>';
+            }
+        }
+        echo '</table>';
+        break;
+    case 'prozesse':
+        if ($config['processlist_refresh'] < 1000) {
+            $config['processlist_refresh'] = 2000;
+        }
+        if (isset($_GET['killid']) && $_GET['killid'] > 0) {
+            $killid = (isset($_GET['killid'])) ? $_GET['killid'] : 0;
+            $wait = (isset($_GET['wait'])) ? $_GET['wait'] : 0;
+            if (0 == $wait) {
+                $ret = mysqli_query($config['dbconnection'], 'KILL '.$_GET['killid']);
+                $wait = 2;
+            } else {
+                $wait += 2;
+            }
 
-			if ($wait==0)
-			{
-				echo '<p class="success">'.$lang['L_PROCESSKILL1'].$_GET['killid'].' '.$lang['L_PROCESSKILL2'].'</p>';
-			}
-			else
-			{
-				echo '<p class="success">'.$lang['L_PROCESSKILL3'].$wait.$lang['L_PROCESSKILL4'].$_GET['killid'].' '.$lang['L_PROCESSKILL2'].'</p>';
-			}
+            if (0 == $wait) {
+                echo '<p class="success">'.$lang['L_PROCESSKILL1'].$_GET['killid'].' '.$lang['L_PROCESSKILL2'].'</p>';
+            } else {
+                echo '<p class="success">'.$lang['L_PROCESSKILL3'].$wait.$lang['L_PROCESSKILL4'].$_GET['killid'].' '.$lang['L_PROCESSKILL2'].'</p>';
+            }
+        }
 
-		}
-
-		$killid=$wait=0;
-		$res=@mysqli_query($config['dbconnection'], "SHOW FULL PROCESSLIST ");
-		if ($res) $numrows=mysqli_num_rows($res);
-		if ($numrows==0)
-		{
-			echo $lang['L_INFO_NOPROCESSES'];
-		}
-		else
-		{
-			echo '<table class="bdr" style="width:100%"><tr class="thead"><th>ID</th><th>User</th><th>Host</th><th>DB</th><th>Command</th><th>Time</th><th>State</th><th width="800">Info</th><th nowrap="nowrap">RT: '.round($config['processlist_refresh']/1000).' sec</th></tr>';
-			for ($i=0; $i<$numrows; $i++)
-			{
-				$cl=($i%2) ? "dbrow" : "dbrow1";
-				$row=mysqli_fetch_array($res);
-				echo '<tr><td>'.$row[0].'</td><td>'.$row[1].'</td>
+        $killid = $wait = 0;
+        $res = mysqli_query($config['dbconnection'], 'SHOW FULL PROCESSLIST ');
+        if ($res) {
+            $numrows = mysqli_num_rows($res);
+        }
+        if (0 == $numrows) {
+            echo $lang['L_INFO_NOPROCESSES'];
+        } else {
+            echo '<table class="bdr" style="width:100%"><tr class="thead"><th>ID</th><th>User</th><th>Host</th><th>DB</th><th>Command</th><th>Time</th><th>State</th><th width="800">Info</th><th nowrap="nowrap">RT: '.round($config['processlist_refresh'] / 1000).' sec</th></tr>';
+            for ($i = 0; $i < $numrows; ++$i) {
+                $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+                $row = mysqli_fetch_array($res);
+                echo '<tr><td>'.$row[0].'</td><td>'.$row[1].'</td>
 					<td>'.$row[2].'</td><td>'.$row[3].'</td><td>'.$row[4].'</td><td>'.$row[5].'</td>
 					<td>'.$row[6].'</td><td>'.$row[7].'</td>
 					<td><a href="main.php?action=vars&amp;var=prozesse&amp;killid='.$row[0].'">kill</a></td></tr>';
-				if ($row[0]==$killid&&$row[4]=="Killed")
-				{
-					$wait=$killid=0;
-				}
-			}
-		}
-		echo '</table>';
-		echo '<form name="f" method="get" action="main.php">
+                if ($row[0] == $killid && 'Killed' == $row[4]) {
+                    $wait = $killid = 0;
+                }
+            }
+        }
+        echo '</table>';
+        echo '<form name="f" method="get" action="main.php">
 			<input type="hidden" name="wait" value="'.$wait.'">
 			<input type="hidden" name="killid" value="'.$killid.'">
 			<input type="hidden" name="action" value="vars">
 			<input type="hidden" name="var" value="prozesse"></form>';
-		echo '<script language="JavaScript" type="text/javascript">window.setTimeout("document.f.submit();","'.$config['processlist_refresh'].'");</script>';
+        echo '<script>window.setTimeout("document.f.submit();","'.$config['processlist_refresh'].'");</script>';
 
-		break;
+        break;
 }
diff --git a/msd/inc/home/protection_create.php b/msd/inc/home/protection_create.php
index 0a22809c..a8381be7 100644
--- a/msd/inc/home/protection_create.php
+++ b/msd/inc/home/protection_create.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,142 +16,152 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
-include ('./language/'.$config['language'].'/lang_sql.php');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+include './language/'.$config['language'].'/lang_sql.php';
 
-$dba=$hta_dir=$Overwrite=$msg='';
-$error=array();
-$is_htaccess=(file_exists('./.htaccess'));
-if ($is_htaccess)
-{
-	$Overwrite='<p class="error">'.$lang['L_HTACCESS8'].'</p>';
-	$htaccess_exist=file('.htaccess'); // read .htaccess
+include './inc/home/apr1_md5/apr1_md5.php';
+use WhiteHat101\Crypt\APR1_MD5;
+
+$dba = $hta_dir = $Overwrite = $msg = '';
+$error = [];
+$is_htaccess = (file_exists('./.htaccess'));
+if ($is_htaccess) {
+    $Overwrite = '<p class="error">'.$lang['L_HTACCESS8'].'</p>';
+    $htaccess_exist = file('.htaccess'); // read .htaccess
 }
 
-$step=(isset($_POST['step'])) ? intval($_POST['step']) : 0;
-$type=0; // default encryption type set to crypt()
-if (strtoupper(substr(MSD_OS,0,3))=='WIN') $type=2; // we are on a Win-System; pre-select encryption type
-if (isset($_POST['type'])) $type=intval($_POST['type']);
-$username=(isset($_POST['username'])) ? $_POST['username'] : '';
-$userpass1=(isset($_POST['userpass1'])) ? $_POST['userpass1'] : '';
-$userpass2=(isset($_POST['userpass2'])) ? $_POST['userpass2'] : '';
+$step = (isset($_POST['step'])) ? intval($_POST['step']) : 0;
+$type = 1; // default encryption type set to MD5(APR)
+if ('WIN' == strtoupper(substr(MOD_OS, 0, 3))) {
+    $type = 2;
+} // we are on a Win-System; pre-select encryption type
+if (isset($_POST['type'])) {
+    $type = intval($_POST['type']);
+}
+$username = (isset($_POST['username'])) ? $_POST['username'] : '';
+$userpass1 = (isset($_POST['userpass1'])) ? $_POST['userpass1'] : '';
+$userpass2 = (isset($_POST['userpass2'])) ? $_POST['userpass2'] : '';
 
 header('Pragma: no-cache');
-header("Cache-Control: no-cache, must-revalidate");
-header("Expires: -1");
+header('Cache-Control: no-cache, must-revalidate');
+header('Expires: -1');
 header('Content-Type: text/html; charset=UTF-8');
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => './tpl/home/protection_create.tpl'));
-$tpl->assign_vars(array(
-	'THEME' => $config['theme'],
-	'HEADLINE' => headline($lang['L_HTACC_CREATE'])));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => './tpl/home/protection_create.tpl', ]);
+$tpl->assign_vars([
+    'THEME' => $config['theme'],
+    'HEADLINE' => headline($lang['L_HTACC_CREATE']), ]);
 
-if (isset($_POST['username']))
-{
-	// Form submitted
-	if ($username=='') $error[]=$lang['L_HTACC_NO_USERNAME'];
-	if (($userpass1!=$userpass2)||($userpass1=='')) $error[]=$lang['L_PASSWORDS_UNEQUAL'];
+if (isset($_POST['username'])) {
+    // Form submitted
+    if ('' == $username) {
+        $error[] = $lang['L_HTACC_NO_USERNAME'];
+    }
+    if (($userpass1 != $userpass2) || ('' == $userpass1)) {
+        $error[] = $lang['L_PASSWORDS_UNEQUAL'];
+    }
 
-	if (sizeof($error)==0)
-	{
-		$htaccess = "<IfModule mod_rewrite.c>\nRewriteEngine off\n</IfModule>\n";
-		$realm='MyOOS-Dumper';
-		$htaccess.="AuthName \"".$realm."\"\nAuthType Basic\nAuthUserFile \""
-		  .$config['paths']['root'].".htpasswd\"\nrequire valid-user";
-		switch ($type)
-		{
-			// Crypt
-			case 0:
-				$userpass=crypt($userpass1);
-				break;
-			// MD5
-			case 1:
-				$userpass=md5($username.':'.$realm.':'.$userpass1);
-				break;
-			// WIn - no encryption
-			case 2:
-				$userpass=$userpass1;
-				break;
-			// SHA
-			case 3:
-				$userpass='{SHA}'.base64_encode(sha1($userpass1,TRUE));
-				break;
-		}
-		$htpasswd=$username.':'.$userpass;
-		@chmod($config['paths']['root'],0777);
+    if (0 == sizeof($error)) {
+        $realm = 'MyOOS-Dumper';
+        $htaccess =
+            "<IfModule mod_rewrite.c>\n".
+            "  RewriteEngine off\n".
+            "</IfModule>\n".
+            'AuthName "'.$realm."\"\n".
+            "AuthType Basic\n".
+            'AuthUserFile "'.$config['paths']['root'].".htpasswd\"\n".
+            'Require valid-user';
+        switch ($type) {
+            // CRYPT
+            case 0:
+                $userpass = crypt($userpass1, 'rl');
+                break;
+            // MD5(APR)
+            case 1:
+                $userpass = APR1_MD5::hash($userpass1);
+                break;
+            // PLAIN TEXT
+            case 2:
+                $userpass = $userpass1;
+                break;
+            // SHA1
+            case 3:
+                $userpass = '{SHA}'.base64_encode(sha1($userpass1, true));
+                break;
+            // BCRYPT
+            case 4:
+                $userpass = password_hash($userpass1, PASSWORD_BCRYPT);
+                break;
+        }
+        $htpasswd = $username.':'.$userpass;
+        @chmod($config['paths']['root'], 0777);
 
-		// save .htpasswd
-		if ($file_htpasswd=@fopen('.htpasswd','w'))
-		{
-			$saved=fputs($file_htpasswd,$htpasswd);
-			fclose($file_htpasswd);
-		}
-		else
-			$saved=false;
+        // save .htpasswd
+        if ($file_htpasswd = @fopen('.htpasswd', 'w')) {
+            $saved = fputs($file_htpasswd, $htpasswd);
+            fclose($file_htpasswd);
+        } else {
+            $saved = false;
+        }
 
-		// save .htaccess
-		if (false!==$saved)
-		{
-			$file_htaccess=@fopen('.htaccess','w');
-			if ($file_htaccess)
-			{
-				$saved=fputs($file_htaccess,$htaccess);
-				fclose($file_htaccess);
-			}
-			else
-				$saved=false;
-		}
-
-		if (false!==$saved)
-		{
-		    if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
-                $output  = array(
-                    'HTACCESS' => nl2br(htmlspecialchars($htaccess), false),
-                    'HTPASSWD' => nl2br(htmlspecialchars($htpasswd), false)
-                );
+        // save .htaccess
+        if (false !== $saved) {
+            $file_htaccess = @fopen('.htaccess', 'w');
+            if ($file_htaccess) {
+                $saved = fputs($file_htaccess, $htaccess);
+                fclose($file_htaccess);
             } else {
-                $output  = array(
-                    'HTACCESS' => nl2br(htmlspecialchars($htaccess)),
-                    'HTPASSWD' => nl2br(htmlspecialchars($htpasswd))
-                );
-		    }
+                $saved = false;
+            }
+        }
 
-		    $msg='<span class="success">'.$lang['L_HTACC_CREATED'].'</span>';
-			$tpl->assign_block_vars('CREATE_SUCCESS', $output);
-			@chmod($config['paths']['root'],0755);
-		}
-		else
-		{
-			$tpl->assign_block_vars('CREATE_ERROR',array(
-				'HTACCESS' => htmlspecialchars($htaccess),
-				'HTPASSWD' => htmlspecialchars($htpasswd)));
-		}
-	}
+        if (false !== $saved) {
+            $msg = '<span class="success">'.$lang['L_HTACC_CREATED'].'</span>';
+            $tpl->assign_block_vars('CREATE_SUCCESS', [
+                'HTACCESS' => htmlspecialchars($htaccess),
+                'HTPASSWD' => htmlspecialchars($htpasswd),
+            ]);
+            @chmod($config['paths']['root'], 0755);
+        } else {
+            $tpl->assign_block_vars('CREATE_ERROR', [
+                'HTACCESS' => htmlspecialchars($htaccess),
+                'HTPASSWD' => htmlspecialchars($htpasswd),
+            ]);
+        }
+    }
 }
 
-if (sizeof($error)>0||!isset($_POST['username']))
-{
-	$tpl->assign_vars(array(
-		'PASSWORDS_UNEQUAL' => my_addslashes($lang['L_PASSWORDS_UNEQUAL']),
-		'HTACC_CONFIRM_DELETE' => my_addslashes($lang['L_HTACC_CONFIRM_DELETE'])));
+if (sizeof($error) > 0 || !isset($_POST['username'])) {
+    $tpl->assign_vars([
+        'PASSWORDS_UNEQUAL' => my_addslashes($lang['L_PASSWORDS_UNEQUAL']),
+        'HTACC_CONFIRM_CREATE' => my_addslashes($lang['L_HTACC_CONFIRM_CREATE']),
+    ]);
 
-	$tpl->assign_block_vars('INPUT',array(
-		'USERNAME' => htmlspecialchars($username),
-		'USERPASS1' => htmlspecialchars($userpass1),
-		'USERPASS2' => htmlspecialchars($userpass2),
-		'TYPE0_CHECKED' => $type==0 ? ' checked="checked"' : '',
-		'TYPE1_CHECKED' => $type==1 ? ' checked="checked"' : '',
-		'TYPE2_CHECKED' => $type==2 ? ' checked="checked"' : '',
-		'TYPE3_CHECKED' => $type==3 ? ' checked="checked"' : ''));
+    $tpl->assign_block_vars('INPUT', [
+        'USERNAME' => htmlspecialchars($username),
+        'USERPASS1' => htmlspecialchars($userpass1),
+        'USERPASS2' => htmlspecialchars($userpass2),
+        'TYPE0_CHECKED' => 0 == $type ? ' checked="checked"' : '',
+        'TYPE1_CHECKED' => 1 == $type ? ' checked="checked"' : '',
+        'TYPE2_CHECKED' => 2 == $type ? ' checked="checked"' : '',
+        'TYPE3_CHECKED' => 3 == $type ? ' checked="checked"' : '',
+        'TYPE4_CHECKED' => 4 == $type ? ' checked="checked"' : '',
+    ]);
 }
 
-if (sizeof($error)>0) $msg='<span class="error">'.implode('<br>',$error).'</span>';
-if ($msg>'') $tpl->assign_block_vars('MSG',array(
-	'TEXT' => $msg));
+if (sizeof($error) > 0) {
+    $msg = '<span class="error">'.implode('<br>', $error).'</span>';
+}
+if ($msg > '') {
+    $tpl->assign_block_vars('MSG', [
+    'TEXT' => $msg, ]);
+}
 
 $tpl->pparse('show');
 
-echo MSDFooter();
+echo MODFooter();
 ob_end_flush();
-die();
+exit();
diff --git a/msd/inc/home/protection_delete.php b/msd/inc/home/protection_delete.php
index ab8bd39b..f4608eb8 100644
--- a/msd/inc/home/protection_delete.php
+++ b/msd/inc/home/protection_delete.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,9 +16,11 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 @unlink($config['paths']['root'].'.htaccess');
 @unlink($config['paths']['root'].'.htpasswd');
-$action='status';
+$action = 'status';
 
 // todo -> give user info about success or failure of deleting action
diff --git a/msd/inc/home/protection_edit.php b/msd/inc/home/protection_edit.php
index 5d501601..ac7321bd 100644
--- a/msd/inc/home/protection_edit.php
+++ b/msd/inc/home/protection_edit.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,46 +16,42 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
-include ('./language/'.$config['language'].'/lang_sql.php');
-echo MSDHeader();
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+include './language/'.$config['language'].'/lang_sql.php';
+echo MODHeader();
 echo headline($lang['L_HTACC_EDIT']);
 
-$htaccessdontexist=0;
+$htaccessdontexist = 0;
 
-if (isset($_POST['hta_dir'])&&isset($_POST['hta_file'])&&is_dir($_POST['hta_dir']))
-{
-	$hta_dir=$_POST['hta_dir'];
-	$hta_file=$_POST['hta_file'];
+if (isset($_POST['hta_dir']) && isset($_POST['hta_file']) && is_dir($_POST['hta_dir'])) {
+    $hta_dir = $_POST['hta_dir'];
+    $hta_file = $_POST['hta_file'];
+} else {
+    $hta_dir = $config['paths']['root'];
+    $hta_file = '.htaccess';
 }
-else
-{
-	$hta_dir=$config['paths']['root'];
-	$hta_file='.htaccess';
+if ('' != $hta_dir & '/' != substr($hta_dir, -1)) {
+    $hta_dir .= '/';
 }
-if ($hta_dir!=''&substr($hta_dir,-1)!='/') $hta_dir.='/';
-$hta_complete=$hta_dir.$hta_file;
+$hta_complete = $hta_dir.$hta_file;
 
-if ((isset($_GET['create'])&&$_GET['create']==1)||(isset($_POST['create'])&&$_POST['create']==1))
-{
-	$fp=fopen($hta_complete,'w');
-	fwrite($fp,"# created by MySQLDumper ".MSD_VERSION."\n");
-	fclose($fp);
+if ((isset($_GET['create']) && 1 == $_GET['create']) || (isset($_POST['create']) && 1 == $_POST['create'])) {
+    $fp = fopen($hta_complete, 'w');
+    fwrite($fp, '# created by MySQLDumper '.MOD_VERSION."\n");
+    fclose($fp);
 }
 
-if (isset($_POST['submit'])&&isset($_POST['thta']))
-{
-	$fp=fopen($hta_complete,'w');
-	fwrite($fp,$_POST['thta']);
-	fclose($fp);
+if (isset($_POST['submit']) && isset($_POST['thta'])) {
+    $fp = fopen($hta_complete, 'w');
+    fwrite($fp, $_POST['thta']);
+    fclose($fp);
 }
-if (file_exists($hta_complete))
-{
-	$htaccess_exist=file($hta_complete);
-}
-else
-{
-	$htaccessdontexist=1;
+if (file_exists($hta_complete)) {
+    $htaccess_exist = file($hta_complete);
+} else {
+    $htaccessdontexist = 1;
 }
 
 echo $lang['L_HTACCESS32'];
@@ -64,12 +60,11 @@ echo '<table>';
 echo '<tr><td>'.$lang['L_DIR'].':</td><td><input type="text" name="hta_dir" value="'.$hta_dir.'" size="60"></td></tr>';
 echo '<tr><td>'.$lang['L_FILE'].':</td><td><input type="text" name="hta_file" value="'.$hta_file.'"></td></tr>';
 echo '</table>';
-if ($htaccessdontexist!=1)
-{
-	echo '<table class="bdr"><tr><td style="width:70%;"><textarea rows="25" cols="40" name="thta" id="thta">'.htmlspecialchars(implode("",$htaccess_exist)).'</textarea><br><br>';
-	echo '</td><td valign="top">';
-	//Presets
-	echo '<h6>Presets</h6><p><strong>'.$lang['L_HTACCESS30'].'</strong><p>
+if (1 != $htaccessdontexist) {
+    echo '<table class="bdr"><tr><td style="width:70%;"><textarea rows="25" cols="40" name="thta" id="thta">'.htmlspecialchars(implode('', $htaccess_exist)).'</textarea><br><br>';
+    echo '</td><td valign="top">';
+    //Presets
+    echo '<h6>Presets</h6><p><strong>'.$lang['L_HTACCESS30'].'</strong><p>
 		<a href="javascript:insertHTA(1,document.ehta.thta)">all-inkl</a><br>
 
 		<br><p><strong>'.$lang['L_HTACCESS31'].'</strong></p>
@@ -83,17 +78,15 @@ if ($htaccessdontexist!=1)
 		<a href="javascript:insertHTA(108,document.ehta.thta)">'.$lang['L_HTACCESS27'].'</a><br>
 		<a href="javascript:insertHTA(109,document.ehta.thta)">'.$lang['L_HTACCESS28'].'</a><br>
 		<br><a href="http://httpd.apache.org/docs/2.0/mod/directives.html" target="_blank">'.$lang['L_HTACCESS29'].'</a>';
-	echo '</td></tr>';
-	echo '<tr><td colspan="2">';
-	echo '<input type="submit" name="submit" value=" '.$lang['L_SAVE'].' " class="Formbutton">&nbsp;&nbsp;&nbsp;';
-	echo '<input type="reset" name="reset" value=" '.$lang['L_RESET'].' " class="Formbutton">&nbsp;&nbsp;&nbsp;';
-	echo '<input type="submit" name="newload" value=" '.$lang['L_HTACCESS19'].' " class="Formbutton">';
-	echo '</td></tr></table></form>';
-}
-else
-{
-	echo '<br>'.$lang['L_FILE_MISSING'].': '.$hta_complete.'<br><br>';
-	echo '<form action="" method="post"><input type="hidden" name="hta_dir" value="'.$hta_dir.'"><input type="hidden" name="hta_file" value="'.$hta_file.'"><input type="hidden" name="create" value="1"><input type="submit" name="createhtaccess" value="'.$lang['L_CREATE'].'" class="Formbutton"></form>';
+    echo '</td></tr>';
+    echo '<tr><td colspan="2">';
+    echo '<input type="submit" name="submit" value=" '.$lang['L_SAVE'].' " class="Formbutton">&nbsp;&nbsp;&nbsp;';
+    echo '<input type="reset" name="reset" value=" '.$lang['L_RESET'].' " class="Formbutton">&nbsp;&nbsp;&nbsp;';
+    echo '<input type="submit" name="newload" value=" '.$lang['L_HTACCESS19'].' " class="Formbutton">';
+    echo '</td></tr></table></form>';
+} else {
+    echo '<br>'.$lang['L_FILE_MISSING'].': '.$hta_complete.'<br><br>';
+    echo '<form action="" method="post"><input type="hidden" name="hta_dir" value="'.$hta_dir.'"><input type="hidden" name="hta_file" value="'.$hta_file.'"><input type="hidden" name="create" value="1"><input type="submit" name="createhtaccess" value="'.$lang['L_CREATE'].'" class="Formbutton"></form>';
 }
 echo '</div>';
 ob_end_flush();
diff --git a/msd/inc/home/system.php b/msd/inc/home/system.php
index 4a5e27c7..3e1b2ebd 100644
--- a/msd/inc/home/system.php
+++ b/msd/inc/home/system.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,96 +16,76 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
-$sysaction=(isset($_GET['dosys'])) ? $_GET['dosys'] : 0;
-$msg="";
-$res=@mysqli_query($config['dbconnection'], "SHOW VARIABLES LIKE 'datadir'");
-if ($res)
-{
-	$row=mysqli_fetch_array($res);
-	$data_dir=$row[1];
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
 }
-switch ($sysaction)
-{
-	case 1: //FLUSH PRIVILEGES
-		$msg="&gt; operating FLUSH PRIVILEGES<br>";
-		$res=@mysqli_query($config['dbconnection'], "FLUSH PRIVILEGES");
-		$meldung=mysqli_error($config['dbconnection']);
-		if ($meldung!="")
-		{
-			$msg.='&gt; MySQL-Error: '.$meldung;
-		}
-		else
-		{
-			$msg.="&gt; Privileges were reloaded.";
-		}
-		break;
-	case 2: //FLUSH STATUS
-		$msg="&gt; operating FLUSH STATUS<br>";
-		$res=@mysqli_query($config['dbconnection'], "FLUSH STATUS");
-		$meldung=mysqli_error($config['dbconnection']);
-		if ($meldung!="")
-		{
-			$msg.='&gt; MySQL-Error: '.$meldung;
-		}
-		else
-		{
-			$msg.="&gt; Status was reset.";
-		}
-		break;
-	case 3: //FLUSH HOSTS
-		$msg="&gt; operating FLUSH HOSTS<br>";
-		$res=@mysqli_query($config['dbconnection'], "FLUSH HOSTS");
-		$meldung=mysqli_error($config['dbconnection']);
-		if ($meldung!="")
-		{
-			$msg.='&gt; MySQL-Error: '.$meldung;
-		}
-		else
-		{
-			$msg.="&gt; Hosts were reloaded.";
-			;
-		}
-		break;
-	case 4: //SHOW MASTER LOGS
-		$msg="> operating SHOW MASTER LOGS<br>";
-		$res=@mysqli_query($config['dbconnection'],"SHOW MASTER LOGS");
-		$meldung=mysqli_error($config['dbconnection']);
-		if ($meldung!="")
-		{
-			$msg.='&gt; MySQL-Error: '.$meldung;
-		}
-		else
-		{
-			$numrows=mysqli_num_rows($res);
-			if ($numrows==0||$numrows===false)
-			{
-				$msg.='&gt; there are no master log-files';
-			}
-			else
-			{
-				$msg.='&gt; there are '.$numrows.' logfiles<br>';
-				for ($i=0; $i<$numrows; $i++)
-				{
-					$row=mysqli_fetch_row($res);
-					$msg.='&gt; '.$row[0].'&nbsp;&nbsp;&nbsp;'.(($data_dir) ? byte_output(@filesize($data_dir.$row[0])) : '').'<br>';
-				}
-			}
-		}
-		break;
-	case 5: //RESET MASTER
-		$msg="&gt; operating RESET MASTER<br>";
-		$res=@mysqli_query($config['dbconnection'], "RESET MASTER");
-		$meldung=mysqli_error($config['dbconnection']);
-		if ($meldung!="")
-		{
-			$msg.='&gt; MySQL-Error: '.$meldung;
-		}
-		else
-		{
-			$msg.="&gt; All Masterlogs were deleted.";
-		}
-		break;
+$sysaction = (isset($_GET['dosys'])) ? $_GET['dosys'] : 0;
+$msg = '';
+$res = mysqli_query($config['dbconnection'], "SHOW VARIABLES LIKE 'datadir'");
+if ($res) {
+    $row = mysqli_fetch_array($res);
+    $data_dir = $row[1];
+}
+switch ($sysaction) {
+    case 1: //FLUSH PRIVILEGES
+        $msg = '&gt; operating FLUSH PRIVILEGES<br>';
+        $res = mysqli_query($config['dbconnection'], 'FLUSH PRIVILEGES');
+        $meldung = mysqli_error($config['dbconnection']);
+        if ('' != $meldung) {
+            $msg .= '&gt; MySQL-Error: '.$meldung;
+        } else {
+            $msg .= '&gt; Privileges were reloaded.';
+        }
+        break;
+    case 2: //FLUSH STATUS
+        $msg = '&gt; operating FLUSH STATUS<br>';
+        $res = mysqli_query($config['dbconnection'], 'FLUSH STATUS');
+        $meldung = mysqli_error($config['dbconnection']);
+        if ('' != $meldung) {
+            $msg .= '&gt; MySQL-Error: '.$meldung;
+        } else {
+            $msg .= '&gt; Status was reset.';
+        }
+        break;
+    case 3: //FLUSH HOSTS
+        $msg = '&gt; operating FLUSH HOSTS<br>';
+        $res = mysqli_query($config['dbconnection'], 'FLUSH HOSTS');
+        $meldung = mysqli_error($config['dbconnection']);
+        if ('' != $meldung) {
+            $msg .= '&gt; MySQL-Error: '.$meldung;
+        } else {
+            $msg .= '&gt; Hosts were reloaded.';
+        }
+        break;
+    case 4: //SHOW MASTER LOGS
+        $msg = '> operating SHOW MASTER LOGS<br>';
+        $res = mysqli_query($config['dbconnection'], 'SHOW MASTER LOGS');
+        $meldung = mysqli_error($config['dbconnection']);
+        if ('' != $meldung) {
+            $msg .= '&gt; MySQL-Error: '.$meldung;
+        } else {
+            $numrows = mysqli_num_rows($res);
+            if (0 == $numrows || false === $numrows) {
+                $msg .= '&gt; there are no master log-files';
+            } else {
+                $msg .= '&gt; there are '.$numrows.' logfiles<br>';
+                for ($i = 0; $i < $numrows; ++$i) {
+                    $row = mysqli_fetch_row($res);
+                    $msg .= '&gt; '.$row[0].'&nbsp;&nbsp;&nbsp;'.(($data_dir) ? byte_output(@filesize($data_dir.$row[0])) : '').'<br>';
+                }
+            }
+        }
+        break;
+    case 5: //RESET MASTER
+        $msg = '&gt; operating RESET MASTER<br>';
+        $res = mysqli_query($config['dbconnection'], 'RESET MASTER');
+        $meldung = mysqli_error($config['dbconnection']);
+        if ('' != $meldung) {
+            $msg .= '&gt; MySQL-Error: '.$meldung;
+        } else {
+            $msg .= '&gt; All Masterlogs were deleted.';
+        }
+        break;
 }
 echo '<h5>'.$lang['L_MYSQLSYS'].'</h5>';
 echo '<div id="hormenu"><ul>
@@ -116,6 +96,6 @@ echo '<div id="hormenu"><ul>
 			<li><a href="main.php?action=sys&amp;dosys=5">Reset Master-Log</a></li>
 			</ul></div>';
 echo '<div align="center" class="MySQLbox">';
-echo '&gt; MySQL Dumper v'.MSD_VERSION.' - Output Console<br><br>';
-echo ($msg!="") ? $msg : '> waiting for operation ...<br>';
+echo '&gt; MySQL Dumper v'.MOD_VERSION.' - Output Console<br><br>';
+echo ('' != $msg) ? $msg : '> waiting for operation ...<br>';
 echo '</div>';
diff --git a/msd/inc/home/update.php b/msd/inc/home/update.php
new file mode 100644
index 00000000..b58bb3d2
--- /dev/null
+++ b/msd/inc/home/update.php
@@ -0,0 +1,87 @@
+<?php
+/* ----------------------------------------------------------------------
+
+   MyOOS [Dumper]
+   http://www.oos-shop.de/
+
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
+   ----------------------------------------------------------------------
+   Based on:
+
+   MySqlDumper
+   http://www.mysqldumper.de
+
+   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
+   ----------------------------------------------------------------------
+   Released under the GNU General Public License
+   ---------------------------------------------------------------------- */
+
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+
+if ($update->newVersionAvailable() && $check_update === true) {
+    // Install new update
+    echo '<p align="center"><a href="main.php">&lt;&lt; Home</a></p>';
+
+    echo $lang['L_NEW_MOD_VERSION'] . ': ' . $update->getLatestVersion() . '<br>';
+    echo $lang['L_INSTALLING_UPDATES'] . ': <br>';
+    /*
+        echo '<pre>';
+        var_dump(array_map(function ($version) {
+            return (string) $version;
+        }, $update->getVersionsToUpdate()));
+        echo '</pre>';
+    */
+    // Optional - empty log file
+    $f = fopen($config['paths']['log'] . 'update.log', 'rb+');
+    if ($f !== false) {
+        ftruncate($f, 0);
+        fclose($f);
+    }
+
+    /*
+        // Optional Callback function - on each version update
+        function eachUpdateFinishCallback($updatedVersion)
+        {
+            echo '<h3>CALLBACK for version ' . $updatedVersion . '</h3>';
+        }
+        $update->onEachUpdateFinish('eachUpdateFinishCallback');
+
+        // Optional Callback function - on each version update
+        function onAllUpdateFinishCallbacks($updatedVersions)
+        {
+            echo '<h3>CALLBACK for all updated versions:</h3>';
+            echo '<ul>';
+            foreach ($updatedVersions as $v) {
+                echo '<li>' . $v . '</li>';
+            }
+            echo '</ul>';
+        }
+        $update->setOnAllUpdateFinishCallbacks('onAllUpdateFinishCallbacks');
+    */
+
+    // This call will only simulate an update.
+    // Set the first argument (simulate) to "false" to install the update
+    // i.e. $update->update(false);
+    $result = $update->update(false);
+
+    if ($result === true) {
+        echo $lang['L_UPDATE_SUCCESSFUL'] . '<br>';
+    } else {
+        echo $lang['L_UPDATE_FAILED'] . ': ' . $result . '!<br>';
+
+        if ($result = AutoUpdate::ERROR_SIMULATE) {
+            echo '<pre>';
+            var_dump($update->getSimulationResults());
+            echo '</pre>';
+        }
+    }
+} else {
+    echo $lang['L_UP_TO_DATE']. '<br>';
+}
+
+echo 'Log:<br>';
+echo nl2br(file_get_contents($config['paths']['log'] . '/update.log'));
+
+echo '<p align="center"><a href="main.php">&lt;&lt; Home</a></p>';
diff --git a/msd/inc/mysql.php b/msd/inc/mysql.php
deleted file mode 100644
index d7cb2671..00000000
--- a/msd/inc/mysql.php
+++ /dev/null
@@ -1,513 +0,0 @@
-<?php
-/* ----------------------------------------------------------------------
-
-   MyOOS [Dumper]
-   http://www.oos-shop.de/
-
-   Copyright (c) 2016 by the MyOOS Development Team.
-   ----------------------------------------------------------------------
-   Based on:
-
-   MySqlDumper
-   http://www.mysqldumper.de
-
-   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
-   ----------------------------------------------------------------------
-   Released under the GNU General Public License
-   ---------------------------------------------------------------------- */
-
-if (!defined('MSD_VERSION')) die('No direct access.');
-
-//Feldspezifikationen
-$feldtypen=Array(
-				"VARCHAR",
-				"TINYINT",
-				"TEXT",
-				"DATE",
-				"SMALLINT",
-				"MEDIUMINT",
-				"INT",
-				"BIGINT",
-				"FLOAT",
-				"DOUBLE",
-				"DECIMAL",
-				"DATETIME",
-				"TIMESTAMP",
-				"TIME",
-				"YEAR",
-				"CHAR",
-				"TINYBLOB",
-				"TINYTEXT",
-				"BLOB",
-				"MEDIUMBLOB",
-				"MEDIUMTEXT",
-				"LONGBLOB",
-				"LONGTEXT",
-				"ENUM",
-				"SET"
-);
-$feldattribute= array (
-					"",
-					"BINARY",
-					"UNSIGNED",
-					"UNSIGNED ZEROFILL"
-);
-$feldnulls=Array(
-				"NOT NULL",
-				"NULL"
-);
-$feldextras=Array(
-				"",
-				"AUTO_INCREMENT"
-);
-$feldkeys=Array(
-				"",
-				"PRIMARY KEY",
-				"UNIQUE KEY",
-				"FULLTEXT"
-);
-$feldrowformat=Array(
-
-					"",
-					"FIXED",
-					"DYNAMIC",
-					"COMPRESSED"
-);
-
-$rechte_daten=Array(
-					"SELECT",
-					"INSERT",
-					"UPDATE",
-					"DELETE",
-					"FILE"
-);
-$rechte_struktur=Array(
-					"CREATE",
-					"ALTER",
-					"INDEX",
-					"DROP",
-					"CREATE TEMPORARY TABLES"
-);
-$rechte_admin=Array(
-					"GRANT",
-					"SUPER",
-					"PROCESS",
-					"RELOAD",
-					"SHUTDOWN",
-					"SHOW DATABASES",
-					"LOCK TABLES",
-					"REFERENCES",
-					"EXECUTE",
-					"REPLICATION CLIENT",
-					"REPLICATION SLAVE"
-);
-$rechte_resourcen=Array(
-						"MAX QUERIES PER HOUR",
-						"MAX UPDATES PER HOUR",
-						"MAX CONNECTIONS PER HOUR"
-);
-
-$sql_keywords=array(
-					'ALTER',
-					'AND',
-					'ADD',
-					'AUTO_INCREMENT',
-					'BETWEEN',
-					'BINARY',
-					'BOTH',
-					'BY',
-					'BOOLEAN',
-					'CHANGE',
-					'CHARSET',
-					'CHECK',
-					'COLLATE',
-					'COLUMNS',
-					'COLUMN',
-					'CROSS',
-					'CREATE',
-					'DATABASES',
-					'DATABASE',
-					'DATA',
-					'DELAYED',
-					'DESCRIBE',
-					'DESC',
-					'DISTINCT',
-					'DELETE',
-					'DROP',
-					'DEFAULT',
-					'ENCLOSED',
-					'ENGINE',
-					'ESCAPED',
-					'EXISTS',
-					'EXPLAIN',
-					'FIELDS',
-					'FIELD',
-					'FLUSH',
-					'FOR',
-					'FOREIGN',
-					'FUNCTION',
-					'FROM',
-					'GROUP',
-					'GRANT',
-					'HAVING',
-					'IGNORE',
-					'INDEX',
-					'INFILE',
-					'INSERT',
-					'INNER',
-					'INTO',
-					'IDENTIFIED',
-					'JOIN',
-					'KEYS',
-					'KILL',
-					'KEY',
-					'LEADING',
-					'LIKE',
-					'LIMIT',
-					'LINES',
-					'LOAD',
-					'LOCAL',
-					'LOCK',
-					'LOW_PRIORITY',
-					'LEFT',
-					'LANGUAGE',
-					'MEDIUMINT',
-					'MODIFY',
-					'MyISAM',
-					'NATURAL',
-					'NOT',
-					'NULL',
-					'NEXTVAL',
-					'OPTIMIZE',
-					'OPTION',
-					'OPTIONALLY',
-					'ORDER',
-					'OUTFILE',
-					'OR',
-					'OUTER',
-					'ON',
-					'PROCEEDURE',
-					'PROCEDURAL',
-					'PRIMARY',
-					'READ',
-					'REFERENCES',
-					'REGEXP',
-					'RENAME',
-					'REPLACE',
-					'RETURN',
-					'REVOKE',
-					'RLIKE',
-					'RIGHT',
-					'SHOW',
-					'SONAME',
-					'STATUS',
-					'STRAIGHT_JOIN',
-					'SELECT',
-					'SETVAL',
-					'TABLES',
-					'TEMINATED',
-					'TO',
-					'TRAILING',
-					'TRUNCATE',
-					'TABLE',
-					'TEMPORARY',
-					'TRIGGER',
-					'TRUSTED',
-					'UNIQUE',
-					'UNLOCK',
-					'USE',
-					'USING',
-					'UPDATE',
-					'UNSIGNED',
-					'VALUES',
-					'VARIABLES',
-					'VIEW',
-					'WITH',
-					'WRITE',
-					'WHERE',
-					'ZEROFILL',
-					'XOR',
-					'ALL',
-					'ASC',
-					'AS',
-					'SET',
-					'IN',
-					'IS',
-					'IF'
-);
-$mysql_doc=Array(
-				"Feldtypen" => "http://dev.mysql.com/doc/mysql/de/Column_types.html"
-);
-$mysql_string_types = array(
-    'char',
-    'varchar',
-    'tinytext',
-    'text',
-    'mediumtext',
-    'longtext',
-    'binary',
-    'varbinary',
-    'tinyblob',
-    'mediumblob',
-    'blob',
-    'longblob',
-    'enum',
-    'set'
-);
-$mysql_SQLhasRecords=array(
-
-						'SELECT',
-						'SHOW',
-						'EXPLAIN',
-						'DESCRIBE',
-						'DESC'
-);
-
-function MSD_mysql_connect($encoding='utf8', $keycheck_off=false, $actual_table='')
-{
-	global $config,$databases;
-    if (isset($config['dbconnection']) && is_resource($config['dbconnection'])) {
-        return $config['dbconnection'];
-    }
-	$port=( isset($config['dbport']) && !empty($config['dbport']) ) ? ':' . $config['dbport'] : '';
-	$socket=( isset($config['dbsocket']) && !empty($config['dbsocket']) ) ? ':' . $config['dbsocket'] : '';
-
-	$config['dbconnection'] = @mysqli_connect($config['dbhost'] . $port . $socket, $config['dbuser'], $config['dbpass']);
-
-	if ( mysqli_connect_errno($config['dbconnection']) ) {
-		die(SQLError("Error establishing a database connection!", mysqli_connect_error($config['dbconnection'])));
-	}
-	if (!defined('MSD_MYSQL_VERSION')) GetMySQLVersion();
-
-	if (!isset($config['mysql_standard_character_set']) || $config['mysql_standard_character_set'] == '') get_sql_encodings();
-
-	if ($config['mysql_standard_character_set'] != $encoding)
-	{
-		$set_encoding=@mysqli_query($config['dbconnection'],'SET NAMES \'' . $encoding . '\'');
-		if ($set_encoding === false) $config['mysql_can_change_encoding']=false;
-		else $config['mysql_can_change_encoding']=true;
-	}
-	if ($keycheck_off) {
-	    // only called with this param when restoring
-	    mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=0');
-	    // also set SQL-Mode NO_AUTO_VALUE_ON_ZERO for magento users
-	    mysqli_query($config['dbconnection'], 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"');
-	}
-
-	return $config['dbconnection'];
-}
-
-function GetMySQLVersion()
-{
-
-	$res=MSD_query("select version()");
-	$row=mysqli_fetch_array($res);
-	$version=$row[0];
-	if (!defined('MSD_MYSQL_VERSION')) define('MSD_MYSQL_VERSION',$version);
-	$versions=explode('.',$version);
-	$new=false;
-	if ($versions[0] == 4 && $versions[1] >= 1) $new=true;
-	if ($versions[0] > 4) $new=true;
-	if (!defined('MSD_NEW_VERSION')) define('MSD_NEW_VERSION',$new);
-
-	return $version;
-}
-
-function MSD_query($query, $error_output=true)
-{
-	global $config;
-	if (!isset($config['dbconnection'])) MSD_mysql_connect();
-//	echo "<br>Query: ".htmlspecialchars($query);
-	$res=mysqli_query($config['dbconnection'],$query);
-	if (false === $res && $error_output) SQLError($query,mysqli_error($config['dbconnection']));
-	return $res;
-
-}
-
-function SQLError($sql, $error, $return_output=false)
-{
-	global $lang;
-
-	$ret='<div align="center"><table style="border:1px solid #ff0000" cellspacing="0">
-<tr bgcolor="#ff0000"><td style="color:white;font-size:16px;"><strong>MySQL-ERROR</strong></td></tr>
-<tr><td style="width:80%;overflow: auto;">' . $lang['L_SQL_ERROR2'] . '<br><span style="color:red;">' . $error . '</span></td></tr>
-<tr><td width="600"><br>' . $lang['L_SQL_ERROR1'] . '<br>' . Highlight_SQL($sql) . '</td></tr>
-</table></div><br />';
-	if ($return_output) return $ret;
-	else echo $ret;
-}
-
-function Highlight_SQL($sql)
-{
-	global $sql_keywords;
-
-	$end='';
-	$tickstart=false;
-	if (function_exists("token_get_all")) $a=@token_get_all("<?php $sql?>");
-	else return $sql;
-	foreach ($a as $token)
-	{
-		if (!is_array($token))
-		{
-			if ($token == '`') $tickstart=!$tickstart;
-			$end.=$token;
-		}
-		else
-		{
-			if ($tickstart) $end.=$token[1];
-			else
-			{
-				switch (token_name($token[0]))
-				{
-					case "T_STRING":
-					case "T_AS":
-					case "T_FOR":
-
-						$end.=( in_array(strtoupper($token[1]),$sql_keywords) ) ? "<span style=\"color:#990099;font-weight:bold;\">" . $token[1] . "</span>" : $token[1];
-						break;
-					case "T_IF":
-					case "T_LOGICAL_AND":
-					case "T_LOGICAL_OR":
-					case "T_LOGICAL_XOR":
-						$end.=( in_array(strtoupper($token[1]),$sql_keywords) ) ? "<span style=\"color:#0000ff;font-weight:bold;\">" . $token[1] . "</span>" : $token[1];
-						break;
-					case "T_CLOSE_TAG":
-					case "T_OPEN_TAG":
-						break;
-					default:
-						$end.=$token[1];
-				}
-			}
-		}
-	}
-	$end=preg_replace("/`(.*?)`/si","<span style=\"color:red;\">`$1`</span>",$end);
-	return $end;
-}
-
-function Fieldlist($db, $tbl)
-{
-	$fl='';
-	$res=MSD_query("SHOW FIELDS FROM `$db`.`$tbl`;");
-	if ($res)
-	{
-		$fl='(';
-		for ($i=0; $i < mysqli_num_rows($res); $i++)
-		{
-			$row=mysqli_fetch_row($res);
-			$fl.='`' . $row[0] . '`,';
-		}
-		$fl=substr($fl,0,strlen($fl) - 1) . ')';
-	}
-	return $fl;
-}
-
-// reads all Tableinfos and place them in $dump-Array
-function getDBInfos()
-{
-	global $databases,$dump,$config,$tbl_sel,$flipped;
-	for ($ii=0; $ii < count($databases['multi']); $ii++)
-	{
-		$dump['dbindex']=$flipped[$databases['multi'][$ii]];
-		$tabellen=mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `' . $databases['Name'][$dump['dbindex']] . '`') or die('getDBInfos: ' . mysqli_error($config['dbconnection']));
-		$num_tables=mysqli_num_rows($tabellen);
-		// Array mit den gewünschten Tabellen zusammenstellen... wenn Präfix angegeben, werden die anderen einfach nicht übernommen
-		if ($num_tables > 0)
-		{
-			for ($i=0; $i < $num_tables; $i++)
-			{
-				$row=mysqli_fetch_array($tabellen);
-				if (isset($row['Type'])) $row['Engine']=$row['Type'];
-				if (isset($row['Comment']) && substr(strtoupper($row['Comment']),0,4) == 'VIEW') $dump['table_types'][]='VIEW';
-				else $dump['table_types'][]=strtoupper($row['Engine']);
-				// check if data needs to be backed up
-				if (strtoupper($row['Comment']) == 'VIEW' || ( isset($row['Engine']) && in_array(strtoupper($row['Engine']),array(
-                    'MEMORY'
-				)) ))
-				{
-					$dump['skip_data'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Name'];
-				}
-                    if ($config['optimize_tables_beforedump'] == 1 && $dump['table_offset'] == -1
-                        && $databases['Name'][$dump['dbindex']]!='information_schema') {
-                        mysqli_select_db($config['dbconnection'], $databases['Name'][$dump['dbindex']]);
-                        $opt = 'OPTIMIZE TABLE `' . $row['Name'] . '`';
-                        $res = mysqli_query($config['dbconnection'], 'OPTIMIZE TABLE `' . $row['Name'] . '`');
-                        if ($res === false) {
-                            die("Error in ".$opt." -> ".mysqli_error($config['dbconnection']));
-                        }
-                    }
-
-            if (isset($tbl_sel))
-				{
-					if (in_array($row['Name'],$dump['tblArray']))
-					{
-						$dump['tables'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Name'];
-						$dump['records'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Rows'];
-						$dump['totalrecords']+=$row['Rows'];
-					}
-				}
-				elseif ($databases['praefix'][$dump['dbindex']] != '' && !isset($tbl_sel))
-				{
-					if (substr($row['Name'],0,strlen($databases['praefix'][$dump['dbindex']])) == $databases['praefix'][$dump['dbindex']])
-					{
-						$dump['tables'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Name'];
-						$dump['records'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Rows'];
-						$dump['totalrecords']+=$row['Rows'];
-					}
-				}
-				else
-				{
-					$dump['tables'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Name'];
-					$dump['records'][]=$databases['Name'][$dump['dbindex']] . '|' . $row['Rows'];
-
-					// Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
-					$sql_2="SELECT count(*) as `count_records` FROM `" . $databases['Name'][$dump['dbindex']] . "`.`" . $row['Name'] . "`";
-					$res2=@mysqli_query($config['dbconnection'], $sql_2);
-					if ($res2 === false)
-					{
-						$read_error='(' . mysql_errno() . ') ' . mysqli_error($config['dbconnection']);
-						SQLError($read_error,$sql_2);
-						WriteLog($read_error);
-						if ($config['stop_with_error'] > 0)
-						{
-							die($read_error);
-						}
-					}
-					else
-					{
-						$row2=@mysqli_fetch_array($res2);
-						$row['Rows']=$row2['count_records'];
-						$dump['totalrecords']+=$row['Rows'];
-					}
-				}
-			}
-			// Correct total number of records; substract skipped data
-			foreach ($dump['skip_data'] as $skip_data)
-			{
-				$index=false;
-				$records_to_skip=0;
-				//find index of table to get the nr of records
-				$count=sizeof($dump['tables']);
-				for ($a=0; $a < $count; $a++)
-				{
-					if ($dump['tables'][$a] == $skip_data)
-					{
-						$index=$a;
-						$t=explode('|',$dump['records'][$a]);
-						$rekords_to_skip=$t[1];
-						break;
-					}
-				}
-				if ($index) $dump['totalrecords']-=$rekords_to_skip;
-			}
-		}
-	}
-}
-
-// gets the numeric index in dump-array and returns it
-function getDBIndex($db, $table)
-{
-	global $dump;
-	$index=array_keys($dump['tables'],$db . '|' . $table);
-	return $index[0];
-}
-
diff --git a/msd/inc/mysqli.php b/msd/inc/mysqli.php
new file mode 100644
index 00000000..c64de282
--- /dev/null
+++ b/msd/inc/mysqli.php
@@ -0,0 +1,543 @@
+<?php
+/* ----------------------------------------------------------------------
+
+   MyOOS [Dumper]
+   http://www.oos-shop.de/
+
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
+   ----------------------------------------------------------------------
+   Based on:
+
+   MySqlDumper
+   http://www.mysqldumper.de
+
+   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
+   ----------------------------------------------------------------------
+   Released under the GNU General Public License
+   ---------------------------------------------------------------------- */
+
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+
+//Feldspezifikationen
+$feldtypen = [
+                'VARCHAR',
+                'TINYINT',
+                'TEXT',
+                'DATE',
+                'SMALLINT',
+                'MEDIUMINT',
+                'INT',
+                'BIGINT',
+                'FLOAT',
+                'DOUBLE',
+                'DECIMAL',
+                'DATETIME',
+                'TIMESTAMP',
+                'TIME',
+                'YEAR',
+                'CHAR',
+                'TINYBLOB',
+                'TINYTEXT',
+                'BLOB',
+                'MEDIUMBLOB',
+                'MEDIUMTEXT',
+                'LONGBLOB',
+                'LONGTEXT',
+                'ENUM',
+                'SET',
+];
+$feldattribute = [
+                    '',
+                    'BINARY',
+                    'UNSIGNED',
+                    'UNSIGNED ZEROFILL',
+];
+$feldnulls = [
+                'NOT NULL',
+                'NULL',
+];
+$feldextras = [
+                '',
+                'AUTO_INCREMENT',
+];
+$feldkeys = [
+                '',
+                'PRIMARY KEY',
+                'UNIQUE KEY',
+                'FULLTEXT',
+];
+$feldrowformat = [
+                    '',
+                    'FIXED',
+                    'DYNAMIC',
+                    'COMPRESSED',
+];
+
+$rechte_daten = [
+                    'SELECT',
+                    'INSERT',
+                    'UPDATE',
+                    'DELETE',
+                    'FILE',
+];
+$rechte_struktur = [
+                    'CREATE',
+                    'ALTER',
+                    'INDEX',
+                    'DROP',
+                    'CREATE TEMPORARY TABLES',
+];
+$rechte_admin = [
+                    'GRANT',
+                    'SUPER',
+                    'PROCESS',
+                    'RELOAD',
+                    'SHUTDOWN',
+                    'SHOW DATABASES',
+                    'LOCK TABLES',
+                    'REFERENCES',
+                    'EXECUTE',
+                    'REPLICATION CLIENT',
+                    'REPLICATION SLAVE',
+];
+$rechte_resourcen = [
+                        'MAX QUERIES PER HOUR',
+                        'MAX UPDATES PER HOUR',
+                        'MAX CONNECTIONS PER HOUR',
+];
+
+$sql_keywords = [
+                    'ALTER',
+                    'AND',
+                    'ADD',
+                    'AUTO_INCREMENT',
+                    'BETWEEN',
+                    'BINARY',
+                    'BOTH',
+                    'BY',
+                    'BOOLEAN',
+                    'CHANGE',
+                    'CHARSET',
+                    'CHECK',
+                    'COLLATE',
+                    'COLUMNS',
+                    'COLUMN',
+                    'CROSS',
+                    'CREATE',
+                    'DATABASES',
+                    'DATABASE',
+                    'DATA',
+                    'DELAYED',
+                    'DESCRIBE',
+                    'DESC',
+                    'DISTINCT',
+                    'DELETE',
+                    'DROP',
+                    'DEFAULT',
+                    'ENCLOSED',
+                    'ENGINE',
+                    'ESCAPED',
+                    'EXISTS',
+                    'EXPLAIN',
+                    'FIELDS',
+                    'FIELD',
+                    'FLUSH',
+                    'FOR',
+                    'FOREIGN',
+                    'FUNCTION',
+                    'FROM',
+                    'GROUP',
+                    'GRANT',
+                    'HAVING',
+                    'IGNORE',
+                    'INDEX',
+                    'INFILE',
+                    'INSERT',
+                    'INNER',
+                    'INTO',
+                    'IDENTIFIED',
+                    'JOIN',
+                    'KEYS',
+                    'KILL',
+                    'KEY',
+                    'LEADING',
+                    'LIKE',
+                    'LIMIT',
+                    'LINES',
+                    'LOAD',
+                    'LOCAL',
+                    'LOCK',
+                    'LOW_PRIORITY',
+                    'LEFT',
+                    'LANGUAGE',
+                    'MEDIUMINT',
+                    'MODIFY',
+                    'MyISAM',
+                    'NATURAL',
+                    'NOT',
+                    'NULL',
+                    'NEXTVAL',
+                    'OPTIMIZE',
+                    'OPTION',
+                    'OPTIONALLY',
+                    'ORDER',
+                    'OUTFILE',
+                    'OR',
+                    'OUTER',
+                    'ON',
+                    'PROCEEDURE',
+                    'PROCEDURAL',
+                    'PRIMARY',
+                    'READ',
+                    'REFERENCES',
+                    'REGEXP',
+                    'RENAME',
+                    'REPLACE',
+                    'RETURN',
+                    'REVOKE',
+                    'RLIKE',
+                    'RIGHT',
+                    'SHOW',
+                    'SONAME',
+                    'STATUS',
+                    'STRAIGHT_JOIN',
+                    'SELECT',
+                    'SETVAL',
+                    'TABLES',
+                    'TEMINATED',
+                    'TO',
+                    'TRAILING',
+                    'TRUNCATE',
+                    'TABLE',
+                    'TEMPORARY',
+                    'TRIGGER',
+                    'TRUSTED',
+                    'UNIQUE',
+                    'UNLOCK',
+                    'USE',
+                    'USING',
+                    'UPDATE',
+                    'UNSIGNED',
+                    'VALUES',
+                    'VARIABLES',
+                    'VIEW',
+                    'WITH',
+                    'WRITE',
+                    'WHERE',
+                    'ZEROFILL',
+                    'XOR',
+                    'ALL',
+                    'ASC',
+                    'AS',
+                    'SET',
+                    'IN',
+                    'IS',
+                    'IF',
+];
+$mysql_doc = [
+                'Feldtypen' => 'http://dev.mysql.com/doc/mysql/de/Column_types.html',
+];
+$mysql_string_types = [
+    'char',
+    'varchar',
+    'tinytext',
+    'text',
+    'mediumtext',
+    'longtext',
+    'binary',
+    'varbinary',
+    'tinyblob',
+    'mediumblob',
+    'blob',
+    'longblob',
+    'enum',
+    'set',
+];
+$mysql_SQLhasRecords = [
+                        'SELECT',
+                        'SHOW',
+                        'EXPLAIN',
+                        'DESCRIBE',
+                        'DESC',
+];
+
+function mod_mysqli_connect($encoding = 'utf8mb4', $keycheck_off = false, $actual_table = '')
+{
+    global $config, $databases;
+
+    if (isset($config['dbconnection']) && is_resource($config['dbconnection'])) {
+        return $config['dbconnection'];
+    }
+
+    $port = (isset($config['dbport']) && !empty($config['dbport'])) ? ':'.$config['dbport'] : '';
+    $socket = (isset($config['dbsocket']) && !empty($config['dbsocket'])) ? ':'.$config['dbsocket'] : '';
+
+    // Forcing error reporting mode to OFF, which is no longer the default
+    // starting with PHP 8.1
+    @mysqli_report(MYSQLI_REPORT_OFF);
+
+    $config['dbconnection'] = @mysqli_connect($config['dbhost'].$port.$socket, $config['dbuser'], $config['dbpass']);
+
+    if (!$config['dbconnection']) {
+        exit(SQLError('Error establishing a database connection!', mysqli_connect_error()));
+    }
+    if (!defined('MOD_MYSQL_VERSION')) {
+        GetMySQLVersion();
+    }
+
+    if (!isset($config['mysql_standard_character_set']) || '' == $config['mysql_standard_character_set']) {
+        get_sql_encodings();
+    }
+
+    if ($config['mysql_standard_character_set'] != $encoding) {
+        $set_encoding = mysqli_query($config['dbconnection'], 'SET NAMES \''.$encoding.'\'');
+        if (false === $set_encoding) {
+            $config['mysql_can_change_encoding'] = false;
+        } else {
+            $config['mysql_can_change_encoding'] = true;
+        }
+    }
+    if ($keycheck_off) {
+        // only called with this param when restoring
+        mysqli_query($config['dbconnection'], 'SET FOREIGN_KEY_CHECKS=0');
+        // also set SQL-Mode NO_AUTO_VALUE_ON_ZERO for magento users
+        mysqli_query($config['dbconnection'], 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"');
+    }
+
+    return $config['dbconnection'];
+}
+
+function GetMySQLVersion()
+{
+    global $config;
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+
+    $res = mod_query('SELECT VERSION()');
+    $row = mysqli_fetch_array($res);
+    $str = $row[0];
+    $version = str_replace(':', '--', $str);
+    if (!defined('MOD_MYSQL_VERSION')) {
+        define('MOD_MYSQL_VERSION', $version);
+    }
+    $versions = explode('.', $version);
+    $new = false;
+    if (4 == $versions[0] && $versions[1] >= 1) {
+        $new = true;
+    }
+    if ($versions[0] > 4) {
+        $new = true;
+    }
+    if (!defined('MOD_NEW_VERSION')) {
+        define('MOD_NEW_VERSION', $new);
+    }
+
+    return $version;
+}
+
+function mod_query($query, $error_output = true)
+{
+    global $config;
+    // print_mem();
+    if (!isset($config['dbconnection'])) {
+        mod_mysqli_connect();
+    }
+    // echo "<br>Query: ".htmlspecialchars($query).'<br>';
+    $res = mysqli_query($config['dbconnection'], $query);
+    // print_mem();
+    if (false === $res && $error_output) {
+        SQLError($query, mysqli_error($config['dbconnection']));
+    }
+    return $res;
+}
+
+function print_mem()
+{
+    /* Currently used memory */
+    $mem_usage = memory_get_usage();
+
+    /* Peak memory usage */
+    $mem_peak = memory_get_peak_usage();
+
+    echo 'The script is now using: <strong>'.round($mem_usage / 1024).' KB</strong> of memory.<br>';
+    echo 'Peak usage: <strong>'.round($mem_peak / 1024).' KB</strong> of memory.<br><br>';
+}
+
+function SQLError($sql, $error, $return_output = false)
+{
+    global $lang;
+
+    $ret = '<div align="center"><table style="border:1px solid #ff0000" cellspacing="0">
+<tr bgcolor="#ff0000"><td style="color:white;font-size:16px;"><strong>MySQL-ERROR</strong></td></tr>
+<tr><td style="width:80%;overflow: auto;">'.$lang['L_SQL_ERROR2'].'<br><span style="color:red;">'.$error.'</span></td></tr>
+<tr><td width="600"><br>'.$lang['L_SQL_ERROR1'].'<br>'.Highlight_SQL($sql).'</td></tr>
+</table></div><br />';
+    if ($return_output) {
+        return $ret;
+    } else {
+        echo $ret;
+    }
+}
+
+function Highlight_SQL($sql)
+{
+    global $sql_keywords;
+
+    $end = '';
+    $tickstart = false;
+    if (function_exists('token_get_all')) {
+        $a = @token_get_all("<?php $sql?>");
+    } else {
+        return $sql;
+    }
+    foreach ($a as $token) {
+        if (!is_array($token)) {
+            if ('`' == $token) {
+                $tickstart = !$tickstart;
+            }
+            $end .= $token;
+        } else {
+            if ($tickstart) {
+                $end .= $token[1];
+            } else {
+                switch (token_name($token[0])) {
+                    case 'T_STRING':
+                    case 'T_AS':
+                    case 'T_FOR':
+                        $end .= (in_array(strtoupper($token[1]), $sql_keywords)) ? '<span style="color:#990099;font-weight:bold;">'.$token[1].'</span>' : $token[1];
+                        break;
+                    case 'T_IF':
+                    case 'T_LOGICAL_AND':
+                    case 'T_LOGICAL_OR':
+                    case 'T_LOGICAL_XOR':
+                        $end .= (in_array(strtoupper($token[1]), $sql_keywords)) ? '<span style="color:#0000ff;font-weight:bold;">'.$token[1].'</span>' : $token[1];
+                        break;
+                    case 'T_CLOSE_TAG':
+                    case 'T_OPEN_TAG':
+                        break;
+                    default:
+                        $end .= $token[1];
+                }
+            }
+        }
+    }
+    $end = preg_replace('/`(.*?)`/si', '<span style="color:red;">`$1`</span>', $end);
+    return $end;
+}
+
+function Fieldlist($db, $tbl)
+{
+    $fl = '';
+    $res = mod_query("SHOW FIELDS FROM `$db`.`$tbl`;");
+    if ($res) {
+        $fl = '(';
+        for ($i = 0; $i < mysqli_num_rows($res); ++$i) {
+            $row = mysqli_fetch_row($res);
+            $fl .= '`'.$row[0].'`,';
+        }
+        $fl = substr($fl, 0, strlen($fl) - 1).')';
+    }
+    return $fl;
+}
+
+// reads all Tableinfos and place them in $dump-Array
+function getDBInfos()
+{
+    global $databases, $dump, $config, $tbl_sel, $flipped;
+    for ($ii = 0; $ii < count($databases['multi']); ++$ii) {
+        $dump['dbindex'] = $flipped[$databases['multi'][$ii]];
+        $tabellen = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['Name'][$dump['dbindex']].'`') or exit('getDBInfos: '.mysqli_error($config['dbconnection']));
+        $num_tables = mysqli_num_rows($tabellen);
+        // Array mit den gewünschten Tabellen zusammenstellen... wenn Präfix angegeben, werden die anderen einfach nicht übernommen
+        if ($num_tables > 0) {
+            for ($i = 0; $i < $num_tables; ++$i) {
+                $row = mysqli_fetch_array($tabellen);
+                if (isset($row['Type'])) {
+                    $row['Engine'] = $row['Type'];
+                }
+                if (isset($row['Comment']) && 'VIEW' == substr(strtoupper($row['Comment']), 0, 4)) {
+                    $dump['table_types'][] = 'VIEW';
+                } else {
+                    $dump['table_types'][] = strtoupper($row['Engine']);
+                }
+                // check if data needs to be backed up
+                if ('VIEW' == strtoupper($row['Comment']) || (isset($row['Engine']) && in_array(strtoupper($row['Engine']), [
+                    'MEMORY',
+                ]))) {
+                    $dump['skip_data'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
+                }
+                if ((isset($config['optimize_tables_beforedump']) && (1 == $config['optimize_tables_beforedump'])) && -1 == $dump['table_offset']
+                        && 'information_schema' != $databases['Name'][$dump['dbindex']]) {
+                    mysqli_select_db($config['dbconnection'], $databases['Name'][$dump['dbindex']]);
+                    $opt = 'OPTIMIZE TABLE `'.$row['Name'].'`';
+                    $res = mysqli_query($config['dbconnection'], 'OPTIMIZE TABLE `'.$row['Name'].'`');
+                    if (false === $res) {
+                        exit('Error in '.$opt.' -> '.mysqli_error($config['dbconnection']));
+                    }
+                }
+
+                if (isset($tbl_sel)) {
+                    if (in_array($row['Name'], $dump['tblArray'])) {
+                        $dump['tables'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
+                        $dump['records'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Rows'];
+                        $dump['totalrecords'] += $row['Rows'];
+                    }
+                } elseif ('' != $databases['praefix'][$dump['dbindex']] && !isset($tbl_sel)) {
+                    if (substr($row['Name'], 0, strlen($databases['praefix'][$dump['dbindex']])) == $databases['praefix'][$dump['dbindex']]) {
+                        $dump['tables'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
+                        $dump['records'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Rows'];
+                        $dump['totalrecords'] += $row['Rows'];
+                    }
+                } else {
+                    $dump['tables'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Name'];
+                    $dump['records'][] = $databases['Name'][$dump['dbindex']].'|'.$row['Rows'];
+
+                    // Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
+                    $sql_2 = 'SELECT count(*) as `count_records` FROM `'.$databases['Name'][$dump['dbindex']].'`.`'.$row['Name'].'`';
+                    $res2 = mysqli_query($config['dbconnection'], $sql_2);
+                    if (false === $res2) {
+                        $read_error = mysqli_error($config['dbconnection']);
+                        SQLError($read_error, $sql_2);
+                        WriteLog($read_error);
+                        if ($config['stop_with_error'] > 0) {
+                            exit($read_error);
+                        }
+                    } else {
+                        $row2 = mysqli_fetch_array($res2);
+                        $row['Rows'] = $row2['count_records'];
+                        $dump['totalrecords'] += $row['Rows'];
+                    }
+                }
+            }
+            // Correct total number of records; substract skipped data
+            foreach ($dump['skip_data'] as $skip_data) {
+                $index = false;
+                $records_to_skip = 0;
+                //find index of table to get the nr of records
+                $count = sizeof($dump['tables']);
+                for ($a = 0; $a < $count; ++$a) {
+                    if ($dump['tables'][$a] == $skip_data) {
+                        $index = $a;
+                        $t = explode('|', $dump['records'][$a]);
+                        $rekords_to_skip = $t[1];
+                        break;
+                    }
+                }
+                if ($index) {
+                    $dump['totalrecords'] -= intval($rekords_to_skip);
+                }
+            }
+        }
+    }
+}
+
+// gets the numeric index in dump-array and returns it
+function getDBIndex($db, $table)
+{
+    global $dump;
+    $index = array_keys($dump['tables'], $db.'|'.$table);
+    return $index[0];
+}
diff --git a/msd/inc/runtime.php b/msd/inc/runtime.php
index 273dfff1..66c8958f 100644
--- a/msd/inc/runtime.php
+++ b/msd/inc/runtime.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,136 +16,135 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
 error_reporting(E_ALL);
 
-
-if (function_exists("date_default_timezone_set")) date_default_timezone_set(@date_default_timezone_get());
+if (function_exists('date_default_timezone_set')) {
+    date_default_timezone_set(@date_default_timezone_get());
+}
 //Konstanten
-if (!defined('MSD_VERSION')) define('MSD_VERSION','4.2.0-dev based on MySQLDumper 1.24.4');
-if (!defined('MSD_OS')) define('MSD_OS',PHP_OS);
-if (!defined('MSD_OS_EXT')) define('MSD_OS_EXT',@php_uname());
-if (!defined('config') || !is_array($config)) $config=array();
-if (!defined('databases') || !is_array($databases)) $databases=array();
+if (!defined('MOD_VERSION')) {
+    define('MOD_VERSION', '5.0.20');
+}
+if (!defined('MOD_OS')) {
+    define('MOD_OS', PHP_OS);
+}
+if (!defined('MOD_OS_EXT')) {
+    define('MOD_OS_EXT', @php_uname());
+}
+if (!defined('config') || !is_array($config)) {
+    $config = [];
+}
+if (!defined('databases') || !is_array($databases)) {
+    $databases = [];
+}
 
 //Pfade und Files
-$config['paths']['root']=Realpfad('./');
-$config['paths']['work']='work/';
-$config['paths']['backup']=$config['paths']['work'] . 'backup/';
-$config['paths']['log']=$config['paths']['work'] . 'log/';
-$config['paths']['config']=$config['paths']['work'] . 'config/';
-$config['paths']['perlexec']='msd_cron/';
+$config['paths']['root'] = Realpfad('./');
+$config['paths']['work'] = 'work/';
+$config['paths']['backup'] = $config['paths']['work'].'backup/';
+$config['paths']['log'] = $config['paths']['work'].'log/';
+$config['paths']['config'] = $config['paths']['work'].'config/';
+$config['paths']['temp'] = $config['paths']['root'].$config['paths']['work'].'temp/';
+$config['paths']['cache'] = $config['paths']['root'].$config['paths']['work'].'cache/';
+$config['paths']['perlexec'] = 'mod_cron/';
 
-if (isset($_SESSION['config_file']))
-{
-	$config['config_file']=$_SESSION['config_file'];
-	$config['cron_configurationfile']=$_SESSION['config_file'];
+
+if (isset($_SESSION['config_file'])) {
+    $config['config_file'] = $_SESSION['config_file'];
+    $config['cron_configurationfile'] = $_SESSION['config_file'];
+} else {
+    $config['config_file'] = 'myoosdumper';
+    $_SESSION['config_file'] = 'myoosdumper';
+    $config['cron_configurationfile'] = 'myoosdumper.conf.php';
 }
-else
-{
-	$config['config_file']='myoosdumper';
-	$_SESSION['config_file']='myoosdumper';
-	$config['cron_configurationfile']='myoosdumper.conf.php';
-}
-$config['files']['log']=$config['paths']['log'] . 'mysqldump.log';
-$config['files']['perllog']=$config['paths']['log'] . 'mysqldump_perl.log';
-$config['files']['perllogcomplete']=$config['paths']['log'] . 'mysqldump_perl.complete.log';
-$config['files']['parameter']=$config['paths']['config'] . $config['config_file'] . '.php';
+$config['files']['log'] = $config['paths']['log'].'myoosdumper.log';
+$config['files']['perllog'] = $config['paths']['log'].'myoosdumper_perl.log';
+$config['files']['perllogcomplete'] = $config['paths']['log'].'myoosdumper_perl.complete.log';
+$config['files']['parameter'] = $config['paths']['config'].$config['config_file'].'.php';
 
 // inti MySQL-Setting-Vars
-$config['mysql_standard_character_set']='';
-$config['mysql_possible_character_sets']=array();
+$config['mysql_standard_character_set'] = '';
+$config['mysql_possible_character_sets'] = [];
 
 //Ini-Parameter
-$config['max_execution_time']=get_cfg_var('max_execution_time');
-$config['max_execution_time']=( $config['max_execution_time'] <= 0 ) ? 30 : $config['max_execution_time'];
-if ($config['max_execution_time'] > 30) $config['max_execution_time']=30;
-$config['upload_max_filesize']=get_cfg_var('upload_max_filesize');
-$config['safe_mode']=get_cfg_var('safe_mode');
-$config['magic_quotes_gpc']=get_magic_quotes_gpc();
-$config['disabled']=get_cfg_var('disable_functions');
-$config['phpextensions']=implode(', ',get_loaded_extensions());
-$m=trim(str_replace('M','',ini_get('memory_limit')));
+$config['max_execution_time'] = get_cfg_var('max_execution_time');
+$config['max_execution_time'] = ($config['max_execution_time'] <= 0) ? 30 : $config['max_execution_time'];
+if ($config['max_execution_time'] > 30) {
+    $config['max_execution_time'] = 30;
+}
+$config['upload_max_filesize'] = get_cfg_var('upload_max_filesize');
+$config['disabled'] = get_cfg_var('disable_functions');
+$config['phpextensions'] = implode(', ', get_loaded_extensions());
+$m = trim(str_replace('M', '', ini_get('memory_limit')));
 // fallback if ini_get doesn't work
-if (intval($m) == 0) $m=trim(str_replace('M','',get_cfg_var('memory_limit')));
-$config['php_ram']=$m;
+if (0 == intval($m)) {
+    $m = trim(str_replace('M', '', get_cfg_var('memory_limit')));
+}
+$config['php_ram'] = $m;
 
 //Ist zlib moeglich?
-$p1=explode(', ',$config['phpextensions']);
-$p2=explode(',',str_replace(' ','',$config['disabled']));
+$p1 = explode(', ', $config['phpextensions']);
+$p2 = explode(',', str_replace(' ', '', $config['disabled']));
 
-//Buggy PHP-Version ?
-$p3=explode('.',PHP_VERSION);
-$buggy=( $p3[0] == 4 && $p3[1] == 3 && $p3[2] < 3 );
-$config['zlib']=( !$buggy ) && ( in_array('zlib',$p1) && ( !in_array('gzopen',$p2) || !in_array('gzwrite',$p2) || !in_array('gzgets',$p2) || !in_array('gzseek',$p2) || !in_array('gztell',$p2) ) );
+$config['zlib'] = (in_array('zlib', $p1) && (!in_array('gzopen', $p2) || !in_array('gzwrite', $p2) || !in_array('gzgets', $p2) || !in_array('gzseek', $p2) || !in_array('gztell', $p2)));
 
 //Tuning-Ecke
-$config['tuning_add']=1.1;
-$config['tuning_sub']=0.9;
-$config['time_buffer']=0.75; //max_zeit=$config['max_execution_time']*$config['time_buffer']
-$config['perlspeed']=10000; //Anzahl der Datensaetze, die in einem Rutsch gelesen werden
+$config['tuning_add'] = 1.1;
+$config['tuning_sub'] = 0.9;
+$config['time_buffer'] = 0.75; //max_zeit= $config['max_execution_time']*$config['time_buffer']
+$config['perlspeed'] = 10000; //Anzahl der Datensaetze, die in einem Rutsch gelesen werden
 $config['ignore_enable_keys'] = 0;
 
 //Bausteine
-$config['homepage']='http://foren.myoos.de/viewforum.php?f=40';
+$config['homepage'] = 'http://foren.myoos.de/viewforum.php?f=40';
 
-$nl="\n";
-$mysql_commentstring='--';
+$nl = "\n";
+$mysql_commentstring = '--';
 
 //config-Variablen, die nicht gesichert werden sollen
-$config_dontsave=Array(
+$config_dontsave = [
+                    'homepage',
+                    'max_execution_time',
+                    'disabled',
+                    'phpextensions',
+                    'php_ram',
+                    'zlib',
+                    'tuning_add',
+                    'tuning_sub',
+                    'time_buffer',
+                    'perlspeed',
+                    'cron_configurationfile',
+                    'dbconnection',
+                    'version',
+                    'mysql_possible_character_sets',
+                    'mysql_standard_character_set',
+                    'config_file',
+                    'upload_max_filesize',
+                    'mysql_can_change_encoding',
+                    'cron_samedb',
+                    'paths',
+                    'files',
+];
 
-					'homepage',
-					'max_execution_time',
-					'safe_mode',
-					'magic_quotes_gpc',
-					'disabled',
-					'phpextensions',
-					'php_ram',
-					'zlib',
-					'tuning_add',
-					'tuning_sub',
-					'time_buffer',
-					'perlspeed',
-					'cron_configurationfile',
-					'dbconnection',
-					'version',
-					'mysql_possible_character_sets',
-					'mysql_standard_character_set',
-					'config_file',
-					'upload_max_filesize',
-					'mysql_can_change_encoding',
-					'cron_samedb',
-					'paths',
-					'files'
-);
-
-$dontBackupDatabases = array('mysql', 'information_schema');
+$dontBackupDatabases = ['mysql', 'information_schema'];
 
 // Automatisches entfernen von Slashes und Leerzeichen vorn und hinten abschneiden
-if (1==get_magic_quotes_gpc())
-{
-	$_POST=stripslashes_deep($_POST);
-	$_GET=stripslashes_deep($_GET);
-}
-$_POST=trim_deep($_POST);
-$_GET=trim_deep($_GET);
+$_POST = trim_deep($_POST);
+$_GET = trim_deep($_GET);
 
 function v($t)
 {
-	echo '<br>';
-	if (is_array($t) || is_object($t))
-	{
-		echo '<pre>';
-		print_r($t);
-		echo '</pre>';
-	}
-	else
-		echo $t;
+    echo '<br>';
+    if (is_array($t) || is_object($t)) {
+        echo '<pre>';
+        print_r($t);
+        echo '</pre>';
+    } else {
+        echo $t;
+    }
 }
 
 function getServerProtocol()
 {
-	return ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
+    return (isset($_SERVER['HTTPS']) && 'on' == strtolower($_SERVER['HTTPS'])) ? 'https://' : 'http://';
 }
-
diff --git a/msd/inc/sql_importexport.php b/msd/inc/sql_importexport.php
index 3d60c50d..bf7b990b 100644
--- a/msd/inc/sql_importexport.php
+++ b/msd/inc/sql_importexport.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,294 +16,275 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
-include('./inc/functions_imexport.php');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+include './inc/functions_imexport.php';
 //Im-/Export
-$import=( isset($_GET['import']) ) ? 1 : 0;
-if ($import == 1)
-{
-	//IMPORT
-	CheckcsvOptions();
-	if (isset($_POST['f_import_csvtrenn'])) $sql['import']['trenn']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_import_csvtrenn']) : $_POST['f_import_csvtrenn'];
-	if (isset($_POST['f_import_csvenc'])) $sql['import']['enc']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_import_csvenc']) : $_POST['f_import_csvenc'];
-	if (isset($_POST['f_import_csvesc'])) $sql['import']['esc']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_import_csvesc']) : $_POST['f_import_csvesc'];
-	if (empty($sql['import']['endline']))
-	{
-		$sql['import']['endline']=$nl;
-	}
-	else
-	{
-		$sql['import']['endline']=str_replace('\\r',"\015",$sql['import']['endline']);
-		$sql['import']['endline']=str_replace('\\n',"\012",$sql['import']['endline']);
-		$sql['import']['endline']=str_replace('\\t',"\011",$sql['import']['endline']);
-	}
-	$sql['import']['endline']=str_replace('\\t',"\011",$sql['import']['endline']);
-	if (isset($_POST['f_import_csvnull'])) $sql['import']['null']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_import_csvnull']) : $_POST['f_import_csvnull'];
-	$sql['import']['namefirstline']=( isset($_POST['f_import_namefirstline']) ) ? $_POST['f_import_namefirstline'] : 0;
-	$sql['import']['emptydb']=( isset($_POST['import_emptydb']) ) ? 1 : 0;
-	$sql['import']['createindex']=( isset($_POST['import_createindex']) ) ? 1 : 0;
-	$sql['import']['table']=( isset($_POST['import_table']) ) ? $_POST['import_table'] : "";
-	$sql['import']['import_source']=isset($_POST['import_source']) ? $_POST['import_source'] : 0;
-	$sql['import']['text']=isset($_POST['import_text']) ? ( ( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['import_text']) : $_POST['import_text'] ) : "";
-	$sql['import']['csv']="";
+$import = (isset($_GET['import'])) ? 1 : 0;
+if (1 == $import) {
+    //IMPORT
+    CheckcsvOptions();
+    if (isset($_POST['f_import_csvtrenn'])) {
+        $sql['import']['trenn'] = $_POST['f_import_csvtrenn'];
+    }
+    if (isset($_POST['f_import_csvenc'])) {
+        $sql['import']['enc'] = $_POST['f_import_csvenc'];
+    }
+    if (isset($_POST['f_import_csvesc'])) {
+        $sql['import']['esc'] = $_POST['f_import_csvesc'];
+    }
+    if (empty($sql['import']['endline'])) {
+        $sql['import']['endline'] = $nl;
+    } else {
+        $sql['import']['endline'] = str_replace('\\r', "\015", $sql['import']['endline']);
+        $sql['import']['endline'] = str_replace('\\n', "\012", $sql['import']['endline']);
+        $sql['import']['endline'] = str_replace('\\t', "\011", $sql['import']['endline']);
+    }
+    $sql['import']['endline'] = str_replace('\\t', "\011", $sql['import']['endline']);
+    if (isset($_POST['f_import_csvnull'])) {
+        $sql['import']['null'] = $_POST['f_import_csvnull'];
+    }
+    $sql['import']['namefirstline'] = (isset($_POST['f_import_namefirstline'])) ? $_POST['f_import_namefirstline'] : 0;
+    $sql['import']['emptydb'] = (isset($_POST['import_emptydb'])) ? 1 : 0;
+    $sql['import']['createindex'] = (isset($_POST['import_createindex'])) ? 1 : 0;
+    $sql['import']['table'] = (isset($_POST['import_table'])) ? $_POST['import_table'] : '';
+    $sql['import']['import_source'] = isset($_POST['import_source']) ? $_POST['import_source'] : 0;
+    $sql['import']['text'] = isset($_POST['import_text']) ? $_POST['import_text'] : '';
+    $sql['import']['csv'] = '';
 
-	if (isset($_POST['do_import']))
-	{
+    if (isset($_POST['do_import'])) {
+        $sql['import']['tablecreate'] = 0;
+        if ('new' == $sql['import']['table']) {
+            $sql['import']['table'] = 'import_';
+            $sql['import']['tablecreate'] = 1;
+        }
+        if ('' == $sql['import']['table']) {
+            $aus .= '<span class="error">'.$lang['L_IMPORT_NOTABLE'].'</span>';
+        } else {
+            if (0 == $_POST['import_source']) {
+                //Import aus textbox
+                $sql['import']['csv'] = explode($sql['import']['endline'], $sql['import']['text']);
+            } else {
+                if (!isset($_FILES['upfile']['name']) || empty($_FILES['upfile']['name'])) {
+                    $aus .= '<span class="error">'.$lang['L_FM_UPLOADFILEREQUEST'].'</span>';
+                } else {
+                    $fn = $_FILES['upfile']['tmp_name'];
 
-		$sql['import']['tablecreate']=0;
-		if ($sql['import']['table'] == "new")
-		{
-			$sql['import']['table']="import_";
-			$sql['import']['tablecreate']=1;
-		}
-		if ($sql['import']['table'] == "")
-		{
-			$aus.='<span class="error">' . $lang['L_IMPORT_NOTABLE'] . '</span>';
-		}
-		else
-		{
-			if ($_POST['import_source'] == 0)
-			{
-				//Import aus textbox
-				$sql['import']['csv']=explode($sql['import']['endline'],$sql['import']['text']);
+                    $sql['import']['csv'] = ('.gz' == substr($_FILES['upfile']['name'], -3)) ? gzfile($fn) : file($fn);
+                    $sql['import']['text'] = implode('', $sql['import']['csv']);
+                    $aus .= '<span>'.$lang['L_SQL_UPLOADEDFILE'].'<strong>'.$_FILES['upfile']['name'].'</strong>&nbsp;&nbsp;&nbsp;'.byte_output(filesize($_FILES['upfile']['tmp_name'])).'</span>';
+                }
+            }
+            if (is_array($sql['import']['csv'])) {
+                $aus .= DoImport();
+            } else {
+                $aus .= '<br><span class="error">'.$lang['L_CSV_NODATA'].'</span>';
+            }
+        }
+    }
+    $impaus = $aus;
 
-			}
-			else
-			{
-				if (!isset($_FILES['upfile']['name']) || empty($_FILES['upfile']['name']))
-				{
-					$aus.='<span class="error">' . $lang['L_FM_UPLOADFILEREQUEST'] . '</span>';
-				}
-				else
-				{
-					$fn=$_FILES['upfile']['tmp_name'];
+    $impaus .= '<form action="sql.php?db='.$db.'&amp;dbid='.$dbid.'&amp;context=4&amp;import=1" method="post" enctype="multipart/form-data">'.$nl;
+    $impaus .= '';
+    $impaus .= '<a href="sql.php?db='.$db.'&amp;dbid='.$dbid.'&amp;context=4">'.$lang['L_EXPORT'].'</a>';
+    $impaus .= '<h6>'.sprintf($lang['L_SQL_IMPORT'], $databases['Name'][$dbid]).'</h6>';
+    $impaus .= '<table class="bordersmall"><tr class="thead"><th>'.$nl;
+    $impaus .= $lang['L_IMPORTOPTIONS'].'</th><th>'.$lang['L_CSVOPTIONS'].'</th></tr>'.$nl;
 
-					$sql['import']['csv']=( substr($_FILES['upfile']['name'],-3) == ".gz" ) ? gzfile($fn) : file($fn);
-					$sql['import']['text']=implode("",$sql['import']['csv']);
-					$aus.='<span>' . $lang['L_SQL_UPLOADEDFILE'] . '<strong>' . $_FILES['upfile']['name'] . '</strong>&nbsp;&nbsp;&nbsp;' . byte_output(filesize($_FILES['upfile']['tmp_name'])) . '</span>';
+    $impaus .= '<tr><td valign="top">'.$nl;
+    $impaus .= '<table cellpadding="0" cellspacing="0">'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_IMPORTTABLE'].'</td><td><select name="import_table">'.TableComboBox($sql['import']['table']).'<option value="new" '.(('import_' == $sql['import']['table']) ? ' selected="selected"' : '').'>== '.$lang['L_NEWTABLE'].' ==</option></select></td></tr>'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_IMPORTSOURCE'].'</td>'.$nl;
+    $impaus .= '<td><input type="radio" class="radio" name="import_source" value="0" '.((0 == $sql['import']['import_source']) ? 'checked' : '').' onclick="check_csvdivs(1); return true">'.$lang['L_FROMTEXTBOX'].'<br>'.$nl;
+    $impaus .= '<input type="radio" class="radio" id="radio_csv0" name="import_source" value="1" '.((1 == $sql['import']['import_source']) ? 'checked' : '').' onclick="check_csvdivs(1); return true">'.$lang['L_FROMFILE'].'</td></tr>'.$nl;
+    $impaus .= '<tr><td colspan="2"><input type="checkbox" class="checkbox" name="import_emptydb" value="1" '.((1 == $sql['import']['emptydb']) ? 'checked' : '').'>'.$lang['L_EMPTYTABLEBEFORE'].'</td></tr>'.$nl;
+    $impaus .= '<tr><td colspan="2"><input type="checkbox" class="checkbox" name="import_createindex" value="1" '.((1 == $sql['import']['createindex']) ? 'checked' : '').'>'.$lang['L_CREATEAUTOINDEX'].'</td></tr>'.$nl;
+    $impaus .= '</table>'.$nl;
 
-				}
-			}
-			if (is_array($sql['import']['csv'])) $aus.=DoImport();
-			else $aus.='<br><span class="error">' . $lang['L_CSV_NODATA'] . '</span>';
+    $impaus .= '</td><td valign="top">'.$nl;
 
-		}
-	}
-	$impaus=$aus;
+    $impaus .= '<table cellpadding="0" cellspacing="0">'.$nl;
+    $impaus .= '<tr><td colspan="2"><input type="checkbox" class="checkbox" name="f_import_namefirstline0" value="1" '.((1 == $sql['import']['namefirstline']) ? 'checked' : '').'>'.$lang['L_CSV_NAMEFIRSTLINE'].'</td></tr>'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_CSV_FIELDSEPERATE'].'</td><td><input type="text" class="text" name="f_import_csvtrenn" size="4" maxlength="12" value="'.$sql['import']['trenn'].'"></td></tr>'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_CSV_FIELDSENCLOSED'].'</td><td><input type="text" class="text" name="f_import_csvenc" size="4" maxlength="12" value="'.htmlspecialchars($sql['import']['enc']).'"></td></tr>'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_CSV_FIELDSESCAPE'].'</td><td><input type="text" class="text" name="f_import_csvesc" size="4" maxlength="12" value="'.$sql['import']['esc'].'"></td></tr>'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_CSV_EOL'].'</td><td><input type="text" class="text" name="f_import_csvztrenn" size="4" maxlength="12" value="'.$sql['import']['ztrenn'].'"></td></tr>'.$nl;
+    $impaus .= '<tr><td>'.$lang['L_CSV_NULL'].'</td><td><input type="text" class="text" name="f_import_csvnull" size="4" maxlength="12" value="'.$sql['import']['null'].'"></td></tr>'.$nl;
+    $impaus .= '</table>'.$nl;
 
-	$impaus.='<form action="sql.php?db=' . $db . '&amp;dbid=' . $dbid . '&amp;context=4&amp;import=1" method="post" enctype="multipart/form-data">' . $nl;
-	$impaus.='';
-	$impaus.='<a href="sql.php?db=' . $db . '&amp;dbid=' . $dbid . '&amp;context=4">' . $lang['L_EXPORT'] . '</a>';
-	$impaus.='<h6>' . sprintf($lang['L_SQL_IMPORT'],$databases['Name'][$dbid]) . '</h6>';
-	$impaus.='<table class="bordersmall"><tr class="thead"><th>' . $nl;
-	$impaus.=$lang['L_IMPORTOPTIONS'] . '</th><th>' . $lang['L_CSVOPTIONS'] . '</th></tr>' . $nl;
+    $impaus .= '</td></tr>';
 
-	$impaus.='<tr><td valign="top">' . $nl;
-	$impaus.='<table cellpadding="0" cellspacing="0">' . $nl;
-	$impaus.='<tr><td>' . $lang['L_IMPORTTABLE'] . '</td><td><select name="import_table">' . TableComboBox($sql['import']['table']) . '<option value="new" ' . ( ( $sql['import']['table'] == "import_" ) ? ' selected="selected"' : '' ) . '>== ' . $lang['L_NEWTABLE'] . ' ==</option></select></td></tr>' . $nl;
-	$impaus.='<tr><td>' . $lang['L_IMPORTSOURCE'] . '</td>' . $nl;
-	$impaus.='<td><input type="radio" class="radio" name="import_source" value="0" ' . ( ( $sql['import']['import_source'] == 0 ) ? 'checked' : '' ) . ' onclick="check_csvdivs(1); return true">' . $lang['L_FROMTEXTBOX'] . '<br>' . $nl;
-	$impaus.='<input type="radio" class="radio" id="radio_csv0" name="import_source" value="1" ' . ( ( $sql['import']['import_source'] == 1 ) ? 'checked' : '' ) . ' onclick="check_csvdivs(1); return true">' . $lang['L_FROMFILE'] . '</td></tr>' . $nl;
-	$impaus.='<tr><td colspan="2"><input type="checkbox" class="checkbox" name="import_emptydb" value="1" ' . ( ( $sql['import']['emptydb'] == 1 ) ? 'checked' : '' ) . '>' . $lang['L_EMPTYTABLEBEFORE'] . '</td></tr>' . $nl;
-	$impaus.='<tr><td colspan="2"><input type="checkbox" class="checkbox" name="import_createindex" value="1" ' . ( ( $sql['import']['createindex'] == 1 ) ? 'checked' : '' ) . '>' . $lang['L_CREATEAUTOINDEX'] . '</td></tr>' . $nl;
-	$impaus.='</table>' . $nl;
-
-	$impaus.='</td><td valign="top">' . $nl;
-
-	$impaus.='<table cellpadding="0" cellspacing="0">' . $nl;
-	$impaus.='<tr><td colspan="2"><input type="checkbox" class="checkbox" name="f_import_namefirstline0" value="1" ' . ( ( $sql['import']['namefirstline'] == 1 ) ? "checked" : "" ) . '>' . $lang['L_CSV_NAMEFIRSTLINE'] . '</td></tr>' . $nl;
-	$impaus.='<tr><td>' . $lang['L_CSV_FIELDSEPERATE'] . '</td><td><input type="text" class="text" name="f_import_csvtrenn" size="4" maxlength="12" value="' . $sql['import']['trenn'] . '"></td></tr>' . $nl;
-	$impaus.='<tr><td>' . $lang['L_CSV_FIELDSENCLOSED'] . '</td><td><input type="text" class="text" name="f_import_csvenc" size="4" maxlength="12" value="' . htmlspecialchars($sql['import']['enc']) . '"></td></tr>' . $nl;
-	$impaus.='<tr><td>' . $lang['L_CSV_FIELDSESCAPE'] . '</td><td><input type="text" class="text" name="f_import_csvesc" size="4" maxlength="12" value="' . $sql['import']['esc'] . '"></td></tr>' . $nl;
-	$impaus.='<tr><td>' . $lang['L_CSV_EOL'] . '</td><td><input type="text" class="text" name="f_import_csvztrenn" size="4" maxlength="12" value="' . $sql['import']['ztrenn'] . '"></td></tr>' . $nl;
-	$impaus.='<tr><td>' . $lang['L_CSV_NULL'] . '</td><td><input type="text" class="text" name="f_import_csvnull" size="4" maxlength="12" value="' . $sql['import']['null'] . '"></td></tr>' . $nl;
-	$impaus.='</table>' . $nl;
-
-	$impaus.='</td></tr>';
-
-	$impaus.='<tr><td colspan="2"><div id="csv0">' . $lang['L_CSV_FILEOPEN'] . ':&nbsp;&nbsp;
+    $impaus .= '<tr><td colspan="2"><div id="csv0">'.$lang['L_CSV_FILEOPEN'].':&nbsp;&nbsp;
 		<input type="file" name="upfile" accept="application/gzip">';
-	$impaus.='<input type="hidden" name="MAX_FILE_SIZE" VALUE="2500000"></div></td></tr>';
+    $impaus .= '<input type="hidden" name="MAX_FILE_SIZE" VALUE="2500000"></div></td></tr>';
 
-	$impaus.='<tr><td colspan="2" align="right"><input class="Formbutton" type="submit" name="do_import" value=" ' . $lang['L_IMPORTIEREN'] . ' "></td></tr>';
+    $impaus .= '<tr><td colspan="2" align="right"><input class="Formbutton" type="submit" name="do_import" value=" '.$lang['L_IMPORTIEREN'].' "></td></tr>';
 
-	$impaus.='</table>' . $nl;
+    $impaus .= '</table>'.$nl;
 
-	$impaus.='<p>&nbsp;</p>' . $lang['L_IMPORT'] . ':<br><textarea name="import_text" wrap="OFF" style="width:760px;height:400px;font-size=11px;">';
-	//$impaus.=$sql['import']['text'];
-	$impaus.='</textarea></form>' . $nl;
+    $impaus .= '<p>&nbsp;</p>'.$lang['L_IMPORT'].':<br><textarea name="import_text" wrap="OFF" style="width:760px;height:400px;font-size=11px;">';
+    //$impaus.= $sql['import']['text'];
+    $impaus .= '</textarea></form>'.$nl;
 
-	$impaus.='<script language="JavaScript" type="text/javascript">check_csvdivs(1);</script>' . $nl;
+    $impaus .= '<script>check_csvdivs(1);</script>'.$nl;
 
-	echo $impaus . $nl;
+    echo $impaus.$nl;
+} else {
+    //EXPORT
+    $tables = 0;
+    $tblstr = '';
+    $sql['export']['db'] = $db;
 
-}
-else
-{
-	//EXPORT
-	$tables=0;
-	$tblstr="";
-	$sql['export']['db']=$db;
-
-	if (isset($_POST['f_export_submit']))
-	{
-		//echo '<pre>'.print_r($_POST,true).'</pre><hr>';
-		$sql['export']['header_sent']="";
-		$sql['export']['lines']=0;
-		$sql['export']['format']=$_POST['f_export_format'];
-		$sql['export']['ztrenn']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_export_csvztrenn']) : $_POST['f_export_csvztrenn'];
-		$sql['endline']['ztrenn']=$sql['export']['ztrenn'];
-		if ($sql['export']['format'] == 0)
-		{
-			//CSV
-			$format=0;
-			$sql['export']['trenn']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_export_csvtrenn']) : $_POST['f_export_csvtrenn'];
-			$sql['export']['enc']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_export_csvenc']) : $_POST['f_export_csvenc'];
-			$sql['export']['esc']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_export_csvesc']) : $_POST['f_export_csvesc'];
-			if (empty($sql['export']['endline']))
-			{
-				$sql['export']['endline']=$nl;
-			}
-			else
-			{
-				$sql['export']['endline']=str_replace('\\r',"\015",$sql['export']['endline']);
-				$sql['export']['endline']=str_replace('\\n',"\012",$sql['export']['endline']);
-				$sql['export']['endline']=str_replace('\\t',"\011",$sql['export']['endline']);
-			}
-			$sql['export']['endline']=str_replace('\\t',"\011",$sql['export']['endline']);
-		}
-		elseif ($sql['export']['format'] == 1)
-		{
-			//EXCEL
-			$format=1;
-			$sql['export']['trenn']=",";
-			$sql['export']['enc']='"';
-			$sql['export']['esc']='"';
-			$sql['export']['endline']="\015\012";
-		}
-		elseif ($sql['export']['format'] == 3)
-		{
-			//EXCEL 2003
-			$format=1;
-			$sql['export']['trenn']=";";
-			$sql['export']['enc']='"';
-			$sql['export']['esc']='"';
-			$sql['export']['endline']="\015\012";
-		}
-		elseif ($sql['export']['format'] == 4)
-		{
-			//XML
-			$format=4;
-			CheckcsvOptions();
-		}
-		elseif ($sql['export']['format'] == 5)
-		{
-			//HTML
-			$format=5;
-			CheckcsvOptions();
-		}
-		if ($format < 3) $sql['export']['null']=( $config['magic_quotes_gpc'] ) ? stripslashes($_POST['f_export_csvnull' . $format]) : $_POST['f_export_csvnull' . $format];
-		$sql['export']['namefirstline']=( isset($_POST['f_export_namefirstline' . $format]) ) ? $_POST['f_export_namefirstline' . $format] : 0;
-
-		$sql['export']['sendfile']=$_POST['f_export_sendresult'];
-		$sql['export']['compressed']=( isset($_POST['f_export_compressed']) ) ? $_POST['f_export_compressed'] : 0;
-
-		$sql['export']['exportfile']="";
-		$sql['export']['xmlstructure']=( isset($_POST['f_export_xmlstructure']) ) ? $_POST['f_export_xmlstructure'] : 0;
-		$sql['export']['htmlstructure']=( isset($_POST['f_export_htmlstructure']) ) ? $_POST['f_export_htmlstructure'] : 0;
-
-		//ausgewählte Tabellen
-		if (isset($_POST['f_export_tables']))
-		{
-			$sql['export']['tables']=$_POST['f_export_tables'];
-		}
-	}
-	else
-		CheckcsvOptions();
-
-	//Tabellenliste
-	$sqlt="SHOW TABLE STATUS FROM `$db`";
-	$res=MSD_query($sqlt);
-	if ($res)
-	{
-		$sql['export']['tablecount']=mysqli_num_rows($res);
-		$sql['export']['recordcount']=0;
-		for ($i=0; $i < $sql['export']['tablecount']; $i++)
-		{
-			$row=mysqli_fetch_array($res);
-			$tblstr.='<option value="' . $row['Name'] . '" ' . ( ( isset($sql['export']['tables']) && in_array($row['Name'],$sql['export']['tables']) ) ? ' selected="selected"' : "" ) . '>' . $row['Name'] . ' (' . $row['Rows'] . ')</option>' . "\n";
-			$sql['export']['recordcount']+=$row['Rows'];
-		}
-	}
-
-	$exaus=$aus . '<h4>' . sprintf($lang['L_SQL_EXPORT'],$databases['Name'][$dbid]) . '</h4>';
-
-	$exaus.='<form action="sql.php?db=' . $db . '&amp;dbid=' . $dbid . '&amp;context=4" method="post">' . $nl;
-	$exaus.='<a href="sql.php?db=' . $db . '&amp;dbid=' . $dbid . '&amp;context=4&amp;import=1">' . $lang['L_IMPORT'] . '</a>';
-	$exaus.='<h6>' . sprintf($lang['L_SQL_EXPORT'],$databases['Name'][$dbid]) . '</h6>';
-	$exaus.='<table class="bdr"><tr class="thead"><th>' . $lang['L_TABLES'] . '</th>' . $nl;
-	$exaus.='<th>' . $lang['L_EXPORTOPTIONS'] . '</th>';
-	$exaus.='<th>' . $lang['L_EXPORT'] . '</th></tr><tr>';
-	$exaus.='';
-
-	$exaus.='<td><span class="ssmall"><strong>' . $sql['export']['tablecount'] . '</strong> ' . $lang['L_TABLES'] . ', <strong>' . $sql['export']['recordcount'] . '</strong> ' . $lang['L_RECORDS'] . '</span>';
-	$exaus.='&nbsp;&nbsp;&nbsp;<a class="ssmall" href="#" onclick="SelectTableList(true);">' . $lang['L_ALL'] . '</a>&nbsp;&nbsp;<a class="ssmall" href="#" onclick="SelectTableList(false);">' . $lang['L_NONE'] . '</a>' . $nl;
-
-	$exaus.='<br><select name="f_export_tables[]" size="12" multiple>' . $tblstr . '</select><br>' . $nl;
-	$exaus.='</td><td>' . $nl;
-	$exaus.='' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_format" id="radio_csv0" value="0" ' . ( ( $sql['export']['format'] == 0 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . "CSV" . '&nbsp;&nbsp;&nbsp;' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_format" id="radio_csv1" value="1" ' . ( ( $sql['export']['format'] == 1 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . "Excel" . '&nbsp;&nbsp;&nbsp;' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_format" id="radio_csv2" value="3" ' . ( ( $sql['export']['format'] == 3 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . $lang['L_EXCEL2003'] . '<br>' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_format" id="radio_csv4" value="4" ' . ( ( $sql['export']['format'] == 4 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . "XML" . '&nbsp;&nbsp;&nbsp;' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_format" id="radio_csv5" value="5" ' . ( ( $sql['export']['format'] == 5 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . "HTML" . '<br><br>' . $nl;
-	$exaus.='<div id="csv0"><fieldset><legend>CSV-Optionen</legend><table cellpadding="0" cellspacing="0"><tr><td colspan="2">' . $nl;
-	$exaus.='<input type="checkbox" class="checkbox" name="f_export_namefirstline0" value="1" ' . ( ( $sql['export']['namefirstline'] == 1 ) ? "checked" : "" ) . '>' . $lang['L_CSV_NAMEFIRSTLINE'] . '</td></tr>' . $nl;
-	$exaus.='<tr><td>' . $lang['L_CSV_FIELDSEPERATE'] . '</td><td><input type="text" class="text" name="f_export_csvtrenn" size="4" maxlength="12" value="' . $sql['export']['trenn'] . '"></td></tr>' . $nl;
-	$exaus.='<tr><td>' . $lang['L_CSV_FIELDSENCLOSED'] . '</td><td><input type="text" class="text" name="f_export_csvenc" size="4" maxlength="12" value="' . htmlspecialchars($sql['export']['enc']) . '"></td></tr>' . $nl;
-	$exaus.='<tr><td>' . $lang['L_CSV_FIELDSESCAPE'] . '</td><td><input type="text" class="text" name="f_export_csvesc" size="4" maxlength="12" value="' . $sql['export']['esc'] . '"></td></tr>' . $nl;
-	$exaus.='<tr><td>' . $lang['L_CSV_EOL'] . '</td><td><input type="text" class="text" name="f_export_csvztrenn" size="4" maxlength="12" value="' . $sql['export']['ztrenn'] . '"></td></tr>' . $nl;
-	$exaus.='<tr><td>' . $lang['L_CSV_NULL'] . '</td><td><input type="text" class="text" name="f_export_csvnull0" size="4" maxlength="12" value="' . $sql['export']['null'] . '"></td></tr>' . $nl;
-	$exaus.='</table></fieldset></div>' . $nl;
-
-	$exaus.='<div id="csv1"><fieldset><legend>Excel-Optionen</legend><table cellpadding="0" cellspacing="0"><tr><td colspan="2">';
-	$exaus.='<input type="checkbox" class="checkbox" name="f_export_namefirstline1" value="1"' . ( ( $sql['export']['namefirstline'] == 1 ) ? "checked" : "" ) . '>' . $lang['L_CSV_NAMEFIRSTLINE'] . '</td></tr>' . $nl;
-	$exaus.='<tr><td>' . $lang['L_CSV_NULL'] . '</td><td><input type="text" class="text" name="f_export_csvnull1" size="4" maxlength="12" value="' . $sql['export']['null'] . '"></td></tr>' . $nl;
-	$exaus.='</table></fieldset></div>' . $nl;
-
-	$exaus.='<div id="csv4"><fieldset><legend>XML-Optionen</legend><table>';
-	$exaus.='<tr><td><input type="checkbox" name="f_export_xmlstructure" value="1" class="checkbox" ' . ( ( $sql['export']['xmlstructure'] == 1 ) ? 'checked' : '' ) . '> mit Struktur</td></tr>';
-	$exaus.='</table></fieldset></div>' . $nl;
-
-	$exaus.='<div id="csv5"><fieldset><legend>HTML-Optionen</legend><table>';
-	$exaus.='<tr><td><input type="checkbox" name="f_export_htmlstructure" value="1" class="checkbox" ' . ( ( $sql['export']['htmlstructure'] == 1 ) ? 'checked' : '' ) . '> mit Struktur</td></tr>';
-	$exaus.='</table></fieldset></div>' . $nl;
-
-	$exaus.='</td><td>' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_sendresult" value="0" ' . ( ( $sql['export']['sendfile'] == 0 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . $lang['L_SHOWRESULT'] . '<br>' . $nl;
-	$exaus.='<input type="radio" class="radio" name="f_export_sendresult" id="radio_csv3" value="1" ' . ( ( $sql['export']['sendfile'] == 1 ) ? "checked" : "" ) . ' onclick="check_csvdivs(0); return true">' . $lang['L_SENDRESULTASFILE'] . '<br>' . $nl;
-	$exaus.='<div id="csv3"><input type="checkbox" class="checkbox" name="f_export_compressed" value="1" ' . ( ( $sql['export']['compressed'] == 1 ) ? "checked" : "" ) . '>' . $lang['L_COMPRESSED'] . '</div><br>' . $nl;
-
-	$exaus.='<img src="' . $icon['blank'] . '" width="60" height="130" border="0"><br><input class="Formbutton" type="submit" name="f_export_submit" value="' . $lang['L_EXPORT'] . '" onclick="if(SelectedTableCount()==0) {alert(msg1);return false;}">' . $nl;
-	$exaus.='</td></tr></table></form>' . $nl;
-
-	$exaus.='<script language="JavaScript" type="text/javascript">check_csvdivs(0);</script>' . $nl;
-
-	if (!$download) echo $exaus . $nl;
-	if (isset($_POST['f_export_submit']) && isset($sql['export']['tables']))
-	{
-		if (!$download) echo '<br><br><table width="90%"><tr><td>' . $lang['L_EXPORT'] . ':</td><td align="right"><a href="javascript:BrowseInput(\'imexta\');">zeige in neuem Fenster</a></td></tr></table><textarea id="imexta" wrap="OFF" style="width:760px;height:400px;font-size=11px;">' . $nl;
-		if ($format < 3) ExportCSV();
-		elseif ($format == 4) ExportXML();
-		elseif ($format == 5) ExportHTML();
-		if (!$download)
-		{
-			echo '</textarea><br>' . $nl;
-			echo '<span style="color:blue;">' . $lang['L_EXPORTFINISHED'] . '</span>&nbsp;&nbsp;' . sprintf($lang['L_EXPORTLINES'],$sql['export']['lines']) . $nl;
-		}
-		else
-		{
-			exit();
-		}
-	}
+    if (isset($_POST['f_export_submit'])) {
+        //echo '<pre>'.print_r($_POST,true).'</pre><hr>';
+        $sql['export']['header_sent'] = '';
+        $sql['export']['lines'] = 0;
+        $sql['export']['format'] = $_POST['f_export_format'];
+        $sql['export']['ztrenn'] = $_POST['f_export_csvztrenn'];
+        $sql['endline']['ztrenn'] = $sql['export']['ztrenn'];
+        if (0 == $sql['export']['format']) {
+            //CSV
+            $format = 0;
+            $sql['export']['trenn'] = $_POST['f_export_csvtrenn'];
+            $sql['export']['enc'] = $_POST['f_export_csvenc'];
+            $sql['export']['esc'] = $_POST['f_export_csvesc'];
+            if (empty($sql['export']['endline'])) {
+                $sql['export']['endline'] = $nl;
+            } else {
+                $sql['export']['endline'] = str_replace('\\r', "\015", $sql['export']['endline']);
+                $sql['export']['endline'] = str_replace('\\n', "\012", $sql['export']['endline']);
+                $sql['export']['endline'] = str_replace('\\t', "\011", $sql['export']['endline']);
+            }
+            $sql['export']['endline'] = str_replace('\\t', "\011", $sql['export']['endline']);
+        } elseif (1 == $sql['export']['format']) {
+            //EXCEL
+            $format = 1;
+            $sql['export']['trenn'] = ',';
+            $sql['export']['enc'] = '"';
+            $sql['export']['esc'] = '"';
+            $sql['export']['endline'] = "\015\012";
+        } elseif (3 == $sql['export']['format']) {
+            //EXCEL 2003
+            $format = 1;
+            $sql['export']['trenn'] = ';';
+            $sql['export']['enc'] = '"';
+            $sql['export']['esc'] = '"';
+            $sql['export']['endline'] = "\015\012";
+        } elseif (4 == $sql['export']['format']) {
+            //XML
+            $format = 4;
+            CheckcsvOptions();
+        } elseif (5 == $sql['export']['format']) {
+            //HTML
+            $format = 5;
+            CheckcsvOptions();
+        }
+        if ($format < 3) {
+            $sql['export']['null'] = $_POST['f_export_csvnull'.$format];
+        }
+        $sql['export']['namefirstline'] = (isset($_POST['f_export_namefirstline'.$format])) ? $_POST['f_export_namefirstline'.$format] : 0;
+
+        $sql['export']['sendfile'] = $_POST['f_export_sendresult'];
+        $sql['export']['compressed'] = (isset($_POST['f_export_compressed'])) ? $_POST['f_export_compressed'] : 0;
+
+        $sql['export']['exportfile'] = '';
+        $sql['export']['xmlstructure'] = (isset($_POST['f_export_xmlstructure'])) ? $_POST['f_export_xmlstructure'] : 0;
+        $sql['export']['htmlstructure'] = (isset($_POST['f_export_htmlstructure'])) ? $_POST['f_export_htmlstructure'] : 0;
+
+        //ausgewählte Tabellen
+        if (isset($_POST['f_export_tables'])) {
+            $sql['export']['tables'] = $_POST['f_export_tables'];
+        }
+    } else {
+        CheckcsvOptions();
+    }
+
+    //Tabellenliste
+    $sqlt = "SHOW TABLE STATUS FROM `$db`";
+    $res = mod_query($sqlt);
+    if ($res) {
+        $sql['export']['tablecount'] = mysqli_num_rows($res);
+        $sql['export']['recordcount'] = 0;
+        for ($i = 0; $i < $sql['export']['tablecount']; ++$i) {
+            $row = mysqli_fetch_array($res);
+            $tblstr .= '<option value="'.$row['Name'].'" '.((isset($sql['export']['tables']) && in_array($row['Name'], $sql['export']['tables'])) ? ' selected="selected"' : '').'>'.$row['Name'].' ('.$row['Rows'].')</option>'."\n";
+            $sql['export']['recordcount'] += $row['Rows'];
+        }
+    }
+
+    $exaus = $aus.'<h4>'.sprintf($lang['L_SQL_EXPORT'], $databases['Name'][$dbid]).'</h4>';
+
+    $exaus .= '<form action="sql.php?db='.$db.'&amp;dbid='.$dbid.'&amp;context=4" method="post">'.$nl;
+    $exaus .= '<a href="sql.php?db='.$db.'&amp;dbid='.$dbid.'&amp;context=4&amp;import=1">'.$lang['L_IMPORT'].'</a>';
+    $exaus .= '<h6>'.sprintf($lang['L_SQL_EXPORT'], $databases['Name'][$dbid]).'</h6>';
+    $exaus .= '<table class="bdr"><tr class="thead"><th>'.$lang['L_TABLES'].'</th>'.$nl;
+    $exaus .= '<th>'.$lang['L_EXPORTOPTIONS'].'</th>';
+    $exaus .= '<th>'.$lang['L_EXPORT'].'</th></tr><tr>';
+    $exaus .= '';
+
+    $exaus .= '<td><span class="ssmall"><strong>'.$sql['export']['tablecount'].'</strong> '.$lang['L_TABLES'].', <strong>'.$sql['export']['recordcount'].'</strong> '.$lang['L_RECORDS'].'</span>';
+    $exaus .= '&nbsp;&nbsp;&nbsp;<a class="ssmall" href="#" onclick="SelectTableList(true);">'.$lang['L_ALL'].'</a>&nbsp;&nbsp;<a class="ssmall" href="#" onclick="SelectTableList(false);">'.$lang['L_NONE'].'</a>'.$nl;
+
+    $exaus .= '<br><select name="f_export_tables[]" size="12" multiple>'.$tblstr.'</select><br>'.$nl;
+    $exaus .= '</td><td>'.$nl;
+    $exaus .= ''.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_format" id="radio_csv0" value="0" '.((0 == $sql['export']['format']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.'CSV'.'&nbsp;&nbsp;&nbsp;'.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_format" id="radio_csv1" value="1" '.((1 == $sql['export']['format']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.'Excel'.'&nbsp;&nbsp;&nbsp;'.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_format" id="radio_csv2" value="3" '.((3 == $sql['export']['format']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.$lang['L_EXCEL2003'].'<br>'.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_format" id="radio_csv4" value="4" '.((4 == $sql['export']['format']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.'XML'.'&nbsp;&nbsp;&nbsp;'.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_format" id="radio_csv5" value="5" '.((5 == $sql['export']['format']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.'HTML'.'<br><br>'.$nl;
+    $exaus .= '<div id="csv0"><fieldset><legend>CSV-Optionen</legend><table cellpadding="0" cellspacing="0"><tr><td colspan="2">'.$nl;
+    $exaus .= '<input type="checkbox" class="checkbox" name="f_export_namefirstline0" value="1" '.((1 == $sql['export']['namefirstline']) ? 'checked' : '').'>'.$lang['L_CSV_NAMEFIRSTLINE'].'</td></tr>'.$nl;
+    $exaus .= '<tr><td>'.$lang['L_CSV_FIELDSEPERATE'].'</td><td><input type="text" class="text" name="f_export_csvtrenn" size="4" maxlength="12" value="'.$sql['export']['trenn'].'"></td></tr>'.$nl;
+    $exaus .= '<tr><td>'.$lang['L_CSV_FIELDSENCLOSED'].'</td><td><input type="text" class="text" name="f_export_csvenc" size="4" maxlength="12" value="'.htmlspecialchars($sql['export']['enc']).'"></td></tr>'.$nl;
+    $exaus .= '<tr><td>'.$lang['L_CSV_FIELDSESCAPE'].'</td><td><input type="text" class="text" name="f_export_csvesc" size="4" maxlength="12" value="'.$sql['export']['esc'].'"></td></tr>'.$nl;
+    $exaus .= '<tr><td>'.$lang['L_CSV_EOL'].'</td><td><input type="text" class="text" name="f_export_csvztrenn" size="4" maxlength="12" value="'.$sql['export']['ztrenn'].'"></td></tr>'.$nl;
+    $exaus .= '<tr><td>'.$lang['L_CSV_NULL'].'</td><td><input type="text" class="text" name="f_export_csvnull0" size="4" maxlength="12" value="'.$sql['export']['null'].'"></td></tr>'.$nl;
+    $exaus .= '</table></fieldset></div>'.$nl;
+
+    $exaus .= '<div id="csv1"><fieldset><legend>Excel-Optionen</legend><table cellpadding="0" cellspacing="0"><tr><td colspan="2">';
+    $exaus .= '<input type="checkbox" class="checkbox" name="f_export_namefirstline1" value="1"'.((1 == $sql['export']['namefirstline']) ? 'checked' : '').'>'.$lang['L_CSV_NAMEFIRSTLINE'].'</td></tr>'.$nl;
+    $exaus .= '<tr><td>'.$lang['L_CSV_NULL'].'</td><td><input type="text" class="text" name="f_export_csvnull1" size="4" maxlength="12" value="'.$sql['export']['null'].'"></td></tr>'.$nl;
+    $exaus .= '</table></fieldset></div>'.$nl;
+
+    $exaus .= '<div id="csv4"><fieldset><legend>XML-Optionen</legend><table>';
+    $exaus .= '<tr><td><input type="checkbox" name="f_export_xmlstructure" value="1" class="checkbox" '.((1 == $sql['export']['xmlstructure']) ? 'checked' : '').'> mit Struktur</td></tr>';
+    $exaus .= '</table></fieldset></div>'.$nl;
+
+    $exaus .= '<div id="csv5"><fieldset><legend>HTML-Optionen</legend><table>';
+    $exaus .= '<tr><td><input type="checkbox" name="f_export_htmlstructure" value="1" class="checkbox" '.((1 == $sql['export']['htmlstructure']) ? 'checked' : '').'> mit Struktur</td></tr>';
+    $exaus .= '</table></fieldset></div>'.$nl;
+
+    $exaus .= '</td><td>'.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_sendresult" value="0" '.((0 == $sql['export']['sendfile']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.$lang['L_SHOWRESULT'].'<br>'.$nl;
+    $exaus .= '<input type="radio" class="radio" name="f_export_sendresult" id="radio_csv3" value="1" '.((1 == $sql['export']['sendfile']) ? 'checked' : '').' onclick="check_csvdivs(0); return true">'.$lang['L_SENDRESULTASFILE'].'<br>'.$nl;
+    $exaus .= '<div id="csv3"><input type="checkbox" class="checkbox" name="f_export_compressed" value="1" '.((1 == $sql['export']['compressed']) ? 'checked' : '').'>'.$lang['L_COMPRESSED'].'</div><br>'.$nl;
+
+    $exaus .= '<img src="'.$icon['blank'].'" width="60" height="130" border="0"><br><input class="Formbutton" type="submit" name="f_export_submit" value="'.$lang['L_EXPORT'].'" onclick="if(SelectedTableCount()==0) {alert(msg1);return false;}">'.$nl;
+    $exaus .= '</td></tr></table></form>'.$nl;
+
+    $exaus .= '<script>check_csvdivs(0);</script>'.$nl;
+
+    if (!$download) {
+        echo $exaus.$nl;
+    }
+    if (isset($_POST['f_export_submit']) && isset($sql['export']['tables'])) {
+        if (!$download) {
+            echo '<br><br><table width="90%"><tr><td>'.$lang['L_EXPORT'].':</td><td align="right"><a href="javascript:BrowseInput(\'imexta\');">zeige in neuem Fenster</a></td></tr></table><textarea id="imexta" wrap="OFF" style="width:760px;height:400px;font-size=11px;">'.$nl;
+        }
+        if ($format < 3) {
+            ExportCSV();
+        } elseif (4 == $format) {
+            ExportXML();
+        } elseif (5 == $format) {
+            ExportHTML();
+        }
+        if (!$download) {
+            echo '</textarea><br>'.$nl;
+            echo '<span style="color:blue;">'.$lang['L_EXPORTFINISHED'].'</span>&nbsp;&nbsp;'.sprintf($lang['L_EXPORTLINES'], $sql['export']['lines']).$nl;
+        } else {
+            exit();
+        }
+    }
 }
diff --git a/msd/inc/sql_tools.php b/msd/inc/sql_tools.php
index b85055ca..b14147e2 100644
--- a/msd/inc/sql_tools.php
+++ b/msd/inc/sql_tools.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,190 +16,182 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 get_sql_encodings();
 
 //Datenbanken
-if (isset($_GET['dbrefresh'])) SetDefault();
-
-echo $aus . '<h4>' . $lang['L_TOOLS'] . '</h4>';
-if (isset($_POST['dbdosubmit']))
-{
-	$newname=$_POST['newname'];
-	$db_index=$_POST['db_index'];
-	$db_action=$_POST['db_action'];
-	$changed=false;
-	$ausgabe=$out="";
-	switch ($db_action)
-	{
-		case "drop":
-            if (MSD_DoSQL("DROP DATABASE `" . $databases['Name'][$db_index] . "`"))
-            {
-                echo SQLOutput($out,'<p class="success">' . $lang['L_DB'] . ' `' . $databases['Name'][$db_index] . '` ' . $lang['L_SQL_DELETED'] . '</p>');
-                $changed=true;
-            }
-		    break;
-		case "empty":
-			EmptyDB($databases['Name'][$db_index]);
-			echo SQLOutput($out,'<p class="success">' . $lang['L_DB'] . ' `' . $databases['Name'][$db_index] . '` ' . $lang['L_SQL_WASEMPTIED'] . '.</p>');
-			break;
-		case "rename":
-			$dbold=$databases['Name'][$db_index];
-            if (DB_Copy($dbold,$newname,1))
-            {
-                echo SQLOutput($out,'<p class="success">' . $lang['L_DB'] . ' `' . $dbold . '` ' . $lang['L_SQL_RENAMEDTO'] . ' `' . $newname . '`.</p>');
-                $changed=true;
-            }
-			break;
-		case "copy":
-			$dbold=$databases['Name'][$db_index];
-            if (DB_Copy($dbold,$newname))
-            {
-                $changed=true;
-                echo SQLOutput($out,'<p class="success">' . sprintf($lang['L_SQL_DBCOPY'],$dbold,$newname) . '</p>');
-            }
-            break;
-		case "structure":
-            if (DB_Copy($databases['Name'][$db_index],$newname,0,0))
-            {
-                $changed=true;
-                echo SQLOutput($out,'<p class="success">' . sprintf($lang['L_SQL_DBSCOPY'],$databases['Name'][$db_index],$newname) . '</p>');
-            }
-            break;
-		case "rights":
-			break;
-	}
-
-	if ($changed==true)
-	{
-		SetDefault();
-		include ( $config['files']['parameter'] );
-		echo '<script language="JavaScript" type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php?action=dbrefresh";</script>';
-
-	}
+if (isset($_GET['dbrefresh'])) {
+    SetDefault();
 }
-if (isset($_POST['dbwantaction']))
-{
-	if (isset($_POST['db_createnew']))
-	{
-		$newname=trim($_POST['db_create']);
-		if (!empty($newname))
-		{
-			$sqlc="CREATE DATABASE `$newname`";
-			$col=( MSD_NEW_VERSION ) ? $_POST['db_collate'] : "";
-			if (isset($_POST['db_default_charset']) && intval(substr(MSD_NEW_VERSION,0,1)) > 3)
-			{
-				$db_default_charset_string=$config['mysql_possible_character_sets'][$_POST['db_default_charset']];
-				$db_default_charset=explode(' ',$db_default_charset_string);
-				if (isset($db_default_charset[0])) $sqlc.=' DEFAULT CHARACTER SET `' . $db_default_charset[0] . '`';
-			}
-			$db_default_collation=@explode('|',$col);
-			if (isset($db_default_collation[1])) $sqlc.=' COLLATE `' . $db_default_collation[1] . '`';
 
-            if (MSD_query($sqlc))
-            {
-                echo $lang['L_DB'] . " `$newname` " . $lang['L_SQL_WASCREATED'] . ".<br>";
-                SetDefault();
-                include ( $config['files']['parameter'] );
-                echo '<script language="JavaScript" type="text/javascript">parent.MyOOS_Dumper_menu.location.href="menu.php?action=dbrefresh";</script>';
+echo $aus.'<h4>'.$lang['L_TOOLS'].'</h4>';
+if (isset($_POST['dbdosubmit'])) {
+    $newname = $_POST['newname'];
+    $db_index = $_POST['db_index'];
+    $db_action = $_POST['db_action'];
+    $changed = false;
+    $ausgabe = $out = '';
+    switch ($db_action) {
+        case 'drop':
+            if (MOD_DoSQL('DROP DATABASE `'.$databases['Name'][$db_index].'`')) {
+                echo SQLOutput($out, '<p class="success">'.$lang['L_DB'].' `'.$databases['Name'][$db_index].'` '.$lang['L_SQL_DELETED'].'</p>');
+                $changed = true;
             }
-		}
-	}
-	$db_action=$newname="";
-	$db_index=-1;
-	for ($i=0; $i < count($databases['Name']); $i++)
-	{
-		if (isset($_POST['db_do_' . $i]))
-		{
-			$newname=$_POST['db_rename' . $i];
-			$db_index=$i;
-			$db_action=$_POST['db_do_action_' . $i];
-			break;
-		}
-	}
-	if ($db_action != "")
-	{
-		echo '<div><div align="left" id="sqleditbox">';
-		echo '<form action="sql.php?context=3" method="post">
-						<input type="hidden" name="db_action" value="' . $db_action . '">
-						<input type="hidden" name="newname" value="' . $newname . '">
-						<input type="hidden" name="db_index" value="' . $db_index . '">';
-		switch ($db_action)
-		{
-			case "drop":
-				echo '<strong>' . sprintf($lang['L_ASKDBDELETE'],$databases['Name'][$i]) . '</strong><br><br>';
-				echo '<input type="submit" name="dbdosubmit" value="' . $lang['L_DO_NOW'] . '" class="Formbutton">';
-				break;
-			case "empty":
-				echo '<strong>' . sprintf($lang['L_ASKDBEMPTY'],$databases['Name'][$i]) . '</strong><br><br>';
-				echo '<input type="submit" name="dbdosubmit" value="' . $lang['L_DO_NOW'] . '" class="Formbutton">';
-				break;
-			case "rename":
-				echo '<strong>' . $lang['L_SQL_RENAMEDB'] . ' `' . $databases['Name'][$db_index] . '` ' . $lang['L_IN'] . ' `' . $newname . '`</strong><br><br>';
-                if ($newname == "") echo '<p class="error">' . $lang['L_SQL_NAMEDEST_MISSING'] . '</p>';
-                else
-                {
-                    echo '<input type="submit" name="dbdosubmit" value="' . $lang['L_DO_NOW'] . '" class="Formbutton">';
+            break;
+        case 'empty':
+            EmptyDB($databases['Name'][$db_index]);
+            echo SQLOutput($out, '<p class="success">'.$lang['L_DB'].' `'.$databases['Name'][$db_index].'` '.$lang['L_SQL_WASEMPTIED'].'.</p>');
+            break;
+        case 'rename':
+            $dbold = $databases['Name'][$db_index];
+            if (DB_Copy($dbold, $newname, 1)) {
+                echo SQLOutput($out, '<p class="success">'.$lang['L_DB'].' `'.$dbold.'` '.$lang['L_SQL_RENAMEDTO'].' `'.$newname.'`.</p>');
+                $changed = true;
+            }
+            break;
+        case 'copy':
+            $dbold = $databases['Name'][$db_index];
+            if (DB_Copy($dbold, $newname)) {
+                $changed = true;
+                echo SQLOutput($out, '<p class="success">'.sprintf($lang['L_SQL_DBCOPY'], $dbold, $newname).'</p>');
+            }
+            break;
+        case 'structure':
+            if (DB_Copy($databases['Name'][$db_index], $newname, 0, 0)) {
+                $changed = true;
+                echo SQLOutput($out, '<p class="success">'.sprintf($lang['L_SQL_DBSCOPY'], $databases['Name'][$db_index], $newname).'</p>');
+            }
+            break;
+        case 'rights':
+            break;
+    }
+
+    if (true == $changed) {
+        SetDefault();
+        include $config['files']['parameter'];
+        echo '<script>parent.MyOOS_Dumper_menu.location.href="menu.php?action=dbrefresh";</script>';
+    }
+}
+if (isset($_POST['dbwantaction'])) {
+    if (isset($_POST['db_createnew'])) {
+        $newname = trim($_POST['db_create']);
+        if (!empty($newname)) {
+            $sqlc = "CREATE DATABASE `$newname`";
+            $col = (MOD_NEW_VERSION) ? $_POST['db_collate'] : '';
+            if (isset($_POST['db_default_charset']) && intval(substr(MOD_NEW_VERSION, 0, 1)) > 3) {
+                $db_default_charset_string = $config['mysql_possible_character_sets'][$_POST['db_default_charset']];
+                $db_default_charset = explode(' ', $db_default_charset_string);
+                if (isset($db_default_charset[0])) {
+                    $sqlc .= ' DEFAULT CHARACTER SET `'.$db_default_charset[0].'`';
                 }
-				break;
-			case "copy":
-				echo '<strong>' . sprintf($lang['L_ASKDBCOPY'],$databases['Name'][$db_index],$newname) . '</strong><br><br>';
-				if ($newname == "") echo '<p class="error">' . $lang['L_SQL_NAMEDEST_MISSING'] . '</p>';
-				else
-				{
-					echo '<input type="submit" name="dbdosubmit" value="' . $lang['L_DO_NOW'] . '" class="Formbutton">';
-				}
-				break;
-			case "structure":
-				echo '<strong>' . $lang['L_FM_ASKDBCOPY1'] . '`' . $databases['Name'][$db_index] . '`' . $lang['L_FM_ASKDBCOPY2'] . '`' . $newname . '`' . $lang['L_FM_ASKDBCOPY3'] . '</strong><br><br>';
-				if ($newname == "") echo '<p class="error">' . $lang['L_SQL_NAMEDEST_MISSING'] . '</p>';
-				else
-				{
-					echo '<input type="submit" name="dbdosubmit" value="' . $lang['L_DO_NOW'] . '" class="Formbutton">';
-				}
-				break;
-			case "rights":
-				break;
-		}
-		echo '</form></div></div><br>';
-	}
+            }
+            $db_default_collation = @explode('|', $col);
+            if (isset($db_default_collation[1])) {
+                $sqlc .= ' COLLATE `'.$db_default_collation[1].'`';
+            }
+
+            if (mod_query($sqlc)) {
+                echo $lang['L_DB']." `$newname` ".$lang['L_SQL_WASCREATED'].'.<br>';
+                SetDefault();
+                include $config['files']['parameter'];
+                echo '<script>parent.MyOOS_Dumper_menu.location.href="menu.php?action=dbrefresh";</script>';
+            }
+        }
+    }
+    $db_action = $newname = '';
+    $db_index = -1;
+    for ($i = 0; $i < count($databases['Name']); ++$i) {
+        if (isset($_POST['db_do_'.$i])) {
+            $newname = $_POST['db_rename'.$i];
+            $db_index = $i;
+            $db_action = $_POST['db_do_action_'.$i];
+            break;
+        }
+    }
+    if ('' != $db_action) {
+        echo '<div><div align="left" id="sqleditbox">';
+        echo '<form action="sql.php?context=3" method="post">
+						<input type="hidden" name="db_action" value="'.$db_action.'">
+						<input type="hidden" name="newname" value="'.$newname.'">
+						<input type="hidden" name="db_index" value="'.$db_index.'">';
+        switch ($db_action) {
+            case 'drop':
+                echo '<strong>'.sprintf($lang['L_ASKDBDELETE'], $databases['Name'][$i]).'</strong><br><br>';
+                echo '<input type="submit" name="dbdosubmit" value="'.$lang['L_DO_NOW'].'" class="Formbutton">';
+                break;
+            case 'empty':
+                echo '<strong>'.sprintf($lang['L_ASKDBEMPTY'], $databases['Name'][$i]).'</strong><br><br>';
+                echo '<input type="submit" name="dbdosubmit" value="'.$lang['L_DO_NOW'].'" class="Formbutton">';
+                break;
+            case 'rename':
+                echo '<strong>'.$lang['L_SQL_RENAMEDB'].' `'.$databases['Name'][$db_index].'` '.$lang['L_IN'].' `'.$newname.'`</strong><br><br>';
+                if ('' == $newname) {
+                    echo '<p class="error">'.$lang['L_SQL_NAMEDEST_MISSING'].'</p>';
+                } else {
+                    echo '<input type="submit" name="dbdosubmit" value="'.$lang['L_DO_NOW'].'" class="Formbutton">';
+                }
+                break;
+            case 'copy':
+                echo '<strong>'.sprintf($lang['L_ASKDBCOPY'], $databases['Name'][$db_index], $newname).'</strong><br><br>';
+                if ('' == $newname) {
+                    echo '<p class="error">'.$lang['L_SQL_NAMEDEST_MISSING'].'</p>';
+                } else {
+                    echo '<input type="submit" name="dbdosubmit" value="'.$lang['L_DO_NOW'].'" class="Formbutton">';
+                }
+                break;
+            case 'structure':
+                echo '<strong>'.$lang['L_FM_ASKDBCOPY1'].'`'.$databases['Name'][$db_index].'`'.$lang['L_FM_ASKDBCOPY2'].'`'.$newname.'`'.$lang['L_FM_ASKDBCOPY3'].'</strong><br><br>';
+                if ('' == $newname) {
+                    echo '<p class="error">'.$lang['L_SQL_NAMEDEST_MISSING'].'</p>';
+                } else {
+                    echo '<input type="submit" name="dbdosubmit" value="'.$lang['L_DO_NOW'].'" class="Formbutton">';
+                }
+                break;
+            case 'rights':
+                break;
+        }
+        echo '</form></div></div><br>';
+    }
 }
 
 echo '<br><form action="sql.php?context=3" method="post"><input type="hidden" name="dbwantaction" value="1">';
 echo '<div><table class="bdr">';
-echo '<tr><td colspan="2" align="center"><strong>' . $lang['L_CREATE_DATABASE'] . '</strong></td></tr>';
+echo '<tr><td colspan="2" align="center"><strong>'.$lang['L_CREATE_DATABASE'].'</strong></td></tr>';
 echo '<tr><td>Name:</td><td><input type="text" class="text" name="db_create" size="20"></td></tr>';
 
-echo '<tr><td>' . $lang['L_DEFAULT_CHARSET'] . ':</td><td><select name="db_default_charset">';
-echo make_options($config['mysql_possible_character_sets'],get_index($config['mysql_possible_character_sets'],$config['mysql_standard_character_set']));
+echo '<tr><td>'.$lang['L_DEFAULT_CHARSET'].':</td><td><select name="db_default_charset">';
+echo make_options($config['mysql_possible_character_sets'], get_index($config['mysql_possible_character_sets'], $config['mysql_standard_character_set']));
 echo '</select></td></tr>';
 
-echo '<tr><td>' . $lang['L_COLLATION'] . '</td><td><select name="db_collate">' . CollationCombo('',1) . '</select></td></tr>';
-echo '<tr><td colspan="2"><input type="submit" name="db_createnew" value="' . $lang['L_CREATE'] . '" class="Formbutton"></td></tr>';
+echo '<tr><td>'.$lang['L_COLLATION'].'</td><td><select name="db_collate">'.CollationCombo('', 1).'</select></td></tr>';
+echo '<tr><td colspan="2"><input type="submit" name="db_createnew" value="'.$lang['L_CREATE'].'" class="Formbutton"></td></tr>';
 echo '</table>';
 
 echo '<br><table class="bdr">';
-echo '<tr class="thead"><th>' . $lang['L_DBS'] . '</th><th>' . $lang['L_SQL_ACTIONS'] . '</th></tr>';
-for ($i=0; $i < count($databases['Name']); $i++)
-{
-	$cl=( $i % 2 ) ? "dbrow" : "dbrow1";
-	echo ( $i == $databases['db_selected_index'] ) ? '<tr class="dbrowsel">' : '<tr class="' . $cl . '">';
-	echo '<td><a href="sql.php?db=' . $databases['Name'][$i] . '&amp;dbid=' . $i . '">' . $databases['Name'][$i] . '</a></td>';
-	echo '<td nowrap="nowrap"><input type="text" class="text" name="db_rename' . $i . '" size="20">';
-	echo '&nbsp;&nbsp;<select name="db_do_action_' . $i . '" onchange="db_do_' . $i . '.disabled=false;">';
-	echo '<option value="">-- ' . $lang['L_SQL_CHOOSEACTION'] . ' --</option>';
-	echo '<option value="drop">' . $lang['L_SQL_DELETEDB'] . '</option>';
-	echo '<option value="empty">' . $lang['L_SQL_EMPTYDB'] . '</option>';
-	if (MSD_NEW_VERSION) echo '<option value="rename">' . $lang['L_SQL_RENAMEDB'] . '</option>';
-	if (MSD_NEW_VERSION) echo '<option value="copy">' . $lang['L_SQL_COPYDATADB'] . '</option>';
-	echo '<option value="structure">' . $lang['L_SQL_COPYSDB'] . '</option>';
+echo '<tr class="thead"><th>'.$lang['L_DBS'].'</th><th>'.$lang['L_SQL_ACTIONS'].'</th></tr>';
+for ($i = 0; $i < count($databases['Name']); ++$i) {
+    $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+    echo ($i == $databases['db_selected_index']) ? '<tr class="dbrowsel">' : '<tr class="'.$cl.'">';
+    echo '<td><a href="sql.php?db='.$databases['Name'][$i].'&amp;dbid='.$i.'">'.$databases['Name'][$i].'</a></td>';
+    echo '<td nowrap="nowrap"><input type="text" class="text" name="db_rename'.$i.'" size="20">';
+    echo '&nbsp;&nbsp;<select name="db_do_action_'.$i.'" onchange="db_do_'.$i.'.disabled=false;">';
+    echo '<option value="">-- '.$lang['L_SQL_CHOOSEACTION'].' --</option>';
+    echo '<option value="drop">'.$lang['L_SQL_DELETEDB'].'</option>';
+    echo '<option value="empty">'.$lang['L_SQL_EMPTYDB'].'</option>';
+    if (MOD_NEW_VERSION) {
+        echo '<option value="rename">'.$lang['L_SQL_RENAMEDB'].'</option>';
+    }
+    if (MOD_NEW_VERSION) {
+        echo '<option value="copy">'.$lang['L_SQL_COPYDATADB'].'</option>';
+    }
+    echo '<option value="structure">'.$lang['L_SQL_COPYSDB'].'</option>';
 
-	echo '</select>';
-	echo "\n\n" . '&nbsp;&nbsp;<input type="submit" name="db_do_' . $i . '" value="' . $lang['L_DO'] . '" disabled="disabled" class="Formbutton">';
+    echo '</select>';
+    echo "\n\n".'&nbsp;&nbsp;<input type="submit" name="db_do_'.$i.'" value="'.$lang['L_DO'].'" disabled="disabled" class="Formbutton">';
 
-	echo '&nbsp;&nbsp;<input type="Button" value="' . $lang['L_SQL_IMEXPORT'] . '" onclick="location.href=\'sql.php?db=' . $databases['Name'][$i] . '&amp;dbid=' . $i . '&amp;context=4\'" class="Formbutton"></td></tr>';
+    echo '&nbsp;&nbsp;<input type="Button" value="'.$lang['L_SQL_IMEXPORT'].'" onclick="location.href=\'sql.php?db='.$databases['Name'][$i].'&amp;dbid='.$i.'&amp;context=4\'" class="Formbutton"></td></tr>';
 }
 
 echo '</table></div></form>';
-
diff --git a/msd/inc/sqlbrowser/mysql_search.php b/msd/inc/sqlbrowser/mysql_search.php
index 211dfb77..bc83efe2 100644
--- a/msd/inc/sqlbrowser/mysql_search.php
+++ b/msd/inc/sqlbrowser/mysql_search.php
@@ -1,397 +1,387 @@
 <?php
-if (!defined('MSD_VERSION')) die('No direct access.');
-//alle Tabellen der aktuellen Datenbank ermitteln und Zugriffs-Array aufbauen
-$sql='SHOW TABLES FROM `'.$db.'`';
-$tables= array ();
-$link=MSD_mysql_connect();
-$res=mysqli_query($link, $sql);
-if (!$res===false)
-{
-	while ($row=mysqli_fetch_array($res,MYSQL_NUM))
-	{
-		$tables[]=$row[0];
-	}
+/* ----------------------------------------------------------------------
+
+   MyOOS [Dumper]
+   http://www.oos-shop.de/
+
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
+   ----------------------------------------------------------------------
+   Based on:
+
+   MySqlDumper
+   http://www.mysqldumper.de
+
+   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
+   ----------------------------------------------------------------------
+   Released under the GNU General Public License
+   ---------------------------------------------------------------------- */
+
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
 }
-else
-	die("No Tables in Database!");
 
-// Suchkriterien aus Session holen oder aus POST-Umgebung
-// so bleiben die Suchkriterien auch erhalten wenn man zwischendurch woanders klickt
-if (isset($_POST['suchbegriffe'])) $_SESSION['mysql_search']['suchbegriffe']=$_POST['suchbegriffe'];
-if (!isset($_SESSION['mysql_search']['suchbegriffe'])) $_SESSION['mysql_search']['suchbegriffe']='';
-$suchbegriffe=$_SESSION['mysql_search']['suchbegriffe'];
+// get all tables of the current database and build access array
+$sql = 'SHOW TABLES FROM `'.$db.'`';
+$tables = [];
+$link = mod_mysqli_connect();
+$res = mysqli_query($link, $sql);
+if (false === !$res) {
+    while ($row = mysqli_fetch_array($res, MYSQLI_NUM)) {
+        $tables[] = $row[0];
+    }
+} else {
+    exit('No Tables in Database!');
+}
 
-if (isset($_POST['suchart'])) $_SESSION['mysql_search']['suchart']=$_POST['suchart'];
-if (!isset($_SESSION['mysql_search']['suchart'])||strlen($_SESSION['mysql_search']['suchart'])<2) $_SESSION['mysql_search']['suchart']='AND';
-$suchart=$_SESSION['mysql_search']['suchart'];
+// get search criteria from session or from POST environment
+// this way the search criteria are preserved even if you click somewhere else in between
+if (isset($_POST['suchbegriffe'])) {
+    $_SESSION['mysql_search']['suchbegriffe'] = $_POST['suchbegriffe'];
+}
+if (!isset($_SESSION['mysql_search']['suchbegriffe'])) {
+    $_SESSION['mysql_search']['suchbegriffe'] = '';
+}
+$suchbegriffe = $_SESSION['mysql_search']['suchbegriffe'];
 
-if (isset($_POST['table_selected'])) $_SESSION['mysql_search']['table_selected']=$_POST['table_selected'];
-if (!isset($_SESSION['mysql_search']['table_selected'])) $_SESSION['mysql_search']['table_selected']=0;
-$table_selected=$_SESSION['mysql_search']['table_selected'];
-// Falls zwischendurch Tabellen geloescht wurden und der Index nicht mehr existiert, zuruecksetzen
-if ($table_selected>count($tables)-1) $table_selected=0;
+if (isset($_POST['suchart'])) {
+    $_SESSION['mysql_search']['suchart'] = $_POST['suchart'];
+}
+if (!isset($_SESSION['mysql_search']['suchart']) || strlen($_SESSION['mysql_search']['suchart']) < 2) {
+    $_SESSION['mysql_search']['suchart'] = 'AND';
+}
+$suchart = $_SESSION['mysql_search']['suchart'];
 
-$offset=(isset($_POST['offset'])) ? intval($_POST['offset']) : 0;
+if (isset($_POST['table_selected'])) {
+    $_SESSION['mysql_search']['table_selected'] = $_POST['table_selected'];
+}
+if (!isset($_SESSION['mysql_search']['table_selected'])) {
+    $_SESSION['mysql_search']['table_selected'] = 0;
+}
+$table_selected = $_SESSION['mysql_search']['table_selected'];
+// If tables were deleted in the meantime and the index does not exist anymore, reset it
+if ($table_selected > count($tables) - 1) {
+    $table_selected = 0;
+}
 
-$tablename=isset($_GET['tablename']) ? urldecode($_GET['tablename']) : '';
+$offset = (isset($_POST['offset'])) ? intval($_POST['offset']) : 0;
+
+$tablename = isset($_GET['tablename']) ? urldecode($_GET['tablename']) : '';
 
 // Delete
-if (isset($_GET['mode'])&&$_GET['mode']=="kill"&&$rk>'')
-{
-	//echo "<br> RK ist: ".$rk."<br><br>";
-	$sqlk="DELETE FROM `$tablename` WHERE ".$rk." LIMIT 1";
-	//echo $sqlk;
-	$res=MSD_query($sqlk);
-	//	echo "<br>".$res;
-	$aus.='<p class="success">'.$lang['L_SQL_RECORDDELETED'].'</p>';
+if (isset($_GET['mode']) && 'kill' == $_GET['mode'] && $rk > '') {
+    // echo "<br> RK ist: ".$rk."<br><br>";
+    $sqlk = "DELETE FROM `$tablename` WHERE ".$rk.' LIMIT 1';
+    // echo $sqlk;
+    $res = mod_query($sqlk);
+    // echo "<br>".$res;
+    $aus .= '<p class="success">'.$lang['L_SQL_RECORDDELETED'].'</p>';
 }
 
-function mysql_search($db, $tabelle, $suchbegriffe, $suchart, $offset=0, $anzahl_ergebnisse=20, $auszuschliessende_tabellen='')
+function mysqli_search($db, $tabelle, $suchbegriffe, $suchart, $offset = 0, $anzahl_ergebnisse = 20, $auszuschliessende_tabellen = '')
 {
-	global $tables,$config;
-	$ret=false;
-	$link=MSD_mysql_connect();
-	if (sizeof($tables)>0)
-	{
-		$suchbegriffe=trim(str_replace('*','',$suchbegriffe));
-		$suchworte=explode(' ',$suchbegriffe);
-		if (($suchbegriffe>'')&&(is_array($suchworte)))
-		{
-			// Leere Einträge (durch doppelte Leerzeichen) entfernen
-			$anzahl_suchworte=sizeof($suchworte);
-			for ($i=0; $i<$anzahl_suchworte; $i++)
-			{
-				if (trim($suchworte[$i])=='') unset($suchworte[$i]);
-			}
+    global $tables, $config, $lang;
 
-			$bedingung='';
-			$where='';
-			$felder='';
+    $ret = false;
+    $link = mod_mysqli_connect();
+    if (sizeof($tables) > 0) {
+        $suchbegriffe = trim(str_replace('*', '', $suchbegriffe));
+        $suchworte = explode(' ', $suchbegriffe);
+        if (($suchbegriffe > '') && (is_array($suchworte))) {
+            // Remove empty entries (due to double spaces)
+            $anzahl_suchworte = sizeof($suchworte);
+            for ($i = 0; $i < $anzahl_suchworte; ++$i) {
+                if ('' == trim($suchworte[$i])) {
+                    unset($suchworte[$i]);
+                }
+            }
 
-			// Felder ermitteln
-			$sql='SHOW COLUMNS FROM `'.$db.'`.`'.$tables[$tabelle].'`';
-			$res=mysqli_query($link,$sql);
-			unset($felder);
-			if (!$res===false)
-			{
-				// Felder der Tabelle ermitteln
-				while ($row=mysqli_fetch_object($res))
-				{
-					$felder[]=$row->Field;
-				}
-			}
+            $bedingung = [];
+            $where = '';
+            $felder = [];
 
-			$feldbedingung='';
-			if ($suchart=='CONCAT')
-			{
-				if (is_array($felder))
-				{
-					//Concat-String bildem
-					$concat=implode('`),LOWER(`',$felder);
-					$concat='CONCAT_WS(\'\',LOWER(`'.$concat.'`))';
-					$where='';
-					foreach ($suchworte as $suchbegriff)
-					{
-						$where.=$concat.' LIKE \'%'.strtolower($suchbegriff).'%\' AND ';
-					}
-					$where=substr($where,0,-4); // letztes AND entfernen
-					$sql='SELECT * FROM `'.$db.'`.`'.$tables[$tabelle].'` WHERE '.$where.' LIMIT '.$offset.','.$anzahl_ergebnisse;
-				}
-			}
-			else
-			{
-				$pattern='`{FELD}` LIKE \'%{SUCHBEGRIFF}%\'';
-				if (is_array($felder))
-				{
-					foreach ($felder as $feld)
-					{
-						unset($feldbedingung);
-						foreach ($suchworte as $suchbegriff)
-						{
-							$suchen= array (
+            // Determine fields
+            $sql = 'SHOW COLUMNS FROM `'.$db.'`.`'.$tables[$tabelle].'`';
+            $res = mysqli_query($link, $sql);
+            if (false === !$res) {
+                // Determine fields of the table
+                while ($row = mysqli_fetch_object($res)) {
+                    $felder[] = $row->Field;
+                }
+            }
 
-								'{FELD}',
-								'{SUCHBEGRIFF}');
-							$ersetzen= array (
+            $feldbedingung = '';
+            if ('CONCAT' == $suchart) {
+                if (count($felder) > 0) {
+                    // Build Concat-String
+                    $concat = implode('`),LOWER(`', $felder);
+                    $concat = 'CONCAT_WS(\'\',LOWER(`'.$concat.'`))';
+                    $where = '';
+                    foreach ($suchworte as $suchbegriff) {
+                        $where .= $concat.' LIKE \'%'.strtolower($suchbegriff).'%\' AND ';
+                    }
+                    $where = substr($where, 0, -4); // Remove last AND
+                    $sql = 'SELECT * FROM `'.$db.'`.`'.$tables[$tabelle].'` WHERE '.$where.' LIMIT '.$offset.','.$anzahl_ergebnisse;
+                } else {
+                    $_SESSION['mysql_search']['suchbegriffe'] = '';
+                    exit(sprintf($lang['L_ERROR_NO_FIELDS'], $tabelle));
+                }
+            } else {
+                $pattern = '`{FELD}` LIKE \'%{SUCHBEGRIFF}%\'';
 
-								$feld,
-								$suchbegriff);
-							$feldbedingung[]=str_replace($suchen,$ersetzen,$pattern);
-						}
-						$bedingung[]='('.implode(' '.$suchart.' ',$feldbedingung).') ';
-					}
-				}
-				else
-					die('<br>Fehler bei Suche: ich konnte nicht ermitteln welche Felder die Tabelle "'.$tabelle.'" hat!');
-				$where=implode(' OR ',$bedingung);
-				$sql='SELECT * FROM `'.$db.'`.`'.$tables[$tabelle].'` WHERE ('.$where.') LIMIT '.$offset.','.$anzahl_ergebnisse;
-			}
-		}
-		else
-			$sql='SELECT * FROM `'.$db.'`.`'.$tables[$tabelle].'` LIMIT '.$offset.','.$anzahl_ergebnisse;
+                if (count($felder) > 0) {
+                    foreach ($felder as $feld) {
+                        unset($feldbedingung);
+                        foreach ($suchworte as $suchbegriff) {
+                            $suchen = [
+                                '{FELD}',
+                                '{SUCHBEGRIFF}',
+                            ];
+                            $ersetzen = [
+                                $feld,
+                                $suchbegriff,
+                            ];
+                            $feldbedingung[] = str_replace($suchen, $ersetzen, $pattern);
+                        }
+                        $bedingung[] = '('.implode(' '.$suchart.' ', $feldbedingung).') ';
+                    }
+                } else {
+                    $_SESSION['mysql_search']['suchbegriffe'] = '';
+                    exit(sprintf($lang['L_ERROR_NO_FIELDS'], $tabelle));
+                }
+                $where = implode(' OR ', $bedingung);
+                $sql = 'SELECT * FROM `'.$db.'`.`'.$tables[$tabelle].'` WHERE ('.$where.') LIMIT '.$offset.','.$anzahl_ergebnisse;
+            }
+        } else {
+            $sql = 'SELECT * FROM `'.$db.'`.`'.$tables[$tabelle].'` LIMIT '.$offset.','.$anzahl_ergebnisse;
+        }
 
-		$res=@mysqli_query($link, $sql);
-		if ($res)
-		{
-			while ($row=mysqli_fetch_array($res,MYSQLI_ASSOC))
-			{
-				//Treffer markieren
-				foreach ($row as $key=>$val)
-				{
-					foreach ($suchworte as $suchbegriff)
-					{
-						$row[$key]=markiere_suchtreffer($suchbegriff,$row[$key]);
-					}
-					$row[$key]=ersetze_suchtreffer($row[$key]);
-				}
-				$ret[]=$row;
-			}
-		}
-	}
-	return $ret;
+        $res = mysqli_query($link, $sql);
+        if (false === !$res) {
+            while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+                // Mark hits
+                foreach ($row as $key => $val) {
+                    foreach ($suchworte as $suchbegriff) {
+                        $row[$key] = markiere_suchtreffer($suchbegriff, $row[$key]);
+                    }
+                    $row[$key] = ersetze_suchtreffer($row[$key]);
+                }
+                $ret[] = $row;
+            }
+        }
+    }
+    return $ret;
 }
 
-// Markiert den Suchbegriff mit einem Code (ASCII 01/02)
-// - falls nicht gefunden : Rückgabe des Originalstrings
-//
+// Marks the search string with a code (ASCII 01/02)
+// - if not found : returns the original string
 function markiere_suchtreffer($suchbegriff, $suchstring)
 {
-	$str=strtolower($suchstring);
-	$suchbegriff=strtolower($suchbegriff);
-	if ((strlen($str)>0)&&(strlen($suchbegriff)>0))
-	{
-		// Treffer Position bestimmen
-		$offset=0;
-		$trefferpos=0;
-		while (($offset<=strlen($str)))
-		//Wenn nur der erste Treffer markiert werden soll, so muss die Zeile so lauten
-		// 		while ( ($offset<=strlen($str)) || ($in_html==false) )
-		{
-			for ($offset=$trefferpos; $offset<=strlen($str); $offset++)
-			{
-				$start=strpos($str,$suchbegriff,$offset);
-				if ($start===false) $offset=strlen($str)+1;
-				else
-				{
-					if ($offset<=strlen($str))
-					{
-						//Treffer überprüfen
-						$in_html=false;
-						// Steht die Fundstelle zwischen < und > (also im HTML-Tag) ?
-						for ($position=$start; $position>=0; $position--)
-						{
-							if (substr($str,$position,1)==">")
-							{
-								$in_html=false;
-								$position=-1; // Schleife verlassen
-							}
-							if (substr($str,$position,1)=="<")
-							{
-								$in_html=true;
-								$position=-1; // Schleife verlassen
-							}
-						}
-						if ($in_html)
-						{
-							for ($position2=$start; $position2<strlen($str); $position2++)
-							{
-								if (substr($str,$position2,1)=="<")
-								{
-									$position2=strlen($str)+1;
-								}
-								if (substr($str,$position2,1)==">")
-								{
-									$in_html=true;
-									$position2=strlen($str)+1;
-									$offset=strlen($str)+1;
-								}
-							}
-						}
-						if (!$in_html)
-						{
-							$ersetzen=substr($suchstring,$start,strlen($suchbegriff));
-							$str=substr($suchstring,0,$start);
-							$str.=chr(1).$ersetzen.chr(2);
-							$str.=substr($suchstring,($start+strlen($ersetzen)),(strlen($suchstring)-strlen($ersetzen)));
-							$suchstring=$str;
-						}
-						if ($in_html)
-						{
-							$trefferpos=$start+1;
-							$offset=$trefferpos;
-						}
-					}
-					$offset=$start+1;
-				}
-			}
-		}
-	}
-	return $suchstring;
+    $str = strtolower($suchstring);
+    $suchbegriff = strtolower($suchbegriff);
+    if ((strlen($str) > 0) && (strlen($suchbegriff) > 0)) {
+        // Determine hit position
+        $offset = 0;
+        $trefferpos = 0;
+        while (($offset <= strlen($str))) {
+            // If only the first hit is to be marked, the line must read as follow
+            // 		while ( ($offset<=strlen($str)) || ($in_html==false) )
+            for ($offset = $trefferpos; $offset <= strlen($str); ++$offset) {
+                $start = strpos($str, $suchbegriff, $offset);
+                if (false === $start) {
+                    $offset = strlen($str) + 1;
+                } else {
+                    if ($offset <= strlen($str)) {
+                        //Treffer überprüfen
+                        $in_html = false;
+                        // Steht die Fundstelle zwischen < und > (also im HTML-Tag) ?
+                        for ($position = $start; $position >= 0; --$position) {
+                            if ('>' == substr($str, $position, 1)) {
+                                $in_html = false;
+                                $position = -1; // Schleife verlassen
+                            }
+                            if ('<' == substr($str, $position, 1)) {
+                                $in_html = true;
+                                $position = -1; // Schleife verlassen
+                            }
+                        }
+                        if ($in_html) {
+                            for ($position2 = $start; $position2 < strlen($str); ++$position2) {
+                                if ('<' == substr($str, $position2, 1)) {
+                                    $position2 = strlen($str) + 1;
+                                }
+                                if ('>' == substr($str, $position2, 1)) {
+                                    $in_html = true;
+                                    $position2 = strlen($str) + 1;
+                                    $offset = strlen($str) + 1;
+                                }
+                            }
+                        }
+                        if (!$in_html) {
+                            $ersetzen = substr($suchstring, $start, strlen($suchbegriff));
+                            $str = substr($suchstring, 0, $start);
+                            $str .= chr(1).$ersetzen.chr(2);
+                            $str .= substr($suchstring, ($start + strlen($ersetzen)), (strlen($suchstring) - strlen($ersetzen)));
+                            $suchstring = $str;
+                        }
+                        if ($in_html) {
+                            $trefferpos = $start + 1;
+                            $offset = $trefferpos;
+                        }
+                    }
+                    $offset = $start + 1;
+                }
+            }
+        }
+    }
+    return $suchstring;
 }
 
 // Ersetzt die Codes letztlich durch die Fontangabe
 function ersetze_suchtreffer($text)
 {
-	$such= array (
-
-		chr(1),
-		chr(2));
-	$ersetzen= array (
-
-		'<span class="treffer">',
-		'</span>');
-	return str_replace($such,$ersetzen,htmlspecialchars($text));
+    $such = [
+        chr(1),
+        chr(2), ];
+    $ersetzen = [
+        '<span class="treffer">',
+        '</span>', ];
+    return str_replace($such, $ersetzen, htmlspecialchars($text));
 }
 
-$suchbegriffe=trim($suchbegriffe); // Leerzeichen vorne und hinten wegschneiden
-if (isset($_POST['reset']))
-{
-	$suchbegriffe='';
-	$_SESSION['mysql_search']['suchbegriffe']='';
-	$suchart='AND';
-	$_SESSION['mysql_search']['suchart']='AND';
-	$table_selected=0;
-	$_SESSION['mysql_search']['table_selected']=0;
+$suchbegriffe = trim($suchbegriffe); // Leerzeichen vorne und hinten wegschneiden
+if (isset($_POST['reset'])) {
+    $suchbegriffe = '';
+    $_SESSION['mysql_search']['suchbegriffe'] = '';
+    $suchart = 'AND';
+    $_SESSION['mysql_search']['suchart'] = 'AND';
+    $table_selected = 0;
+    $_SESSION['mysql_search']['table_selected'] = 0;
 }
-$showtables=0; // Anzeige der Tabellendaten im restlichen SQL-Browser ausschalten
-
+$showtables = 0; // Anzeige der Tabellendaten im restlichen SQL-Browser ausschalten
 
 // Fix bis zur kompletten Umstellung auf Templates
 echo $aus;
-$aus='';
+$aus = '';
 
-$anzahl_tabellen=sizeof($tables);
-$table_options='';
-if ($anzahl_tabellen>0)
-{
-	for ($i=0; $i<$anzahl_tabellen; $i++)
-	{
-		if (isset($tables[$i]))
-		{
-			$table_options.='<option value="'.$i.'"';
-			if (($i==$table_selected)||($tables[$i]==$tablename))
-			{
-				$table_options.=' selected';
-				$table_selected=$i;
-			}
-			$table_options.='>'.$tables[$i].'</option>'."\n";
-		}
-	}
+$anzahl_tabellen = sizeof($tables);
+$table_options = '';
+if ($anzahl_tabellen > 0) {
+    for ($i = 0; $i < $anzahl_tabellen; ++$i) {
+        if (isset($tables[$i])) {
+            $table_options .= '<option value="'.$i.'"';
+            if (($i == $table_selected) || ($tables[$i] == $tablename)) {
+                $table_options .= ' selected';
+                $table_selected = $i;
+            }
+            $table_options .= '>'.$tables[$i].'</option>'."\n";
+        }
+    }
 }
 
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => './tpl/sqlbrowser/mysql_search.tpl', ]);
 
-	'show' => './tpl/sqlbrowser/mysql_search.tpl'));
+$tpl->assign_vars([
+    'DB_NAME_URLENCODED' => urlencode($db),
+    'LANG_SQLSEARCH' => $lang['L_SQL_SEARCH'],
+    'LANG_SQL_SEARCHWORDS' => $lang['L_SQL_SEARCHWORDS'],
+    'SUCHBEGRIFFE' => $suchbegriffe,
+    'LANG_START_SQLSEARCH' => $lang['L_START_SQL_SEARCH'],
+    'LANG_RESET_SEARCHWORDS' => $lang['L_RESET_SEARCHWORDS'],
+    'LANG_SEARCH_OPTIONS' => $lang['L_SEARCH_OPTIONS'],
+    'AND_SEARCH' => 'AND' == $suchart ? ' checked' : '',
+    'OR_SEARCH' => 'OR' == $suchart ? ' checked' : '',
+    'CONCAT_SEARCH' => 'CONCAT' == $suchart ? ' checked' : '',
+    'TABLE_OPTIONS' => $table_options,
+    'LANG_SEARCH_OPTIONS_AND' => $lang['L_SEARCH_OPTIONS_AND'],
+    'LANG_SEARCH_OPTIONS_OR' => $lang['L_SEARCH_OPTIONS_OR'],
+    'LANG_SEARCH_OPTIONS_CONCAT' => $lang['L_SEARCH_OPTIONS_CONCAT'],
+    'LANG_SEARCH_IN_TABLE' => $lang['L_SEARCH_IN_TABLE'], ]);
 
-$tpl->assign_vars(array(
-	'DB_NAME_URLENCODED' => urlencode($db),
-	'LANG_SQLSEARCH' => $lang['L_SQL_SEARCH'],
-	'LANG_SQL_SEARCHWORDS' => $lang['L_SQL_SEARCHWORDS'],
-	'SUCHBEGRIFFE' => $suchbegriffe,
-	'LANG_START_SQLSEARCH' => $lang['L_START_SQL_SEARCH'],
-	'LANG_RESET_SEARCHWORDS' => $lang['L_RESET_SEARCHWORDS'],
-	'LANG_SEARCH_OPTIONS' => $lang['L_SEARCH_OPTIONS'],
-	'AND_SEARCH' => $suchart=='AND' ? ' checked' : '',
-	'OR_SEARCH' => $suchart=='OR' ? ' checked' : '',
-	'CONCAT_SEARCH' => $suchart=='CONCAT' ? ' checked' : '',
-	'TABLE_OPTIONS' => $table_options,
-	'LANG_SEARCH_OPTIONS_AND' => $lang['L_SEARCH_OPTIONS_AND'],
-	'LANG_SEARCH_OPTIONS_OR' => $lang['L_SEARCH_OPTIONS_OR'],
-	'LANG_SEARCH_OPTIONS_CONCAT' => $lang['L_SEARCH_OPTIONS_CONCAT'],
-	'LANG_SEARCH_IN_TABLE' => $lang['L_SEARCH_IN_TABLE']));
+$max_treffer = 20;
+$treffer = mysqli_search($db, $table_selected, $suchbegriffe, $suchart, $offset, $max_treffer + 1);
+if (is_array($treffer) && isset($treffer[0])) {
+    $search_message = sprintf($lang['L_SEARCH_RESULTS'], $suchbegriffe, $tables[$table_selected]);
+    $anzahl_treffer = count($treffer);
+    // Blaettern-Buttons
+    $tpl->assign_block_vars('HITS', [
+        'LANG_SEARCH_RESULTS' => $search_message,
+        'LAST_OFFSET' => $offset - $max_treffer,
+        'BACK_BUTTON_DISABLED' => $offset > 0 ? '' : ' disabled',
+        'NEXT_OFFSET' => $offset + $max_treffer,
+        'NEXT_BUTTON_DISABLED' => ($anzahl_treffer != $max_treffer + 1) ? ' disabled' : '',
+        'LANG_ACCESS_KEYS' => $lang['L_SEARCH_ACCESS_KEYS'], ]);
 
-$max_treffer=20;
-$treffer=mysql_search($db,$table_selected,$suchbegriffe,$suchart,$offset,$max_treffer+1);
-if (is_array($treffer)&&isset($treffer[0]))
-{
-	$search_message=sprintf($lang['L_SEARCH_RESULTS'],$suchbegriffe,$tables[$table_selected]);
-	$anzahl_treffer=count($treffer);
-	// Blaettern-Buttons
-	$tpl->assign_block_vars('HITS',array(
+    // Ausgabe der Treffertabelle
+    $anzahl_felder = sizeof($treffer[0]);
 
-		'LANG_SEARCH_RESULTS' => $search_message,
-		'LAST_OFFSET' => $offset-$max_treffer,
-		'BACK_BUTTON_DISABLED' => $offset>0 ? '' : ' disabled',
-		'NEXT_OFFSET' => $offset+$max_treffer,
-		'NEXT_BUTTON_DISABLED' => ($anzahl_treffer!=$max_treffer+1) ? ' disabled' : '',
-		'LANG_ACCESS_KEYS' => $lang['L_SEARCH_ACCESS_KEYS']));
+    // Ausgabe der Tabellenueberschrift/ Feldnamen
+    foreach ($treffer[0] as $key => $val) {
+        $tpl->assign_block_vars('HITS.TABLEHEAD', [
+            'KEY' => $key, ]);
+    }
 
-	// Ausgabe der Treffertabelle
-	$anzahl_felder=sizeof($treffer[0]);
+    // Ausgabe der Daten
+    $zeige_treffer = sizeof($treffer);
+    if ($zeige_treffer == $max_treffer + 1) {
+        $zeige_treffer = $max_treffer;
+    }
 
-	// Ausgabe der Tabellenueberschrift/ Feldnamen
-	foreach ($treffer[0] as $key=>$val)
-	{
-		$tpl->assign_block_vars('HITS.TABLEHEAD',array(
+    // built key - does a primary key exist?
+    $fieldinfos = getExtendedFieldinfo($db, $tables[$table_selected]);
+    //v($fieldinfos);
+    // auf zusammengesetzte Schlüssel untersuchen
+    $table_keys = isset($fieldinfos['primary_keys']) ? $fieldinfos['primary_keys'] : '';
 
-			'KEY' => $key));
-	}
+    for ($a = 0; $a < $zeige_treffer; ++$a) {
+        $tablename = array_keys($treffer[$a]);
+        if (is_array($table_keys) && sizeof($table_keys) > 0) {
+            // a primary key exitst
+            $keystring = '';
+            foreach ($table_keys as $k) {
+                // remove hit marker from value
+                $x = str_replace('<span class="treffer">', '', $treffer[$a][$k]);
+                $x = str_replace('</span>', '', $x);
+                $keystring .= '`'.$k.'`="'.addslashes($x).'" AND ';
+            }
+            $keystring = substr($keystring, 0, -5);
+            $rk = build_recordkey($keystring);
+        } else {
+            $rk = urlencode(build_where_from_record($treffer[$a])); // no keys
+        }
 
-	// Ausgabe der Daten
-	$zeige_treffer=sizeof($treffer);
-	if ($zeige_treffer==$max_treffer+1) $zeige_treffer=$max_treffer;
+        $delete_link = 'sql.php?search=1&mode=kill&db='.urlencode($db).'&tablename='.urlencode($tables[$table_selected]).'&rk='.$rk;
+        $edit_link = 'sql.php?mode=searchedit&db='.urlencode($db).'&tablename='.urlencode($tables[$table_selected]).'&recordkey='.$rk;
 
-	// built key - does a primary key exist?
-	$fieldinfos=getExtendedFieldinfo($db,$tables[$table_selected]);
-	//v($fieldinfos);
-	// auf zusammengesetzte Schlüssel untersuchen
-	$table_keys=isset($fieldinfos['primary_keys']) ? $fieldinfos['primary_keys'] : '';
+        $tpl->assign_block_vars('HITS.TABLEROW', [
+            'CLASS' => ($a % 2) ? 'dbrow' : 'dbrow1',
+            'NR' => $a + $offset + 1,
+            'TABLENAME' => $tables[$table_selected],
+            'LINK_EDIT' => $edit_link,
+            'ICON_EDIT' => $icon['edit'],
+            'LINK_DELETE' => $delete_link,
+            'ICON_DELETE' => $icon['delete'], ]);
 
-	for ($a=0; $a<$zeige_treffer; $a++)
-	{
-		$tablename=array_keys($treffer[$a]);
-		if (is_array($table_keys)&&sizeof($table_keys)>0)
-		{
-			// a primary key exitst
-			$keystring='';
-			foreach ($table_keys as $k)
-			{
-				// remove hit marker from value
-				$x=str_replace('<span class="treffer">','',$treffer[$a][$k]);
-				$x=str_replace('</span>','',$x);
-				$keystring.='`'.$k.'`="'.addslashes($x).'" AND ';
-			}
-			$keystring=substr($keystring,0,-5);
-			$rk=build_recordkey($keystring);
-		}
-		else
-		{
-			$rk=urlencode(build_where_from_record($treffer[$a])); // no keys
-		}
-
-		$delete_link='sql.php?search=1&mode=kill&db='.urlencode($db).'&tablename='.urlencode($tables[$table_selected]).'&rk='.$rk;
-		$edit_link='sql.php?mode=searchedit&db='.urlencode($db).'&tablename='.urlencode($tables[$table_selected]).'&recordkey='.$rk;
-
-		$tpl->assign_block_vars('HITS.TABLEROW',array(
-
-			'CLASS' => ($a%2) ? 'dbrow' : 'dbrow1',
-			'NR' => $a+$offset+1,
-			'TABLENAME' => $tables[$table_selected],
-			'LINK_EDIT' => $edit_link,
-			'ICON_EDIT' => $icon['edit'],
-			'LINK_DELETE' => $delete_link,
-			'ICON_DELETE' => $icon['delete']));
-
-		foreach ($treffer[$a] as $key=>$val)
-		{
-			if ($val=='') $val="&nbsp;";
-			$tpl->assign_block_vars('HITS.TABLEROW.TABLEDATA',array(
-
-				'VAL' => $val));
-		}
-	}
-}
-else
-{
-	if (!isset($tables[$table_selected])) $tables[$table_selected]='';
-	if ($suchbegriffe=='') $tpl->assign_block_vars('NO_ENTRIES',array(
-
-		'LANG_NO_ENTRIES' => sprintf($lang['L_NO_ENTRIES'],$tables[$table_selected])));
-	else
-		$tpl->assign_block_vars('NO_RESULTS',array(
-
-			'LANG_SEARCH_NO_RESULTS' => sprintf($lang['L_SEARCH_NO_RESULTS'],$suchbegriffe,$tables[$table_selected])));
+        foreach ($treffer[$a] as $key => $val) {
+            if ('' == $val) {
+                $val = '&nbsp;';
+            }
+            $tpl->assign_block_vars('HITS.TABLEROW.TABLEDATA', [
+                'VAL' => $val, ]);
+        }
+    }
+} else {
+    if (!isset($tables[$table_selected])) {
+        $tables[$table_selected] = '';
+    }
+    if ('' == $suchbegriffe) {
+        $tpl->assign_block_vars('NO_ENTRIES', [
+        'LANG_NO_ENTRIES' => sprintf($lang['L_NO_ENTRIES'], $tables[$table_selected]), ]);
+    } else {
+        $tpl->assign_block_vars('NO_RESULTS', [
+            'LANG_SEARCH_NO_RESULTS' => sprintf($lang['L_SEARCH_NO_RESULTS'], $suchbegriffe, $tables[$table_selected]), ]);
+    }
 }
 
 $tpl->pparse('show');
diff --git a/msd/inc/sqlbrowser/sql_commands.php b/msd/inc/sqlbrowser/sql_commands.php
index ad11b2b7..0d5e93c2 100644
--- a/msd/inc/sqlbrowser/sql_commands.php
+++ b/msd/inc/sqlbrowser/sql_commands.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,93 +16,99 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+
 function nl2null($string)
 {
-	$search=array("\r","\n");
-	$replace=array('','');
-	return trim(str_replace($search,$replace,$string));
+    $search = ["\r", "\n"];
+    $replace = ['', ''];
+
+    return trim(str_replace($search, $replace, $string));
 }
+
 //SQL-Strings
-echo $aus.='<h4>' . $lang['L_SQL_BEFEHLE'] . ' (' . count($SQL_ARRAY) . ')</h4>';
-echo '<a href="' . $params . '&amp;sqlconfig=1&amp;new=1">' . $lang['L_SQL_BEFEHLNEU'] . '</a><br><br>';
-if (isset($_POST['sqlnewupdate']))
-{
-	$ind=count($SQL_ARRAY);
-	if (count($SQL_ARRAY) > 0) array_push($SQL_ARRAY,$_POST['sqlname' . $ind] . "|" . $_POST['sqlstring' . $ind]);
-	else $SQL_ARRAY[0]=htmlspecialchars($_POST['sqlname0'],ENT_COMPAT ,'UTF-8') . '|' . $_POST['sqlstring0'];
-	WriteSQL();
-	echo '<p>' . $lang['L_SQL_BEFEHLSAVED1'] . ' \'' . $_POST['sqlname' . $ind] . '\' ' . $lang['L_SQL_BEFEHLSAVED2'] . '</p>';
+if (!is_array($SQL_ARRAY)) {
+    $SQL_ARRAY = [];
+}
+
+echo $aus .= '<h4>'.$lang['L_SQL_BEFEHLE'].' ('.count($SQL_ARRAY).')</h4>';
+echo '<a href="'.$params.'&amp;sqlconfig=1&amp;new=1">'.$lang['L_SQL_BEFEHLNEU'].'</a><br><br>';
+
+if (isset($_POST['sqlnewupdate'])) {
+    $ind = count($SQL_ARRAY);
+    if (count($SQL_ARRAY) > 0) {
+        array_push($SQL_ARRAY, $_POST['sqlname'.$ind].'|'.$_POST['sqlstring'.$ind]);
+    } else {
+        $SQL_ARRAY[0] = htmlspecialchars($_POST['sqlname0'], ENT_COMPAT, 'UTF-8').'|'.$_POST['sqlstring0'];
+    }
+    WriteSQL();
+    echo '<p>'.$lang['L_SQL_BEFEHLSAVED1'].' \''.$_POST['sqlname'.$ind].'\' '.$lang['L_SQL_BEFEHLSAVED2'].'</p>';
 }
 echo '<form name="sqlform" action="sql.php" method="post">
 	<input type="hidden" name="context" value="1">
 	<input type="hidden" name="sqlconfig" value="1">
-	<input type="hidden" name="tablename" value="' . $tablename . '">
-	<input type="hidden" name="dbid" value="' . $dbid . '">';
-echo '<table class="bdr" style="width:100%"><tr class="thead"><th>#</th><th>' . $lang['L_NAME'] . '</th><th>SQL</th><th>' . $lang['L_COMMAND'] . '</th></tr>';
-$i=0;
-if (count($SQL_ARRAY) > 0)
-{
-	for ($i=0; $i < count($SQL_ARRAY); $i++)
-	{
-		if (isset($_POST['sqlupdate' . $i]))
-		{
+	<input type="hidden" name="tablename" value="'.$tablename.'">
+	<input type="hidden" name="dbid" value="'.$dbid.'">';
+echo '<table class="bdr" style="width:100%"><tr class="thead"><th>#</th><th>'.$lang['L_NAME'].'</th><th>SQL</th><th>'.$lang['L_COMMAND'].'</th></tr>';
 
-			echo '<tr><td colspan="4"><p class="success">' . $lang['L_SQL_BEFEHLSAVED1']
-			. ' \'' . htmlspecialchars($_POST['sqlname' . $i],ENT_COMPAT ,'UTF-8') . '\' ' . $lang['L_SQL_BEFEHLSAVED3'] . '</p></td></tr>';
-			$SQL_ARRAY[$i]=$_POST['sqlname' . $i] . "|" . nl2null($_POST['sqlstring' . $i]);
-			WriteSQL();
-		}
-		if (isset($_POST['sqlmove' . $i]))
-		{
-			echo '<tr><td colspan="4"><p class="success">' . $lang['L_SQL_BEFEHLSAVED1'] . ' \'' . $_POST['sqlname' . $i] . '\' ' . $lang['L_SQL_BEFEHLSAVED4'] . '</p></td></tr>';
-			$a[]=$SQL_ARRAY[$i];
-			array_splice($SQL_ARRAY,$i,1);
-			$SQL_ARRAY=array_merge($a,$SQL_ARRAY);
-			WriteSQL();
-		}
-		if (isset($_POST['sqldelete' . $i]))
-		{
-			echo '<tr><td colspan="4"><p class="success">' . $lang['L_SQL_BEFEHLSAVED1'] . ' \'' . $_POST['sqlname' . $i] . '\' ' . $lang['L_SQL_BEFEHLSAVED5'] . '</p></td></tr>';
-			array_splice($SQL_ARRAY,$i,1);
-			WriteSQL();
-		}
-	}
-	for ($i=0; $i < count($SQL_ARRAY); $i++)
-	{
-		$cl=( $i % 2 ) ? "dbrow" : "dbrow1";
-		echo '<tr class="' . $cl . '"><td>' . ( $i + 1 ) . '.</td><td>';
-		echo '<input type="text" class="text" name="sqlname' . $i . '" value="' . htmlspecialchars(SQL_Name($i),ENT_COMPAT,'UTF-8') . '"></td>';
-		echo '<td><textarea rows="4" cols="80" style="width:100%;" name="sqlstring' . $i . '">' . stripslashes(SQL_String($i)) . '</textarea></td>';
-		echo '<td><input class="Formbutton" style="width:80px;" type="submit" name="sqlupdate' . $i . '" value="save"><br>
-			<input class="Formbutton" style="width:80px;" type="submit" name="sqlmove' . $i . '" value="move up"><br>
-			<input class="Formbutton" style="width:80px;"  type="submit" name="sqldelete' . $i . '" value="delete"></td></tr>';
-	}
+$i = 0;
+if (count($SQL_ARRAY) > 0) {
+    for ($i = 0; $i < count($SQL_ARRAY); ++$i) {
+        if (isset($_POST['sqlupdate'.$i])) {
+            echo '<tr><td colspan="4"><p class="success">'.$lang['L_SQL_BEFEHLSAVED1']
+            .' \''.htmlspecialchars($_POST['sqlname'.$i], ENT_COMPAT, 'UTF-8').'\' '.$lang['L_SQL_BEFEHLSAVED3'].'</p></td></tr>';
+            $SQL_ARRAY[$i] = $_POST['sqlname'.$i].'|'.nl2null($_POST['sqlstring'.$i]);
+            WriteSQL();
+        }
+        if (isset($_POST['sqlmove'.$i])) {
+            echo '<tr><td colspan="4"><p class="success">'.$lang['L_SQL_BEFEHLSAVED1'].' \''.$_POST['sqlname'.$i].'\' '.$lang['L_SQL_BEFEHLSAVED4'].'</p></td></tr>';
+            $a[] = $SQL_ARRAY[$i];
+            array_splice($SQL_ARRAY, $i, 1);
+            $SQL_ARRAY = array_merge($a, $SQL_ARRAY);
+            WriteSQL();
+        }
+        if (isset($_POST['sqldelete'.$i])) {
+            echo '<tr><td colspan="4"><p class="success">'.$lang['L_SQL_BEFEHLSAVED1'].' \''.$_POST['sqlname'.$i].'\' '.$lang['L_SQL_BEFEHLSAVED5'].'</p></td></tr>';
+            array_splice($SQL_ARRAY, $i, 1);
+            WriteSQL();
+        }
+    }
+    for ($i = 0; $i < count($SQL_ARRAY); ++$i) {
+        $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+        echo '<tr class="'.$cl.'"><td>'.($i + 1).'.</td><td>';
+        echo '<input type="text" class="text" name="sqlname'.$i.'" value="'.htmlspecialchars(SQL_Name($i), ENT_COMPAT, 'UTF-8').'"></td>';
+        echo '<td><textarea rows="4" cols="80" style="width:100%;" name="sqlstring'.$i.'">'.stripslashes(SQL_String($i)).'</textarea></td>';
+        echo '<td><input class="Formbutton" style="width:80px;" type="submit" name="sqlupdate'.$i.'" value="save"><br>
+			<input class="Formbutton" style="width:80px;" type="submit" name="sqlmove'.$i.'" value="move up"><br>
+			<input class="Formbutton" style="width:80px;"  type="submit" name="sqldelete'.$i.'" value="delete"></td></tr>';
+    }
 }
-if (isset($_GET['new']))
-{
-	$cl=( $i % 2 ) ? "dbrow" : "dbrow1";
-	echo '<tr class="' . $cl . '"><td>' . ( $i + 1 ) . '</td><td>';
-	echo '<input type="text" class="text" name="sqlname' . $i . '" id="sqlname' . $i . '" value="SQL ' . ( $i + 1 ) . '"><br><div class="small" align="center">' . $lang['L_SQL_LIBRARY'] . '<br>';
-	echo '<select id="sqllib" name="sqllib" onChange="InsertLib(' . $i . ');" class="small">';
-	echo '<option value=""></option>';
-	$og=false;
-	for ($j=0; $j < count($sqllib); $j++)
-	{
-		if ($sqllib[$j]['sql'] == "trenn")
-		{
-			if ($og) echo '</optgroup>';
-			echo '<optgroup label="' . $sqllib[$j]['name'] . '">';
-			$og=true;
-		}
-		else
-		{
-			echo '<option value="' . $sqllib[$j]['sql'] . '">' . $sqllib[$j]['name'] . '</option>';
-		}
-	}
-	if ($og) echo '</optgroup>';
-	echo '</select></div></td>
-		<td><textarea rows="3" cols="40" name="sqlstring' . $i . '" id="sqlstring' . $i . '">SELECT * FROM</textarea></td>
+
+if (isset($_GET['new'])) {
+    $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+    echo '<tr class="'.$cl.'"><td>'.($i + 1).'</td><td>';
+    echo '<input type="text" class="text" name="sqlname'.$i.'" id="sqlname'.$i.'" value="SQL '.($i + 1).'"><br><div class="small" align="center">'.$lang['L_SQL_LIBRARY'].'<br>';
+    echo '<select id="sqllib" name="sqllib" onChange="InsertLib('.$i.');" class="small">';
+    echo '<option value=""></option>';
+    $og = false;
+    for ($j = 0; $j < count($sqllib); ++$j) {
+        if ('trenn' == $sqllib[$j]['sql']) {
+            if ($og) {
+                echo '</optgroup>';
+            }
+            echo '<optgroup label="'.$sqllib[$j]['name'].'">';
+            $og = true;
+        } else {
+            echo '<option value="'.$sqllib[$j]['sql'].'">'.$sqllib[$j]['name'].'</option>';
+        }
+    }
+    if ($og) {
+        echo '</optgroup>';
+    }
+    echo '</select></div></td>
+		<td><textarea rows="3" cols="40" name="sqlstring'.$i.'" id="sqlstring'.$i.'">SELECT * FROM</textarea></td>
 		<td><input class="Formbutton" style="width:80px;" type="submit" name="sqlnewupdate" value="save"></td></tr>';
 }
 echo '</table></form>';
diff --git a/msd/inc/sqlbrowser/sql_dataview.php b/msd/inc/sqlbrowser/sql_dataview.php
index 5974c12c..be8fe1ef 100644
--- a/msd/inc/sqlbrowser/sql_dataview.php
+++ b/msd/inc/sqlbrowser/sql_dataview.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,365 +16,391 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 // fuegt eine Sortierungsnummer hinzu, um die Ausgabereihenfolge der Daten steuern zu koennen
 // (das Feld ENGINE interessiert mich nicht so sehr und muss nicht vorne stehen)
-$keysort=array(
+$keysort = [
+            'Name' => 0,
+            'Rows' => 1,
+            'Data_length' => 2,
+            'Auto_increment' => 3,
+            'Avg_row_length' => 4,
+            'Max_data_length' => 5,
+            'Comment' => 6,
+            'Row_format' => 7,
+            'Index_length' => 8,
+            'Data_free' => 9,
+            'Collation' => 10,
+            'Create_time' => 11,
+            'Update_time' => 12,
+            'Check_time' => 13,
+            'Create_options' => 14,
+            'Version' => 15,
+            'Engine' => 16,
+            'Checksum' => 17,
+];
 
-			'Name' => 0,
-			'Rows' => 1,
-			'Data_length' => 2,
-			'Auto_increment' => 3,
-			'Avg_row_length' => 4,
-			'Max_data_length' => 5,
-			'Comment' => 6,
-			'Row_format' => 7,
-			'Index_length' => 8,
-			'Data_free' => 9,
-			'Collation' => 10,
-			'Create_time' => 11,
-			'Update_time' => 12,
-			'Check_time' => 13,
-			'Create_options' => 14,
-			'Version' => 15,
-			'Engine' => 16,
-			'Checksum' => 17
-);
-
-$byte_output=array(
-
-				'Data_length',
-				'Avg_row_length',
-				'Max_data_length',
-				'Index_length',
-				'Data_free'
-);
+$byte_output = [
+                'Data_length',
+                'Avg_row_length',
+                'Max_data_length',
+                'Index_length',
+                'Data_free',
+];
 
 function add_sortkey($name)
 {
-	global $keysort;
-	//echo "<br>Uebergeben: ".$name;
-	if (array_key_exists($name,$keysort)) $ret=$keysort[$name];
-	else $ret=0;
-	return $ret;
+    global $keysort;
+    //echo "<br>Uebergeben: ".$name;
+    if (array_key_exists($name, $keysort)) {
+        $ret = $keysort[$name];
+    } else {
+        $ret = 0;
+    }
+    return $ret;
 }
 
 //Data-View
-echo $aus . '<h4>' . ( ( $showtables == 1 ) ? $lang['L_SQL_TABLEVIEW'] : $lang['L_SQL_DATAVIEW'] ) . '</h4><p>';
-if ($showtables == 0)
-{
-	$p='sql.php?sql_statement=' . urlencode($sql['sql_statement']) . '&amp;db=' . $db . '&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '&amp;limitstart=' . $limitstart . '&amp;order=' . urlencode($order) . '&amp;orderdir=' . $orderdir . '&amp;tdc=' . $tdcompact;
-	echo '<a href="' . $p . '&amp;mode=new">' . $lang['L_SQL_RECORDNEW'] . '</a>&nbsp;&nbsp;&nbsp;&nbsp;';
-	echo '<a href="sql.php?db=' . $databases['db_actual'] . '&amp;dbid=' . $dbid . '&amp;tablename=' . $tablename . '&amp;context=2">' . $lang['L_SQL_EDIT_TABLESTRUCTURE'] . '</a>';
-}
-else
-{
-	$p='sql.php?db=' . $db . '&amp;dbid=' . $dbid . '&amp;context=2';
-	echo '<a href="' . $p . '">' . $lang['L_SQL_TABLENEW'] . '</a>';
+echo $aus.'<h4>'.((1 == $showtables) ? $lang['L_SQL_TABLEVIEW'] : $lang['L_SQL_DATAVIEW']).'</h4><p>';
+if (0 == $showtables) {
+    $p = 'sql.php?sql_statement='.urlencode($sql['sql_statement']).'&amp;db='.$db.'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;limitstart='.$limitstart.'&amp;order='.urlencode($order).'&amp;orderdir='.$orderdir.'&amp;tdc='.$tdcompact;
+    echo '<a href="'.$p.'&amp;mode=new">'.$lang['L_SQL_RECORDNEW'].'</a>&nbsp;&nbsp;&nbsp;&nbsp;';
+    echo '<a href="sql.php?db='.$databases['db_actual'].'&amp;dbid='.$dbid.'&amp;tablename='.$tablename.'&amp;context=2">'.$lang['L_SQL_EDIT_TABLESTRUCTURE'].'</a>';
+} else {
+    $p = 'sql.php?db='.$db.'&amp;dbid='.$dbid.'&amp;context=2';
+    echo '<a href="'.$p.'">'.$lang['L_SQL_TABLENEW'].'</a>';
 }
 
 //Statuszeile
-$tn=ExtractTablenameFromSQL($sql['sql_statement']);
-if ($databases['Name'][$dbid]!=$databases['db_actual'])
-{
-	// Table is located in a different databasse
-	// switch the actual database
-	$databases['db_actual']=$databases['Name'][$dbid];
-	// refresh menu to switch to actual database
-	echo '<script type="text/javascript" language="javascript">'
-		.'parent.MyOOS_Dumper_menu.location.href=\'menu.php?dbindex='.$dbid.'\';</script>';
-
+$tn = ExtractTablenameFromSQL($sql['sql_statement']);
+if ($databases['Name'][$dbid] != $databases['db_actual']) {
+    // Table is located in a different databasse
+    // switch the actual database
+    $databases['db_actual'] = $databases['Name'][$dbid];
+    // refresh menu to switch to actual database
+    echo '<script>'
+        .'parent.MyOOS_Dumper_menu.location.href=\'menu.php?dbindex='.$dbid.'\';</script>';
 }
-echo '</p><p class="tablename">' . ( $tn != '' ? $lang['L_TABLE'] . ' <strong>`' . $databases['db_actual'] . '`.`' . $tn . '`</strong><br>' : '' );
-if (isset($msg)) echo $msg;
 
-$numrowsabs=-1;
-$numrows=0;
+echo '</p><p class="tablename">'.('' != $tn ? $lang['L_TABLE'].' <strong>`'.$databases['db_actual'].'`.`'.$tn.'`</strong><br>' : '');
+if (isset($msg)) {
+    echo $msg;
+}
+
+$numrowsabs = -1;
+$numrows = 0;
 // Vorgehensweise - es soll die Summe der Datensaetze ermittelt werden, wenn es kein LIMIT gibt,
 // um die Blaettern-Links korrekt anzuzeigen
-$skip_mysql_execution=false;
-if ($sql_to_display_data == 0)
-{
-	//mehrere SQL-Statements
-	$numrowsabs=$numrows=0;
-	MSD_DoSQL($sql['sql_statement']);
-	echo SQLOutput($out);
-	$skip_mysql_execution=true;
-}
-else
-{
-	$sql_temp=strtolower($sql['sql_statement']);
-	if (substr($sql_temp,0,7) == 'select ')
-	{
-		if (false !== strpos($sql_temp,' limit '))
-		{
-			// es wurde ein eigenes Lmit im Query angegeben - eigene Berechnung abbrechen
-			$numrowsabs=-1;
-		}
-		else
-		{
-			$sql_temp="SELECT count(*) as anzahl FROM (".$sql_temp.") as query;";
-			$res=@MSD_query($sql_temp,false);
-			if ($res)
-			{
-				if ($row=mysqli_fetch_object($res))
-				{
-					$numrowsabs=$row->anzahl;
-				}
-			}
-			else
-			{
-				// Query ergab Fehler - Anzahl unbekannt; -1 übernimmt dann die Groesse des Resultsets
-				$numrowsabs=-1;
-			}
-		}
-	}
+$skip_mysql_execution = false;
+
+if (0 == $sql_to_display_data) {
+    //mehrere SQL-Statements
+    $numrowsabs = $numrows = 0;
+    MOD_DoSQL($sql['sql_statement']);
+    echo SQLOutput($out);
+    $skip_mysql_execution = true;
+} else {
+    // auch alle Tabellen-Namen werden lowercase -> das kann zu Problemen fuehren
+    // siehe https://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html
+    $sql_temp = strtolower($sql['sql_statement']);
+
+    if ('select ' == substr($sql_temp, 0, 7)) {
+        if (false !== strpos($sql_temp, ' limit ')) {
+            // es wurde ein eigenes Limit im Query angegeben - eigene Berechnung abbrechen
+            $numrowsabs = -1;
+        } else {
+            // anstatt sql_temp in lowerase hier das 'original' sql_statement verwenden
+            $sql_temp = "SELECT count(*) as anzahl FROM (".$sql['sql_statement'].") as query;";
+            $res = @mod_query($sql_temp, false);
+            if ($res) {
+                if ($row = mysqli_fetch_object($res)) {
+                    $numrowsabs = $row->anzahl;
+                }
+            } else {
+                // Query ergab Fehler - Anzahl unbekannt; -1 übernimmt dann die Groesse des Resultsets
+                $numrowsabs = -1;
+            }
+        }
+    }
 }
 
-$sqltmp=$sql['sql_statement'] . $sql['order_statement'] . ( strpos(strtolower($sql['sql_statement'] . $sql['order_statement']),' limit ') ? '' : $limit );
-if (!$skip_mysql_execution) $res=MSD_query($sqltmp);
-$numrows=@mysqli_num_rows($res);
-if ($numrowsabs == -1) $numrowsabs=$numrows;
-if ($limitende > $numrowsabs) $limitende=$numrowsabs;
+$sqltmp = $sql['sql_statement'].$sql['order_statement'].(strpos(strtolower($sql['sql_statement'].$sql['order_statement']), ' limit ') ? '' : $limit);
 
-if ($numrowsabs > 0 && $Anzahl_SQLs <= 1)
-{
-	if ($showtables == 0)
-	{
-		$command_line=$lang['L_INFO_RECORDS'] . " " . ( $limitstart + 1 ) . " - ";
-		if ($limitstart + $limitende > $numrowsabs) $command_line.=$numrowsabs;
-		else $command_line.=$limitstart + $limitende;
-		$command_line.=" " . $lang['L_SQL_VONINS'] . " $numrowsabs &nbsp;&nbsp;&nbsp;";
-		$command_line.=( $limitstart > 0 ) ? '<a href="' . $params . '&amp;limitstart=0">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;&nbsp;' : '&lt;&lt;&nbsp;&nbsp;&nbsp;&nbsp;';
-		$command_line.=( $limitstart > 0 ) ? '<a href="' . $params . '&amp;limitstart=' . ( ( $limitstart - $config['sql_limit'] < 0 ) ? 0 : $limitstart - $config['sql_limit'] ) . '">&lt;</a>&nbsp;&nbsp;&nbsp;&nbsp;' : '&lt;&nbsp;&nbsp;&nbsp;&nbsp;';
-		$command_line.=( $limitstart + $limitende < $numrowsabs ) ? '<a href="' . $params . '&amp;limitstart=' . ( $limitstart + $config['sql_limit'] ) . '">&gt;</a>&nbsp;&nbsp;&nbsp;&nbsp;' : '&gt;&nbsp;&nbsp;&nbsp;&nbsp;';
-		$command_line.=( $limitstart + $limitende < ( $numrowsabs - $config['sql_limit'] ) ) ? '<a href="' . $params . '&amp;limitstart=' . ( $numrowsabs - $config['sql_limit'] ) . '">&gt;&gt;</a>' : '&gt;&gt;';
-		echo $command_line;
-	}
-	else
-	{
-		echo $numrowsabs.' '.($numrowsabs>1 ? $lang['L_TABLES']:$lang['L_TABLE']);
-	}
-	echo '</p>';
-	//Datentabelle
-	echo '<table class="bdr" id="dataTable">';
-
-	$t=$d="";
-	$fdesc=Array();
-	$key=-1;
-	if ($numrows > 0)
-	{
-		//Infos und Header holen
-		//1.Datensatz fuer Feldinfos
-		$row=mysqli_fetch_row($res);
-		//Kompaktmodus-Switcher
-		$t='<td colspan="' . ( count($row) + 1 ) . '" align="left"><a href="sql.php?db=' . $db . '&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '&amp;order=' . urlencode($order) . '&amp;orderdir=' . $orderdir . '&amp;limitstart=' . $limitstart . '&amp;sql_statement=' . urlencode($sql['sql_statement']) . '&amp;tdc=' . ( ( $tdcompact == 0 ) ? '1' : '0' ) . '">' . ( ( $tdcompact == 1 ) ? $lang['L_SQL_VIEW_STANDARD'] : $lang['L_SQL_VIEW_COMPACT'] ) . '</a>';
-		$t.='&nbsp;&nbsp;&nbsp;' . $lang['L_SQL_QUERYENTRY'] . ' ' . count($row) . ' ' . $lang['L_SQL_COLUMNS'];
-		$t.='</td></tr><tr class="thead">';
-		$t.='<th>&nbsp;</th><th>#</th>';
-		$temp=array();
-
-		for ($x=0; $x < count($row); $x++)
-		{
-		    //	$temp[$x]['data']=mysqli_fetch_field($res,$x);
-			$temp[$x]['data']=mysqli_fetch_field($res);
-			$temp[$x]['sort']=add_sortkey($temp[$x]['data']->name);
-		}
-
-		if ($showtables == 1) $temp=mu_sort($temp,'sort');
-
-		for ($x=0; $x < count($temp); $x++)
-		{
-			$str=$temp[$x]['data'];
-			$t.='<th align="left" nowrap="nowrap">';
-			$pic="";
-			$fdesc[$temp[$x]['data']->name]['name']=isset($str->name) ? $str->name : '';
-			$fdesc[$temp[$x]['data']->name]['table']=isset($str->table) ? $str->table : '';
-			$fdesc[$temp[$x]['data']->name]['max_length']=isset($str->max_length) ? $str->max_length : '';
-			$fdesc[$temp[$x]['data']->name]['not_null']=isset($str->not_null) ? $str->not_null : '';
-			$fdesc[$temp[$x]['data']->name]['primary_key']=isset($str->primary_key) ? $str->primary_key : '';
-			$fdesc[$temp[$x]['data']->name]['unique_key']=isset($str->unique_key) ? $str->unique_key : '';
-			$fdesc[$temp[$x]['data']->name]['multiple_key']=isset($str->multiple_key) ? $str->multiple_key : '';
-			$fdesc[$temp[$x]['data']->name]['numeric']=isset($str->numeric) ? $str->numeric : '';
-			$fdesc[$temp[$x]['data']->name]['blob']=isset($str->blob) ? $str->blob : '';
-			$fdesc[$temp[$x]['data']->name]['type']=isset($str->type) ? $str->type : '';
-			$fdesc[$temp[$x]['data']->name]['unsigned']=isset($str->unsigned) ? $str->unsigned : '';
-			$fdesc[$temp[$x]['data']->name]['zerofill']=isset($str->zerofill) ? $str->zerofill : '';
-			$fdesc[$temp[$x]['data']->name]['Check_time']=isset($str->Check_time) ? $str->Check_time : '';
-			$fdesc[$temp[$x]['data']->name]['Checksum']=isset($str->Checksum) ? $str->Checksum : '';
-			$fdesc[$temp[$x]['data']->name]['Engine']=isset($str->Engine) ? $str->Engine : '';
-			if (isset($str->Comment) && substr($str->Comment,0,4) == 'VIEW') $fdesc[$temp[$x]['data']->name]['Engine']='View';
-			$fdesc[$temp[$x]['data']->name]['Version']=isset($str->Version) ? $str->Version : '';
-
-			$tt=$lang['L_NAME'] . ': ' . $fdesc[$temp[$x]['data']->name]['name'] . ' Type: ' . $fdesc[$temp[$x]['data']->name]['type'] . " Max Length: " . $fdesc[$temp[$x]['data']->name]['max_length'] . " Unsigned: " . $fdesc[$temp[$x]['data']->name]['unsigned'] . " zerofill: " . $fdesc[$temp[$x]['data']->name]['zerofill'];
-
-			$pic='<img src="' . $icon['blank'] . '" alt="" width="1" height="1" border="0">';
-			if ( (isset($str->primary_key) && ($str->primary_key == 1)) || (isset($str->unique_key) && ($str->unique_key == 1)) )
-
-			{
-				if ($key == -1) $key=$temp[$x]['data']->name;
-				else $key.='|' . $temp[$x]['data']->name;
-
-				if ($str->primary_key == 1) $pic=$icon['key_primary'];
-				elseif ($str->unique_key == 1) $pic=$icon['index'];
-			}
-
-			// show sorting icon
-			$arname=( $orderdir == "ASC" ) ? $icon['arrow_down'] : $icon['arrow_up'];
-			if ($str->name == $order) $t.=$arname;
-
-			if ($bb == -1) $bb_link=( $str->type == "blob" ) ? '&nbsp;&nbsp;&nbsp;<a style="font-size:10px;color:blue;" title="use BB-Code for this field" href="sql.php?db=' . $db . '&amp;bb=' . $x . '&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '&amp;order=' . $order . '&amp;orderdir=' . $orderdir . '&amp;limitstart=' . $limitstart . '&amp;sql_statement=' . urlencode($sql['sql_statement']) . '&amp;tdc=' . $tdcompact . '">[BB]</a>' : '';
-			else $bb_link=( $str->type == "blob" ) ? '&nbsp;&nbsp;&nbsp;<a title="use BB-Code for this field" href="sql.php?db=' . $db . '&amp;bb=-1&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '&amp;order=' . urlencode($order) . '&amp;orderdir=' . $orderdir . '&amp;limitstart=' . $limitstart . '&amp;sql_statement=' . urlencode($sql['sql_statement']) . '&amp;tdc=' . $tdcompact . '">[no BB]</a>' : '';
-			if ($no_order == false && $showtables == 0) $t.=$pic . '&nbsp;<a title="' . $tt . '" href="sql.php?db=' . $db . '&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '&amp;order=' . urlencode($str->name) . '&amp;orderdir=' . $norder . '&amp;sql_statement=' . urlencode($sql['sql_statement']) . '&amp;tdc=' . $tdcompact . '">' . $str->name . '</a>' . $bb_link;
-			else $t.=$pic . '&nbsp;<span title="' . $tt . '" >' . $str->name . '</span>' . $bb_link;
-			$t.='</th>';
-		}
-		unset($temp);
-
-		$temp=array();
-		//und jetzt Daten holen
-		mysqli_data_seek($res,0);
-
-		$s=$keysort;
-		$s=array_flip($keysort);
-		ksort($s);
-		for ($i=0; $i < $numrows; $i++)
-		{
-			$data[0]=mysqli_fetch_array($res,MYSQLI_ASSOC);
-			if ($showtables == 1 && $tabellenansicht == 1)
-			{
-				// Spalten sortieren, wenn wir uns in einer Tabellenuebersicht befinden
-				$xx=mu_sort($data,"$s[0],$s[1],$s[2],$s[3],$s[4],$s[5],$s[6],$s[7],$s[8],$s[9],$s[10],$s[11],$s[12],$s[13],$s[14],$s[15],$s[16]");
-				$temp[$i]=$xx[0];
-			}
-			else
-				$temp[$i]=$data[0];
-		}
-
-		$rownr=$limitstart + 1;
-		for ($i=0; $i < $numrows; $i++)
-		{
-			$row=$temp[$i]; // mysqli_fetch_row($res);
-			$cl=( $i % 2 ) ? 'dbrow' : 'dbrow1';
-			$erste_spalte=1;
-
-			// bei Tabellenuebersicht soll nach vorgefertigter Reihenfolge sortiert werden, ansonsten einfach Daten anzeigen
-			if ($showtables == 1) $sortkey=$keysort;
-			else $sortkey=$row;
-			$spalte=0;
-
-			// get primary key link for editing
-			if ($key > -1)
-			{
-				$primary_key='';
-				$keys=explode('|',$key);
-				foreach ($sortkey as $rowkey=>$rowval)
-				{
-					if (in_array($rowkey,$keys))
-					{
-						if (strlen($primary_key) > 0) $primary_key.=' AND ';
-						$primary_key.='`' . urlencode($rowkey) . '`=\'' . urlencode($rowval) . '\'';
-					}
-				}
-				//echo "<br><br>Primaerschluessel erkannt: ".$primary_key;
-			}
-
-			foreach ($sortkey as $rowkey=>$rowval)
-			{
-				if (( $rowkey == 'Name' ) && $tabellenansicht == 1 && isset($row['Name'])) $tablename=$row['Name'];
-
-				if ($erste_spalte == 1)
-				{
-					//edit-pics
-					$d.=$nl . '<td valign="top" nowrap="nowrap" class="small">&nbsp;' . $nl;
-					$p='sql.php?sql_statement=' . urlencode($sql['sql_statement']) . '&amp;db=' . $databases['db_actual'] . '&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '&amp;limitstart=' . $limitstart . '&amp;order=' . urlencode($order) . '&amp;orderdir=' . $orderdir . '&amp;tdc=' . $tdcompact;
-					if ($key == -1)
-					{
-						$rk=build_where_from_record($temp[$i]);
-						$p.='&amp;recordkey=' . urlencode($rk);
-					}
-					else
-					{
-						//Key vorhanden
-						$p.='&amp;recordkey=' . urlencode($primary_key); //urlencode("`".$fdesc[$key]['name']."`='".$rowval."'");
-					}
-					if ($showtables == 1) $p.='&amp;recordkey=' . urlencode($tablename);
-					if (!isset($no_edit) || !$no_edit)
-					{
-						if ($showtables == 0)
-						{
-							$d.='<a href="' . $p . '&amp;mode=edit">' . $icon['edit'] . '</a>&nbsp;';
-						}
-					}
-
-					if ($showtables == 0 && $tabellenansicht == 0)
-					{
-						$d.='<a href="' . $p . '&amp;mode=kill" onclick="if(!confirm(\'' . $lang['L_ASKDELETERECORD'] . '\')) return false;">' . $icon['delete'] . '</a>';
-					}
-					else
-					{
-						if ($tabellenansicht == 1 && $showtables == 1)
-						{
-							$d.='<a href="sql.php?db=' . $db . '&amp;dbid=' . $dbid . '&amp;tablename=' . $tablename . '&amp;context=2">' . $icon['edit'] . '</a>&nbsp;' . $nl . $nl;
-							if (!( isset($row['Comment']) && ( substr(strtoupper($row['Comment']),0,4) == 'VIEW' ) ))
-							{
-								$d.='<a href="' . $p . '&amp;mode=empty" onclick="if(!confirm(\'' . sprintf($lang['L_ASKTABLEEMPTY'],$tablename) . '\')) return false;">' . $icon['table_truncate'] . '</a>&nbsp;' . $nl . $nl;
-								$d.='<a href="' . $p . '&amp;mode=emptyk" onclick="if(!confirm(\'' . sprintf($lang['L_ASKTABLEEMPTYKEYS'],$tablename) . '\')) return false;">' . $icon['table_truncate_reset'] . '</a>&nbsp;' . $nl . $nl;
-								$d.='<a href="' . $p . '&amp;mode=kill" onclick="if(!confirm(\'' . sprintf($lang['L_ASKDELETETABLE'],$tablename) . '\')) return false;">' . $icon['delete'] . '</a>&nbsp;' . $nl . $nl;
-							}
-							else
-							{
-								$d.='<a href="' . $p . '&amp;mode=kill_view" onclick="if(!confirm(\'' . sprintf($lang['L_ASKDELETETABLE'],$tablename) . '\')) return false;">' . $icon['delete'] . '</a>&nbsp;' . $nl . $nl;
-							}
-						}
-					}
-					$d.='</td><td valign="top" class="small" style="text-align:right">' . $rownr . '.&nbsp;</td>';
-					$rownr++;
-					$erste_spalte=0;
-				}
-				$d.='<td valign="top" class="small" nowrap="nowrap">';
-				$divstart='<div' . ( ( $tdcompact == 1 ) ? ' class="tdcompact" ' : ' class="tdnormal"' ) . '>';
-				$divend='</div>';
-				if ($bb == $spalte)
-				{
-					$data=convert_to_utf8(simple_bbcode_conversion($rowval));
-				}
-				else
-				{
-					if ($showtables == 0)
-					{
-						if (isset($fdesc[$rowkey]['type'])) $data=( $fdesc[$rowkey]['type'] == 'string' || $fdesc[$rowkey]['type'] == 'blob' ) ? convert_to_utf8($rowval) : $rowval;
-					}
-					else
-					{
-						if (isset($temp[$i][$rowkey])) $data=( $fdesc[$rowkey]['type'] == 'string' || $fdesc[$rowkey]['type'] == 'blob' ) ? convert_to_utf8($temp[$i][$rowkey]) : $temp[$i][$rowkey];
-						else $data='';
-						if (in_array($rowkey,$byte_output)) $data=byte_output($data);
-
-					}
-				}
-				//v($fdesc[$rowkey]);
-				if ($showtables==0)
-				{
-					if (is_null($rowval)) $data='<i>NULL</i>';
-
-					else $data=htmlspecialchars($data,ENT_COMPAT,'UTF-8');
-				}
-				$spalte++;
-				$browse_link='<a href="sql.php?db=' . $db . '&amp;tablename=' . $tablename . '&amp;dbid=' . $dbid . '" title="' . $data . '">';
-				$d.=( $tabellenansicht == 1 && $rowkey == 'Name' ) ? $divstart . $browse_link . $icon['browse'] . "</a>&nbsp;" . $browse_link . $data . "</a>$divend" : $divstart . $data . $divend;
-				$d.='</td>';
-			}
-			// Tabellenueberschrift en ausgeben
-			if ($i == 0) echo '<tr>' . $t . '</tr>';
-			// Daten anzeigen
-			echo "\n\n" . '<tr class="' . $cl . '">' . $d . '</tr>' . "\n\n";
-			$d="";
-		}
-	}
-	echo '</table>';
-
-	if ($showtables == 0) echo '<br>' . $command_line;
+if (!$skip_mysql_execution) {
+    $res = mod_query($sqltmp);
+}
+$numrows = mysqli_num_rows($res);
+
+if (-1 == $numrowsabs) {
+    $numrowsabs = $numrows;
+}
+if ($limitende > $numrowsabs) {
+    $limitende = $numrowsabs;
+}
+
+if ($numrowsabs > 0 && $Anzahl_SQLs <= 1) {
+    if (0 == $showtables) {
+        $command_line = $lang['L_INFO_RECORDS'].' '.($limitstart + 1).' - ';
+        if ($limitstart + $limitende > $numrowsabs) {
+            $command_line .= $numrowsabs;
+        } else {
+            $command_line .= $limitstart + $limitende;
+        }
+        $command_line .= ' '.$lang['L_SQL_VONINS']." $numrowsabs &nbsp;&nbsp;&nbsp;";
+        $command_line .= ($limitstart > 0) ? '<a href="'.$params.'&amp;limitstart=0">&lt;&lt;</a>&nbsp;&nbsp;&nbsp;&nbsp;' : '&lt;&lt;&nbsp;&nbsp;&nbsp;&nbsp;';
+        $command_line .= ($limitstart > 0) ? '<a href="'.$params.'&amp;limitstart='.(($limitstart - $config['sql_limit'] < 0) ? 0 : $limitstart - $config['sql_limit']).'">&lt;</a>&nbsp;&nbsp;&nbsp;&nbsp;' : '&lt;&nbsp;&nbsp;&nbsp;&nbsp;';
+        $command_line .= ($limitstart + $limitende < $numrowsabs) ? '<a href="'.$params.'&amp;limitstart='.($limitstart + $config['sql_limit']).'">&gt;</a>&nbsp;&nbsp;&nbsp;&nbsp;' : '&gt;&nbsp;&nbsp;&nbsp;&nbsp;';
+        $command_line .= ($limitstart + $limitende < ($numrowsabs - $config['sql_limit'])) ? '<a href="'.$params.'&amp;limitstart='.($numrowsabs - $config['sql_limit']).'">&gt;&gt;</a>' : '&gt;&gt;';
+        echo $command_line;
+    } else {
+        echo $numrowsabs.' '.($numrowsabs > 1 ? $lang['L_TABLES'] : $lang['L_TABLE']);
+    }
+    echo '</p>';
+    //Datentabelle
+    echo '<table class="bdr" id="dataTable">';
+
+    $t = $d = '';
+    $fdesc = [];
+    $key = -1;
+    if ($numrows > 0) {
+        //Infos und Header holen
+        //1.Datensatz fuer Feldinfos
+        $row = mysqli_fetch_row($res);
+        //Kompaktmodus-Switcher
+        $t = '<td colspan="'.(count($row) + 1).'" align="left"><a href="sql.php?db='.$db.'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;order='.urlencode($order).'&amp;orderdir='.$orderdir.'&amp;limitstart='.$limitstart.'&amp;sql_statement='.urlencode($sql['sql_statement']).'&amp;tdc='.((0 == $tdcompact) ? '1' : '0').'">'.((1 == $tdcompact) ? $lang['L_SQL_VIEW_STANDARD'] : $lang['L_SQL_VIEW_COMPACT']).'</a>';
+        $t .= '&nbsp;&nbsp;&nbsp;'.$lang['L_SQL_QUERYENTRY'].' '.count($row).' '.$lang['L_SQL_COLUMNS'];
+        $t .= '</td></tr><tr class="thead">';
+        $t .= '<th>&nbsp;</th><th>#</th>';
+        $temp = [];
+
+        for ($x = 0; $x < count($row); ++$x) {
+            //	$temp[$x]['data'] =mysqli_fetch_field($res, $x);
+            $temp[$x]['data'] = mysqli_fetch_field($res);
+            $temp[$x]['sort'] = add_sortkey($temp[$x]['data']->name);
+        }
+
+        if (1 == $showtables) {
+            $temp = mu_sort($temp, 'sort');
+        }
+
+        for ($x = 0; $x < count($temp); ++$x) {
+            $str = $temp[$x]['data'];
+            $t .= '<th align="left" nowrap="nowrap">';
+            $pic = '';
+            $fdesc[$temp[$x]['data']->name]['name'] = isset($str->name) ? $str->name : '';
+            $fdesc[$temp[$x]['data']->name]['table'] = isset($str->table) ? $str->table : '';
+            $fdesc[$temp[$x]['data']->name]['max_length'] = isset($str->max_length) ? $str->max_length : '';
+            $fdesc[$temp[$x]['data']->name]['not_null'] = isset($str->not_null) ? $str->not_null : '';
+            $fdesc[$temp[$x]['data']->name]['primary_key'] = isset($str->primary_key) ? $str->primary_key : '';
+            $fdesc[$temp[$x]['data']->name]['unique_key'] = isset($str->unique_key) ? $str->unique_key : '';
+            $fdesc[$temp[$x]['data']->name]['multiple_key'] = isset($str->multiple_key) ? $str->multiple_key : '';
+            $fdesc[$temp[$x]['data']->name]['numeric'] = isset($str->numeric) ? $str->numeric : '';
+            $fdesc[$temp[$x]['data']->name]['blob'] = isset($str->blob) ? $str->blob : '';
+            $fdesc[$temp[$x]['data']->name]['type'] = isset($str->type) ? $str->type : '';
+            $fdesc[$temp[$x]['data']->name]['unsigned'] = isset($str->unsigned) ? $str->unsigned : '';
+            $fdesc[$temp[$x]['data']->name]['zerofill'] = isset($str->zerofill) ? $str->zerofill : '';
+            $fdesc[$temp[$x]['data']->name]['Check_time'] = isset($str->Check_time) ? $str->Check_time : '';
+            $fdesc[$temp[$x]['data']->name]['Checksum'] = isset($str->Checksum) ? $str->Checksum : '';
+            $fdesc[$temp[$x]['data']->name]['Engine'] = isset($str->Engine) ? $str->Engine : '';
+            if (isset($str->Comment) && 'VIEW' == substr($str->Comment, 0, 4)) {
+                $fdesc[$temp[$x]['data']->name]['Engine'] = 'View';
+            }
+            $fdesc[$temp[$x]['data']->name]['Version'] = isset($str->Version) ? $str->Version : '';
+
+            $tt = $lang['L_NAME'].': '.$fdesc[$temp[$x]['data']->name]['name'].' Type: '.$fdesc[$temp[$x]['data']->name]['type'].' Max Length: '.$fdesc[$temp[$x]['data']->name]['max_length'].' Unsigned: '.$fdesc[$temp[$x]['data']->name]['unsigned'].' zerofill: '.$fdesc[$temp[$x]['data']->name]['zerofill'];
+
+            $pic = '<img src="'.$icon['blank'].'" alt="" width="1" height="1" border="0">';
+            if ((isset($str->primary_key) && (1 == $str->primary_key)) || (isset($str->unique_key) && (1 == $str->unique_key))) {
+                if (-1 == $key) {
+                    $key = $temp[$x]['data']->name;
+                } else {
+                    $key .= '|'.$temp[$x]['data']->name;
+                }
+
+                if (1 == $str->primary_key) {
+                    $pic = $icon['key_primary'];
+                } elseif (1 == $str->unique_key) {
+                    $pic = $icon['index'];
+                }
+            }
+
+            // show sorting icon
+            $arname = ('ASC' == $orderdir) ? $icon['arrow_down'] : $icon['arrow_up'];
+            if ($str->name == $order) {
+                $t .= $arname;
+            }
+
+            if (-1 == $bb) {
+                $bb_link = ('blob' == $str->type) ? '&nbsp;&nbsp;&nbsp;<a style="font-size:10px;color:blue;" title="use BB-Code for this field" href="sql.php?db='.$db.'&amp;bb='.$x.'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;order='.$order.'&amp;orderdir='.$orderdir.'&amp;limitstart='.$limitstart.'&amp;sql_statement='.urlencode($sql['sql_statement']).'&amp;tdc='.$tdcompact.'">[BB]</a>' : '';
+            } else {
+                $bb_link = ('blob' == $str->type) ? '&nbsp;&nbsp;&nbsp;<a title="use BB-Code for this field" href="sql.php?db='.$db.'&amp;bb=-1&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;order='.urlencode($order).'&amp;orderdir='.$orderdir.'&amp;limitstart='.$limitstart.'&amp;sql_statement='.urlencode($sql['sql_statement']).'&amp;tdc='.$tdcompact.'">[no BB]</a>' : '';
+            }
+            if (false == $no_order && 0 == $showtables) {
+                $t .= $pic.'&nbsp;<a title="'.$tt.'" href="sql.php?db='.$db.'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;order='.urlencode($str->name).'&amp;orderdir='.$norder.'&amp;sql_statement='.urlencode($sql['sql_statement']).'&amp;tdc='.$tdcompact.'">'.$str->name.'</a>'.$bb_link;
+            } else {
+                $t .= $pic.'&nbsp;<span title="'.$tt.'" >'.$str->name.'</span>'.$bb_link;
+            }
+            $t .= '</th>';
+        }
+        unset($temp);
+
+        $temp = [];
+
+        //und jetzt Daten holen
+        mysqli_data_seek($res, 0);
+
+        $s = $keysort;
+        $s = array_flip($keysort);
+        ksort($s);
+        for ($i = 0; $i < $numrows; ++$i) {
+            $data[0] = mysqli_fetch_array($res, MYSQLI_ASSOC);
+            if (1 == $showtables && 1 == $tabellenansicht) {
+                // Spalten sortieren, wenn wir uns in einer Tabellenuebersicht befinden
+                $xx = mu_sort($data, "$s[0], $s[1], $s[2], $s[3], $s[4], $s[5], $s[6], $s[7], $s[8], $s[9], $s[10], $s[11], $s[12], $s[13], $s[14], $s[15], $s[16]");
+                $temp[$i] = $xx[0];
+
+                /***********************
+                Ergänzung www.betanet-web.ch - 30.04.2019
+                Anz. Einträge in der Tabelle wird in Ausgabe Array überschrieben, damit alle Daten exportiert werden.
+                ************************/
+
+                $tabellenname = $data[0]['Name'];
+                $numrows12 = 0;
+                $select12 = "select * from $tabellenname";
+                $res12 = mod_query($select12, false);
+                if (!empty($res12)) {
+                    $numrows12 = mysqli_num_rows($res12);
+                }
+
+                // Überschreiben mit neuem Wert
+                $temp[$i]['Rows'] = $numrows12;
+            } else {
+                $temp[$i] = $data[0];
+            }
+        }
+
+        $rownr = $limitstart + 1;
+        for ($i = 0; $i < $numrows; ++$i) {
+            $row = $temp[$i]; // mysqli_fetch_row($res);
+            $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+            $erste_spalte = 1;
+
+            // bei Tabellenuebersicht soll nach vorgefertigter Reihenfolge sortiert werden, ansonsten einfach Daten anzeigen
+            if (1 == $showtables) {
+                $sortkey = $keysort;
+            } else {
+                $sortkey = $row;
+            }
+            $spalte = 0;
+
+            // get primary key link for editing
+            if ($key > -1) {
+                $primary_key = '';
+                $keys = explode('|', $key);
+                foreach ($sortkey as $rowkey => $rowval) {
+                    if (in_array($rowkey, $keys)) {
+                        if (strlen($primary_key) > 0) {
+                            $primary_key .= ' AND ';
+                        }
+                        $primary_key .= '`'.urlencode($rowkey).'`=\''.urlencode($rowval).'\'';
+                    }
+                }
+                //echo "<br><br>Primaerschluessel erkannt: ".$primary_key;
+            }
+
+            foreach ($sortkey as $rowkey => $rowval) {
+                if (('Name' == $rowkey) && 1 == $tabellenansicht && isset($row['Name'])) {
+                    $tablename = $row['Name'];
+                }
+
+                if (1 == $erste_spalte) {
+                    //edit-pics
+                    $d .= $nl.'<td valign="top" nowrap="nowrap" class="small">&nbsp;'.$nl;
+                    $p = 'sql.php?sql_statement='.urlencode($sql['sql_statement']).'&amp;db='.$databases['db_actual'].'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;limitstart='.$limitstart.'&amp;order='.urlencode($order).'&amp;orderdir='.$orderdir.'&amp;tdc='.$tdcompact;
+                    if (-1 == $key) {
+                        $rk = build_where_from_record($temp[$i]);
+                        $p .= '&amp;recordkey='.urlencode($rk);
+                    } else {
+                        //Key vorhanden
+                        $p .= '&amp;recordkey='.urlencode($primary_key); //urlencode("`".$fdesc[$key]['name']."`='".$rowval."'");
+                    }
+                    if (1 == $showtables) {
+                        $p .= '&amp;recordkey='.urlencode($tablename);
+                    }
+                    if (!isset($no_edit) || !$no_edit) {
+                        if (0 == $showtables) {
+                            $d .= '<a href="'.$p.'&amp;mode=edit">'.$icon['edit'].'</a>&nbsp;';
+                        }
+                    }
+
+                    if (0 == $showtables && 0 == $tabellenansicht) {
+                        $d .= '<a href="'.$p.'&amp;mode=kill" onclick="if(!confirm(\''.$lang['L_ASKDELETERECORD'].'\')) return false;">'.$icon['delete'].'</a>';
+                    } else {
+                        if (1 == $tabellenansicht && 1 == $showtables) {
+                            $d .= '<a href="sql.php?db='.$db.'&amp;dbid='.$dbid.'&amp;tablename='.$tablename.'&amp;context=2">'.$icon['edit'].'</a>&nbsp;'.$nl.$nl;
+                            if (!(isset($row['Comment']) && ('VIEW' == substr(strtoupper($row['Comment']), 0, 4)))) {
+                                $d .= '<a href="'.$p.'&amp;mode=empty" onclick="if(!confirm(\''.sprintf($lang['L_ASKTABLEEMPTY'], $tablename).'\')) return false;">'.$icon['table_truncate'].'</a>&nbsp;'.$nl.$nl;
+                                $d .= '<a href="'.$p.'&amp;mode=emptyk" onclick="if(!confirm(\''.sprintf($lang['L_ASKTABLEEMPTYKEYS'], $tablename).'\')) return false;">'.$icon['table_truncate_reset'].'</a>&nbsp;'.$nl.$nl;
+                                $d .= '<a href="'.$p.'&amp;mode=kill" onclick="if(!confirm(\''.sprintf($lang['L_ASKDELETETABLE'], $tablename).'\')) return false;">'.$icon['delete'].'</a>&nbsp;'.$nl.$nl;
+                            } else {
+                                $d .= '<a href="'.$p.'&amp;mode=kill_view" onclick="if(!confirm(\''.sprintf($lang['L_ASKDELETETABLE'], $tablename).'\')) return false;">'.$icon['delete'].'</a>&nbsp;'.$nl.$nl;
+                            }
+                        }
+                    }
+                    $d .= '</td><td valign="top" class="small" style="text-align:right">'.$rownr.'.&nbsp;</td>';
+                    ++$rownr;
+                    $erste_spalte = 0;
+                }
+                $d .= '<td valign="top" class="small" nowrap="nowrap">';
+                $divstart = '<div'.((1 == $tdcompact) ? ' class="tdcompact" ' : ' class="tdnormal"').'>';
+                $divend = '</div>';
+                if ($bb == $spalte) {
+                    $data = convert_to_utf8(simple_bbcode_conversion($rowval));
+                } else {
+                    if (0 == $showtables) {
+                        if (isset($fdesc[$rowkey]['type'])) {
+                            $data = ('string' == $fdesc[$rowkey]['type'] || 'blob' == $fdesc[$rowkey]['type']) ? convert_to_utf8($rowval) : $rowval;
+                        }
+                    } else {
+                        if (isset($temp[$i][$rowkey])) {
+                            $data = ('string' == $fdesc[$rowkey]['type'] || 'blob' == $fdesc[$rowkey]['type']) ? convert_to_utf8($temp[$i][$rowkey]) : $temp[$i][$rowkey];
+                        } else {
+                            $data = '';
+                        }
+                        if (in_array($rowkey, $byte_output)) {
+                            $data = byte_output($data);
+                        }
+                    }
+                }
+                //v($fdesc[$rowkey]);
+                if (0 == $showtables) {
+                    if (is_null($rowval)) {
+                        $data = '<i>NULL</i>';
+                    } else {
+                        $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
+                    }
+                }
+                ++$spalte;
+                $browse_link = '<a href="sql.php?db='.$db.'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'" title="'.$data.'">';
+                $d .= (1 == $tabellenansicht && 'Name' == $rowkey) ? $divstart.$browse_link.$icon['browse'].'</a>&nbsp;'.$browse_link.$data."</a>$divend" : $divstart.$data.$divend;
+                $d .= '</td>';
+            }
+            // Tabellenueberschrift en ausgeben
+            if (0 == $i) {
+                echo '<tr>'.$t.'</tr>';
+            }
+            // Daten anzeigen
+            echo "\n\n".'<tr class="'.$cl.'">'.$d.'</tr>'."\n\n";
+            $d = '';
+        }
+    }
+    echo '</table>';
+
+    if (0 == $showtables) {
+        echo '<br>'.$command_line;
+    }
+} else {
+    echo '<p class="success">'.$lang['L_SQL_NODATA'].'</p>';
 }
-else
-	echo '<p class="success">' . $lang['L_SQL_NODATA'] . '</p>';
diff --git a/msd/inc/sqlbrowser/sql_record_insert_inputmask.php b/msd/inc/sqlbrowser/sql_record_insert_inputmask.php
index 454290ac..ac673c0c 100644
--- a/msd/inc/sqlbrowser/sql_record_insert_inputmask.php
+++ b/msd/inc/sqlbrowser/sql_record_insert_inputmask.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -17,42 +17,44 @@
    ---------------------------------------------------------------------- */
 
 // insert a new record
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => './tpl/sqlbrowser/sql_record_insert_inputmask.tpl'));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => './tpl/sqlbrowser/sql_record_insert_inputmask.tpl', ]);
 
-$sqledit="SHOW FIELDS FROM `$tablename`";
-$res=MSD_query($sqledit);
-$num=mysqli_num_rows($res);
+$sqledit = "SHOW FIELDS FROM `$tablename`";
+$res = mod_query($sqledit);
+if ($res) {
+    $num = mysqli_num_rows($res);
 
-$feldnamen="";
-for ($x=0; $x<$num; $x++)
-{
-	$row=mysqli_fetch_object($res);
-	$feldnamen.=$row->Field.'|';
-	$tpl->assign_block_vars('ROW',array(
-		'CLASS' => ($x%2) ? 1 : 2,
-		'FIELD_NAME' => $row->Field,
-		'FIELD_ID' => correct_post_index($row->Field)));
+    $feldnamen = '';
+    for ($x = 0; $x < $num; ++$x) {
+        $row = mysqli_fetch_object($res);
+        $feldnamen .= $row->Field.'|';
+        $tpl->assign_block_vars('ROW', [
+            'CLASS' => ($x % 2) ? 1 : 2,
+            'FIELD_NAME' => $row->Field,
+            'FIELD_ID' => correct_post_index($row->Field), ]);
 
-	$type=strtoupper($row->Type);
+        $type = strtoupper($row->Type);
 
-	if (strtoupper($row->Null)=='YES')
-	{
-		//field is nullable
-		$tpl->assign_block_vars('ROW.IS_NULLABLE',array());
-	}
+        if ('YES' == strtoupper($row->Null)) {
+            //field is nullable
+            $tpl->assign_block_vars('ROW.IS_NULLABLE', []);
+        }
 
-	if (in_array($type,array(
-		'BLOB',
-		'TEXT'))) $tpl->assign_block_vars('ROW.IS_TEXTAREA',array());
-	else
-		$tpl->assign_block_vars('ROW.IS_TEXTINPUT',array());
+        if (in_array($type, [
+            'BLOB',
+            'TEXT', ])) {
+            $tpl->assign_block_vars('ROW.IS_TEXTAREA', []);
+        } else {
+            $tpl->assign_block_vars('ROW.IS_TEXTINPUT', []);
+        }
+    }
 }
 
-$tpl->assign_vars(array(
-	'HIDDEN_FIELDS' => FormHiddenParams(),
-	'FIELDNAMES' => substr($feldnamen,0,strlen($feldnamen)-1),
-	'SQL_STATEMENT' => my_quotes($sql['sql_statement'])));
+$tpl->assign_vars([
+    'HIDDEN_FIELDS' => FormHiddenParams(),
+    'FIELDNAMES' => substr($feldnamen, 0, strlen($feldnamen) - 1),
+    'SQL_STATEMENT' => my_quotes($sql['sql_statement']), ]);
 
 $tpl->pparse('show');
diff --git a/msd/inc/sqlbrowser/sql_record_update_inputmask.php b/msd/inc/sqlbrowser/sql_record_update_inputmask.php
index cf4f07d8..782b781f 100644
--- a/msd/inc/sqlbrowser/sql_record_update_inputmask.php
+++ b/msd/inc/sqlbrowser/sql_record_update_inputmask.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,53 +16,51 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
 // Edit record -> built Edit-Form
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => './tpl/sqlbrowser/sql_record_update_inputmask.tpl'));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => './tpl/sqlbrowser/sql_record_update_inputmask.tpl', ]);
 
-$target=($mode=="searchedit") ? '?mode=searchedit' : '?mode=update'; // jump back to search hit list after saving
-$fields=getExtendedFieldInfo($db,$tablename);
-
-$sqledit="SELECT * FROM `$tablename` WHERE ".$recordkey;
-$res=MSD_query($sqledit);
-$record=mysqli_fetch_array($res,MYSQLI_ASSOC); // get the record
-$num=sizeof($record); // get the nr of fields of the record
+$target = ('searchedit' == $mode) ? '?mode=searchedit' : '?mode=update'; // jump back to search hit list after saving
+$fields = getExtendedFieldInfo($db, $tablename);
 
+$sqledit = "SELECT * FROM `$tablename` WHERE ".$recordkey;
+$res = mod_query($sqledit);
+$record = mysqli_fetch_array($res, MYSQLI_ASSOC); // get the record
+$num = sizeof($record); // get the nr of fields of the record
 
 // iterate fields
-$x=0;
-$fieldnames='';
-foreach ($record as $field=>$fieldvalue)
-{
-	$fieldnames.=$field.'|';
-	$tpl->assign_block_vars('ROW',array(
-		'CLASS' => ($x%2) ? 1 : 2,
-		'FIELD_NAME' => $field,
-		'FIELD_VALUE' => my_quotes($fieldvalue),
-		'FIELD_ID' => correct_post_index($field)));
+$x = 0;
+$fieldnames = '';
+foreach ($record as $field => $fieldvalue) {
+    $fieldnames .= $field.'|';
+    $tpl->assign_block_vars('ROW', [
+        'CLASS' => ($x % 2) ? 1 : 2,
+        'FIELD_NAME' => $field,
+        'FIELD_VALUE' => my_quotes($fieldvalue),
+        'FIELD_ID' => correct_post_index($field), ]);
 
-	if ('YES'==$fields[$field]['null'])
-	{
-		//field is nullable - precheck checkbox if value is null
-		$tpl->assign_block_vars('ROW.IS_NULLABLE',array(
-			'NULL_CHECKED' => is_null($fieldvalue) ? ' checked="checked"' : ''));
-	}
+    if ('YES' == $fields[$field]['null']) {
+        //field is nullable - precheck checkbox if value is null
+        $tpl->assign_block_vars('ROW.IS_NULLABLE', [
+            'NULL_CHECKED' => is_null($fieldvalue) ? ' checked="checked"' : '', ]);
+    }
 
-	$type=strtoupper($fields[$field]['type']);
-	if (in_array($type,array(
-		'BLOB',
-		'TEXT'))) $tpl->assign_block_vars('ROW.IS_TEXTAREA',array());
-	else
-		$tpl->assign_block_vars('ROW.IS_TEXTINPUT',array());
-	$x++;
+    $type = strtoupper($fields[$field]['type']);
+    if (in_array($type, [
+        'BLOB',
+        'TEXT', ])) {
+        $tpl->assign_block_vars('ROW.IS_TEXTAREA', []);
+    } else {
+        $tpl->assign_block_vars('ROW.IS_TEXTINPUT', []);
+    }
+    ++$x;
 }
-$tpl->assign_vars(array(
-	'HIDDEN_FIELDS' => FormHiddenParams(),
-	'FIELDNAMES' => substr($fieldnames,0,strlen($fieldnames)-1),
-	'SQL_STATEMENT' => my_quotes($sql['sql_statement']),
-	'RECORDKEY' => my_quotes($recordkey),
-	'TARGET' => $target));
+$tpl->assign_vars([
+    'HIDDEN_FIELDS' => FormHiddenParams(),
+    'FIELDNAMES' => substr($fieldnames, 0, strlen($fieldnames) - 1),
+    'SQL_STATEMENT' => my_quotes($sql['sql_statement']),
+    'RECORDKEY' => my_quotes($recordkey),
+    'TARGET' => $target, ]);
 
 $tpl->pparse('show');
diff --git a/msd/inc/sqlbrowser/sql_tables.php b/msd/inc/sqlbrowser/sql_tables.php
index 9a84adc8..01983bbd 100644
--- a/msd/inc/sqlbrowser/sql_tables.php
+++ b/msd/inc/sqlbrowser/sql_tables.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,520 +16,495 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 //Tabellen
 echo $aus.'<h6>'.$lang['L_SQL_TABLESOFDB'].' `'.$databases['Name'][$dbid].'` '.$lang['L_SQL_EDIT'].'</h6>';
 
 //Primaerschluessel loeschen
-if (isset($_GET['killPrimaryKey']))
-{
-	$keys=getPrimaryKeys($databases['Name'][$dbid],$_GET['tablename']);
-	//Zu loeschenden Schluessel aus dem Array entfernen
-	$keyPos=array_search($_GET['killPrimaryKey'],$keys['name']);
-	if (!(false===$keyPos))
-	{
-		unset($keys['name'][$keyPos]);
-		unset($keys['size'][$keyPos]);
-		$keys['name']=array_values($keys['name']);
-		$keys['size']=array_values($keys['size']);
-		$res=setNewPrimaryKeys($databases['Name'][$dbid], $_GET['tablename'], $keys['name'], $keys['size']);
-		if ($res)
-		{
-			echo '<script language="JavaScript">
+if (isset($_GET['killPrimaryKey'])) {
+    $keys = getPrimaryKeys($databases['Name'][$dbid], $_GET['tablename']);
+    //Zu loeschenden Schluessel aus dem Array entfernen
+    $keyPos = array_search($_GET['killPrimaryKey'], $keys['name']);
+    if (!(false === $keyPos)) {
+        unset($keys['name'][$keyPos]);
+        unset($keys['size'][$keyPos]);
+        $keys['name'] = array_values($keys['name']);
+        $keys['size'] = array_values($keys['size']);
+        $res = setNewPrimaryKeys($databases['Name'][$dbid], $_GET['tablename'], $keys['name'], $keys['size']);
+        if ($res) {
+            echo '<script>
 						alert("'.$lang['L_PRIMARYKEY_DELETED'].': '.$_GET['killPrimaryKey'].'");
 					</script>';
-		}
-		else
-		{
-			echo '<script language="JavaScript">
+        } else {
+            echo '<script>
 						alert("'.$lang['L_PRIMARYKEYS_CHANGINGERROR'].': '.$_GET['killPrimaryKey'].'");
 					</script>';
-		}
-	}
-	else
-	{
-		echo '<script language="JavaScript">
+        }
+    } else {
+        echo '<script>
 					alert("'.$lang['L_PRIMARYKEY_NOTFOUND'].': '.$_GET['killPrimaryKey'].'");
 				</script>';
-	}
+    }
 }
 //Primärschlüssel löschen ende
 
-
 //Neue Schlüssel setzen
-if (isset($_POST['setNewKeys']))
-{
-	$fields=getAllFields($databases['Name'][$dbid],$_GET['tablename']);
-	$newKeysArray=Array();
-	$newKeySizesArray=Array();
-	foreach ($fields as $index=>$field)
-	{
-		if ((isset($_POST["setNewKey".$index]))&&($_POST["setNewKey".$index]!=""))
-		{
-			$newKeysArray[]=$_POST["setNewKey".$index];
-			$newKeySizesArray[]=isset($_POST["indexSize".$index]) ? (int) $_POST["indexSize".$index]:'';
-		}
-	}
-	//doppelte Elemente entfernen
-	$newKeysArray=array_unique($newKeysArray);
-	$newKeySizesArray=array_intersect_key($newKeySizesArray, $newKeysArray);
+if (isset($_POST['setNewKeys'])) {
+    $fields = getAllFields($databases['Name'][$dbid], $_GET['tablename']);
+    $newKeysArray = [];
+    $newKeySizesArray = [];
+    foreach ($fields as $index => $field) {
+        if ((isset($_POST['setNewKey'.$index])) && ('' != $_POST['setNewKey'.$index])) {
+            $newKeysArray[] = $_POST['setNewKey'.$index];
+            $newKeySizesArray[] = isset($_POST['indexSize'.$index]) ? (int) $_POST['indexSize'.$index] : '';
+        }
+    }
+    //doppelte Elemente entfernen
+    $newKeysArray = array_unique($newKeysArray);
+    $newKeySizesArray = array_intersect_key($newKeySizesArray, $newKeysArray);
 
-	if ($_POST["indexType"]=="primary")
-	{
-		$res=setNewPrimaryKeys($databases['Name'][$dbid], $_GET['tablename'], $newKeysArray, $newKeySizesArray);
-		if ($res)
-		{
-			echo '<script language="JavaScript">
+    if ('primary' == $_POST['indexType']) {
+        $res = setNewPrimaryKeys($databases['Name'][$dbid], $_GET['tablename'], $newKeysArray, $newKeySizesArray);
+        if ($res) {
+            echo '<script>
 						alert("'.$lang['L_PRIMARYKEYS_CHANGED'].'");
 					</script>';
-		}
-		else
-		{
-			echo '<script language="JavaScript">
+        } else {
+            echo '<script>
 						alert("'.$lang['L_PRIMARYKEYS_CHANGINGERROR'].'");
 					</script>';
-		}
-	}
-	else
-	{
-		if ($_POST["indexType"]=="unique")
-		{
-			$newIndexType="UNIQUE";
-		}
-		elseif ($_POST["indexType"]=="fulltext")
-		{
-			$newIndexType="FULLTEXT";
-		}
-		else
-		{
-			$newIndexType="INDEX";
-		}
+        }
+    } else {
+        if ('unique' == $_POST['indexType']) {
+            $newIndexType = 'UNIQUE';
+        } elseif ('fulltext' == $_POST['indexType']) {
+            $newIndexType = 'FULLTEXT';
+        } else {
+            $newIndexType = 'INDEX';
+        }
 
-		$res=setNewKeys($databases['Name'][$dbid], $_GET['tablename'], $newKeysArray, $newIndexType, $_POST['indexName'], $newKeySizesArray);
-		if ($res)
-		{
-			echo '<script language="JavaScript">
+        $res = setNewKeys($databases['Name'][$dbid], $_GET['tablename'], $newKeysArray, $newIndexType, $_POST['indexName'], $newKeySizesArray);
+        if ($res) {
+            echo '<script>
 						alert("'.$lang['L_KEY_ADDED'].'");
 					</script>';
-		}
-		else
-		{
-			echo '<script language="JavaScript">
+        } else {
+            echo '<script>
 						alert("'.$lang['L_KEY_ADDERROR'].'");
 					</script>';
-		}
-	}
+        }
+    }
 }
 
 //Andere Indizes löschen
-if (isset($_GET['killIndex']))
-{
-	$res = killKey($databases['Name'][$dbid], $_GET['tablename'], $_GET['killIndex']);
-	if ($res)
-	{
-		echo '<script language="JavaScript">
+if (isset($_GET['killIndex'])) {
+    $res = killKey($databases['Name'][$dbid], $_GET['tablename'], $_GET['killIndex']);
+    if ($res) {
+        echo '<script>
 					alert("'.$lang['L_KEY_DELETED'].': '.$_GET['killIndex'].'");
 				</script>';
-	}
-	else
-	{
-		echo '<script language="JavaScript">
+    } else {
+        echo '<script>
 					alert("'.$lang['L_KEY_DELETEERROR'].': '.$_GET['killIndex'].'");
 				</script>';
-	}
+    }
 }
 
-if (isset($_GET['kill']))
-{
-	if ($_GET['anz']==1) echo '<p class="error">'.$lang['L_SQL_NOFIELDDELETE'].'</p>';
-	else
-	{
-		$sql_alter="ALTER TABLE `".$databases['Name'][$dbid]."`.`".$_GET['tablename']."` DROP COLUMN `".$_GET['kill']."`";
-		$res = MSD_DoSQL($sql_alter);
-		if ($res)
-		{
-			echo '<div align="left" id="sqleditbox" style="font-size: 11px;width:90%;padding=6px;">';
-			echo '<p class="success">'.$lang['L_SQL_FIELDDELETE1'].' `'.$_GET['kill'].'` '.$lang['L_SQL_DELETED'].'.</p>'.highlight_sql($out).'</div>';
-		}
-	}
+if (isset($_GET['kill'])) {
+    if (1 == $_GET['anz']) {
+        echo '<p class="error">'.$lang['L_SQL_NOFIELDDELETE'].'</p>';
+    } else {
+        $sql_alter = 'ALTER TABLE `'.$databases['Name'][$dbid].'`.`'.$_GET['tablename'].'` DROP COLUMN `'.$_GET['kill'].'`';
+        $res = MOD_DoSQL($sql_alter);
+        if ($res) {
+            echo '<div align="left" id="sqleditbox" style="font-size: 11px;width:90%;padding=6px;">';
+            echo '<p class="success">'.$lang['L_SQL_FIELDDELETE1'].' `'.$_GET['kill'].'` '.$lang['L_SQL_DELETED'].'.</p>'.highlight_sql($out).'</div>';
+        }
+    }
 }
-if (isset($_POST['tablecopysubmit']))
-{
-	$table_edit_name=$_GET['tablename'];
-	if ($_POST['tablecopyname']=="")
-	{
-		echo '<p class="error">'.$lang['L_SQL_NODEST_COPY'].'</p>';
-	}
-	elseif (Table_Exists($databases['Name'][$dbid],$_POST['tablecopyname']))
-	{
-		echo '<p class="error">'.$lang['L_SQL_DESTTABLE_EXISTS'].'</p>';
-	}
-	else
-	{
-		Table_Copy("`".$databases['Name'][$dbid]."`.`".$table_edit_name."`",$_POST['tablecopyname'],$_POST['copyatt']);
-		echo '<div align="left" id="sqleditbox">';
-        echo ($_POST['copyatt']==0) ? '<p class="success">'.sprintf($lang['L_SQL_SCOPY'],$table_edit_name,$_POST['tablecopyname']).'</p>' : sprintf($lang['L_SQL_TCOPY'],$table_edit_name,$_POST['tablecopyname']).'</p>';		echo highlight_sql($out).'</div>';
-		$tablename=$_POST['tablecopyname'];
-	}
+if (isset($_POST['tablecopysubmit'])) {
+    $table_edit_name = $_GET['tablename'];
+    if ('' == $_POST['tablecopyname']) {
+        echo '<p class="error">'.$lang['L_SQL_NODEST_COPY'].'</p>';
+    } elseif (Table_Exists($databases['Name'][$dbid], $_POST['tablecopyname'])) {
+        echo '<p class="error">'.$lang['L_SQL_DESTTABLE_EXISTS'].'</p>';
+    } else {
+        Table_Copy('`'.$databases['Name'][$dbid].'`.`'.$table_edit_name.'`', $_POST['tablecopyname'], $_POST['copyatt']);
+        echo '<div align="left" id="sqleditbox">';
+        echo (0 == $_POST['copyatt']) ? '<p class="success">'.sprintf($lang['L_SQL_SCOPY'], $table_edit_name, $_POST['tablecopyname']).'</p>' : sprintf($lang['L_SQL_TCOPY'], $table_edit_name, $_POST['tablecopyname']).'</p>';
+        echo highlight_sql($out).'</div>';
+        $tablename = $_POST['tablecopyname'];
+    }
 }
-if (isset($_POST['newtablesubmit']))
-{
-	if ($_POST['newtablename']=="")
-	{
-		echo '<p class="error">'.$lang['L_SQL_TABLENONAME'].'</p>';
-	}
-	else
-	{
-		$sql_alter="CREATE TABLE `".$databases['Name'][$dbid]."`.`".$_POST['newtablename']."` (`id` int(11) unsigned not null AUTO_INCREMENT PRIMARY KEY ) ".((MSD_NEW_VERSION) ? "ENGINE" : "TYPE")."=MyISAM;";
-		$res = MSD_DoSQL($sql_alter);
-		if ($res)
-		{
-			echo SQLOutput($out,$lang['L_TABLE'].' `'.$_POST['newtablename'].'` '.$lang['L_SQL_CREATED']);
-		}
-	}
+if (isset($_POST['newtablesubmit'])) {
+    if ('' == $_POST['newtablename']) {
+        echo '<p class="error">'.$lang['L_SQL_TABLENONAME'].'</p>';
+    } else {
+        $sql_alter = 'CREATE TABLE `'.$databases['Name'][$dbid].'`.`'.$_POST['newtablename'].'` (`id` int(11) unsigned not null AUTO_INCREMENT PRIMARY KEY ) '.((MOD_NEW_VERSION) ? 'ENGINE' : 'TYPE').'=MyISAM;';
+        $res = MOD_DoSQL($sql_alter);
+        if ($res) {
+            echo SQLOutput($out, $lang['L_TABLE'].' `'.$_POST['newtablename'].'` '.$lang['L_SQL_CREATED']);
+        }
+    }
 }
-if (isset($_POST['t_edit_submit']))
-{
-	$sql_alter="ALTER TABLE `".$databases['Name'][$dbid]."`.`".$_POST['table_edit_name']."` ";
-	if ($_POST['t_edit_name']=="") echo '<p class="error">'.$lang['L_SQL_TBLNAMEEMPTY'].'</p>';
-	elseif (MSD_NEW_VERSION&&$_POST['t_edit_collate']!=""&&substr($_POST['t_edit_collate'],0,strlen($_POST['t_edit_charset']))!=$_POST['t_edit_charset']) echo '<p class="error">'.$lang['L_SQL_COLLATENOTMATCH'].'</p>';
-	else
-	{
-		if ($_POST['table_edit_name']!=$_POST['t_edit_name'])
-		{
-			$sql_alter.="RENAME TO `".$_POST['t_edit_name']."`, ";
-			$table_edit_name=$_POST['t_edit_name'];
-		}
-		else
-			$table_edit_name=$_POST['table_edit_name'];
-		if ($_POST['t_edit_engine']!="") $sql_alter.=((MSD_NEW_VERSION) ? "ENGINE=" : "TYPE=").$_POST['t_edit_engine'].", ";
-		if ($_POST['t_edit_rowformat']!="") $sql_alter.="ROW_FORMAT=".$_POST['t_edit_rowformat'].", ";
-		if (MSD_NEW_VERSION&&$_POST['t_edit_charset']!="") $sql_alter.="DEFAULT CHARSET=".$_POST['t_edit_charset'].", ";
-		if (MSD_NEW_VERSION&&$_POST['t_edit_collate']!="") $sql_alter.="COLLATE ".$_POST['t_edit_collate'].", ";
-		$sql_alter.="COMMENT='".$_POST['t_edit_comment']."' ";
+if (isset($_POST['t_edit_submit'])) {
+    $sql_alter = 'ALTER TABLE `'.$databases['Name'][$dbid].'`.`'.$_POST['table_edit_name'].'` ';
+    if ('' == $_POST['t_edit_name']) {
+        echo '<p class="error">'.$lang['L_SQL_TBLNAMEEMPTY'].'</p>';
+    } elseif (MOD_NEW_VERSION && '' != $_POST['t_edit_collate'] && substr($_POST['t_edit_collate'], 0, strlen($_POST['t_edit_charset'])) != $_POST['t_edit_charset']) {
+        echo '<p class="error">'.$lang['L_SQL_COLLATENOTMATCH'].'</p>';
+    } else {
+        if ($_POST['table_edit_name'] != $_POST['t_edit_name']) {
+            $sql_alter .= 'RENAME TO `'.$_POST['t_edit_name'].'`, ';
+            $table_edit_name = $_POST['t_edit_name'];
+        } else {
+            $table_edit_name = $_POST['table_edit_name'];
+        }
+        if ('' != $_POST['t_edit_engine']) {
+            $sql_alter .= ((MOD_NEW_VERSION) ? 'ENGINE=' : 'TYPE=').$_POST['t_edit_engine'].', ';
+        }
+        if ('' != $_POST['t_edit_rowformat']) {
+            $sql_alter .= 'ROW_FORMAT='.$_POST['t_edit_rowformat'].', ';
+        }
+        if (MOD_NEW_VERSION && '' != $_POST['t_edit_charset']) {
+            $sql_alter .= 'DEFAULT CHARSET='.$_POST['t_edit_charset'].', ';
+        }
+        if (MOD_NEW_VERSION && '' != $_POST['t_edit_collate']) {
+            $sql_alter .= 'COLLATE '.$_POST['t_edit_collate'].', ';
+        }
+        $sql_alter .= "COMMENT='".$_POST['t_edit_comment']."' ";
 
-		$res = MSD_DoSQL($sql_alter);
-		if ($res)
-		{
-			echo SQLOutput($out,$lang['L_TABLE'].' `'.$_POST['table_edit_name'].'` '.$lang['L_SQL_CHANGED']);
-		}
-	}
+        $res = MOD_DoSQL($sql_alter);
+        if ($res) {
+            echo SQLOutput($out, $lang['L_TABLE'].' `'.$_POST['table_edit_name'].'` '.$lang['L_SQL_CHANGED']);
+        }
+    }
+} else {
+    if (!isset($table_edit_name) || '' == $table_edit_name) {
+        $table_edit_name = (isset($_GET['tablename'])) ? $_GET['tablename'] : '';
+        if (isset($_POST['tableselect'])) {
+            $table_edit_name = $_POST['tableselect'];
+        }
+        if (isset($_POST['newtablesubmit'])) {
+            $table_edit_name = $_POST['newtablename'];
+        }
+    }
 }
-else
-{
-	if (!isset($table_edit_name)||$table_edit_name=="")
-	{
-		$table_edit_name=(isset($_GET['tablename'])) ? $_GET['tablename'] : "";
-		if (isset($_POST['tableselect'])) $table_edit_name=$_POST['tableselect'];
-		if (isset($_POST['newtablesubmit'])) $table_edit_name=$_POST['newtablename'];
-	}
-}
-if (isset($_POST['newfield_posted']))
-{
-	//build sql for alter
-	if ($_POST['f_name']=='')
-	{
-		echo '<p class="error">'.$lang['L_SQL_FIELDNAMENOTVALID'].' ('.$_POST['f_name'].')</p>';
-		$field_fehler=1;
-	}
-	else
-	{
-		//alter Key
-		$oldkeys[0]=$_POST['f_primary'];
-		$oldkeys[1]=$_POST['f_unique'];
-		$oldkeys[2]=$_POST['f_index'];
-		$oldkeys[3]=$_POST['f_fulltext'];
-		//neuer Key
-		$newkeys[0]=($_POST['f_index_new']=="primary") ? 1 : 0;
-		$newkeys[1]=($_POST['f_index_new']=="unique") ? 1 : 0;
-		$newkeys[2]=($_POST['f_index_new']=="index") ? 1 : 0;
-		$newkeys[3]=(isset($_POST['f_indexfull'])) ? 1 : 0;
+if (isset($_POST['newfield_posted'])) {
+    //build sql for alter
+    if ('' == $_POST['f_name']) {
+        echo '<p class="error">'.$lang['L_SQL_FIELDNAMENOTVALID'].' ('.$_POST['f_name'].')</p>';
+        $field_fehler = 1;
+    } else {
+        //alter Key
+        $oldkeys[0] = $_POST['f_primary'];
+        $oldkeys[1] = $_POST['f_unique'];
+        $oldkeys[2] = $_POST['f_index'];
+        $oldkeys[3] = $_POST['f_fulltext'];
+        //neuer Key
+        $newkeys[0] = ('primary' == $_POST['f_index_new']) ? 1 : 0;
+        $newkeys[1] = ('unique' == $_POST['f_index_new']) ? 1 : 0;
+        $newkeys[2] = ('index' == $_POST['f_index_new']) ? 1 : 0;
+        $newkeys[3] = (isset($_POST['f_indexfull'])) ? 1 : 0;
 
-		$add_sql.=ChangeKeys($oldkeys,$newkeys,$_POST['f_name'],$_POST['f_size'],"drop_only");
+        $add_sql .= ChangeKeys($oldkeys, $newkeys, $_POST['f_name'], $_POST['f_size'], 'drop_only');
 
-		$sql_stamm="ALTER TABLE `".$databases['Name'][$dbid]."`.`$table_edit_name` ";
-		$sql_alter=$sql_stamm.((isset($_POST['editfield'])) ? "CHANGE COLUMN `".$_POST['fieldname']."` `".$_POST['f_name']."` " : "ADD COLUMN `".$_POST['f_name']."` ");
-		$sql_alter.=$_POST['f_type'];
-		$wl=stripslashes($_POST['f_size']);
-		if ($wl!=""&&!preg_match('@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT)$@i',$_POST['f_type']))
-		{
-			$sql_alter.="($wl) ";
-		}
-		elseif ($_POST['f_size']==""&&preg_match('@^(VARCHAR)$@i',$_POST['f_type']))
-		{
-			$sql_alter.="("."255".") ";
-		}
-		else
-			$sql_alter.=" ";
-		$sql_alter.=$_POST['f_attribut']." ";
-		$sql_alter.=$_POST['f_null']." ";
-		$sql_alter.=($_POST['f_default']!="") ? "DEFAULT '".addslashes($_POST['f_default'])."' " : "";
+        $sql_stamm = 'ALTER TABLE `'.$databases['Name'][$dbid]."`.`$table_edit_name` ";
+        $sql_alter = $sql_stamm.((isset($_POST['editfield'])) ? 'CHANGE COLUMN `'.$_POST['fieldname'].'` `'.$_POST['f_name'].'` ' : 'ADD COLUMN `'.$_POST['f_name'].'` ');
+        $sql_alter .= $_POST['f_type'];
+        $wl = stripslashes($_POST['f_size']);
+        if ('' != $wl && !preg_match('@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT)$@i', $_POST['f_type'])) {
+            $sql_alter .= "($wl) ";
+        } elseif ('' == $_POST['f_size'] && preg_match('@^(VARCHAR)$@i', $_POST['f_type'])) {
+            $sql_alter .= '('.'255'.') ';
+        } else {
+            $sql_alter .= ' ';
+        }
+        $sql_alter .= $_POST['f_attribut'].' ';
+        $sql_alter .= $_POST['f_null'].' ';
+        $sql_alter .= ('' != $_POST['f_default']) ? "DEFAULT '".addslashes($_POST['f_default'])."' " : '';
 
-		if (MSD_NEW_VERSION&&$_POST['f_collate']!="") $sql_alter.="COLLATE ".$_POST['f_collate']." ";
+        if (MOD_NEW_VERSION && '' != $_POST['f_collate']) {
+            $sql_alter .= 'COLLATE '.$_POST['f_collate'].' ';
+        }
 
-		if ($_POST['f_extra']=="AUTO_INCREMENT")
-		{
-			$sql_alter.=" AUTO_INCREMENT ";
-		}
-		$sql_alter.=$_POST['f_position'];
+        if ('AUTO_INCREMENT' == $_POST['f_extra']) {
+            $sql_alter .= ' AUTO_INCREMENT ';
+        }
+        $sql_alter .= $_POST['f_position'];
 
-		if ($newkeys[0]==1) $sql_alter.=", ADD PRIMARY KEY (`".$_POST['f_name']."`)";
-		if ($newkeys[1]==1) $sql_alter.=", ADD UNIQUE (`".$_POST['f_name']."`)";
-		if ($newkeys[2]==1) $sql_alter.=", ADD INDEX (`".$_POST['f_name']."`)";
-		if ($newkeys[3]==1) $sql_alter.=", ADD FULLTEXT INDEX (`".$_POST['f_name']."`)";
+        if (1 == $newkeys[0]) {
+            $sql_alter .= ', ADD PRIMARY KEY (`'.$_POST['f_name'].'`)';
+        }
+        if (1 == $newkeys[1]) {
+            $sql_alter .= ', ADD UNIQUE (`'.$_POST['f_name'].'`)';
+        }
+        if (1 == $newkeys[2]) {
+            $sql_alter .= ', ADD INDEX (`'.$_POST['f_name'].'`)';
+        }
+        if (1 == $newkeys[3]) {
+            $sql_alter .= ', ADD FULLTEXT INDEX (`'.$_POST['f_name'].'`)';
+        }
 
-		$sql_alter.=";";
+        $sql_alter .= ';';
 
-		if ($add_sql!="")
-		{
-			$add_sql=$sql_stamm.$add_sql;
-			$sql_alter="$sql_alter\n$add_sql;";
-		}
-		$res = MSD_DoSQL($sql_alter);
-		if ($res)
-		{
-			echo '<div align="left" id="sqleditbox" style="font-size: 11px;width:90%;padding=6px;">';
-			echo '<p class="success"> `'.$_POST['f_name'].'` '.((isset($_POST['editfield'])) ? $lang['L_SQL_CHANGED'] : $lang['L_SQL_CREATED']).'</p>';
-			echo highlight_sql($out).'</div>';
-		}
-		$fields_infos=getFieldinfos($databases['Name'][$dbid],$table_edit_name);
-	}
+        if ('' != $add_sql) {
+            $add_sql = $sql_stamm.$add_sql;
+            $sql_alter = "$sql_alter\n$add_sql;";
+        }
+        $res = MOD_DoSQL($sql_alter);
+        if ($res) {
+            echo '<div align="left" id="sqleditbox" style="font-size: 11px;width:90%;padding=6px;">';
+            echo '<p class="success"> `'.$_POST['f_name'].'` '.((isset($_POST['editfield'])) ? $lang['L_SQL_CHANGED'] : $lang['L_SQL_CREATED']).'</p>';
+            echo highlight_sql($out).'</div>';
+        }
+        $fields_infos = getFieldinfos($databases['Name'][$dbid], $table_edit_name);
+    }
 }
 mysqli_select_db($config['dbconnection'], $databases['Name'][$dbid]);
-$sqlt="SHOW TABLE STATUS FROM `".$databases['Name'][$dbid]."` ;";
-$res=MSD_query($sqlt);
-$anz_tabellen=mysqli_num_rows($res);
-$p="sql.php?db=".$databases['Name'][$dbid]."&amp;dbid=$dbid&amp;tablename=$table_edit_name&amp;context=2";
+$sqlt = 'SHOW TABLE STATUS FROM `'.$databases['Name'][$dbid].'` ;';
+$res = mod_query($sqlt);
+$anz_tabellen = mysqli_num_rows($res);
+$p = 'sql.php?db='.$databases['Name'][$dbid]."&amp;dbid= $dbid&amp;tablename= $table_edit_name&amp;context=2";
 
 echo '<form action="sql.php?db='.$databases['Name'][$dbid].'&amp;dbid='.$dbid.'&amp;tablename='.$table_edit_name.'&amp;context=2" method="post">';
 echo '<table class="bdr"><tr class="dbrow"><td>'.$lang['L_SQL_CREATETABLE'].': </td><td colspan="2"><input type="text" class="text" name="newtablename" size="30" maxlength="150"></td><td><input type="submit" name="newtablesubmit" value="'.$lang['L_SQL_CREATETABLE'].'" class="Formbutton"></td></tr>';
-echo '<tr class="dbrow1"><td>'.$lang['L_SQL_COPYTABLE'].': </td><td><input type="text" class="text" name="tablecopyname" size="20" maxlength="150"></td><td><select name="copyatt"><option value="0">'.$lang['L_SQL_STRUCTUREONLY'].'</option>'.((MSD_NEW_VERSION) ? '<option value="1">'.$lang['L_SQL_STRUCTUREDATA'].'</option>' : '').'</select></td><td><input type="submit" class="Formbutton" name="tablecopysubmit" value="'.$lang['L_SQL_COPYTABLE'].'" '.(($table_edit_name=="") ? "disabled=\"disabled\"" : "").'></td></tr>';
+echo '<tr class="dbrow1"><td>'.$lang['L_SQL_COPYTABLE'].': </td><td><input type="text" class="text" name="tablecopyname" size="20" maxlength="150"></td><td><select name="copyatt"><option value="0">'.$lang['L_SQL_STRUCTUREONLY'].'</option>'.((MOD_NEW_VERSION) ? '<option value="1">'.$lang['L_SQL_STRUCTUREDATA'].'</option>' : '').'</select></td><td><input type="submit" class="Formbutton" name="tablecopysubmit" value="'.$lang['L_SQL_COPYTABLE'].'" '.(('' == $table_edit_name) ? 'disabled="disabled"' : '').'></td></tr>';
 
-if ($anz_tabellen==0)
-{
-	echo '<tr><td>'.$lang['L_SQL_NOTABLESINDB'].' `'.$databases['Name'][$dbid].'`</td></tr>';
-}
-else
-{
-
-	echo '<tr><td>'.$lang['L_SQL_SELECTTABLE'].':&nbsp;&nbsp;&nbsp;</td>';
-	echo '<td colspan="2"><select name="tableselect" onchange="this.form.submit()"><option value="1" SELECTED></option>';
-	for ($i=0; $i<$anz_tabellen; $i++)
-	{
-		$row=mysqli_fetch_array($res);
-		echo '<option value="'.$row['Name'].'">'.$row['Name'].'</option>';
-	}
-	echo '</select>&nbsp;&nbsp;</td>';
-	echo '<td><input type="button" class="Formbutton" value="'.$lang['L_SQL_SHOWDATATABLE'].'" onclick="location.href=\'sql.php?db='.$databases['Name'][$dbid].'&amp;dbid='.$dbid.'&amp;tablename='.$tablename.'\'"></td></tr>';
+if (0 == $anz_tabellen) {
+    echo '<tr><td>'.$lang['L_SQL_NOTABLESINDB'].' `'.$databases['Name'][$dbid].'`</td></tr>';
+} else {
+    echo '<tr><td>'.$lang['L_SQL_SELECTTABLE'].':&nbsp;&nbsp;&nbsp;</td>';
+    echo '<td colspan="2"><select name="tableselect" onchange="this.form.submit()"><option value="1" SELECTED></option>';
+    for ($i = 0; $i < $anz_tabellen; ++$i) {
+        $row = mysqli_fetch_array($res);
+        echo '<option value="'.$row['Name'].'">'.$row['Name'].'</option>';
+    }
+    echo '</select>&nbsp;&nbsp;</td>';
+    echo '<td><input type="button" class="Formbutton" value="'.$lang['L_SQL_SHOWDATATABLE'].'" onclick="location.href=\'sql.php?db='.$databases['Name'][$dbid].'&amp;dbid='.$dbid.'&amp;tablename='.$tablename.'\'"></td></tr>';
 }
 echo '</table></form><p>&nbsp;</p>';
-if ($table_edit_name!="")
-{
-	$sqlf="SHOW FULL FIELDS FROM `".$databases['Name'][$dbid]."`.`$table_edit_name` ;";
-	$res=MSD_query($sqlf);
-	$anz_fields=mysqli_num_rows($res);
-	$fields_infos=getFieldinfos($databases['Name'][$dbid],$table_edit_name);
+if ('' != $table_edit_name) {
+    $sqlf = 'SHOW FULL FIELDS FROM `'.$databases['Name'][$dbid]."`.`$table_edit_name` ;";
+    $res = mod_query($sqlf);
+    $anz_fields = mysqli_num_rows($res);
+    $fields_infos = getFieldinfos($databases['Name'][$dbid], $table_edit_name);
 
-	if (MSD_NEW_VERSION) $t_engine=(isset($fields_infos['_tableinfo_']['ENGINE'])) ? $fields_infos['_tableinfo_']['ENGINE'] : "MyISAM";
-	else
-		$t_engine=(isset($fields_infos['_tableinfo_']['TYPE'])) ? $fields_infos['_tableinfo_']['TYPE'] : "MyISAM";
+    if (MOD_NEW_VERSION) {
+        $t_engine = (isset($fields_infos['_tableinfo_']['ENGINE'])) ? $fields_infos['_tableinfo_']['ENGINE'] : 'MyISAM';
+    } else {
+        $t_engine = (isset($fields_infos['_tableinfo_']['TYPE'])) ? $fields_infos['_tableinfo_']['TYPE'] : 'MyISAM';
+    }
 
-	$t_charset=(isset($fields_infos['_tableinfo_']['DEFAULT CHARSET'])) ? $fields_infos['_tableinfo_']['DEFAULT CHARSET'] : "";
-	$t_collation=isset($row['Collation']) ? $row['Collation'] : ""; //(isset($fields_infos['_tableinfo_']['COLLATE'])) ? $fields_infos['_tableinfo_']['COLLATE'] : "";
-	$t_comment=(isset($fields_infos['_tableinfo_']['COMMENT'])) ? substr($fields_infos['_tableinfo_']['COMMENT'],1,strlen($fields_infos['_tableinfo_']['COMMENT'])-2) : "";
-	$t_rowformat=(isset($fields_infos['_tableinfo_']['ROW_FORMAT'])) ? $fields_infos['_tableinfo_']['ROW_FORMAT'] : "";
-	echo "<h6>".$lang['L_TABLE']." `$table_edit_name`</h6>";
-	$td='<td valign="top" nowrap="nowrap" class="small">';
+    $t_charset = (isset($fields_infos['_tableinfo_']['DEFAULT CHARSET'])) ? $fields_infos['_tableinfo_']['DEFAULT CHARSET'] : '';
+    $t_collation = isset($row['Collation']) ? $row['Collation'] : ''; //(isset($fields_infos['_tableinfo_']['COLLATE'])) ? $fields_infos['_tableinfo_']['COLLATE'] : '';
+    $t_comment = (isset($fields_infos['_tableinfo_']['COMMENT'])) ? substr($fields_infos['_tableinfo_']['COMMENT'], 1, strlen($fields_infos['_tableinfo_']['COMMENT']) - 2) : '';
+    $t_rowformat = (isset($fields_infos['_tableinfo_']['ROW_FORMAT'])) ? $fields_infos['_tableinfo_']['ROW_FORMAT'] : '';
+    echo '<h6>'.$lang['L_TABLE']." `$table_edit_name`</h6>";
+    $td = '<td valign="top" nowrap="nowrap" class="small">';
 
-	//Tabelleneigenschaften
-	echo '<form action="'.$p.'" method="post"><input type="hidden" name="table_edit_name" value="'.$table_edit_name.'"><table class="bdr">';
-	echo '<tr class="sqlNew"><td colspan="4" style="font-size:10pt;font-weight:bold;">'.$lang['L_SQL_TBLPROPSOF'].' `'.$table_edit_name.'` ('.$anz_fields.' '.$lang['L_FIELDS'].')</td>';
-	echo '<td class="small" colspan="2" align="center">Name<br><input type="text" class="text" name="t_edit_name" value="'.$table_edit_name.'" size="30" maxlength="150" style="font-size:11px;"></td></tr>';
-	echo '<tr class="sqlNew">';
-	echo '<td class="small" align="center">Engine<br><select name="t_edit_engine"  style="font-size:11px;">'.EngineCombo($t_engine).'</select></td>';
-	echo '<td class="small" align="center">Row Format<br><select name="t_edit_rowformat"  style="font-size:11px;">'.GetOptionsCombo($feldrowformat,$t_rowformat).'</select></td>';
-	echo '<td class="small" align="center">'.$lang['L_CHARSET'].'<br><select name="t_edit_charset"  style="font-size:11px;">'.CharsetCombo($t_charset).'</select></td>';
-	echo '<td class="small" align="center">'.$lang['L_COLLATION'].'<br><select name="t_edit_collate"  style="font-size:11px;">'.CollationCombo($t_collation).'</select></td>';
-	echo '<td class="small" align="center">'.$lang['L_COMMENT'].'<br><input type="text" class="text" name="t_edit_comment" value="'.$t_comment.'" size="30" maxlength="100" style="font-size:11px;"></td>';
-	echo '<td class="small" align="center">&nbsp;<br><input type="submit" name="t_edit_submit" value="'.$lang['L_CHANGE'].'" class="Formbutton"></td></tr>';
-	echo '</table></form><p>&nbsp;</p>';
+    //Tabelleneigenschaften
+    echo '<form action="'.$p.'" method="post"><input type="hidden" name="table_edit_name" value="'.$table_edit_name.'"><table class="bdr">';
+    echo '<tr class="sqlNew"><td colspan="4" style="font-size:10pt;font-weight:bold;">'.$lang['L_SQL_TBLPROPSOF'].' `'.$table_edit_name.'` ('.$anz_fields.' '.$lang['L_FIELDS'].')</td>';
+    echo '<td class="small" colspan="2" align="center">Name<br><input type="text" class="text" name="t_edit_name" value="'.$table_edit_name.'" size="30" maxlength="150" style="font-size:11px;"></td></tr>';
+    echo '<tr class="sqlNew">';
+    echo '<td class="small" align="center">Engine<br><select name="t_edit_engine"  style="font-size:11px;">'.EngineCombo($t_engine).'</select></td>';
+    echo '<td class="small" align="center">Row Format<br><select name="t_edit_rowformat"  style="font-size:11px;">'.GetOptionsCombo($feldrowformat, $t_rowformat).'</select></td>';
+    echo '<td class="small" align="center">'.$lang['L_CHARSET'].'<br><select name="t_edit_charset"  style="font-size:11px;">'.CharsetCombo($t_charset).'</select></td>';
+    echo '<td class="small" align="center">'.$lang['L_COLLATION'].'<br><select name="t_edit_collate"  style="font-size:11px;">'.CollationCombo($t_collation).'</select></td>';
+    echo '<td class="small" align="center">'.$lang['L_COMMENT'].'<br><input type="text" class="text" name="t_edit_comment" value="'.$t_comment.'" size="30" maxlength="100" style="font-size:11px;"></td>';
+    echo '<td class="small" align="center">&nbsp;<br><input type="submit" name="t_edit_submit" value="'.$lang['L_CHANGE'].'" class="Formbutton"></td></tr>';
+    echo '</table></form><p>&nbsp;</p>';
 
-	$field_fehler=0;
-	echo '<h6>'.$lang['L_FIELDS_OF_TABLE'].' `'.$table_edit_name.'`</h6>';
+    $field_fehler = 0;
+    echo '<h6>'.$lang['L_FIELDS_OF_TABLE'].' `'.$table_edit_name.'`</h6>';
 
-	$d_collate='';
-	$d_comment='';
+    $d_collate = '';
+    $d_comment = '';
 
-	if (isset($_GET['newfield'])||isset($_GET['editfield'])||$field_fehler>0||isset($_POST['newfield_posted']))
-	{
-		if (isset($_GET['editfield'])) $id=$_GET['editfield'];
-		$d_name=(isset($_GET['editfield'])) ? $fields_infos[$id]['name'] : "";
-		$d_type=(isset($_GET['editfield'])) ? $fields_infos[$id]['type'] : "";
-		$d_size=(isset($_GET['editfield'])) ? $fields_infos[$id]['size'] : "";
-		$d_null=(isset($_GET['editfield'])) ? $fields_infos[$id]['null'] : "";
-		$d_attribute=(isset($_GET['editfield'])) ? $fields_infos[$id]['attributes'] : "";
+    if (isset($_GET['newfield']) || isset($_GET['editfield']) || $field_fehler > 0 || isset($_POST['newfield_posted'])) {
+        if (isset($_GET['editfield'])) {
+            $id = $_GET['editfield'];
+        }
+        $d_name = (isset($_GET['editfield'])) ? $fields_infos[$id]['name'] : '';
+        $d_type = (isset($_GET['editfield'])) ? $fields_infos[$id]['type'] : '';
+        $d_size = (isset($_GET['editfield'])) ? $fields_infos[$id]['size'] : '';
+        $d_null = (isset($_GET['editfield'])) ? $fields_infos[$id]['null'] : '';
+        $d_attribute = (isset($_GET['editfield'])) ? $fields_infos[$id]['attributes'] : '';
 
-		$d_default='';
-		if (isset($id)&&isset($fields_infos[$id])&&isset($fields_infos[$id]['default']))
-		{
-			if ($fields_infos[$id]['default']=='NULL') $d_default='NULL';
-			else
-				$d_default=substr($fields_infos[$id]['default'],1,strlen($fields_infos[$id]['default'])-2);
-		}
-		$d_extra=(isset($_GET['editfield'])) ? $fields_infos[$id]['extra'] : "";
+        $d_default = '';
+        if (isset($id) && isset($fields_infos[$id]) && isset($fields_infos[$id]['default'])) {
+            if ('NULL' == $fields_infos[$id]['default']) {
+                $d_default = 'NULL';
+            } else {
+                $d_default = substr($fields_infos[$id]['default'], 1, strlen($fields_infos[$id]['default']) - 2);
+            }
+        }
+        $d_extra = (isset($_GET['editfield'])) ? $fields_infos[$id]['extra'] : '';
 
-		$d_primary=$d_unique=$d_index=$d_fulltext=0;
-		if (isset($id))
-		{
-			if (isset($fields_infos[$id]['collate'])) $d_collate=(isset($_GET['editfield'])) ? $fields_infos[$id]['collate'] : "";
-			if (isset($fields_infos[$id]['comment'])) $d_comment=(isset($_GET['editfield'])) ? $fields_infos[$id]['comment'] : "";
-		}
-		$d_privileges=(isset($_GET['editfield'])) ? $fields_infos[$id]['privileges'] : "";
-		if (isset($_GET['editfield']))
-		{
-			$d_primary=(in_array($fields_infos[$id]['name'],$fields_infos['_primarykeys_'])) ? 1 : 0;
-			$d_index=(in_array($fields_infos[$id]['name'],$fields_infos['_key_'])) ? 1 : 0;
-			$d_fulltext=(in_array($fields_infos[$id]['name'],$fields_infos['_fulltextkey_'])) ? 1 : 0;
-			$d_unique=(in_array($fields_infos[$id]['name'],$fields_infos['_uniquekey_'])) ? 1 : 0;
-		}
-		echo '<form action="'.$p.'" method="post" id="smallform"><input type="hidden" name="newfield_posted" value="1">';
-		if (isset($_GET['editfield'])) echo '<input type="hidden" name="editfield" value="'.$id.'"><input type="hidden" name="fieldname" value="'.$d_name.'">';
-		if (isset($_POST['newtablesubmit'])) echo '<input type="hidden" name="newtablename" value="'.$_POST['newtablename'].'">';
-		echo '<input type="hidden" name="f_primary" value="'.$d_primary.'"><input type="hidden" name="f_unique" value="'.$d_unique.'">';
-		echo '<input type="hidden" name="f_index" value="'.$d_index.'"><input type="hidden" name="f_fulltext" value="'.$d_fulltext.'">';
-		echo '<table class="bdr"><tr class="thead"><th colspan="6" align="center">'.((isset($_GET['editfield'])) ? $lang['L_SQL_EDITFIELD']." `".$d_name."`" : $lang['L_SQL_NEWFIELD']).'</th></tr>';
-		echo '<tr><td class="small">Name<br><input type="text" class="text" value="'.$d_name.'" name="f_name" size="30"></td>';
-		echo '<td>Type<br><select name="f_type">'.GetOptionsCombo($feldtypen,$d_type).'</select></td>';
-		echo '<td>Size&nbsp;<br><input type="text" class="text" value="'.$d_size.'" name="f_size" size="3" maxlength="80"></td>';
-		echo '<td>NULL<br><select name="f_null">'.GetOptionsCombo($feldnulls,$d_null).'</select></td>';
-		echo '<td align="center">Default<br><input type="text" class="text" name="f_default" value="'.$d_default.'" size="10"></td>';
-		echo '<td align="center">Extra<br><select name="f_extra">'.GetOptionsCombo($feldextras,$d_extra).'</select></td>';
+        $d_primary = $d_unique = $d_index = $d_fulltext = 0;
+        if (isset($id)) {
+            if (isset($fields_infos[$id]['collate'])) {
+                $d_collate = (isset($_GET['editfield'])) ? $fields_infos[$id]['collate'] : '';
+            }
+            if (isset($fields_infos[$id]['comment'])) {
+                $d_comment = (isset($_GET['editfield'])) ? $fields_infos[$id]['comment'] : '';
+            }
+        }
+        $d_privileges = (isset($_GET['editfield'])) ? $fields_infos[$id]['privileges'] : '';
+        if (isset($_GET['editfield'])) {
+            $d_primary = (in_array($fields_infos[$id]['name'], $fields_infos['_primarykeys_'])) ? 1 : 0;
+            $d_index = (in_array($fields_infos[$id]['name'], $fields_infos['_key_'])) ? 1 : 0;
+            $d_fulltext = (in_array($fields_infos[$id]['name'], $fields_infos['_fulltextkey_'])) ? 1 : 0;
+            $d_unique = (in_array($fields_infos[$id]['name'], $fields_infos['_uniquekey_'])) ? 1 : 0;
+        }
+        echo '<form action="'.$p.'" method="post" id="smallform"><input type="hidden" name="newfield_posted" value="1">';
+        if (isset($_GET['editfield'])) {
+            echo '<input type="hidden" name="editfield" value="'.$id.'"><input type="hidden" name="fieldname" value="'.$d_name.'">';
+        }
+        if (isset($_POST['newtablesubmit'])) {
+            echo '<input type="hidden" name="newtablename" value="'.$_POST['newtablename'].'">';
+        }
+        echo '<input type="hidden" name="f_primary" value="'.$d_primary.'"><input type="hidden" name="f_unique" value="'.$d_unique.'">';
+        echo '<input type="hidden" name="f_index" value="'.$d_index.'"><input type="hidden" name="f_fulltext" value="'.$d_fulltext.'">';
+        echo '<table class="bdr"><tr class="thead"><th colspan="6" align="center">'.((isset($_GET['editfield'])) ? $lang['L_SQL_EDITFIELD'].' `'.$d_name.'`' : $lang['L_SQL_NEWFIELD']).'</th></tr>';
+        echo '<tr><td class="small">Name<br><input type="text" class="text" value="'.$d_name.'" name="f_name" size="30"></td>';
+        echo '<td>Type<br><select name="f_type">'.GetOptionsCombo($feldtypen, $d_type).'</select></td>';
+        echo '<td>Size&nbsp;<br><input type="text" class="text" value="'.$d_size.'" name="f_size" size="3" maxlength="80"></td>';
+        echo '<td>NULL<br><select name="f_null">'.GetOptionsCombo($feldnulls, $d_null).'</select></td>';
+        echo '<td align="center">Default<br><input type="text" class="text" name="f_default" value="'.$d_default.'" size="10"></td>';
+        echo '<td align="center">Extra<br><select name="f_extra">'.GetOptionsCombo($feldextras, $d_extra).'</select></td>';
 
-		echo '</tr><tr><td align="center">'.$lang['L_SQL_INDEXES'].'<br>';
-		echo '<input type="radio" class="radio" name="f_index_new" id="k_no_index" value="no" '.(($d_primary+$d_unique+$d_index+$d_fulltext==0) ? 'checked="checked"' : '').'>';
-		echo '<label for="k_no_index">'.$icon['key_nokey'].'</label>&nbsp;&nbsp;';
+        echo '</tr><tr><td align="center">'.$lang['L_SQL_INDEXES'].'<br>';
+        echo '<input type="radio" class="radio" name="f_index_new" id="k_no_index" value="no" '.((0 == $d_primary + $d_unique + $d_index + $d_fulltext) ? 'checked="checked"' : '').'>';
+        echo '<label for="k_no_index">'.$icon['key_nokey'].'</label>&nbsp;&nbsp;';
 
-		echo '<input type="radio" class="radio" name="f_index_new" id="k_primary" value="primary" '.(($d_primary==1) ? "checked" : "").'>';
-		echo '<label for="k_primary">'.$icon['key_primary'].'</label>&nbsp;&nbsp;';
+        echo '<input type="radio" class="radio" name="f_index_new" id="k_primary" value="primary" '.((1 == $d_primary) ? 'checked' : '').'>';
+        echo '<label for="k_primary">'.$icon['key_primary'].'</label>&nbsp;&nbsp;';
 
-		echo '<input type="radio" class="radio" name="f_index_new" id="k_unique" value="unique" '.(($d_unique==1) ? "checked" : "").'>';
-		echo '<label for="k_unique">'.$icon['key_unique'].'</label>&nbsp;&nbsp;';
+        echo '<input type="radio" class="radio" name="f_index_new" id="k_unique" value="unique" '.((1 == $d_unique) ? 'checked' : '').'>';
+        echo '<label for="k_unique">'.$icon['key_unique'].'</label>&nbsp;&nbsp;';
 
-		echo '<input type="radio" class="radio" name="f_index_new" id="k_index" value="index" '.(($d_index==1) ? "checked" : "").'>&nbsp;';
-		echo '<label for="k_index">'.$icon['index'].'</label>&nbsp;&nbsp;';
+        echo '<input type="radio" class="radio" name="f_index_new" id="k_index" value="index" '.((1 == $d_index) ? 'checked' : '').'>&nbsp;';
+        echo '<label for="k_index">'.$icon['index'].'</label>&nbsp;&nbsp;';
 
-		echo '<input type="checkbox" class="checkbox" name="f_indexfull" id="k_fulltext" value="1" '.(($d_fulltext==1) ? "checked" : "").'>';
-		echo '<label for="k_fulltext">'.$icon['key_fulltext'].'</label>&nbsp;&nbsp;</td>';
+        echo '<input type="checkbox" class="checkbox" name="f_indexfull" id="k_fulltext" value="1" '.((1 == $d_fulltext) ? 'checked' : '').'>';
+        echo '<label for="k_fulltext">'.$icon['key_fulltext'].'</label>&nbsp;&nbsp;</td>';
 
-		echo '<td align="center" colspan="2" >'.$lang['L_COLLATION'].'<br><select name="f_collate">'.CollationCombo($d_collate).'</select></td>';
-		echo '<td align="center">'.$lang['L_SQL_ATTRIBUTES'].'<br><select name="f_attribut">'.AttributeCombo($d_attribute).'</select></td>';
-		echo '<td align="center">'.$lang['L_SQL_ATPOSITION'].':<br><select name="f_position"><option value=""></option><option value="FIRST">'.$lang['L_SQL_FIRST'].'</option>';
-		if ($anz_fields>0)
-		{
-			for ($i=0; $i<$anz_fields; $i++)
-			{
-				echo '<option value="AFTER `'.$fields_infos[$i]['name'].'`">'.$lang['L_SQL_AFTER'].' `'.$fields_infos[$i]['name'].'`</option>';
-			}
-		}
-		echo '</select></td><td align="center"><br><input type="submit" name="newfieldsubmit" value="'.((isset($_GET['editfield'])) ? $lang['L_SQL_CHANGEFIELD'] : $lang['L_SQL_INSERTFIELD']).'" class="Formbutton"></td></tr></table></form><p>&nbsp;</p>';
-	}
-	else
-		echo '<a style="font-size:8pt;padding-bottom:8px;" href="'.$p.'&amp;newfield=1">'.$lang['L_SQL_INSERTNEWFIELD'].'</a><br><br>';
-		//Felder ausgeben
-	echo '<table class="bdr">';
-	for ($i=0; $i<$anz_fields; $i++)
-	{
-		$cl=($i%2) ? "dbrow" : "dbrow1";
-		if ($i==0) echo '<tr class="thead"><th colspan="2">&nbsp;</th><th>Field</th><th>Type</th><th>Size</th><th>NULL</th><th>Key</th><th>Attribute</th><th>Default</th><th>Extra</th><th>'.
-		$lang['L_COLLATION'].'</th><th>'.$lang['L_COMMENT'].'</th></tr>';
-		echo '<tr class="'.$cl.'">';
-		echo '<td nowrap="nowrap">';
-		echo '<a href="'.$p.'&amp;editfield='.$i.'"><img src="'.$config['files']['iconpath'].'edit.gif" title="edit field" alt="edit field" border="0"></a>&nbsp;&nbsp;';
-		echo '<a href="'.$p.'&amp;kill='.$fields_infos[$i]['name'].'&amp;anz='.$anz_fields.'" onclick="if(!confirm(\''.$lang['L_ASKDELETEFIELD'].'\')) return false;"><img src="'.$config['files']['iconpath'].'delete.gif" alt="delete field" border="0"></a>&nbsp;&nbsp;';
+        echo '<td align="center" colspan="2" >'.$lang['L_COLLATION'].'<br><select name="f_collate">'.CollationCombo($d_collate).'</select></td>';
+        echo '<td align="center">'.$lang['L_SQL_ATTRIBUTES'].'<br><select name="f_attribut">'.AttributeCombo($d_attribute).'</select></td>';
+        echo '<td align="center">'.$lang['L_SQL_ATPOSITION'].':<br><select name="f_position"><option value=""></option><option value="FIRST">'.$lang['L_SQL_FIRST'].'</option>';
+        if ($anz_fields > 0) {
+            for ($i = 0; $i < $anz_fields; ++$i) {
+                echo '<option value="AFTER `'.$fields_infos[$i]['name'].'`">'.$lang['L_SQL_AFTER'].' `'.$fields_infos[$i]['name'].'`</option>';
+            }
+        }
+        echo '</select></td><td align="center"><br><input type="submit" name="newfieldsubmit" value="'.((isset($_GET['editfield'])) ? $lang['L_SQL_CHANGEFIELD'] : $lang['L_SQL_INSERTFIELD']).'" class="Formbutton"></td></tr></table></form><p>&nbsp;</p>';
+    } else {
+        echo '<a style="font-size:8pt;padding-bottom:8px;" href="'.$p.'&amp;newfield=1">'.$lang['L_SQL_INSERTNEWFIELD'].'</a><br><br>';
+    }
+    //Felder ausgeben
+    echo '<table class="bdr">';
+    for ($i = 0; $i < $anz_fields; ++$i) {
+        $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+        if (0 == $i) {
+            echo '<tr class="thead"><th colspan="2">&nbsp;</th><th>Field</th><th>Type</th><th>Size</th><th>NULL</th><th>Key</th><th>Attribute</th><th>Default</th><th>Extra</th><th>'.
+        $lang['L_COLLATION'].'</th><th>'.$lang['L_COMMENT'].'</th></tr>';
+        }
+        echo '<tr class="'.$cl.'">';
+        echo '<td nowrap="nowrap">';
+        echo '<a href="'.$p.'&amp;editfield='.$i.'"><img src="'.$config['files']['iconpath'].'edit.gif" title="edit field" alt="edit field" border="0"></a>&nbsp;&nbsp;';
+        echo '<a href="'.$p.'&amp;kill='.$fields_infos[$i]['name'].'&amp;anz='.$anz_fields.'" onclick="if(!confirm(\''.$lang['L_ASKDELETEFIELD'].'\')) return false;"><img src="'.$config['files']['iconpath'].'delete.gif" alt="delete field" border="0"></a>&nbsp;&nbsp;';
 
-		echo '</td>';
-		echo '<td style="text-align:right">'.($i+1).'.</td>';
+        echo '</td>';
+        echo '<td style="text-align:right">'.($i + 1).'.</td>';
 
-		echo '<td><strong>'.$fields_infos[$i]['name'].'</strong></td><td>'.$fields_infos[$i]['type'].'</td><td>'.$fields_infos[$i]['size'].'</td>';
-		echo '<td>'.get_output_attribut_null($fields_infos[$i]['null']).'</td><td>';
-		//key
-		if (in_array($fields_infos[$i]['name'],$fields_infos['_primarykeys_'])) echo $icon['key_primary'];
-		if (in_array($fields_infos[$i]['name'],$fields_infos['_fulltextkey_'])) echo $icon['key_fulltext'];
-		if (in_array($fields_infos[$i]['name'],$fields_infos['_uniquekey_'])) echo $icon['key_unique'];
-		if (in_array($fields_infos[$i]['name'],$fields_infos['_key_'])) echo $icon['index'];
-		echo '</td><td>'.$fields_infos[$i]['attributes'].'</td>';
-		echo '<td>'.$fields_infos[$i]['default'].'</td>'.$td.$fields_infos[$i]['extra'].'</td>';
-		echo '<td>'.((MSD_NEW_VERSION) ? $fields_infos[$i]['collate'] : "&nbsp;").'</td>';
-        echo '<td>'.((isset($fields_infos[$i]['comment'])) ? $fields_infos[$i]['comment'] : "&nbsp;").'</td>';
-        echo "</tr>";
-	}
-	echo '</table><br>';
+        echo '<td><strong>'.$fields_infos[$i]['name'].'</strong></td><td>'.$fields_infos[$i]['type'].'</td><td>'.$fields_infos[$i]['size'].'</td>';
+        echo '<td>'.get_output_attribut_null($fields_infos[$i]['null']).'</td><td>';
+        //key
+        if (in_array($fields_infos[$i]['name'], $fields_infos['_primarykeys_'])) {
+            echo $icon['key_primary'];
+        }
+        if (in_array($fields_infos[$i]['name'], $fields_infos['_fulltextkey_'])) {
+            echo $icon['key_fulltext'];
+        }
+        if (in_array($fields_infos[$i]['name'], $fields_infos['_uniquekey_'])) {
+            echo $icon['key_unique'];
+        }
+        if (in_array($fields_infos[$i]['name'], $fields_infos['_key_'])) {
+            echo $icon['index'];
+        }
+        echo '</td><td>'.$fields_infos[$i]['attributes'].'</td>';
+        echo '<td>'.$fields_infos[$i]['default'].'</td>'.$td.$fields_infos[$i]['extra'].'</td>';
+        echo '<td>'.((MOD_NEW_VERSION) ? $fields_infos[$i]['collate'] : '&nbsp;').'</td>';
+        echo '<td>'.((isset($fields_infos[$i]['comment'])) ? $fields_infos[$i]['comment'] : '&nbsp;').'</td>';
+        echo '</tr>';
+    }
+    echo '</table><br>';
 
-	echo '<h6>'.$lang['L_SQL_TABLEINDEXES'].' `'.$table_edit_name.'`</h6>';
-	echo '<table class="bdr">
+    echo '<h6>'.$lang['L_SQL_TABLEINDEXES'].' `'.$table_edit_name.'`</h6>';
+    echo '<table class="bdr">
 	   <tr class="thead">
 	       <th colspan="2">&nbsp;</th>
 	       <th>'.$lang['L_NAME'].'</th>
 	       <th>'.$lang['L_SQL_COLUMNS'].'</th>
 	       <th>'.$lang['L_INFO_SIZE'].'</th>
-	       '.((MSD_NEW_VERSION) ? '<th>'.$lang['L_TABLE_TYPE'].'</th>' : '').'
+	       '.((MOD_NEW_VERSION) ? '<th>'.$lang['L_TABLE_TYPE'].'</th>' : '').'
 	       <th>'.$lang['L_SQL_ALLOWDUPS'].'</th>
 	       <th>'.$lang['L_SQL_CARDINALITY'].'</th>
 	       <th>'.$lang['L_COMMENT'].'</th>
 	   </tr>';
-	$sqlk="SHOW KEYS FROM `".$databases['Name'][$dbid]."`.`$table_edit_name`;";
-	$res=MSD_query($sqlk);
-	$num=mysqli_num_rows($res);
-	if ($num==0)
-	{
-		echo '<tr><td colspan="6">'.$lang['L_SQL_TABLENOINDEXES'].'</td></tr>';
-	}
-	else
-	{
-		for ($i=0; $i<$num; $i++)
-		{
-			$row=mysqli_fetch_array($res,MYSQLI_ASSOC);
-			if (!isset($row['Comment'])) {
-			    $row['Comment'] = '';
-			}
-			$cl=($i%2) ? "dbrow" : "dbrow1";
-			//Images
-			echo '<tr class="'.$cl.'">';
-			echo '<td>';
-			if ($row['Key_name']=="PRIMARY")
-			{
-				echo '<a href="'.$p.'&amp;killPrimaryKey='.$row['Column_name'].'" onclick="if(!confirm(\''.$lang['L_PRIMARYKEY_CONFIRMDELETE'].'\')) return false;">';
-				echo '<img src="'.$config['files']['iconpath'].'delete.gif" alt="" border="0">';
-				echo '</a>';
-			}
-			else
-			{
-				echo '<a href="'.$p.'&amp;killIndex='.$row['Key_name'].'" onclick="if(!confirm(\''.$lang['L_KEY_CONFIRMDELETE'].'\')) return false;">';
-				echo '<img src="'.$config['files']['iconpath'].'delete.gif" alt="" border="0">';
-				echo '</a>';
-			}
-			echo '</td>';
-			echo '<td style="text-align:right">'.($i+1).'.</td>';
-			echo '<td>'.$row['Key_name'].'</td>';
-			echo '<td>'.$row['Column_name'].'</td>';
-            echo '<td class="right">';
-            if (isset($row['Sub_part']) && $row['Sub_part']>0) echo $row['Sub_part'];
+    $sqlk = 'SHOW KEYS FROM `'.$databases['Name'][$dbid]."`.`$table_edit_name`;";
+    $res = mod_query($sqlk);
+    $num = mysqli_num_rows($res);
+    if (0 == $num) {
+        echo '<tr><td colspan="6">'.$lang['L_SQL_TABLENOINDEXES'].'</td></tr>';
+    } else {
+        for ($i = 0; $i < $num; ++$i) {
+            $row = mysqli_fetch_array($res, MYSQLI_ASSOC);
+            if (!isset($row['Comment'])) {
+                $row['Comment'] = '';
+            }
+            $cl = ($i % 2) ? 'dbrow' : 'dbrow1';
+            //Images
+            echo '<tr class="'.$cl.'">';
+            echo '<td>';
+            if ('PRIMARY' == $row['Key_name']) {
+                echo '<a href="'.$p.'&amp;killPrimaryKey='.$row['Column_name'].'" onclick="if(!confirm(\''.$lang['L_PRIMARYKEY_CONFIRMDELETE'].'\')) return false;">';
+                echo '<img src="'.$config['files']['iconpath'].'delete.gif" alt="" border="0">';
+                echo '</a>';
+            } else {
+                echo '<a href="'.$p.'&amp;killIndex='.$row['Key_name'].'" onclick="if(!confirm(\''.$lang['L_KEY_CONFIRMDELETE'].'\')) return false;">';
+                echo '<img src="'.$config['files']['iconpath'].'delete.gif" alt="" border="0">';
+                echo '</a>';
+            }
             echo '</td>';
-			if (MSD_NEW_VERSION) echo '<td>'.$row['Index_type'].'</td>';
-			echo '<td align="center">'.(($row['Non_unique']==1) ? $lang['L_YES'] : $lang['L_NO']).'</td>';
-			echo '<td>'.(($row['Cardinality']>=0) ? $row['Cardinality'] : $lang['L_NO']).'</td>';
+            echo '<td style="text-align:right">'.($i + 1).'.</td>';
+            echo '<td>'.$row['Key_name'].'</td>';
+            echo '<td>'.$row['Column_name'].'</td>';
+            echo '<td class="right">';
+            if (isset($row['Sub_part']) && $row['Sub_part'] > 0) {
+                echo $row['Sub_part'];
+            }
+            echo '</td>';
+            if (MOD_NEW_VERSION) {
+                echo '<td>'.$row['Index_type'].'</td>';
+            }
+            echo '<td align="center">'.((1 == $row['Non_unique']) ? $lang['L_YES'] : $lang['L_NO']).'</td>';
+            echo '<td>'.(($row['Cardinality'] >= 0) ? $row['Cardinality'] : $lang['L_NO']).'</td>';
             echo '<td>'.$row['Comment'].'</td>';
-			echo '</tr>';
-		}
-	}
-	echo '</table><br><input type="Button" value="'.$lang['L_SQL_CREATEINDEX'].'" onclick="location.href=\''.$p.'&amp;sql_createindex=1#setnewkeys\'" class="Formbutton">';
+            echo '</tr>';
+        }
+    }
+    echo '</table><br><input type="Button" value="'.$lang['L_SQL_CREATEINDEX'].'" onclick="location.href=\''.$p.'&amp;sql_createindex=1#setnewkeys\'" class="Formbutton">';
 
-	if ((isset($_GET['sql_createindex']))&&($_GET['sql_createindex']=="1"))
-	{ ?>
-<script type="text/javascript">
+    if ((isset($_GET['sql_createindex'])) && ('1' == $_GET['sql_createindex'])) { ?>
+<script>
 	function toggleIndexLength(id)
 	{
-		var mysqlStrings = ['<?php echo implode("','", $mysql_string_types);?>'];
+		var mysqlStrings = ['<?php echo implode("','", $mysql_string_types); ?>'];
 		var field = 'setNewKey'+id;
 		var sel = document.getElementById(field).selectedIndex;
 		var val = document.getElementById(field).options[sel].innerHTML;
@@ -544,69 +519,65 @@ if ($table_edit_name!="")
 	}
 </script>
     <?php
-		echo '<br><a name="setnewkeys"></a>';
-		echo '<form action="'.$p.'" method="POST">';
-		echo '<h6>'.$lang['L_SETKEYSFOR'].' `'.$table_edit_name.'`</h6>';
-		//kopf
-		echo '<table class="bdr">';
-		//body
-		$sqlFelder="DESCRIBE `".$databases['Name'][$dbid]."`.`".$_GET['tablename']."`;";
-		$res=MSD_query($sqlFelder);
-		$num=mysqli_num_rows($res);
-		if ($num==0)
-		{
-			echo '<tr><td>'.$lang['L_SQL_TABLENOINDEXES'].'</td></tr>';
-		}
-		else
-		{
-	       	echo '<tr class="thead"><th>'.$lang['L_NAME'].'</th><th>'.$lang['L_TABLE_TYPE'].'</th></tr>';
+        echo '<br><a name="setnewkeys"></a>';
+        echo '<form action="'.$p.'" method="POST">';
+        echo '<h6>'.$lang['L_SETKEYSFOR'].' `'.$table_edit_name.'`</h6>';
+        //kopf
+        echo '<table class="bdr">';
+        //body
+        $sqlFelder = 'DESCRIBE `'.$databases['Name'][$dbid].'`.`'.$_GET['tablename'].'`;';
+        $res = mod_query($sqlFelder);
+        $num = mysqli_num_rows($res);
+        if (0 == $num) {
+            echo '<tr><td>'.$lang['L_SQL_TABLENOINDEXES'].'</td></tr>';
+        } else {
+            echo '<tr class="thead"><th>'.$lang['L_NAME'].'</th><th>'.$lang['L_TABLE_TYPE'].'</th></tr>';
             echo '<tr>';
-			echo '<td><input type="text" name="indexName" value="" class="text">';
-			echo '<td><select name="indexType"><option value="primary">'.$lang['L_TITLE_KEY_PRIMARY'].'</option><option value="unique">'.$lang['L_TITLE_KEY_UNIQUE'].'</option><option value="index" selected="selected">'.$lang['L_TITLE_INDEX'].'</option><option value="fulltext">'.$lang['L_TITLE_KEY_FULLTEXT'].'</option></select></td>';
-			echo '</tr>';
-    		echo '</table><br>';
+            echo '<td><input type="text" name="indexName" value="" class="text">';
+            echo '<td><select name="indexType"><option value="primary">'.$lang['L_TITLE_KEY_PRIMARY'].'</option><option value="unique">'.$lang['L_TITLE_KEY_UNIQUE'].'</option><option value="index" selected="selected">'.$lang['L_TITLE_INDEX'].'</option><option value="fulltext">'.$lang['L_TITLE_KEY_FULLTEXT'].'</option></select></td>';
+            echo '</tr>';
+            echo '</table><br>';
 
-    		//alle Felder holen
-			$feldArray=Array();
+            //alle Felder holen
+            $feldArray = [];
             echo '<table class="bdr">';
-    		echo '<tr class="thead"><th>#</th><th>'.$lang['L_PRIMARYKEY_FIELD'].'</th><th>'.$lang['L_INFO_SIZE'].'</th>';
+            echo '<tr class="thead"><th>#</th><th>'.$lang['L_PRIMARYKEY_FIELD'].'</th><th>'.$lang['L_INFO_SIZE'].'</th>';
 
-			while ($row=mysqli_fetch_array($res, MYSQLI_ASSOC))
-			{
-				$feldArray[$row['Field']]=$row['Type'];
-			}
-			//Primaerschluessel holen, um automatisch vorzuselektieren
-			$primaryKeys=getPrimaryKeys($databases['Name'][$dbid],$_GET['tablename']);
-			//eine Select-Box pro Feld anzeigen, Felder für Name und Typ nur in der ersten Zeile
-			for ($i=0; $i<$num; $i++)
-			{
-				echo '<tr><td class="right">'.($i+1).'.</td><td>';
-				$options ="\n\n".'<option value="">---</option>';
-				$selectedFeldTyp = false;
-				foreach ($feldArray as $feldName=>$feldTyp)
-				{
-					$options.="\n".'<option value="'.$feldName.'"';
-					//alle Primaerschluessel vorselektieren
-					if (isset($primaryKeys['name'][$i]) && $primaryKeys['name'][$i]==$feldName) {
-					    $options.=' selected="selected"';
-					    $selectedFeldTyp = $feldTyp;
-					}
-					$options.='>'.$feldName.' ['.$feldTyp.']</option>';
-				}
-				echo '<select id="setNewKey'.$i.'" name="setNewKey'.$i.'" onchange="toggleIndexLength('.$i.');">';
-				echo $options."\n".'</select></td>';
-				echo '<td>';
-                $type =explode('(', $selectedFeldTyp);
-				echo '<input type="text" id="indexSize'.$i.'" name="indexSize'.$i.'" value="" size="10" class="text"';
-				if (!isset($type[0]) || !in_array($type[0], $mysql_string_types)) echo ' disabled="disabled"';
-				echo '></td>';
-				echo '</tr>';
-			}
-			$i ++;
-		}
-		echo '</table>';
-		//Speichern Knopf
-		echo '<br><input name="setNewKeys" type="submit" value="'.$lang['L_SAVE'].'" class="Formbutton">';
-		echo '</form>';
-	}
+            while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
+                $feldArray[$row['Field']] = $row['Type'];
+            }
+            //Primaerschluessel holen, um automatisch vorzuselektieren
+            $primaryKeys = getPrimaryKeys($databases['Name'][$dbid], $_GET['tablename']);
+            //eine Select-Box pro Feld anzeigen, Felder für Name und Typ nur in der ersten Zeile
+            for ($i = 0; $i < $num; ++$i) {
+                echo '<tr><td class="right">'.($i + 1).'.</td><td>';
+                $options = "\n\n".'<option value="">---</option>';
+                $selectedFeldTyp = false;
+                foreach ($feldArray as $feldName => $feldTyp) {
+                    $options .= "\n".'<option value="'.$feldName.'"';
+                    //alle Primaerschluessel vorselektieren
+                    if (isset($primaryKeys['name'][$i]) && $primaryKeys['name'][$i] == $feldName) {
+                        $options .= ' selected="selected"';
+                        $selectedFeldTyp = $feldTyp;
+                    }
+                    $options .= '>'.$feldName.' ['.$feldTyp.']</option>';
+                }
+                echo '<select id="setNewKey'.$i.'" name="setNewKey'.$i.'" onchange="toggleIndexLength('.$i.');">';
+                echo $options."\n".'</select></td>';
+                echo '<td>';
+                $type = explode('(', $selectedFeldTyp);
+                echo '<input type="text" id="indexSize'.$i.'" name="indexSize'.$i.'" value="" size="10" class="text"';
+                if (!isset($type[0]) || !in_array($type[0], $mysql_string_types)) {
+                    echo ' disabled="disabled"';
+                }
+                echo '></td>';
+                echo '</tr>';
+            }
+            ++$i;
+        }
+        echo '</table>';
+        //Speichern Knopf
+        echo '<br><input name="setNewKeys" type="submit" value="'.$lang['L_SAVE'].'" class="Formbutton">';
+        echo '</form>';
+    }
 }
diff --git a/msd/inc/sqlbrowser/sqlbox.php b/msd/inc/sqlbrowser/sqlbox.php
index 64f05045..7b68032d 100644
--- a/msd/inc/sqlbrowser/sqlbox.php
+++ b/msd/inc/sqlbrowser/sqlbox.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,69 +16,73 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 //Start SQL-Box
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => $config['paths']['root'].'./tpl/sqlbrowser/sqlbox.tpl'));
-
-if (isset($_GET['readfile'])&&$_GET['readfile']==1)
-{
-	$tpl->assign_block_vars('SQLUPLOAD',array(
-
-		'POSTTARGET' => $params,
-		'LANG_OPENSQLFILE' => $lang['L_SQL_OPENFILE'],
-		'LANG_OPENSQLFILE_BUTTON' => $lang['L_SQL_OPENFILE_BUTTON'],
-		'LANG_SQL_MAXSIZE' => $lang['L_MAX_UPLOAD_SIZE'],
-		'MAX_FILESIZE' => $config['upload_max_filesize']));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => $config['paths']['root'].'./tpl/sqlbrowser/sqlbox.tpl', ]);
 
+if (isset($_GET['readfile']) && 1 == $_GET['readfile']) {
+    $tpl->assign_block_vars('SQLUPLOAD', [
+        'POSTTARGET' => $params,
+        'LANG_OPENSQLFILE' => $lang['L_SQL_OPENFILE'],
+        'LANG_OPENSQLFILE_BUTTON' => $lang['L_SQL_OPENFILE_BUTTON'],
+        'LANG_SQL_MAXSIZE' => $lang['L_MAX_UPLOAD_SIZE'],
+        'MAX_FILESIZE' => $config['upload_max_filesize'], ]);
 }
 
-if (isset($_POST['submit_openfile']))
-{
-	//open file
-	if (!isset($_FILES['upfile']['name'])||empty($_FILES['upfile']['name'])) $aus.='<span class="error">'.$lang['L_FM_UPLOADFILEREQUEST'].'</span>';
-	else
-	{
-		$fn=$_FILES['upfile']['tmp_name'];
-		if (strtolower(substr($_FILES['upfile']['name'],-3))==".gz") $read__user_sqlfile=gzfile($fn);
-		else
-			$read__user_sqlfile=file($fn);
-		$aus.='<span>geladenes File: <strong>'.$_FILES['upfile']['name'].'</strong>&nbsp;&nbsp;&nbsp;'.byte_output(filesize($_FILES['upfile']['tmp_name'])).'</span>';
-		$sql_loaded=implode("",$read__user_sqlfile);
-	}
+if (isset($_POST['submit_openfile'])) {
+    //open file
+    if (!isset($_FILES['upfile']['name']) || empty($_FILES['upfile']['name'])) {
+        $aus .= '<span class="error">'.$lang['L_FM_UPLOADFILEREQUEST'].'</span>';
+    } else {
+        $fn = $_FILES['upfile']['tmp_name'];
+        if ('.gz' == strtolower(substr($_FILES['upfile']['name'], -3))) {
+            $read__user_sqlfile = gzfile($fn);
+        } else {
+            $read__user_sqlfile = file($fn);
+        }
+        $aus .= '<span>geladenes File: <strong>'.$_FILES['upfile']['name'].'</strong>&nbsp;&nbsp;&nbsp;'.byte_output(filesize($_FILES['upfile']['tmp_name'])).'</span>';
+        $sql_loaded = implode('', $read__user_sqlfile);
+    }
 }
 
 // Sind SQL-Befehle in der SQLLib vorhanden?
-$sqlcombo=SQL_ComboBox();
-if ($sqlcombo>'') $tpl->assign_block_vars('SQLCOMBO',array(
-	'SQL_COMBOBOX' => $sqlcombo));
+$sqlcombo = SQL_ComboBox();
+if ($sqlcombo > '') {
+    $tpl->assign_block_vars('SQLCOMBO', [
+    'SQL_COMBOBOX' => $sqlcombo, ]);
+}
 
-$tpl->assign_vars(array(
-	'LANG_SQL_WARNING' => $lang['L_SQL_WARNING'],
-	'ICONPATH' => $config['files']['iconpath'],
-	'MYSQL_REF' => $mysql_help_ref,
-	'BOXSIZE' => $config['interface_sqlboxsize'],
-	'BOXCONTENT' => ((isset($sql_loaded)) ? $sql_loaded : $sql['sql_statement'].$sql['order_statement']),
-	'LANG_SQL_BEFEHLE' => $lang['L_SQL_BEFEHLE'],
-	'TABLE_COMBOBOX' => Table_ComboBox(),
-	'LANG_SQL_EXEC' => $lang['L_SQL_EXEC'],
-	'LANG_RESET' => $lang['L_RESET'],
-	'PARAMS' => $params,
-	'DB' => $databases['Name'][$dbid],
-	'DBID' => $dbid,
-	'TABLENAME' => $tablename,
-	'ICON_SEARCH' => $icon['search'],
-	'ICON_UPLOAD' => $icon['upload'],
-	'ICON_MYSQL_HELP' => $icon['mysql_help'],
-	'MYSQL_HELP' => $lang['L_TITLE_MYSQL_HELP'],
-	'DBID' => $databases['db_selected_index'],
-	'LANG_TOOLBOX' => $lang['L_TOOLS_TOOLBOX'],
-	'LANG_TOOLS' => $lang['L_TOOLS'],
-	'LANG_DB' => $lang['L_DB'],
-	'LANG_TABLE' => $lang['L_TABLE'],
-	'LANG_SQL_TABLEVIEW' => $lang['L_SQL_TABLEVIEW'],
-	'LANG_BACK_TO_DB_OVERVIEW' => $lang['L_SQL_BACKDBOVERVIEW']));
-if ($tablename>'') $tpl->assign_block_vars('TABLE_SELECTED',array());
+$tpl->assign_vars([
+    'LANG_SQL_WARNING' => $lang['L_SQL_WARNING'],
+    'ICONPATH' => $config['files']['iconpath'],
+    'MYSQL_REF' => $mysql_help_ref,
+    'BOXSIZE' => ((isset($config['interface_sqlboxsize'])) ? $config['interface_sqlboxsize'] : ''),
+    'BOXCONTENT' => ((isset($sql_loaded)) ? $sql_loaded : $sql['sql_statement'].$sql['order_statement']),
+    'LANG_SQL_BEFEHLE' => $lang['L_SQL_BEFEHLE'],
+    'TABLE_COMBOBOX' => Table_ComboBox(),
+    'LANG_SQL_EXEC' => $lang['L_SQL_EXEC'],
+    'LANG_RESET' => $lang['L_RESET'],
+    'PARAMS' => $params,
+    'DB' => $databases['Name'][$dbid],
+    'DBID' => $dbid,
+    'TABLENAME' => $tablename,
+    'ICON_SEARCH' => $icon['search'],
+    'ICON_UPLOAD' => $icon['upload'],
+    'ICON_MYSQL_HELP' => $icon['mysql_help'],
+    'MYSQL_HELP' => $lang['L_TITLE_MYSQL_HELP'],
+    'DBID' => $databases['db_selected_index'],
+    'LANG_TOOLBOX' => $lang['L_TOOLS_TOOLBOX'],
+    'LANG_TOOLS' => $lang['L_TOOLS'],
+    'LANG_DB' => $lang['L_DB'],
+    'LANG_TABLE' => $lang['L_TABLE'],
+    'LANG_SQL_TABLEVIEW' => $lang['L_SQL_TABLEVIEW'],
+    'LANG_BACK_TO_DB_OVERVIEW' => $lang['L_SQL_BACKDBOVERVIEW'], ]);
+if ($tablename > '') {
+    $tpl->assign_block_vars('TABLE_SELECTED', []);
+}
 
 $tpl->pparse('show');
diff --git a/msd/inc/sqllib.php b/msd/inc/sqllib.php
index 1a82b70c..8a03004b 100644
--- a/msd/inc/sqllib.php
+++ b/msd/inc/sqllib.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,54 +16,54 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-if (!defined('MSD_VERSION')) die('No direct access.');
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
 //SQL-Library
-include ( './language/' . $config['language'] . '/lang_sql.php' );
+include './language/'.$config['language'].'/lang_sql.php';
 /*
 Template
-if $sqllib[$i]['sql']=trenn, Then it is a Heading
-$sqllib[$i]['name']="";
-$sqllib[$i]['sql']="";
+if $sqllib[$i]['sql'] =trenn, Then it is a Heading
+$sqllib[$i]['name'] = '';
+$sqllib[$i]['sql'] = '';
 $i++;
 */
-$i=0;
-$sqllib= array ();
+$i = 0;
+$sqllib = [];
 
-$sqllib[$i]['name']=$lang['L_SQLLIB_GENERALFUNCTIONS'];
-$sqllib[$i]['sql']="trenn";
-$i++;
+$sqllib[$i]['name'] = $lang['L_SQLLIB_GENERALFUNCTIONS'];
+$sqllib[$i]['sql'] = 'trenn';
+++$i;
 
-$sqllib[$i]['name']=$lang['L_SQLLIB_RESETAUTO'];
-$sqllib[$i]['sql']="ALTER TABLE `table` AUTO_INCREMENT=1;";
-$i++;
+$sqllib[$i]['name'] = $lang['L_SQLLIB_RESETAUTO'];
+$sqllib[$i]['sql'] = 'ALTER TABLE `table` AUTO_INCREMENT=1;';
+++$i;
 
 /********* phpBB-Boards *********************************/
-$sqllib[$i]['name']="phpBB-" . $lang['L_SQLLIB_BOARDS'];
-$sqllib[$i]['sql']="trenn";
-$i++;
+$sqllib[$i]['name'] = 'phpBB-'.$lang['L_SQLLIB_BOARDS'];
+$sqllib[$i]['sql'] = 'trenn';
+++$i;
 
 // Bord de-/aktivieren
-$sqllib[$i]['name']=$lang['L_SQLLIB_DEACTIVATEBOARD'] . ' [phpBB]';
-$sqllib[$i]['sql']="UPDATE `phpbb_config` set config_value=1 where config_name='board_disable'";
-$i++;
+$sqllib[$i]['name'] = $lang['L_SQLLIB_DEACTIVATEBOARD'].' [phpBB]';
+$sqllib[$i]['sql'] = "UPDATE `phpbb_config` set config_value=1 where config_name='board_disable'";
+++$i;
 
-$sqllib[$i]['name']=$lang['L_SQLLIB_ACTIVATEBOARD'] . ' [phpBB]';
-$sqllib[$i]['sql']="UPDATE `phpbb_config` set config_value=0 where config_name='board_disable'";
-$i++;
+$sqllib[$i]['name'] = $lang['L_SQLLIB_ACTIVATEBOARD'].' [phpBB]';
+$sqllib[$i]['sql'] = "UPDATE `phpbb_config` set config_value=0 where config_name='board_disable'";
+++$i;
 
 // Bord de-/aktivieren
 
-
-$sqllib[$i]['name']="vBulletin-" . $lang['L_SQLLIB_BOARDS'];
-$sqllib[$i]['sql']="trenn";
-$i++;
+$sqllib[$i]['name'] = 'vBulletin-'.$lang['L_SQLLIB_BOARDS'];
+$sqllib[$i]['sql'] = 'trenn';
+++$i;
 
 // Bord de-/aktivieren
-$sqllib[$i]['name']=$lang['L_SQLLIB_DEACTIVATEBOARD'] . ' [vBulletin]';
-$sqllib[$i]['sql']="UPDATE forum SET options = options - 1 WHERE options & 1";
-$i++;
-
-$sqllib[$i]['name']=$lang['L_SQLLIB_ACTIVATEBOARD'] . ' [vBulletin]';
-$sqllib[$i]['sql']="UPDATE forum SET options = options + 1 WHERE NOT (options & 1)";
-$i++;
+$sqllib[$i]['name'] = $lang['L_SQLLIB_DEACTIVATEBOARD'].' [vBulletin]';
+$sqllib[$i]['sql'] = 'UPDATE forum SET options = options - 1 WHERE options & 1';
+++$i;
 
+$sqllib[$i]['name'] = $lang['L_SQLLIB_ACTIVATEBOARD'].' [vBulletin]';
+$sqllib[$i]['sql'] = 'UPDATE forum SET options = options + 1 WHERE NOT (options & 1)';
+++$i;
diff --git a/msd/inc/tabellenabfrage.php b/msd/inc/tabellenabfrage.php
deleted file mode 100644
index d6d671da..00000000
--- a/msd/inc/tabellenabfrage.php
+++ /dev/null
@@ -1,189 +0,0 @@
-<?php
-/* ----------------------------------------------------------------------
-
-   MyOOS [Dumper]
-   http://www.oos-shop.de/
-
-   Copyright (c) 2016 by the MyOOS Development Team.
-   ----------------------------------------------------------------------
-   Based on:
-
-   MySqlDumper
-   http://www.mysqldumper.de
-
-   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
-   ----------------------------------------------------------------------
-   Released under the GNU General Public License
-   ---------------------------------------------------------------------- */
-
-
-if (!defined('MSD_VERSION')) die('No direct access.');
-include ( './language/' . $config['language'] . '/lang.php' );
-include ( './language/' . $config['language'] . '/lang_dump.php' );
-include ( './inc/template.php' );
-$tblr=( $tblfrage_refer == 'dump' ) ? 'Backup' : 'Restore';
-$filename=( isset($_GET['filename']) ) ? $_GET['filename'] : '';
-if (isset($_POST['file'][0])) $filename=$_POST['file'][0];
-
-ob_start();
-$tpl=new MSDTemplate();
-$sel_dump_encoding=isset($_POST['sel_dump_encoding']) ? $_POST['sel_dump_encoding'] : '';
-$tpl=new MSDtemplate();
-
-//Informationen zusammenstellen
-if ($tblr == 'Backup')
-{
-	$tpl->set_filenames(array(
-							'show' => './tpl/dump_select_tables.tpl'
-	));
-	$button_name='dump_tbl';
-	//Info aus der Datenbank lesen
-	MSD_mysql_connect();
-	$res=mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `' . $databases['db_actual'] . '`');
-	$numrows=mysqli_num_rows($res);
-	$tbl_zeile='';
-	for ($i=0; $i < $numrows; $i++)
-	{
-		$row=mysqli_fetch_array($res,MYSQLI_ASSOC);
-		//v($row);
-		// Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
-		$sql_2="SELECT count(*) as `count_records` FROM `" . $databases['db_actual'] . "`.`" . $row['Name'] . "`";
-		$res2=@mysqli_query($config['dbconnection'], $sql_2);
-		if ($res2 === false)
-		{
-			$read_error='(' . mysql_errno() . ') ' . mysqli_error($config['dbconnection']);
-			$row['Rows']='<span class="error">' . $lang['L_ERROR'] . ': ' . $read_error . '</span>';
-		}
-		else
-		{
-			$row2=@mysqli_fetch_array($res2);
-			$row['Rows']=$row2['count_records'];
-		}
-
-		$klasse=( $i % 2 ) ? 1 : '';
-		$table_size=$row['Data_length'] + $row['Index_length'];
-		$table_type=$row['Engine'];
-		if (substr($row['Comment'],0,4) == 'VIEW')
-		{
-			$table_type='View';
-			$table_size='-';
-		}
-		$tpl->assign_block_vars('ROW',array(
-
-											'CLASS' => 'dbrow' . $klasse,
-											'ID' => $i,
-											'NR' => $i + 1,
-											'TABLENAME' => $row['Name'],
-											'TABLETYPE' => $table_type,
-											'RECORDS' => $table_type == 'View' ? '<i>' . $row['Rows'] . '</i>' : '<strong>' . $row['Rows'] . '</strong>',
-											'SIZE' => is_int($table_size) ? byte_output($table_size) : $table_size,
-											'LAST_UPDATE' => $row['Update_time']
-		));
-	}
-}
-else
-{
-	$tpl->set_filenames(array(
-
-							'show' => './tpl/restore_select_tables.tpl'
-	));
-	//Restore - Header aus Backupfile lesen
-	$button_name='restore_tbl';
-	$gz=( substr($filename,-3) ) == '.gz' ? 1 : 0;
-	if ($gz)
-	{
-		$fp=gzopen($fpath . $filename,"r");
-		$statusline=gzgets($fp,40960);
-		$offset=gztell($fp);
-	}
-	else
-	{
-		$fp=fopen($fpath . $filename,"r");
-		$statusline=fgets($fp,5000);
-		$offset=ftell($fp);
-	}
-	//Header auslesen
-	$sline=ReadStatusline($statusline);
-
-	$anzahl_tabellen=$sline['tables'];
-	$anzahl_eintraege=$sline['records'];
-	$tbl_zeile='';
-	$part=( $sline['part'] == '' ) ? 0 : substr($sline['part'],3);
-	if ($anzahl_eintraege == -1)
-	{
-		// not a backup of MySQLDumper
-		$tpl->assign_block_vars('NO_MSD_BACKUP',array());
-	}
-	else
-	{
-		$tabledata=array();
-		$i=0;
-		//Tabellenfinos lesen
-		gzseek($fp,$offset);
-		$eof=false;
-		while (!$eof)
-		{
-			$line=$gz ? gzgets($fp,40960) : fgets($fp,40960);
-
-			if (substr($line,0,9) == '-- TABLE|')
-			{
-				$d=explode('|',$line);
-				$tabledata[$i]['name']=$d[1];
-				$tabledata[$i]['records']=$d[2];
-				$tabledata[$i]['size']=$d[3];
-				$tabledata[$i]['update']=$d[4];
-				$tabledata[$i]['engine']=isset($d[5]) ? $d[5] : '';
-				$i++;
-			}
-			if (substr($line,0,6) == '-- EOF') $eof=true;
-			if (substr(strtolower($line),0,6) == 'create') $eof=true;
-		}
-		for ($i=0; $i < sizeof($tabledata); $i++)
-		{
-			$klasse=( $i % 2 ) ? 1 : '';
-			$tpl->assign_block_vars('ROW',array(
-
-												'CLASS' => 'dbrow' . $klasse,
-												'ID' => $i,
-												'NR' => $i + 1,
-												'TABLENAME' => $tabledata[$i]['name'],
-												'RECORDS' => $tabledata[$i]['records'],
-												'SIZE' => byte_output($tabledata[$i]['size']),
-												'LAST_UPDATE' => $tabledata[$i]['update'],
-												'TABLETYPE' => $tabledata[$i]['engine']
-			));
-		}
-	}
-	if ($gz) gzclose($fp);
-	else fclose($fp);
-}
-
-if (!isset($dk)) $dk='';
-
-$confirm_restore=$lang['L_FM_ALERTRESTORE1'] . ' `' . $databases['db_actual'] . '`  ' . $lang['L_FM_ALERTRESTORE2'] . ' ' . $filename . ' ' . $lang['L_FM_ALERTRESTORE3'];
-
-$tpl->assign_vars(array(
-
-						'PAGETITLE' => $tblr . ' -' . $lang['L_TABLESELECTION'],
-						'L_NAME' => $lang['L_NAME'],
-						'L_DATABASE' => $lang['L_DB'],
-						'DATABASE' => $databases['db_actual'],
-						'L_LAST_UPDATE' => $lang['L_LASTBUFROM'],
-						'SEL_DUMP_ENCODING' => $sel_dump_encoding,
-						'FILENAME' => $filename,
-						'DUMP_COMMENT' => $dk,
-						'BUTTON_NAME' => $button_name,
-						'L_START_BACKUP' => $lang['L_STARTDUMP'],
-						'L_START_RESTORE' => $lang['L_FM_RESTORE'],
-						'L_ROWS' => $lang['L_INFO_RECORDS'],
-						'L_SIZE' => $lang['L_INFO_SIZE'],
-						'L_TABLE_TYPE' => $lang['L_TABLE_TYPE'],
-						'L_SELECT_ALL' => $lang['L_SELECTALL'],
-						'L_DESELECT_ALL' => $lang['L_DESELECTALL'],
-						'L_RESTORE' => $lang['L_RESTORE'],
-						'L_NO_MSD_BACKUP' => $lang['L_NOT_SUPPORTED'],
-						'L_CONFIRM_RESTORE' => $confirm_restore
-));
-
-$tpl->pparse('show');
-ob_end_flush();
diff --git a/msd/inc/table_query.php b/msd/inc/table_query.php
new file mode 100644
index 00000000..0b1d51f5
--- /dev/null
+++ b/msd/inc/table_query.php
@@ -0,0 +1,181 @@
+<?php
+/* ----------------------------------------------------------------------
+
+   MyOOS [Dumper]
+   http://www.oos-shop.de/
+
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
+   ----------------------------------------------------------------------
+   Based on:
+
+   MySqlDumper
+   http://www.mysqldumper.de
+
+   Copyright (C)2004-2011 Daniel Schlichtholz (admin@mysqldumper.de)
+   ----------------------------------------------------------------------
+   Released under the GNU General Public License
+   ---------------------------------------------------------------------- */
+
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+include './language/'.$config['language'].'/lang.php';
+include './language/'.$config['language'].'/lang_dump.php';
+include './inc/template.php';
+$tblr = ('dump' == $tblfrage_refer) ? 'Backup' : 'Restore';
+$filename = (isset($_GET['filename'])) ? $_GET['filename'] : '';
+if (isset($_POST['file'][0])) {
+    $filename = $_POST['file'][0];
+}
+
+ob_start();
+$tpl = new MODTemplate();
+$sel_dump_encoding = isset($_POST['sel_dump_encoding']) ? $_POST['sel_dump_encoding'] : '';
+$tpl = new MODtemplate();
+
+//Informationen zusammenstellen
+if ('Backup' == $tblr) {
+    $tpl->set_filenames([
+                            'show' => './tpl/dump_select_tables.tpl',
+    ]);
+    $button_name = 'dump_tbl';
+    //Info aus der Datenbank lesen
+    mod_mysqli_connect();
+    $res = mysqli_query($config['dbconnection'], 'SHOW TABLE STATUS FROM `'.$databases['db_actual'].'`');
+    $numrows = mysqli_num_rows($res);
+    $tbl_zeile = '';
+    for ($i = 0; $i < $numrows; ++$i) {
+        $row = mysqli_fetch_array($res, MYSQLI_ASSOC);
+        //v($row);
+        // Get nr of records -> need to do it this way because of incorrect returns when using InnoDBs
+        $sql_2 = 'SELECT count(*) as `count_records` FROM `'.$databases['db_actual'].'`.`'.$row['Name'].'`';
+        $res2 = mysqli_query($config['dbconnection'], $sql_2);
+        if (false === $res2) {
+            $read_error = mysqli_error($config['dbconnection']);
+            $row['Rows'] = '<span class="error">'.$lang['L_ERROR'].': '.$read_error.'</span>';
+        } else {
+            $row2 = mysqli_fetch_array($res2);
+            $row['Rows'] = $row2['count_records'];
+        }
+
+        $klasse = ($i % 2) ? 1 : '';
+        $table_size = $row['Data_length'] + $row['Index_length'];
+        $table_type = $row['Engine'];
+        if ('VIEW' == substr($row['Comment'], 0, 4)) {
+            $table_type = 'View';
+            $table_size = '-';
+        }
+        $tpl->assign_block_vars('ROW', [
+                                            'CLASS' => 'dbrow'.$klasse,
+                                            'ID' => $i,
+                                            'NR' => $i + 1,
+                                            'TABLENAME' => $row['Name'],
+                                            'TABLETYPE' => $table_type,
+                                            'RECORDS' => 'View' == $table_type ? '<i>'.$row['Rows'].'</i>' : '<strong>'.$row['Rows'].'</strong>',
+                                            'SIZE' => is_int($table_size) ? byte_output($table_size) : $table_size,
+                                            'LAST_UPDATE' => $row['Update_time'],
+        ]);
+    }
+} else {
+    $tpl->set_filenames([
+                            'show' => './tpl/restore_select_tables.tpl',
+    ]);
+    //Restore - Header aus Backupfile lesen
+    $button_name = 'restore_tbl';
+    $gz = (substr($filename, -3)) == '.gz' ? 1 : 0;
+    if ($gz) {
+        $fp = gzopen($fpath.$filename, 'r');
+        $statusline = gzgets($fp, 40960);
+        $offset = gztell($fp);
+    } else {
+        $fp = fopen($fpath.$filename, 'r');
+        $statusline = fgets($fp, 5000);
+        $offset = ftell($fp);
+    }
+    //Header auslesen
+    $sline = ReadStatusline($statusline);
+
+    $anzahl_tabellen = $sline['tables'];
+    $anzahl_eintraege = $sline['records'];
+    $tbl_zeile = '';
+    $part = ('' == $sline['part']) ? 0 : substr($sline['part'], 3);
+    if (-1 == $anzahl_eintraege) {
+        // not a backup of MySQLDumper
+        $tpl->assign_block_vars('NO_MOD_BACKUP', []);
+    } else {
+        $tabledata = [];
+        $i = 0;
+        //Tabellenfinos lesen
+        gzseek($fp, $offset);
+        $eof = false;
+        while (!$eof) {
+            $line = $gz ? gzgets($fp, 40960) : fgets($fp, 40960);
+
+            if ('-- TABLE|' == substr($line, 0, 9)) {
+                $d = explode('|', $line);
+                $tabledata[$i]['name'] = $d[1];
+                $tabledata[$i]['records'] = $d[2];
+                $tabledata[$i]['size'] = $d[3];
+                $tabledata[$i]['update'] = $d[4];
+                $tabledata[$i]['engine'] = isset($d[5]) ? $d[5] : '';
+                ++$i;
+            }
+            if ('-- EOF' == substr($line, 0, 6)) {
+                $eof = true;
+            }
+            if ('create' == substr(strtolower($line), 0, 6)) {
+                $eof = true;
+            }
+        }
+        for ($i = 0; $i < sizeof($tabledata); ++$i) {
+            $klasse = ($i % 2) ? 1 : '';
+            $tpl->assign_block_vars('ROW', [
+                                                'CLASS' => 'dbrow'.$klasse,
+                                                'ID' => $i,
+                                                'NR' => $i + 1,
+                                                'TABLENAME' => $tabledata[$i]['name'],
+                                                'RECORDS' => $tabledata[$i]['records'],
+                                                'SIZE' => byte_output($tabledata[$i]['size']),
+                                                'LAST_UPDATE' => $tabledata[$i]['update'],
+                                                'TABLETYPE' => $tabledata[$i]['engine'],
+            ]);
+        }
+    }
+    if ($gz) {
+        gzclose($fp);
+    } else {
+        fclose($fp);
+    }
+}
+
+if (!isset($dk)) {
+    $dk = '';
+}
+
+$confirm_restore = $lang['L_FM_ALERTRESTORE1'].' `'.$databases['db_actual'].'`  '.$lang['L_FM_ALERTRESTORE2'].' '.$filename.' '.$lang['L_FM_ALERTRESTORE3'];
+
+$tpl->assign_vars([
+                        'PAGETITLE' => $tblr.' -'.$lang['L_TABLESELECTION'],
+                        'L_NAME' => $lang['L_NAME'],
+                        'L_DATABASE' => $lang['L_DB'],
+                        'DATABASE' => $databases['db_actual'],
+                        'L_LAST_UPDATE' => $lang['L_LASTBUFROM'],
+                        'SEL_DUMP_ENCODING' => $sel_dump_encoding,
+                        'FILENAME' => $filename,
+                        'DUMP_COMMENT' => $dk,
+                        'BUTTON_NAME' => $button_name,
+                        'L_START_BACKUP' => $lang['L_STARTDUMP'],
+                        'L_START_RESTORE' => $lang['L_FM_RESTORE'],
+                        'L_ROWS' => $lang['L_INFO_RECORDS'],
+                        'L_SIZE' => $lang['L_INFO_SIZE'],
+                        'L_TABLE_TYPE' => $lang['L_TABLE_TYPE'],
+                        'L_SELECT_ALL' => $lang['L_SELECTALL'],
+                        'L_DESELECT_ALL' => $lang['L_DESELECTALL'],
+                        'L_RESTORE' => $lang['L_RESTORE'],
+                        'L_NO_MOD_BACKUP' => $lang['L_NOT_SUPPORTED'],
+                        'L_CONFIRM_RESTORE' => $confirm_restore,
+]);
+
+$tpl->pparse('show');
+ob_end_flush();
+exit();
diff --git a/msd/inc/template.php b/msd/inc/template.php
index c77457b0..94a020ef 100644
--- a/msd/inc/template.php
+++ b/msd/inc/template.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,9 +16,10 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
-if (!defined('MSD_VERSION')) die('No direct access.');
-define('TPL_DEBUG',0); // used if evaluationg of template fails
+if (!defined('MOD_VERSION')) {
+    exit('No direct access.');
+}
+define('TPL_DEBUG', 0); // used if evaluationg of template fails
 /***************************************************************************
  *                              template.php
  *                            -------------------
@@ -44,457 +45,412 @@ define('TPL_DEBUG',0); // used if evaluationg of template fails
  * Template class. By Nathan Codding of the phpBB group.
  * The interface was originally inspired by PHPLib templates,
  * and the template file formats are quite similar.
- *
  */
-
-class MSDTemplate
+class MODTemplate
 {
-	var $classname="MSDTemplate";
+    public $classname = 'MODTemplate';
 
-	// variable that holds all the data we'll be substituting into
-	// the compiled templates.
-	// ...
-	// This will end up being a multi-dimensional array like this:
-	// $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
-	// if it's a root-level variable, it'll be like this:
-	// $this->_tpldata[.][0][varname] == value
-	var $_tpldata=array();
+    // variable that holds all the data we'll be substituting into
+    // the compiled templates.
+    // ...
+    // This will end up being a multi-dimensional array like this:
+    // $this->_tpldata[block.][iteration#][child.][iteration#][child2.][iteration#][variablename] == value
+    // if it's a root-level variable, it'll be like this:
+    // $this->_tpldata[.][0][varname] == value
+    public $_tpldata = [];
 
-	// Hash of filenames for each template handle.
-	var $files=array();
+    // Hash of filenames for each template handle.
+    public $files = [];
 
-	// Root template directory.
-	var $root="";
+    // Root template directory.
+    public $root = '';
 
-	// this will hash handle names to the compiled code for that handle.
-	var $compiled_code=array();
+    // this will hash handle names to the compiled code for that handle.
+    public $compiled_code = [];
 
-	// This will hold the uncompiled code for that handle.
-	var $uncompiled_code=array();
+    // This will hold the uncompiled code for that handle.
+    public $uncompiled_code = [];
 
-	/**
-	 * Constructor. Simply sets the root dir.
-	 *
-	 */
-	public function __construct($root=".")
-	{
-		$this->set_rootdir($root);
-	}
+    /**
+     * Constructor. Simply sets the root dir.
+     */
+    public function __construct($root = '.')
+    {
+        $this->set_rootdir($root);
+    }
 
-	/**
-	 * Destroys this template object. Should be called when you're done with it, in order
-	 * to clear out the template data so you can load/parse a new template set.
-	 */
-	public function destroy()
-	{
-		$this->_tpldata=array();
-	}
+    /**
+     * Destroys this template object. Should be called when you're done with it, in order
+     * to clear out the template data so you can load/parse a new template set.
+     */
+    public function destroy()
+    {
+        $this->_tpldata = [];
+    }
 
-	/**
-	 * Sets the template root directory for this Template object.
-	 */
-	public function set_rootdir($dir)
-	{
-		if (!is_dir($dir))
-		{
-			return false;
-		}
-		$this->root=$dir;
-		return true;
-	}
+    /**
+     * Sets the template root directory for this Template object.
+     */
+    public function set_rootdir($dir)
+    {
+        if (!is_dir($dir)) {
+            return false;
+        }
+        $this->root = $dir;
+        return true;
+    }
 
-	/**
-	 * Sets the template filenames for handles. $filename_array
-	 * should be a hash of handle => filename pairs.
-	 */
-	public function set_filenames($filename_array)
-	{
-		if (!is_array($filename_array))
-		{
-			return false;
-		}
+    /**
+     * Sets the template filenames for handles. $filename_array
+     * should be a hash of handle => filename pairs.
+     */
+    public function set_filenames($filename_array)
+    {
+        if (!is_array($filename_array)) {
+            return false;
+        }
 
-		reset($filename_array);
-		while (list ($handle, $filename)=each($filename_array))
-		{
-			$this->files[$handle]=$this->make_filename($filename);
-		}
+        reset($filename_array);
+        foreach ($filename_array as $handle => $filename) {
+            $this->files[$handle] = $this->make_filename($filename);
+        }
 
-		return true;
-	}
+        return true;
+    }
 
-	/**
-	 * Load the file for the handle, compile the file,
-	 * and run the compiled code. This will print out
-	 * the results of executing the template.
-	 */
-	public function pparse($handle)
-	{
-		// Edit DSB: autimatically assign language vars
-		global $lang;
-		$this->assign_vars($lang);
+    /**
+     * Load the file for the handle, compile the file,
+     * and run the compiled code. This will print out
+     * the results of executing the template.
+     */
+    public function pparse($handle)
+    {
+        // Edit DSB: autimatically assign language vars
+        global $lang;
+        $this->assign_vars($lang);
 
-		if (!$this->loadfile($handle))
-		{
-			die("Template->pparse(): Couldn't load template file for handle $handle");
-		}
+        if (!$this->loadfile($handle)) {
+            exit("Template->pparse(): Couldn't load template file for handle $handle");
+        }
 
-		// actually compile the template now.
-		if (!isset($this->compiled_code[$handle]) || empty($this->compiled_code[$handle]))
-		{
-			// Actually compile the code now.
-			$this->compiled_code[$handle]=$this->compile($this->uncompiled_code[$handle]);
-		}
+        // actually compile the template now.
+        if (!isset($this->compiled_code[$handle]) || empty($this->compiled_code[$handle])) {
+            // Actually compile the code now.
+            $this->compiled_code[$handle] = $this->compile($this->uncompiled_code[$handle]);
+        }
 
-		// Run the compiled code.
-		if (defined(TPL_DEBUG) && TPL_DEBUG>0) echo '<pre>'.htmlspecialchars($this->compiled_code[$handle]).'</pre>';
-		eval($this->compiled_code[$handle]);
-		return true;
-	}
+        // Run the compiled code.
+        if (defined(TPL_DEBUG) && TPL_DEBUG > 0) {
+            echo '<pre>'.htmlspecialchars($this->compiled_code[$handle]).'</pre>';
+        }
+        eval($this->compiled_code[$handle]);
+        return true;
+    }
 
-	/**
-	 * Inserts the uncompiled code for $handle as the
-	 * value of $varname in the root-level. This can be used
-	 * to effectively include a template in the middle of another
-	 * template.
-	 * Note that all desired assignments to the variables in $handle should be done
-	 * BEFORE calling this function.
-	 */
-	public function assign_var_from_handle($varname, $handle)
-	{
-		if (!$this->loadfile($handle))
-		{
-			die("Template->assign_var_from_handle(): Couldn't load template file for handle $handle");
-		}
+    /**
+     * Inserts the uncompiled code for $handle as the
+     * value of $varname in the root-level. This can be used
+     * to effectively include a template in the middle of another
+     * template.
+     * Note that all desired assignments to the variables in $handle should be done
+     * BEFORE calling this function.
+     */
+    public function assign_var_from_handle($varname, $handle)
+    {
+        if (!$this->loadfile($handle)) {
+            exit("Template->assign_var_from_handle(): Couldn't load template file for handle $handle");
+        }
 
-		// Compile it, with the "no echo statements" option on.
-		$_str="";
-		$code=$this->compile($this->uncompiled_code[$handle],true,'_str');
+        // Compile it, with the "no echo statements" option on.
+        $_str = '';
+        $code = $this->compile($this->uncompiled_code[$handle], true, '_str');
 
-		// evaluate the variable assignment.
-		eval($code);
-		// assign the value of the generated variable to the given varname.
-		$this->assign_var($varname,$_str);
+        // evaluate the variable assignment.
+        eval($code);
+        // assign the value of the generated variable to the given varname.
+        $this->assign_var($varname, $_str);
 
-		return true;
-	}
+        return true;
+    }
 
-	/**
-	 * Block-level variable assignment. Adds a new block iteration with the given
-	 * variable assignments. Note that this should only be called once per block
-	 * iteration.
-	 */
-	public function assign_block_vars($blockname, $vararray)
-	{
-		if (strstr($blockname,'.'))
-		{
-			// Nested block.
-			$blocks=explode('.',$blockname);
-			$blockcount=sizeof($blocks) - 1;
-			$str='$this->_tpldata';
-			for ($i=0; $i < $blockcount; $i++)
-			{
-				$str.='[\'' . $blocks[$i] . '.\']';
-				eval('$lastiteration = sizeof(' . $str . ') - 1;');
-				$str.='[' . $lastiteration . ']';
-			}
-			// Now we add the block that we're actually assigning to.
-			// We're adding a new iteration to this block with the given
-			// variable assignments.
-			$str.='[\'' . $blocks[$blockcount] . '.\'][] = $vararray;';
+    /**
+     * Block-level variable assignment. Adds a new block iteration with the given
+     * variable assignments. Note that this should only be called once per block
+     * iteration.
+     */
+    public function assign_block_vars($blockname, $vararray)
+    {
+        if (strstr($blockname, '.')) {
+            // Nested block.
+            $blocks = explode('.', $blockname);
+            $blockcount = sizeof($blocks) - 1;
+            $str = '$this->_tpldata';
+            for ($i = 0; $i < $blockcount; ++$i) {
+                $str .= '[\''.$blocks[$i].'.\']';
+                eval('$lastiteration = sizeof('.$str.') - 1;');
+                $str .= '['.$lastiteration.']';
+            }
+            // Now we add the block that we're actually assigning to.
+            // We're adding a new iteration to this block with the given
+            // variable assignments.
+            $str .= '[\''.$blocks[$blockcount].'.\'][] = $vararray;';
 
-			// Now we evaluate this assignment we've built up.
-			eval($str);
-		}
-		else
-		{
-			// Top-level block.
-			// Add a new iteration to this block with the variable assignments
-			// we were given.
-			$this->_tpldata[$blockname . '.'][]=$vararray;
-		}
+            // Now we evaluate this assignment we've built up.
+            eval($str);
+        } else {
+            // Top-level block.
+            // Add a new iteration to this block with the variable assignments
+            // we were given.
+            $this->_tpldata[$blockname.'.'][] = $vararray;
+        }
 
-		return true;
-	}
+        return true;
+    }
 
-	/**
-	 * Root-level variable assignment. Adds to current assignments, overriding
-	 * any existing variable assignment with the same name.
-	 */
-	public function assign_vars($vararray)
-	{
-		global $lang;
-		while (list ($key, $val)=each($vararray))
-		{
-			$this->_tpldata['.'][0][$key]=$val;
-		}
+    /**
+     * Root-level variable assignment. Adds to current assignments, overriding
+     * any existing variable assignment with the same name.
+     */
+    public function assign_vars($vararray)
+    {
+        global $lang;
+        foreach ($vararray as $key => $val) {
+            $this->_tpldata['.'][0][$key] = $val;
+        }
 
-		return true;
-	}
+        return true;
+    }
 
-	/**
-	 * Root-level variable assignment. Adds to current assignments, overriding
-	 * any existing variable assignment with the same name.
-	 */
-	public function assign_var($varname, $varval)
-	{
-		$this->_tpldata['.'][0][$varname]=$varval;
+    /**
+     * Root-level variable assignment. Adds to current assignments, overriding
+     * any existing variable assignment with the same name.
+     */
+    public function assign_var($varname, $varval)
+    {
+        $this->_tpldata['.'][0][$varname] = $varval;
 
-		return true;
-	}
+        return true;
+    }
 
-	/**
-	 * Generates a full path+filename for the given filename, which can either
-	 * be an absolute name, or a name relative to the rootdir for this Template
-	 * object.
-	 */
-	public function make_filename($filename)
-	{
-		// Check if it's an absolute or relative path.
-		/*
-		if (substr($filename, 0, 1) != '/')
-		{
-       		$filename = $this->root . '/' . $filename;
-		}
-*/
-		if (!file_exists($filename))
-		{
-			die("Template->make_filename(): Error - file $filename does not exist");
-		}
+    /**
+     * Generates a full path+filename for the given filename, which can either
+     * be an absolute name, or a name relative to the rootdir for this Template
+     * object.
+     */
+    public function make_filename($filename)
+    {
+        // Check if it's an absolute or relative path.
+        /*
+        if (substr($filename, 0, 1) != '/')
+        {
+               $filename = $this->root.'/'.$filename;
+        }
+        */
+        if (!file_exists($filename)) {
+            exit("Template->make_filename(): Error - file $filename does not exist");
+        }
 
-		return $filename;
-	}
+        return $filename;
+    }
 
-	/**
-	 * If not already done, load the file for the given handle and populate
-	 * the uncompiled_code[] hash with its code. Do not compile.
-	 */
-	public function loadfile($handle)
-	{
-		// If the file for this handle is already loaded and compiled, do nothing.
-		if (isset($this->uncompiled_code[$handle]) && !empty($this->uncompiled_code[$handle]))
-		{
-			return true;
-		}
+    /**
+     * If not already done, load the file for the given handle and populate
+     * the uncompiled_code[] hash with its code. Do not compile.
+     */
+    public function loadfile($handle)
+    {
+        // If the file for this handle is already loaded and compiled, do nothing.
+        if (isset($this->uncompiled_code[$handle]) && !empty($this->uncompiled_code[$handle])) {
+            return true;
+        }
 
-		// If we don't have a file assigned to this handle, die.
-		if (!isset($this->files[$handle]))
-		{
-			die("Template->loadfile(): No file specified for handle $handle");
-		}
+        // If we don't have a file assigned to this handle, die.
+        if (!isset($this->files[$handle])) {
+            exit("Template->loadfile(): No file specified for handle $handle");
+        }
 
-		$filename=$this->files[$handle];
+        $filename = $this->files[$handle];
 
-		$str=implode("",@file($filename));
-		if (empty($str))
-		{
-			die("Template->loadfile(): File $filename for handle $handle is empty");
-		}
+        $str = implode('', @file($filename));
+        if (empty($str)) {
+            exit("Template->loadfile(): File $filename for handle $handle is empty");
+        }
 
-		$this->uncompiled_code[$handle]=$str;
+        $this->uncompiled_code[$handle] = $str;
 
-		return true;
-	}
+        return true;
+    }
 
-	/**
-	 * Compiles the given string of code, and returns
-	 * the result in a string.
-	 * If "do_not_echo" is true, the returned code will not be directly
-	 * executable, but can be used as part of a variable assignment
-	 * for use in assign_code_from_handle().
-	 */
-	public function compile($code, $do_not_echo=false, $retvar='')
-	{
-		// replace \ with \\ and then ' with \'.
-		$code=str_replace('\\','\\\\',$code);
-		$code=str_replace('\'','\\\'',$code);
+    /**
+     * Compiles the given string of code, and returns
+     * the result in a string.
+     * If "do_not_echo" is true, the returned code will not be directly
+     * executable, but can be used as part of a variable assignment
+     * for use in assign_code_from_handle().
+     */
+    public function compile($code, $do_not_echo = false, $retvar = '')
+    {
+        // replace \ with \\ and then ' with \'.
+        $code = str_replace('\\', '\\\\', $code);
+        $code = str_replace('\'', '\\\'', $code);
 
+        // change template varrefs into PHP varrefs
 
-		// change template varrefs into PHP varrefs
+        // This one will handle varrefs WITH namespaces
+        $varrefs = [];
+        preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is', $code, $varrefs);
+        $varcount = sizeof($varrefs[1]);
+        for ($i = 0; $i < $varcount; ++$i) {
+            $namespace = $varrefs[1][$i];
+            $varname = $varrefs[3][$i];
+            $new = $this->generate_block_varref($namespace, $varname);
 
+            $code = str_replace($varrefs[0][$i], $new, $code);
+        }
 
-		// This one will handle varrefs WITH namespaces
-		$varrefs=array();
-		preg_match_all('#\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}#is',$code,$varrefs);
-		$varcount=sizeof($varrefs[1]);
-		for ($i=0; $i < $varcount; $i++)
-		{
-			$namespace=$varrefs[1][$i];
-			$varname=$varrefs[3][$i];
-			$new=$this->generate_block_varref($namespace,$varname);
+        // This will handle the remaining root-level varrefs
+        $code = preg_replace('#\{([a-z0-9\-_]*?)\}#is', '\'.( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'', $code);
 
-			$code=str_replace($varrefs[0][$i],$new,$code);
-		}
+        // Break it up into lines.
+        $code_lines = explode("\n", $code);
 
-		// This will handle the remaining root-level varrefs
-		$code=preg_replace('#\{([a-z0-9\-_]*?)\}#is','\' . ( ( isset($this->_tpldata[\'.\'][0][\'\1\']) ) ? $this->_tpldata[\'.\'][0][\'\1\'] : \'\' ) . \'',$code);
+        $block_nesting_level = 0;
+        $block_names = [];
+        $block_names[0] = '.';
 
-		// Break it up into lines.
-		$code_lines=explode("\n",$code);
+        // Second: prepend echo ', append '."\n"; to each line.
+        $line_count = sizeof($code_lines);
+        for ($i = 0; $i < $line_count; ++$i) {
+            $code_lines[$i] = chop($code_lines[$i]);
+            if (preg_match('#<!-- BEGIN (.*?) -->#', $code_lines[$i], $m)) {
+                $n[0] = $m[0];
+                $n[1] = $m[1];
 
-		$block_nesting_level=0;
-		$block_names=array();
-		$block_names[0]=".";
+                // Added: dougk_ff7-Keeps templates from bombing if begin is on the same line as end.. I think. :)
+                if (preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $n)) {
+                    ++$block_nesting_level;
+                    $block_names[$block_nesting_level] = $m[1];
+                    if ($block_nesting_level < 2) {
+                        // Block is not nested.
+                        $code_lines[$i] = '$_'.$n[1].'_count = ( isset($this->_tpldata[\''.$n[1].'.\']) ) ?  sizeof($this->_tpldata[\''.$n[1].'.\']) : 0;';
+                        $code_lines[$i] .= "\n".'for ($_'.$n[1].'_i = 0; $_'.$n[1].'_i < $_'.$n[1].'_count; $_'.$n[1].'_i++)';
+                        $code_lines[$i] .= "\n".'{';
+                    } else {
+                        // This block is nested.
 
-		// Second: prepend echo ', append ' . "\n"; to each line.
-		$line_count=sizeof($code_lines);
-		for ($i=0; $i < $line_count; $i++)
-		{
-			$code_lines[$i]=chop($code_lines[$i]);
-			if (preg_match('#<!-- BEGIN (.*?) -->#',$code_lines[$i],$m))
-			{
-				$n[0]=$m[0];
-				$n[1]=$m[1];
+                        // Generate a namespace string for this block.
+                        $namespace = implode('.', $block_names);
+                        // strip leading period from root level..
+                        $namespace = substr($namespace, 2);
+                        // Get a reference to the data array for this block that depends on the
+                        // current indices of all parent blocks.
+                        $varref = $this->generate_block_data_ref($namespace, false);
+                        // Create the for loop code to iterate over this block.
+                        $code_lines[$i] = '$_'.$n[1].'_count = ( isset('.$varref.') ) ? sizeof('.$varref.') : 0;';
+                        $code_lines[$i] .= "\n".'for ($_'.$n[1].'_i = 0; $_'.$n[1].'_i < $_'.$n[1].'_count; $_'.$n[1].'_i++)';
+                        $code_lines[$i] .= "\n".'{';
+                    }
 
-				// Added: dougk_ff7-Keeps templates from bombing if begin is on the same line as end.. I think. :)
-				if (preg_match('#<!-- END (.*?) -->#',$code_lines[$i],$n))
-				{
-					$block_nesting_level++;
-					$block_names[$block_nesting_level]=$m[1];
-					if ($block_nesting_level < 2)
-					{
-						// Block is not nested.
-						$code_lines[$i]='$_' . $n[1] . '_count = ( isset($this->_tpldata[\'' . $n[1] . '.\']) ) ?  sizeof($this->_tpldata[\'' . $n[1] . '.\']) : 0;';
-						$code_lines[$i].="\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
-						$code_lines[$i].="\n" . '{';
-					}
-					else
-					{
-						// This block is nested.
+                    // We have the end of a block.
+                    unset($block_names[$block_nesting_level]);
+                    --$block_nesting_level;
+                    $code_lines[$i] .= '} // END '.$n[1];
+                    $m[0] = $n[0];
+                    $m[1] = $n[1];
+                } else {
+                    // We have the start of a block.
+                    ++$block_nesting_level;
+                    $block_names[$block_nesting_level] = $m[1];
+                    if ($block_nesting_level < 2) {
+                        // Block is not nested.
+                        $code_lines[$i] = '$_'.$m[1].'_count = ( isset($this->_tpldata[\''.$m[1].'.\']) ) ? sizeof($this->_tpldata[\''.$m[1].'.\']) : 0;';
+                        $code_lines[$i] .= "\n".'for ($_'.$m[1].'_i = 0; $_'.$m[1].'_i < $_'.$m[1].'_count; $_'.$m[1].'_i++)';
+                        $code_lines[$i] .= "\n".'{';
+                    } else {
+                        // This block is nested.
 
+                        // Generate a namespace string for this block.
+                        $namespace = implode('.', $block_names);
+                        // strip leading period from root level..
+                        $namespace = substr($namespace, 2);
+                        // Get a reference to the data array for this block that depends on the
+                        // current indices of all parent blocks.
+                        $varref = $this->generate_block_data_ref($namespace, false);
+                        // Create the for loop code to iterate over this block.
+                        $code_lines[$i] = '$_'.$m[1].'_count = ( isset('.$varref.') ) ? sizeof('.$varref.') : 0;';
+                        $code_lines[$i] .= "\n".'for ($_'.$m[1].'_i = 0; $_'.$m[1].'_i < $_'.$m[1].'_count; $_'.$m[1].'_i++)';
+                        $code_lines[$i] .= "\n".'{';
+                    }
+                }
+            } elseif (preg_match('#<!-- END (.*?) -->#', $code_lines[$i], $m)) {
+                // We have the end of a block.
+                unset($block_names[$block_nesting_level]);
+                --$block_nesting_level;
+                $code_lines[$i] = '} // END '.$m[1];
+            } else {
+                // We have an ordinary line of code.
+                if (!$do_not_echo) {
+                    $code_lines[$i] = 'echo \''.$code_lines[$i].'\'."\\n";';
+                } else {
+                    $code_lines[$i] = '$'.$retvar.'.= \''.$code_lines[$i].'\'."\\n";';
+                }
+            }
+        }
 
-						// Generate a namespace string for this block.
-						$namespace=implode('.',$block_names);
-						// strip leading period from root level..
-						$namespace=substr($namespace,2);
-						// Get a reference to the data array for this block that depends on the
-						// current indices of all parent blocks.
-						$varref=$this->generate_block_data_ref($namespace,false);
-						// Create the for loop code to iterate over this block.
-						$code_lines[$i]='$_' . $n[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
-						$code_lines[$i].="\n" . 'for ($_' . $n[1] . '_i = 0; $_' . $n[1] . '_i < $_' . $n[1] . '_count; $_' . $n[1] . '_i++)';
-						$code_lines[$i].="\n" . '{';
-					}
+        // Bring it back into a single string of lines of code.
+        $code = implode("\n", $code_lines);
+        return $code;
+    }
 
-					// We have the end of a block.
-					unset($block_names[$block_nesting_level]);
-					$block_nesting_level--;
-					$code_lines[$i].='} // END ' . $n[1];
-					$m[0]=$n[0];
-					$m[1]=$n[1];
-				}
-				else
-				{
-					// We have the start of a block.
-					$block_nesting_level++;
-					$block_names[$block_nesting_level]=$m[1];
-					if ($block_nesting_level < 2)
-					{
-						// Block is not nested.
-						$code_lines[$i]='$_' . $m[1] . '_count = ( isset($this->_tpldata[\'' . $m[1] . '.\']) ) ? sizeof($this->_tpldata[\'' . $m[1] . '.\']) : 0;';
-						$code_lines[$i].="\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
-						$code_lines[$i].="\n" . '{';
-					}
-					else
-					{
-						// This block is nested.
+    /**
+     * Generates a reference to the given variable inside the given (possibly nested)
+     * block namespace. This is a string of the form:
+     * '.$this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'].'
+     * It's ready to be inserted into an "echo" line in one of the templates.
+     * NOTE: expects a trailing "." on the namespace.
+     */
+    public function generate_block_varref($namespace, $varname)
+    {
+        // Strip the trailing period.
+        $namespace = substr($namespace, 0, strlen($namespace) - 1);
 
+        // Get a reference to the data block for this namespace.
+        $varref = $this->generate_block_data_ref($namespace, true);
+        // Prepend the necessary code to stick this in an echo line.
 
-						// Generate a namespace string for this block.
-						$namespace=implode('.',$block_names);
-						// strip leading period from root level..
-						$namespace=substr($namespace,2);
-						// Get a reference to the data array for this block that depends on the
-						// current indices of all parent blocks.
-						$varref=$this->generate_block_data_ref($namespace,false);
-						// Create the for loop code to iterate over this block.
-						$code_lines[$i]='$_' . $m[1] . '_count = ( isset(' . $varref . ') ) ? sizeof(' . $varref . ') : 0;';
-						$code_lines[$i].="\n" . 'for ($_' . $m[1] . '_i = 0; $_' . $m[1] . '_i < $_' . $m[1] . '_count; $_' . $m[1] . '_i++)';
-						$code_lines[$i].="\n" . '{';
-					}
-				}
-			}
-			elseif (preg_match('#<!-- END (.*?) -->#',$code_lines[$i],$m))
-			{
-				// We have the end of a block.
-				unset($block_names[$block_nesting_level]);
-				$block_nesting_level--;
-				$code_lines[$i]='} // END ' . $m[1];
-			}
-			else
-			{
-				// We have an ordinary line of code.
-				if (!$do_not_echo)
-				{
-					$code_lines[$i]='echo \'' . $code_lines[$i] . '\' . "\\n";';
-				}
-				else
-				{
-					$code_lines[$i]='$' . $retvar . '.= \'' . $code_lines[$i] . '\' . "\\n";';
-				}
-			}
-		}
+        // Append the variable reference.
+        $varref .= '[\''.$varname.'\']';
 
-		// Bring it back into a single string of lines of code.
-		$code=implode("\n",$code_lines);
-		return $code;
+        $varref = '\'.( ( isset('.$varref.') ) ? '.$varref.' : \'\' ) . \'';
 
-	}
+        return $varref;
+    }
 
-	/**
-	 * Generates a reference to the given variable inside the given (possibly nested)
-	 * block namespace. This is a string of the form:
-	 * ' . $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . '
-	 * It's ready to be inserted into an "echo" line in one of the templates.
-	 * NOTE: expects a trailing "." on the namespace.
-	 */
-	public function generate_block_varref($namespace, $varname)
-	{
-		// Strip the trailing period.
-		$namespace=substr($namespace,0,strlen($namespace) - 1);
-
-		// Get a reference to the data block for this namespace.
-		$varref=$this->generate_block_data_ref($namespace,true);
-		// Prepend the necessary code to stick this in an echo line.
-
-
-		// Append the variable reference.
-		$varref.='[\'' . $varname . '\']';
-
-		$varref='\' . ( ( isset(' . $varref . ') ) ? ' . $varref . ' : \'\' ) . \'';
-
-		return $varref;
-
-	}
-
-	/**
-	 * Generates a reference to the array of data values for the given
-	 * (possibly nested) block namespace. This is a string of the form:
-	 * $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN']
-	 *
-	 * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
-	 * NOTE: does not expect a trailing "." on the blockname.
-	 */
-	public function generate_block_data_ref($blockname, $include_last_iterator)
-	{
-		// Get an array of the blocks involved.
-		$blocks=explode(".",$blockname);
-		$blockcount=sizeof($blocks) - 1;
-		$varref='$this->_tpldata';
-		// Build up the string with everything but the last child.
-		for ($i=0; $i < $blockcount; $i++)
-		{
-			$varref.='[\'' . $blocks[$i] . '.\'][$_' . $blocks[$i] . '_i]';
-		}
-		// Add the block reference for the last child.
-		$varref.='[\'' . $blocks[$blockcount] . '.\']';
-		// Add the iterator for the last child if requried.
-		if ($include_last_iterator)
-		{
-			$varref.='[$_' . $blocks[$blockcount] . '_i]';
-		}
-
-		return $varref;
-	}
+    /**
+     * Generates a reference to the array of data values for the given
+     * (possibly nested) block namespace. This is a string of the form:
+     * $this->_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN'].
+     *
+     * If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
+     * NOTE: does not expect a trailing "." on the blockname.
+     */
+    public function generate_block_data_ref($blockname, $include_last_iterator)
+    {
+        // Get an array of the blocks involved.
+        $blocks = explode('.', $blockname);
+        $blockcount = sizeof($blocks) - 1;
+        $varref = '$this->_tpldata';
+        // Build up the string with everything but the last child.
+        for ($i = 0; $i < $blockcount; ++$i) {
+            $varref .= '[\''.$blocks[$i].'.\'][$_'.$blocks[$i].'_i]';
+        }
+        // Add the block reference for the last child.
+        $varref .= '[\''.$blocks[$blockcount].'.\']';
+        // Add the iterator for the last child if requried.
+        if ($include_last_iterator) {
+            $varref .= '[$_'.$blocks[$blockcount].'_i]';
+        }
 
+        return $varref;
+    }
 }
diff --git a/msd/index.php b/msd/index.php
index 6523aca7..c2fa1526 100644
--- a/msd/index.php
+++ b/msd/index.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,14 +18,16 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-include ('./inc/functions.php');
-$page=(isset($_GET['page'])) ? $_GET['page'] : 'main.php';
-if (!file_exists("./work/config/myoosdumper.php"))
-{
-	header("location: install.php");
-	ob_end_flush();
-	die();
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
+include './inc/functions.php';
+$page = (isset($_GET['page'])) ? $_GET['page'] : 'main.php';
+if (!file_exists('./work/config/myoosdumper.php')) {
+    header('location: install.php');
+    ob_end_flush();
+    exit();
 }
 ?>
 <!DOCTYPE HTML>
@@ -34,18 +36,16 @@ if (!file_exists("./work/config/myoosdumper.php"))
 	<meta charset="utf-8" />
 	<meta name="robots" content="noindex,nofollow" />
 	<meta http-equiv="X-UA-Compatible" content="IE=Edge">
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 	<title>MyOOS [Dumper]</title>
 </head>
 
 <frameset border=0 cols="190,*">
 	<frame name="MyOOS_Dumper_menu" src="menu.php" scrolling="no" noresize
 		frameborder="0" marginwidth="0" marginheight="0">
-	<frame name="MyOOS_Dumper_content" src="<?php
-	echo $page;
-	?>"
-		scrolling="auto" frameborder="0" marginwidth="0" marginheight="0">
+	<frame name="MyOOS_Dumper_content" src="<?php echo $page; ?>" scrolling="auto" frameborder="0" marginwidth="0" marginheight="0">
 </frameset>
 </html>
 <?php
+
 ob_end_flush();
+exit();
diff --git a/msd/install.php b/msd/install.php
index d1d1f04f..d6ee0279 100644
--- a/msd/install.php
+++ b/msd/install.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,81 +18,81 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-$install_ftp_server=$install_ftp_user_name=$install_ftp_user_pass=$install_ftp_path="";
-$dbhost=$dbuser=$dbpass=$dbport=$dbsocket=$manual_db='';
-foreach ($_GET as $getvar=>$getval)
-{
-	${$getvar}=$getval;
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
 }
-foreach ($_POST as $postvar=>$postval)
-{
-	${$postvar}=$postval;
-}
-include_once ( './inc/functions.php' );
-include_once ( './inc/mysql.php' );
-include_once ( './inc/runtime.php' );
-if (!isset($language)) $language="en";
 
-$config['language']=$language;
-include ( './language/lang_list.php' );
-include ( 'language/' . $language . '/lang_install.php' );
-include ( 'language/' . $language . '/lang_main.php' );
-include ( 'language/' . $language . '/lang_config_overview.php' );
-
-//Übergabe der Parameter über FORM
-if (isset($_POST['dbhost']))
-{
-	$config['dbhost']=$dbhost;
-	$config['dbuser']=$dbuser;
-	$config['dbpass']=$dbpass;
-	$config['dbport']=$dbport;
-	$config['dbsocket']=$dbsocket;
-	$config['manual_db']=$manual_db;
+$install_ftp_server = $install_ftp_user_name = $install_ftp_user_pass = $install_ftp_path = '';
+$dbhost = $dbuser = $dbpass = $dbport = $dbsocket = $manual_db = '';
+foreach ($_GET as $getvar => $getval) {
+    ${$getvar} = $getval;
 }
-else
-{
-	// Wenn Connection-String existiert -> Verbindungsdaten aus connstr auslesen
-	if (isset($connstr) && !empty($connstr))
-	{
-		$p=explode("|", $connstr);
-		$dbhost=$config['dbhost']=$p[0];
-		$dbuser=$config['dbuser']=$p[1];
-		$dbpass=$config['dbpass']=$p[2];
-		$dbport=$config['dbport']=$p[3];
-		$dbsocket=$config['dbsocket']=$p[4];
-		$manual_db=$config['manual_db']=$p[5];
-	}
-	else
-		$connstr="";
+foreach ($_POST as $postvar => $postval) {
+    ${$postvar} = $postval;
+}
+include_once './inc/functions.php';
+include_once './inc/mysqli.php';
+include_once './inc/runtime.php';
+if (!isset($language)) {
+    $language = 'en';
+}
+
+$config['language'] = $language;
+include './language/lang_list.php';
+include 'language/'.$language.'/lang_install.php';
+include 'language/'.$language.'/lang_main.php';
+include 'language/'.$language.'/lang_config_overview.php';
+
+// Passing the parameters via FORM
+if (isset($_POST['dbhost'])) {
+    $config['dbhost'] = $dbhost;
+    $config['dbuser'] = $dbuser;
+    $config['dbpass'] = $dbpass;
+    $config['dbport'] = $dbport;
+    $config['dbsocket'] = $dbsocket;
+    $config['manual_db'] = $manual_db;
+} else {
+    // If connection string exists -> read connection data from connstr
+    if (isset($connstr) && !empty($connstr)) {
+        $p = explode('|', $connstr);
+        $dbhost = $config['dbhost'] = $p[0];
+        $dbuser = $config['dbuser'] = $p[1];
+        $dbpass = $config['dbpass'] = $p[2];
+        $dbport = $config['dbport'] = $p[3];
+        $dbsocket = $config['dbsocket'] = $p[4];
+        $manual_db = $config['manual_db'] = $p[5];
+    } else {
+        $connstr = '';
+    }
 }
 
 //Variabeln
-$phase=( isset($phase) ) ? $phase : 0;
-if (isset($_POST['manual_db'])) $manual_db=trim($_POST['manual_db']);
+$phase = (isset($phase)) ? $phase : 0;
+if (isset($_POST['manual_db'])) {
+    $manual_db = trim($_POST['manual_db']);
+}
 $connstr = "$dbhost|$dbuser|$dbpass|$dbport|$dbsocket|$manual_db";
-$connection='';
-$delfiles=Array();
+$connection = '';
+$delfiles = [];
 
-$config['files']['iconpath']='./css/msd/icons/';
-$img_ok='<img src="' . $config['files']['iconpath'] . 'ok.gif" width="16" height="16" alt="ok">';
-$img_failed='<img src="' . $config['files']['iconpath'] . 'notok.gif" width="16" height="16" alt="failed">';
-$href="install.php?language=$language&phase=$phase&connstr=$connstr";
+$config['files']['iconpath'] = './css/mod/icons/';
+$img_ok = '<img src="'.$config['files']['iconpath'].'ok.gif" width="16" height="16" alt="ok">';
+$img_failed = '<img src="'.$config['files']['iconpath'].'notok.gif" width="16" height="16" alt="failed">';
+$href = "install.php?language=$language&phase=$phase&connstr=$connstr";
 header('content-type: text/html; charset=utf-8');
 ?>
 <!DOCTYPE HTML>
 <html>
 <head>
-	<meta charset="utf-8" />
-	<meta name="robots" content="noindex,nofollow" />
+	<meta charset="utf-8">
+	<meta name="robots" content="noindex,nofollow">
 	<meta http-equiv="X-UA-Compatible" content="IE=Edge">
 	<meta http-equiv="pragma" content="no-cache">
 	<meta http-equiv="expires" content="0">
 	<meta http-equiv="cache-control" content="must-revalidate">
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 	<title>MyOOS [Dumper]  - Installation</title>
 
-	<link rel="stylesheet" type="text/css" href="css/msd/style.css">
+	<link rel="stylesheet" type="text/css" href="css/mod/style.css">
 	<script src="js/script.js" type="text/javascript"></script>
 <style type="text/css" media="screen">
 td {
@@ -105,464 +105,340 @@ td table td {
 </style>
 </head>
 <body class="content">
-<script language="JavaScript" type="text/javascript">
+<script>
 function hide_tooldivs() {
 	<?php
-	foreach ($lang['languages'] as $key)
-	{
-		echo 'document.getElementById("' . $key . '").style.display = \'none\';' . "\n";
-	}
-	?>
+    foreach ($lang['languages'] as $key) {
+        echo 'document.getElementById("'.$key.'").style.display = \'none\';'."\n";
+    }
+    ?>
 }
 
 function show_tooldivs(lab) {
 	hide_tooldivs();
 	switch(lab) {
 		<?php
-		foreach ($lang['languages'] as $key)
-		{
-			echo 'case "' . $key . '":' . "\n" . 'document.getElementById("' . $key . '").style.display = \'block\';' . "\n" . 'break;' . "\n";
-		}
-		?>
+        foreach ($lang['languages'] as $key) {
+            echo 'case "'.$key.'":'."\n".'document.getElementById("'.$key.'").style.display = \'block\';'."\n".'break;'."\n";
+        }
+        ?>
 
 	}
 }
 </script>
 
 <?php
-if ($phase < 10)
-{
-	if ($phase == 0) $Anzeige=$lang['L_INSTALL'] . ' - ' . $lang['L_INSTALLMENU'];
-	else $Anzeige=$lang['L_INSTALL'] . ' - ' . $lang['L_STEP'] . ' ' . ( $phase );
-}
-elseif ($phase > 9 && $phase < 12)
-{
-	$Anzeige=$lang['L_INSTALL'] . ' - ' . $lang['L_STEP'] . ' ' . ( $phase - 7 );
-}
-elseif ($phase > 19 && $phase < 100)
-{
-	$Anzeige=$lang['L_TOOLS'];
-}
-else
-{
-	$Anzeige=$lang['L_UNINSTALL'] . ' - ' . $lang['L_STEP'] . ' ' . ( $phase - 99 );
-}
+if ($phase < 10) {
+            if (0 == $phase) {
+                $content = $lang['L_INSTALL'].' - '.$lang['L_INSTALLMENU'];
+            } else {
+                $content = $lang['L_INSTALL'].' - '.$lang['L_STEP'].' '.($phase);
+            }
+        } elseif ($phase > 9 && $phase < 12) {
+            $content = $lang['L_INSTALL'].' - '.$lang['L_STEP'].' '.($phase - 7);
+        } elseif ($phase > 19 && $phase < 100) {
+            $content = $lang['L_TOOLS'];
+        } else {
+            $content = $lang['L_UNINSTALL'].' - '.$lang['L_STEP'].' '.($phase - 99);
+        }
 
-echo '<img src="css/msd/pics/h1_logo.gif" alt="' . $lang['L_INSTALL_TOMENU'] . '">';
+echo '<img src="css/mod/pics/h1_logo.gif" alt="'.$lang['L_INSTALL_TOMENU'].'">';
 echo '<div id="pagetitle"><p>
-' . $Anzeige . '
+'.$content.'
 </p></div>';
 
-echo '<div id="content" align="center"><p class="small"><strong>Version ' . MSD_VERSION . '</strong><br></p>';
+echo '<div id="content" align="center"><p class="small"><strong>Version '.MOD_VERSION.'</strong><br></p>';
 
-switch ($phase)
-{
+switch ($phase) {
+    case 0: // Anfang - Sprachauswahl
+        // da viele ja nicht in die Anleitung schauen -> versuchen die Perldateien automatisch richtig zu chmodden
+        @chmod('./mod_cron/crondump.pl', 0755);
+        @chmod('./mod_cron/perltest.pl', 0755);
+        @chmod('./mod_cron/simpletest.pl', 0755);
 
-	case 0: // Anfang - Sprachauswahl
-		// da viele ja nicht in die Anleitung schauen -> versuchen die Perldateien automatisch richtig zu chmodden
-		@chmod('./msd_cron/crondump.pl',0755);
-		@chmod('./msd_cron/perltest.pl',0755);
-		@chmod('./msd_cron/simpletest.pl',0755);
+        echo '<form action="install.php" method="get"><input type="hidden" name="phase" value="1">';
+        echo '<table class="bdr"><tr class="thead"><th>Language</th><th>Tools</th></tr>';
+        echo '<tr><td valign="top" width="300"><table>';
+        echo GetLanguageCombo('radio', 'radio', 'language', '<tr><td>', '</td></tr>');
+        echo '</table></td><td valign="top">';
 
-		echo '<form action="install.php" method="get"><input type="hidden" name="phase" value="1">';
-		echo '<table class="bdr"><tr class="thead"><th>Language</th><th>Tools</th></tr>';
-		echo '<tr><td valign="top" width="300"><table>';
-		echo GetLanguageCombo("radio","radio","language","<tr><td>","</td></tr>");
-		echo '</table></td><td valign="top">';
+        foreach ($lang['languages'] as $key) {
+            echo "\n<div id=\"".$key.'"><a href="install.php?language='.$key.'&phase=100">'.$lang['L_TOOLS1'][$key].'</a><br><br>';
+            echo '</div>';
+        }
 
-		foreach ($lang['languages'] as $key)
-		{
-			echo ( "\n<div id=\"" . $key . '"><a href="install.php?language=' . $key . '&phase=100">' . $lang['L_TOOLS1'][$key] . '</a><br><br>' );
-			echo ( "</div>" );
-		}
+        echo "\n</td></tr><tr><td colspan=\"2\" style=\"padding: 4px\"><input type=\"submit\" name=\"submit\" value=\"Installation\" class=\"Formbutton\"></td></tr></table></form>";
+        echo '<script>show_tooldivs("'.$language.'");</script>';
+        break;
+    case 1: // checken
+        @chmod('config.php', 0666);
+        echo '<h6>'.$lang['L_DBPARAMETER'].'</h6>';
+        if (!is_writable('config.php')) {
+            echo '<p class="warning">'.$lang['L_CONFIGNOTWRITABLE'].'</p>';
+            echo '<a href="'.$href.'">'.$lang['L_TRYAGAIN'].'</a>';
+            echo '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="install.php">'.$lang['L_INSTALL_TOMENU'].'</a>';
+        } else {
+            $tmp = file('config.php');
 
-		echo ( "\n</td></tr><tr><td colspan=\"2\" style=\"padding: 4px\"><input type=\"submit\" name=\"submit\" value=\"Installation\" class=\"Formbutton\"></td></tr></table></form>" );
-		echo '<script language="JavaScript" type="text/javascript">show_tooldivs("' . $language . '");</script>';
-		break;
-	case 1: // checken
-		@chmod("config.php",0666);
-		echo '<h6>' . $lang['L_DBPARAMETER'] . '</h6>';
-		if (!is_writable("config.php"))
-		{
-			echo '<p class="warning">' . $lang['L_CONFIGNOTWRITABLE'] . '</p>';
-			echo '<a href="' . $href . '">' . $lang['L_TRYAGAIN'] . '</a>';
-			echo '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="install.php">' . $lang['L_INSTALL_TOMENU'] . '</a>';
-		}
-		else
-		{
-			$tmp=file("config.php");
-			$stored=0;
+            $stored = 0;
 
-			if (!isset($_POST['dbconnect']))
-			{
-				// Erstaufruf - Daten aus config.php auslesen
-				for ($i=0; $i < count($tmp); $i++)
-				{
-					if (substr($tmp[$i],0,17) == '$config[\'dbhost\']')
-					{
-						$config['dbhost']=extractValue($tmp[$i]);
-						$dbhost=$config['dbhost'];
-						$stored++;
-					}
-					if (substr($tmp[$i],0,17) == '$config[\'dbport\']')
-					{
-						$config['dbport']=extractValue($tmp[$i]);
-						$dbport=$config['dbport'];
-						$stored++;
-					}
-					if (substr($tmp[$i],0,19) == '$config[\'dbsocket\']')
-					{
-						$config['dbsocket']=extractValue($tmp[$i]);
-						$dbsocket=$config['dbsocket'];
-						$stored++;
-					}
-					if (substr($tmp[$i],0,17) == '$config[\'dbuser\']')
-					{
-						$config['dbuser']=extractValue($tmp[$i]);
-						$dbuser=$config['dbuser'];
-						$stored++;
-					}
-					if (substr($tmp[$i],0,17) == '$config[\'dbpass\']')
-					{
-						$config['dbpass']=extractValue($tmp[$i]);
-						$dbpass=$config['dbpass'];
-						$stored++;
-					}
-					if (substr($tmp[$i],0,19) == '$config[\'language\']')
-					{
-						$config['language']=extractValue($tmp[$i]);
-						$stored++;
-					}
-					if ($stored == 6) break;
-				}
-			}
+            if (!isset($_POST['dbconnect'])) {
+                // Erstaufruf - Daten aus config.php auslesen
+                for ($i = 0; $i < count($tmp); ++$i) {
+                    if ('$config[\'dbhost\']' == substr($tmp[$i], 0, 17)) {
+                        $config['dbhost'] = extractValue($tmp[$i]);
+                        $dbhost = $config['dbhost'];
+                        ++$stored;
+                    }
+                    if ('$config[\'dbport\']' == substr($tmp[$i], 0, 17)) {
+                        $config['dbport'] = extractValue($tmp[$i]);
+                        $dbport = $config['dbport'];
+                        ++$stored;
+                    }
+                    if ('$config[\'dbsocket\']' == substr($tmp[$i], 0, 19)) {
+                        $config['dbsocket'] = extractValue($tmp[$i]);
+                        $dbsocket = $config['dbsocket'];
+                        ++$stored;
+                    }
+                    if ('$config[\'dbuser\']' == substr($tmp[$i], 0, 17)) {
+                        $config['dbuser'] = extractValue($tmp[$i]);
+                        $dbuser = $config['dbuser'];
+                        ++$stored;
+                    }
+                    if ('$config[\'dbpass\']' == substr($tmp[$i], 0, 17)) {
+                        $config['dbpass'] = extractValue($tmp[$i]);
+                        $dbpass = $config['dbpass'];
+                        ++$stored;
+                    }
+                    if ('$config[\'language\']' == substr($tmp[$i], 0, 19)) {
+                        $config['language'] = extractValue($tmp[$i]);
+                        ++$stored;
+                    }
+                    if (6 == $stored) {
+                        break;
+                    }
+                }
+            }
 
-			if (!isset($config['dbport'])) $config['dbport']="";
-			if (!isset($config['dbsocket'])) $config['dbsocket']="";
+            if (!isset($config['dbport'])) {
+                $config['dbport'] = '';
+            }
+            if (!isset($config['dbsocket'])) {
+                $config['dbsocket'] = '';
+            }
 
-			echo '<form action="install.php?language=' . $language . '&phase=' . $phase . '" method="post">';
-			echo '<table class="bdr" style="width:700px;">';
-			echo '<tr><td>' . $lang['L_DB_HOST'] . ':</td><td><input type="text" name="dbhost" value="' . $dbhost . '" size="60" maxlength="100"></td></tr>';
-			echo '<tr><td>' . $lang['L_DB_USER'] . ':</td><td><input type="text" name="dbuser" value="' . $dbuser . '" size="60" maxlength="100"></td></tr>';
-			echo '<tr><td>' . $lang['L_DB_PASS'] . ':</td><td><input type="password" name="dbpass" value="' . $dbpass . '" size="60" maxlength="100"></td></tr>';
-			echo '<tr><td>* ' . $lang['L_DB'] . ':<p class="small">('.$lang['L_ENTER_DB_INFO'].')</p></td><td><input type="text" name="manual_db" value="' . $manual_db . '" size="60" maxlength="100"></td></tr>';
-			echo '<tr><td>';
-			echo $lang['L_PORT'] . ':</td><td><input type="text" name="dbport" value="' . $dbport . '" size="5" maxlength="5">&nbsp;&nbsp;' . $lang['L_INSTALL_HELP_PORT'] . '</td></tr>';
-			echo '<tr><td>' . $lang['L_SOCKET'] . ':</td><td><input type="text" name="dbsocket" value="' . $dbsocket . '" size="30" maxlength="255">&nbsp;&nbsp;' . $lang['L_INSTALL_HELP_SOCKET'] . '</td></tr>';
+            echo '<form action="install.php?language='.$language.'&phase='.$phase.'" method="post">';
+            echo '<table class="bdr" style="width:700px;">';
+            echo '<tr><td>'.$lang['L_DB_HOST'].':</td><td><input type="text" name="dbhost" value="'.$dbhost.'" size="60" maxlength="100"></td></tr>';
+            echo '<tr><td>'.$lang['L_DB_USER'].':</td><td><input type="text" name="dbuser" value="'.$dbuser.'" size="60" maxlength="100"></td></tr>';
+            echo '<tr><td>'.$lang['L_DB_PASS'].':</td><td><input type="password" name="dbpass" value="'.$dbpass.'" size="60" maxlength="100"></td></tr>';
+            echo '<tr><td>* '.$lang['L_DB'].':<p class="small">('.$lang['L_ENTER_DB_INFO'].')</p></td><td><input type="text" name="manual_db" value="'.$manual_db.'" size="60" maxlength="100"></td></tr>';
+            echo '<tr><td>';
+            echo $lang['L_PORT'].':</td><td><input type="text" name="dbport" value="'.$dbport.'" size="5" maxlength="5">&nbsp;&nbsp;'.$lang['L_INSTALL_HELP_PORT'].'</td></tr>';
+            echo '<tr><td>'.$lang['L_SOCKET'].':</td><td><input type="text" name="dbsocket" value="'.$dbsocket.'" size="30" maxlength="255">&nbsp;&nbsp;'.$lang['L_INSTALL_HELP_SOCKET'].'</td></tr>';
 
-			echo '<tr><td>' . $lang['L_TESTCONNECTION'] . ':</td><td><input type="submit" name="dbconnect" value="' . $lang['L_CONNECTTOMYSQL'] . '" class="Formbutton"></td></tr>';
-			if (isset($_POST['dbconnect']))
-			{
-				echo '<tr class="thead"><th colspan="2">' . $lang['L_DBCONNECTION'] . '</th></tr>';
-				echo '<tr><td colspan="2">';
-				$connection=MSD_mysql_connect();
+            echo '<tr><td>'.$lang['L_TESTCONNECTION'].':</td><td><input type="submit" name="dbconnect" value="'.$lang['L_CONNECTTOMYSQL'].'" class="Formbutton"></td></tr>';
+            if (isset($_POST['dbconnect'])) {
+                echo '<tr class="thead"><th colspan="2">'.$lang['L_DBCONNECTION'].'</th></tr>';
+                echo '<tr><td colspan="2">';
+                $connection = mod_mysqli_connect();
 
-				if ($connection === false)
-				{
-					echo '<p class="error">' . $lang['L_CONNECTIONERROR'] . '</p><span>&nbsp;';
-				}
-				else
-				{
-				    $databases = array();
-					echo '<p class="success">' . $lang['L_CONNECTION_OK'] . '</p><span class="ssmall">';
-					$connection="ok";
-					$connstr="$dbhost|$dbuser|$dbpass|$dbport|$dbsocket|$manual_db";
-					echo '<input type="hidden" name="connstr" value="' . $connstr . '">';
-					if ($manual_db > '') SearchDatabases(1,$manual_db);
-					else SearchDatabases(1);
-					if (!isset($databases['Name']) || !in_array($manual_db, $databases['Name'])) {
+                if (false === $connection) {
+                    echo '<p class="error">'.$lang['L_CONNECTIONERROR'].'</p><span>&nbsp;';
+                } else {
+                    $databases = [];
+                    echo '<p class="success">'.$lang['L_CONNECTION_OK'].'</p><span class="ssmall">';
+                    $connection = 'ok';
+                    $connstr = "$dbhost|$dbuser|$dbpass|$dbport|$dbsocket|$manual_db";
+                    echo '<input type="hidden" name="connstr" value="'.$connstr.'">';
+                    if ($manual_db > '') {
+                        SearchDatabases(1, $manual_db);
+                    } else {
+                        SearchDatabases(1);
+                    }
+                    if (!isset($databases['Name']) || !in_array($manual_db, $databases['Name'])) {
                         // conect to manual db was not successful
-					    $connstr = substr($connstr,0, strlen($connstr)-strlen($manual_db));
-					    $manual_db = '';
-					}
-				}
-				echo '</span></td></tr>';
-			}
-			echo '</table></form><br>';
+                        $connstr = substr($connstr, 0, strlen($connstr) - strlen($manual_db));
+                        $manual_db = '';
+                    }
+                }
+                echo '</span></td></tr>';
+            }
+            echo '</table></form><br>';
 
-			if ($connection == "ok")
-			{
-				if (!isset($databases['Name'][0])) echo '<br>' . $lang['L_NO_DB_FOUND_INFO'];
+            if ('ok' == $connection) {
+                if (!isset($databases['Name'][0])) {
+                    echo '<br>'.$lang['L_NO_DB_FOUND_INFO'];
+                }
 
-				echo '<form action="install.php?language=' . $language . '&phase=' . ( $phase + 1 ) . '" method="post">';
-				echo '<input type="hidden" name="dbhost" value="' . $config['dbhost'] . '">
-			<input type="hidden" name="dbuser" value="' . $config['dbuser'] . '">
-			<input type="hidden" name="dbpass" value="' . $config['dbpass'] . '">
-			<input type="hidden" name="manual_db" value="' . $manual_db . '">
-			<input type="hidden" name="dbport" value="' . $config['dbport'] . '">
-			<input type="hidden" name="dbsocket" value="' . $config['dbsocket'] . '">
-			<input type="hidden" name="connstr" value="' . $connstr . '">';
-				echo '<input type="submit" name="submit" value=" ' . $lang['L_SAVEANDCONTINUE'] . ' " class="Formbutton"></form>';
-			}
-		}
-		break;
+                echo '<form action="install.php?language='.$language.'&phase='.($phase + 1).'" method="post">';
+                echo '<input type="hidden" name="dbhost" value="'.$config['dbhost'].'">
+			<input type="hidden" name="dbuser" value="'.$config['dbuser'].'">
+			<input type="hidden" name="dbpass" value="'.$config['dbpass'].'">
+			<input type="hidden" name="manual_db" value="'.$manual_db.'">
+			<input type="hidden" name="dbport" value="'.$config['dbport'].'">
+			<input type="hidden" name="dbsocket" value="'.$config['dbsocket'].'">
+			<input type="hidden" name="connstr" value="'.$connstr.'">';
+                echo '<input type="submit" name="submit" value=" '.$lang['L_SAVEANDCONTINUE'].' " class="Formbutton"></form>';
+            }
+        }
+        break;
 
-	case 2: //
-		echo '<h6>MyOOS [Dumper] - ' . $lang['L_CONFBASIC'] . '</h6>';
-		$tmp=@file("config.php");
-		$stored=0;
-		for ($i=0; $i < count($tmp); $i++)
-		{
-			if (substr($tmp[$i],0,17) == '$config[\'dbhost\']')
-			{
-				$tmp[$i]='$config[\'dbhost\'] = \'' . $dbhost . '\';' . "\n";
-				$stored++;
-			}
-			if (substr($tmp[$i],0,17) == '$config[\'dbport\']')
-			{
-				$tmp[$i]='$config[\'dbport\'] = \'' . $dbport . '\';' . "\n";
-				$stored++;
-			}
-			if (substr($tmp[$i],0,19) == '$config[\'dbsocket\']')
-			{
-				$tmp[$i]='$config[\'dbsocket\'] = \'' . $dbsocket . '\';' . "\n";
-				$stored++;
-			}
-			if (substr($tmp[$i],0,17) == '$config[\'dbuser\']')
-			{
-				$tmp[$i]='$config[\'dbuser\'] = \'' . $dbuser . '\';' . "\n";
-				$stored++;
-			}
-			if (substr($tmp[$i],0,17) == '$config[\'dbpass\']')
-			{
-				$tmp[$i]='$config[\'dbpass\'] = \'' . $dbpass . '\';' . "\n";
-				$stored++;
-			}
+    case 2:
+        echo '<h6>MyOOS [Dumper] - '.$lang['L_CONFBASIC'].'</h6>';
+        $tmp = @file('config.php');
+        $stored = 0;
+        for ($i = 0; $i < count($tmp); ++$i) {
+            if ('$config[\'dbhost\']' == substr($tmp[$i], 0, 17)) {
+                $tmp[$i] = '$config[\'dbhost\'] = \''.$dbhost.'\';'."\n";
+                ++$stored;
+            }
+            if ('$config[\'dbport\']' == substr($tmp[$i], 0, 17)) {
+                $tmp[$i] = '$config[\'dbport\'] = \''.$dbport.'\';'."\n";
+                ++$stored;
+            }
+            if ('$config[\'dbsocket\']' == substr($tmp[$i], 0, 19)) {
+                $tmp[$i] = '$config[\'dbsocket\'] = \''.$dbsocket.'\';'."\n";
+                ++$stored;
+            }
+            if ('$config[\'dbuser\']' == substr($tmp[$i], 0, 17)) {
+                $tmp[$i] = '$config[\'dbuser\'] = \''.$dbuser.'\';'."\n";
+                ++$stored;
+            }
+            if ('$config[\'dbpass\']' == substr($tmp[$i], 0, 17)) {
+                $tmp[$i] = '$config[\'dbpass\'] = \''.$dbpass.'\';'."\n";
+                ++$stored;
+            }
 
-			if ($stored == 6) break;
-		}
-		$ret=true;
-		if ($fp=fopen("config.php","wb"))
-		{
-			if (!fwrite($fp,implode($tmp,""))) $ret=false;
-			if (!fclose($fp)) $ret=false;
-			@chmod("config.php",0644);
-		}
-		if (!$ret)
-		{
-			echo '<p class="warnung">' . $lang['L_CONFIG_SAVE_ERROR'] . '</p>';
-		}
-		else
-		{
-			if (ini_get('safe_mode') == 1)
-			{
-				$nextphase=( extension_loaded("ftp") ) ? 10 : 9;
-			}
-			else
-				$nextphase=$phase + 2;
-			echo $lang['L_INSTALL_STEP2FINISHED'];
-			echo '<p>&nbsp;</p>';
-			echo '<form action="install.php?language=' . $language . '&phase=' . $nextphase . '" method="post" name="continue"><input type="hidden" name="connstr" value="' . $connstr . '"><input class="Formbutton" style="width:360px;" type="submit" name="continue2" value=" ' . $lang['L_INSTALL_STEP2_1'] . ' "></form>';
-			echo '<script language="javascript">';
-			echo 'document.forms["continue"].submit();';
-			echo '</script>';
-		}
+            if (6 == $stored) {
+                break;
+            }
+        }
+        $ret = true;
+        if ($fp = fopen('config.php', 'wb')) {
+            if (!fwrite($fp, implode('', $tmp))) {
+                $ret = false;
+            }
+            @chmod('config.php', 0644);
+        }
+        if (!$ret) {
+            echo '<p class="warnung">'.$lang['L_SAVE_ERROR'].'</p>';
+        } else {
+            echo $lang['L_INSTALL_STEP2FINISHED'];
+            echo '<p>&nbsp;</p>';
+            echo '<form action="install.php?language='.$language.'&phase='.($phase + 2).'" method="post" name="continue"><input type="hidden" name="connstr" value="'.$connstr.'"><input class="Formbutton" style="width:360px;" type="submit" name="continue2" value=" '.$lang['L_INSTALL_STEP2_1'].' "></form>';
+            echo '<script>';
+            echo 'document.forms["continue"].submit();';
+            echo '</script>';
+        }
 
-		break;
+        break;
 
-	case 4: //Verzeichnisse
-		if (isset($_POST['submit']))
-		{
-			$ret=true;
-			if ($fp=fopen("config.php","wb"))
-			{
-				if (!fwrite($fp,stripslashes(stripslashes($_POST['configfile'])))) $ret=false;
-				if (!fclose($fp)) $ret=false;
-			}
-			else
-				$ret=false;
+    case 4: //Verzeichnisse
+        if (isset($_POST['submit'])) {
+            $ret = true;
+            if ($fp = fopen('config.php', 'wb')) {
+                if (!fwrite($fp, stripslashes(stripslashes($_POST['configfile'])))) {
+                    $ret = false;
+                }
+                if (!fclose($fp)) {
+                    $ret = false;
+                }
+            } else {
+                $ret = false;
+            }
 
-			if ($ret == false)
-			{
-				echo '<br><strong>' . $lang['L_ERRORMAN'] . ' config.php ' . $lang['L_MANUELL'] . '.';
-				die();
-			}
-		}
+            if (false == $ret) {
+                echo '<br><strong>'.$lang['L_ERRORMAN'].' config.php '.$lang['L_MANUELL'].'.';
+                exit();
+            }
+        }
 
-		echo '<h6>' . $lang['L_CREATEDIRS'] . '</h6>';
-		$check_dirs= array (
+        echo '<h6>'.$lang['L_CREATEDIRS'].'</h6>';
+        $check_dirs = [
+                            'work/',
+                            'work/config/',
+                            'work/log/',
+                            'work/backup/',
+                            'work/cache/',
+                            'work/temp/'
+        ];
+        $msg = '';
+        foreach ($check_dirs as $d) {
+            $success = SetFileRechte($d, 1, 0777);
+            if (1 != $success) {
+                $msg .= $success.'<br>';
+            }
+        }
 
-							"work/",
-							"work/config/",
-							"work/log/",
-							"work/backup/"
-		);
-		$msg='';
-		foreach ($check_dirs as $d)
-		{
-			$success=SetFileRechte($d,1,0777);
-			if ($success != 1) $msg.=$success . '<br>';
-		}
-
-		if ($msg > '') echo '<b>' . $msg . '</b>';
-
-		$iw[0]=IsWritable("work");
-		$iw[1]=IsWritable("work/config");
-		$iw[2]=IsWritable("work/log");
-		$iw[3]=IsWritable("work/backup");
-/*
-		// save manual_db
-		if ($manual_db > '')
-		{
-			if (file_exists('./' . $config['files']['dbs_manual'])) @unlink('./' . $config['files']['dbs_manual']);
-			$file_handle=fopen('./' . $config['files']['dbs_manual'],'a');
-			if ($file_handle)
-			{
-				fwrite($file_handle,$manual_db);
-				fclose($file_handle);
-				@chmod('./' . $config['files']['dbs_manual'],0777);
-			}
-		}
-*/
-		if ($iw[0] && $iw[1] && $iw[2] && $iw[3])
-		{
-			echo '<script language="javascript">';
-			echo 'self.location.href=\'install.php?language=' . $language . '&phase=5&connstr=' . $connstr . '\'';
-			echo '</script>';
-		}
-
-		echo '<form action="install.php?language=' . $language . '&phase=4" method="post"><table class="bdr"><tr class="thead">';
-		echo '<th>' . $lang['L_DIR'] . '</th><th>' . $lang['L_RECHTE'] . '</th><th>' . $lang['L_STATUS'] . '</th></tr>';
-		echo '<tr><td><strong>work</strong></td><td>' . Rechte("work") . '</td><td>' . ( ( $iw[0] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/config</strong></td><td>' . Rechte("work/config") . '</td><td>' . ( ( $iw[1] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/log</strong></td><td>' . Rechte("work/log") . '</td><td>' . ( ( $iw[2] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/backup</strong></td><td>' . Rechte("work/backup") . '</td><td>' . ( ( $iw[3] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td colspan="3" align="right"><input type="hidden" name="connstr" value="' . $connstr . '"><input class="Formbutton" type="submit" name="dir_check" value=" ' . $lang['L_CHECK_DIRS'] . ' "></td></tr>';
-		if ($iw[0] && $iw[1] && $iw[2] && $iw[3]) echo '<tr><td colspan="2">' . $lang['L_DIRS_CREATED'] . '<br><br><input class="Formbutton" type="Button" value=" ' . $lang['L_INSTALL_CONTINUE'] . ' " onclick="location.href=\'install.php?language=' . $language . '&phase=5&connstr=' . $connstr . '\'"></td></tr>';
-		echo '</table></form>';
-		break;
-	case 5:
-		echo '<h6>' . $lang['L_LASTSTEP'] . '</h6>';
-
-		echo '<br><h4>' . $lang['L_INSTALLFINISHED'] . '</h4>';
-		SetDefault(1);
-		include ( "language/" . $language . "/lang_install.php" );
-
-		// direkt zum Start des Dumeprs
-		echo '<script language="javascript">self.location.href=\'index.php\';</script>';
-		break;
-	case 9:
-
-		clearstatcache();
-		$iw[0]=IsWritable("work");
-		$iw[1]=IsWritable("work/config");
-		$iw[2]=IsWritable("work/log");
-		$iw[3]=IsWritable("work/backup");
-		echo '<h6>' . $lang['L_FTPMODE'] . '</h6>';
-		echo '<p align="left" style="padding-left:100px; padding-right:100px;">' . $lang['L_SAFEMODEDESC'] . '</p>';
-
-		echo '<form action="install.php?language=' . $language . '&phase=9" method="post"><input type="hidden" name="connstr" value="' . $connstr . '"><table>';
-		echo '<tr><td class="hd2" colspan="2">' . $lang['L_IDOMANUAL'] . '</td></tr>';
-		echo '<tr><td colspan="2">' . $lang['L_DOFROM'] . '<br><div class="small">' . Realpfad('./') . '</div></td></tr>';
-		echo '<tr><td><strong>work</strong></td><td>' . ( ( $iw[0] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/config</strong></td><td>' . ( ( $iw[1] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/log</strong></td><td>' . ( ( $iw[2] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/backup</strong></td><td>' . ( ( $iw[3] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td colspan="3" align="right"><input type="submit" class="Formbutton" name="dir_check" value=" ' . $lang['L_CHECK_DIRS'] . ' "></td></tr>';
-
-		// Wenn Verzeichnisse erstellt wurden - direkt weitermachen
-		if ($iw[0] && $iw[1] && $iw[2] && $iw[3])
-		{
-			echo '<script language="javascript">';
-			echo 'self.location.href=\'install.php?language=' . $language . '&phase=4&connstr=' . $connstr . '\'';
-			echo '</script>';
-		}
-		echo '</table>';
-
-		break;
-	case 10: //safe_mode FTP
-		$config['ftp_useSSL']=0;
-		clearstatcache();
-		$iw[0]=IsWritable("work");
-		$iw[1]=IsWritable("work/config");
-		$iw[2]=IsWritable("work/log");
-		$iw[3]=IsWritable("work/backup");
-		if (!isset($install_ftp_port) || $install_ftp_port < 1) $install_ftp_port=21;
-		echo '<h6>' . $lang['L_FTPMODE'] . '</h6>';
-		echo '<p align="left" style="padding-left:100px; padding-right:100px;">' . $lang['L_SAFEMODEDESC'] . '</p>';
-
-		echo '<form action="install.php?language=' . $language . '&phase=10" method="post"><input type="hidden" name="connstr" value="' . $connstr . '">
-		<table width="80%"><tr><td width="50%" valign="top"><table>';
-		echo '<tr><td class="hd2" colspan="2">' . $lang['L_IDOMANUAL'] . '</td></tr>';
-		echo '<tr><td colspan="2">' . $lang['L_DOFROM'] . '<br><div class="small">' . Realpfad('./') . '</div></td></tr>';
-		echo '<tr><td><strong>work</strong></td><td>' . ( ( $iw[0] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/config</strong></td><td>' . ( ( $iw[1] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/log</strong></td><td>' . ( ( $iw[2] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td><strong>work/backup</strong></td><td>' . ( ( $iw[3] ) ? $img_ok : $img_failed ) . '</td></tr>';
-		echo '<tr><td colspan="3" align="right"><input type="submit" name="dir_check" value=" ' . $lang['L_CHECK_DIRS'] . ' " class="Formbutton"></td></tr>';
-		if ($iw[0] && $iw[1] && $iw[2] && $iw[3]) echo '<tr><td colspan="2">' . $lang['L_DIRS_CREATED'] . '<br><input class="Formbutton" type="Button" value=" ' . $lang['L_INSTALL_CONTINUE'] . ' " onclick="location.href=\'install.php?language=' . $language . '&phase=4&connstr=' . $connstr . '\'"></td></tr>';
-		echo '</table></td><td width="50%" valign="top">';
-		echo '<table><tr><td class="hd2" colspan="2">' . $lang['L_FTPMODE2'] . '</td></tr>';
-		echo '<tr><td>FTP-Server</td><td><input type="text" name="install_ftp_server" value="' . $install_ftp_server . '"></td></tr>';
-		echo '<tr><td>FTP-Port</td><td><input type="text" name="install_ftp_port" value="' . $install_ftp_port . '" size="4"></td></tr>';
-		echo '<tr><td>FTP-User</td><td><input type="text" name="install_ftp_user_name" value="' . $install_ftp_user_name . '"></td></tr>';
-		echo '<tr><td>FTP-' . $lang['L_PASS'] . '</td><td><input type="text" name="install_ftp_user_pass" value="' . $install_ftp_user_pass . '"></td></tr>';
-		echo '<tr><td>' . $lang['L_INFO_SCRIPTDIR'] . '</td><td><input type="text" name="install_ftp_path" value="' . $install_ftp_path . '"></td></tr>';
-		echo '<tr><td colspan="2" align="right">
-		<input type="submit" name="ftp_connect" value="' . $lang['L_CONNECT'] . '" class="Formbutton"></td></tr></table></table></form>';
-		if (isset($ftp_connect))
-		{
-			echo '<table><tr><td class="small">';
-			$tftp=TesteFTP($install_ftp_server,$install_ftp_port,$install_ftp_user_name,$install_ftp_user_pass,$install_ftp_path);
-			echo $tftp;
-			echo '</td><td colspan="2" align="right">&nbsp;';
-			if (substr($tftp,-9) == "</strong>")
-			{
-				echo '<form action="install.php?language=' . $language . '&phase=11" method="post">
-				<input type="hidden" name="connstr" value="' . $connstr . '">';
-				echo '<input type="hidden" name="install_ftp_server" value="' . $install_ftp_server . '">
-				<input type="hidden" name="install_ftp_port" value="' . $install_ftp_port . '">
-				<input type="hidden" name="install_ftp_user_name" value="' . $install_ftp_user_name . '">
-				<input type="hidden" name="install_ftp_user_pass" value="' . $install_ftp_user_pass . '">
-				<input type="hidden" name="install_ftp_path" value="' . $install_ftp_path . '">';
-				echo '<input type="submit" name="submit" value=" ' . $lang['L_CREATEDIRS2'] . ' " class="Formbutton"></form>';
-			}
-			echo '</td></tr></table>';
-		}
-		//echo '</td></tr>';
+        if ($msg > '') {
+            echo '<b>'.$msg.'</b>';
+        }
 
 
-		//echo '</table>';
+        $iw[0] = IsWritable('work');
+        $iw[1] = IsWritable('work/config');
+        $iw[2] = IsWritable('work/log');
+        $iw[3] = IsWritable('work/backup');
+        $iw[4] = IsWritable('work/cache');
+        $iw[5] = IsWritable('work/temp');
 
+        if ($iw[0] && $iw[1] && $iw[2] && $iw[3] && $iw[4] && $iw[5]) {
+            echo '<script>';
+            echo 'self.location.href=\'install.php?language='.$language.'&phase=5&connstr='.$connstr.'\'';
+            echo '</script>';
+        }
 
-		break;
+        echo '<form action="install.php?language='.$language.'&phase=4" method="post"><table class="bdr"><tr class="thead">';
+        echo '<th>'.$lang['L_DIR'].'</th><th>'.$lang['L_RECHTE'].'</th><th>'.$lang['L_STATUS'].'</th></tr>';
+        echo '<tr><td><strong>work</strong></td><td>'.Rechte('work').'</td><td>'.(($iw[0]) ? $img_ok : $img_failed).'</td></tr>';
+        echo '<tr><td><strong>work/config</strong></td><td>'.Rechte('work/config').'</td><td>'.(($iw[1]) ? $img_ok : $img_failed).'</td></tr>';
+        echo '<tr><td><strong>work/log</strong></td><td>'.Rechte('work/log').'</td><td>'.(($iw[2]) ? $img_ok : $img_failed).'</td></tr>';
+        echo '<tr><td><strong>work/backup</strong></td><td>'.Rechte('work/backup').'</td><td>'.(($iw[3]) ? $img_ok : $img_failed).'</td></tr>';
+        echo '<tr><td><strong>work/cache</strong></td><td>'.Rechte('work/cache').'</td><td>'.(($iw[4]) ? $img_ok : $img_failed).'</td></tr>';
+        echo '<tr><td><strong>work/temp</strong></td><td>'.Rechte('work/temp').'</td><td>'.(($iw[5]) ? $img_ok : $img_failed).'</td></tr>';
 
-	case 11: //FTP-Create Dirs
-		echo '<h6>' . $lang['L_FTPMODE'] . '</h6>';
-		if (CreateDirsFTP() == 1)
-		{
-			SetDefault(true);
-			echo DirectoryWarnings();
-			echo '<br>' . $lang['L_INSTALLFINISHED'];
-		}
-		break;
-	case 100: //uninstall
-		echo '<h6>' . $lang['L_UI1'] . '</h6>';
-		echo '<h6>' . $lang['L_UI2'] . '</h6>';
-		echo '<a href="install.php">' . $lang['L_UI3'] . '</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
-		echo '<a href="install.php?language=' . $language . '&phase=101">' . $lang['L_UI4'] . '</a>';
-		break;
-	case 101:
-		echo '<h6>' . $lang['L_UI5'] . '</h6>';
-		$paths=Array();
-		$w=substr($config['paths']['work'],0,strlen($config['paths']['work']) - 1);
-		if (is_dir($w)) $res=rec_rmdir($w);
-		else $res=0;
-		// wurde das Verzeichnis korrekt gelöscht
-		if ($res == 0)
-		{
-			// das Verzeichnis wurde korrekt gelöscht
-			echo '<p>' . $lang['L_UI6'] . '</p>';
-			echo $lang['L_UI7'] . "<br>\"" . Realpfad("./") . "\"<br> " . $lang['L_MANUELL'] . ".<br><br>";
-			echo '<a href="../">' . $lang['L_UI8'] . '</a>';
+        echo '<tr><td colspan="3" align="right"><input type="hidden" name="connstr" value="'.$connstr.'"><input class="Formbutton" type="submit" name="dir_check" value=" '.$lang['L_CHECK_DIRS'].' "></td></tr>';
+        if ($iw[0] && $iw[1] && $iw[2] && $iw[3] && $iw[4] && $iw[5]) {
+            echo '<tr><td colspan="2">'.$lang['L_DIRS_CREATED'].'<br><br><input class="Formbutton" type="Button" value=" '.$lang['L_INSTALL_CONTINUE'].' " onclick="location.href=\'install.php?language='.$language.'&phase=5&connstr='.$connstr.'\'"></td></tr>';
+        }
+        echo '</table></form>';
+        break;
+    case 5:
+        echo '<h6>'.$lang['L_LASTSTEP'].'</h6>';
 
-		}
-		else
-		{
-			echo '<p class="Warnung">' . $lang['L_UI9'] . '"' . $paths[count($paths) - 1] . '"';
+        echo '<br><h4>'.$lang['L_INSTALLFINISHED'].'</h4>';
+        SetDefault(1);
+        include 'language/'.$language.'/lang_install.php';
 
-		}
-		break;
+        // direkt zum Start des Dumeprs
+        echo '<script>self.location.href=\'index.php\';</script>';
+        break;
+    case 100: //uninstall
+        echo '<h6>'.$lang['L_UI1'].'</h6>';
+        echo '<h6>'.$lang['L_UI2'].'</h6>';
+        echo '<a href="install.php">'.$lang['L_UI3'].'</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+        echo '<a href="install.php?language='.$language.'&phase=101">'.$lang['L_UI4'].'</a>';
+        break;
+    case 101:
+        echo '<h6>'.$lang['L_UI5'].'</h6>';
+        $paths = [];
+        $w = substr($config['paths']['work'], 0, strlen($config['paths']['work']) - 1);
+        if (is_dir($w)) {
+            $res = rec_rmdir($w);
+        } else {
+            $res = 0;
+        }
+        // wurde das Verzeichnis korrekt gelöscht
+        if (0 == $res) {
+            // das Verzeichnis wurde korrekt gelöscht
+            echo '<p>'.$lang['L_UI6'].'</p>';
+            echo $lang['L_UI7'].'<br>"'.Realpfad('./').'"<br> '.$lang['L_MANUELL'].'.<br><br>';
+            echo '<a href="../">'.$lang['L_UI8'].'</a>';
+        } else {
+            echo '<p class="Warnung">'.$lang['L_UI9'].'"'.$paths[count($paths) - 1].'"';
+        }
+        break;
 }
 
 ?>
@@ -584,102 +460,94 @@ switch ($phase)
 //        kein Link
 function rec_rmdir($path)
 {
-	global $paths;
-	$paths[]=$path;
-	// schau' nach, ob das ueberhaupt ein Verzeichnis ist
-	if (!is_dir($path))
-	{
-		return -1;
-	}
-	// oeffne das Verzeichnis
-	$dir=@opendir($path);
-	// Fehler?
-	if (!$dir)
-	{
-		return -2;
-	}
+    global $paths;
+    $paths[] = $path;
+    // schau' nach, ob das ueberhaupt ein Verzeichnis ist
+    if (!is_dir($path)) {
+        return -1;
+    }
+    // oeffne das Verzeichnis
+    $dir = @opendir($path);
+    // Fehler?
+    if (!$dir) {
+        return -2;
+    }
 
-	// gehe durch das Verzeichnis
-	while ($entry=@readdir($dir))
-	{
-		// wenn der Eintrag das aktuelle Verzeichnis oder das Elternverzeichnis
-		// ist, ignoriere es
-		if ($entry == '.' || $entry == '..') continue;
-		// wenn der Eintrag ein Verzeichnis ist, dann
-		if (is_dir($path . '/' . $entry))
-		{
-			// rufe mich selbst auf
-			$res=rec_rmdir($path . '/' . $entry);
-			// wenn ein Fehler aufgetreten ist
-			if ($res == -1)
-			{ // dies duerfte gar nicht passieren
-				@closedir($dir); // Verzeichnis schliessen
-				return -2; // normalen Fehler melden
-			}
-			elseif ($res == -2)
-			{ // Fehler?
-				@closedir($dir); // Verzeichnis schliessen
-				return -2; // Fehler weitergeben
-			}
-			elseif ($res == -3)
-			{ // nicht unterstuetzer Dateityp?
-				@closedir($dir); // Verzeichnis schliessen
-				return -3; // Fehler weitergeben
-			}
-			elseif ($res != 0)
-			{ // das duerfe auch nicht passieren...
-				@closedir($dir); // Verzeichnis schliessen
-				return -2; // Fehler zurueck
-			}
-		}
-		elseif (is_file($path . '/' . $entry) || is_link($path . '/' . $entry))
-		{
-			// ansonsten loesche diese Datei / diesen Link
-			$res=@unlink($path . '/' . $entry);
-			// Fehler?
-			if (!$res)
-			{
-				@closedir($dir); // Verzeichnis schliessen
-				return -2; // melde ihn
-			}
-		}
-		else
-		{
-			// ein nicht unterstuetzer Dateityp
-			@closedir($dir); // Verzeichnis schliessen
-			return -3; // tut mir schrecklich leid...
-		}
-	}
+    // gehe durch das Verzeichnis
+    while ($entry = @readdir($dir)) {
+        // wenn der Eintrag das aktuelle Verzeichnis oder das Elternverzeichnis
+        // ist, ignoriere es
+        if ('.' == $entry || '..' == $entry) {
+            continue;
+        }
+        // wenn der Eintrag ein Verzeichnis ist, dann
+        if (is_dir($path.'/'.$entry)) {
+            // rufe mich selbst auf
+            $res = rec_rmdir($path.'/'.$entry);
+            // wenn ein Fehler aufgetreten ist
+            if (-1 == $res) { // dies duerfte gar nicht passieren
+                @closedir($dir); // Verzeichnis schliessen
+                return -2; // normalen Fehler melden
+            } elseif (-2 == $res) { // Fehler?
+                @closedir($dir); // Verzeichnis schliessen
+                return -2; // Fehler weitergeben
+            } elseif (-3 == $res) { // nicht unterstuetzer Dateityp?
+                @closedir($dir); // Verzeichnis schliessen
+                return -3; // Fehler weitergeben
+            } elseif (0 != $res) { // das duerfe auch nicht passieren...
+                @closedir($dir); // Verzeichnis schliessen
+                return -2; // Fehler zurueck
+            }
+        } elseif (is_file($path.'/'.$entry) || is_link($path.'/'.$entry)) {
+            // ansonsten loesche diese Datei / diesen Link
+            $res = @unlink($path.'/'.$entry);
+            // Fehler?
+            if (!$res) {
+                @closedir($dir); // Verzeichnis schliessen
+                return -2; // melde ihn
+            }
+        } else {
+            // ein nicht unterstuetzer Dateityp
+            @closedir($dir); // Verzeichnis schliessen
+            return -3; // tut mir schrecklich leid...
+        }
+    }
 
-	// schliesse nun das Verzeichnis
-	@closedir($dir);
+    // schliesse nun das Verzeichnis
+    @closedir($dir);
 
-	// versuche nun, das Verzeichnis zu loeschen
-	$res=@rmdir($path);
+    // versuche nun, das Verzeichnis zu loeschen
+    $res = @rmdir($path);
 
-	// gab's einen Fehler?
-	if (!$res)
-	{
-		return -2; // melde ihn
-	}
+    // gab's einen Fehler?
+    if (!$res) {
+        return -2; // melde ihn
+    }
 
-	// alles ok
-	return 0;
+    // alles ok
+    return 0;
 }
 
 function Rechte($file)
 {
-	clearstatcache();
-	return @substr(decoct(fileperms($file)),-3);
+    clearstatcache();
+
+    return @substr(decoct(fileperms($file)), -3);
 }
 
 function extractValue($s)
 {
-	$r=trim(substr($s,strpos($s,"=") + 1));
-	$r=substr($r,0,strlen($r) - 1);
-	if (substr($r,-1) == "'" || substr($r,-1) == '"') $r=substr($r,0,strlen($r) - 1);
-	if (substr($r,0,1) == "'" || substr($r,0,1) == '"') $r=substr($r,1);
-	return $r;
+    $r = trim(substr($s, strpos($s, '=') + 1));
+    $r = substr($r, 0, strlen($r) - 1);
+    if ("'" == substr($r, -1) || '"' == substr($r, -1)) {
+        $r = substr($r, 0, strlen($r) - 1);
+    }
+    if ("'" == substr($r, 0, 1) || '"' == substr($r, 0, 1)) {
+        $r = substr($r, 1);
+    }
+
+    return $r;
 }
 
 ob_end_flush();
+exit();
diff --git a/msd/js/script.js b/msd/js/script.js
index c840c488..4b431d08 100644
--- a/msd/js/script.js
+++ b/msd/js/script.js
@@ -1,7 +1,6 @@
-var NS=(document.layers);var IE=(document.all);function obj_enable(objid)
-{var e=document.getElementById(objid);e.disabled=false;}
-function obj_disable(objid)
-{var e=document.getElementById(objid);e.disabled=true;}
+var NS=(document.layers);var IE=(document.all);
+function obj_disable(objid, state)
+{var e=document.getElementById(objid);e.disabled=!state;}
 function setactiveMenuFromContent()
 {var a=parent.MyOOS_Dumper_content.location.href;var menuid=1;if(a.indexOf("config_overview.php")!=-1)menuid=2;if(a.indexOf("filemanagement.php")!=-1)
 {if(a.indexOf("action=dump")!=-1)menuid=3;if(a.indexOf("action=restore")!=-1)menuid=4;if(a.indexOf("action=files")!=-1)menuid=5;}
@@ -52,4 +51,4 @@ return anz;}
 function SelectTableList(s){var obj=document.getElementsByName('f_export_tables[]')[0];for(var i=0;i<obj.options.length;i++){obj.options[i].selected=s;}}
 function hide_csvdivs(i){document.getElementById("csv0").style.display='none';if(i==0){document.getElementById("csv1").style.display='none';document.getElementById("csv4").style.display='none';document.getElementById("csv5").style.display='none';}}
 function check_csvdivs(i){hide_csvdivs(i);if(document.getElementById("radio_csv0").checked){document.getElementById("csv0").style.display='block';}
-if(i==0){if(document.getElementById("radio_csv1").checked){document.getElementById("csv1").style.display='block';}else if(document.getElementById("radio_csv2").checked){document.getElementById("csv1").style.display='block';}else if(document.getElementById("radio_csv4").checked){document.getElementById("csv4").style.display='block';}else if(document.getElementById("radio_csv5").checked){document.getElementById("csv5").style.display='block';}}}
\ No newline at end of file
+if(i==0){if(document.getElementById("radio_csv1").checked){document.getElementById("csv1").style.display='block';}else if(document.getElementById("radio_csv2").checked){document.getElementById("csv1").style.display='block';}else if(document.getElementById("radio_csv4").checked){document.getElementById("csv4").style.display='block';}else if(document.getElementById("radio_csv5").checked){document.getElementById("csv5").style.display='block';}}}
diff --git a/msd/language/ar/help.html b/msd/language/ar/help.html
new file mode 100644
index 00000000..64a1411b
--- /dev/null
+++ b/msd/language/ar/help.html
@@ -0,0 +1,147 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/ar/help.php b/msd/language/ar/help.php
deleted file mode 100644
index 242b8ca8..00000000
--- a/msd/language/ar/help.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>About this project</h3>
-The idea for this project comes from Daniel Schlichtholz.<p>In 2004 he created a forum called <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> and soon, programmers who wrote new scripts, supplemented Daniel's scripts.<br>After a short time the small backup-script developed into a stately project.<p>If you have any improvement suggestions you can visit the MySQLDumper-Forum: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>We wish you a lot of fun with this project.<br><br><h4>The MySQLDumper-Team</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-
-<h3>MySQLDumper Help</h3>
-
-<h4>Download</h4>
-This Script is available on the Homepage of MySQLDumper.<br>
-It is recommanded to visit the Homepage frequently to get the latest information, updates and help.<br>
-The address is <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>System Mandatories</h4>
-The Script works with nearly any server (Windows, Linux, ...) <br>
-and PHP >= Version 4.3.4 with GZip-Library, MySQL (>= 3.23), JavaScript (must be enabled).
-
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
-The installation is very easy.
-Unpack the archive in any folder,
-which is accessible from the Webserver<br>
-(e.g. in the root directory [Server rootdir/]MySQLDumper)<br>
-change config.php to chmod 777<br>
-... all done!<br>
-you can start MySQLDumper in your Browser by typing "http://webserver/MySQLDumper"
-to complete the setup, just follow the instructions.
-
-<br><b>Note:</b><br><i>If your webserver runs with the option safemode=ON MySqlDump mustn't create directories.<br>
-You will have to do that yourself.<br>
-MySqlDump breaks in that case and tells you what to do.<br>
-After you created the directories MySqlDump will function normally.</i><br>
-
-<a name="perl"></a><h4>Guidance for the Perl script</h4>
-
-Most have a cgi-bin directory, in which Perl can be executed. <br>
-This is usually by Browser over http://www.domain.de/cgi-bin/ available. <br><br>
-
-Make the following steps for this case please.  <br><br>
-
-1.  Call in MySQLDumper the page Backup and click "Backup Perl"   <br>
-2.  Copy the path, that stands behind entry in crondump.pl for $absolute_path_of_configdir:    <br>
-3. open the file "crondump.pl" in the editor <br>
-4. paste the copied path there with absolute_path_of_configdir (no blanks) <br>
-5.  Save crondump.pl <br>
-6. copy crondump.pl, as well as perltest.pl and simpletest.pl to the cgi-bin directory (ASCII mode in the ftp-client!) <br>
-7. chmod 755 to the scripts.  <br>
-7b. If the ending cgi is desired, change the ending of all 3 files  pl - > cgi (rename)  <br>
-8.  Call in the MySQLDumper the page Configuration<br>
-9. click on Cronscript <br>
-10. changes Perl execution path to /cgi-bin/<br>
-10b. if the Scripts are renamed to *.cgi , change Fileextension to cgi <br>
-11 save the Configuration <br><br>
-
-Ready ! The scripts are available from the Page "Backup" <br><br>
-
-When you can execute Perl anywhere, only following step are needed:  <br><br>
-
-1.  Call in MySQLDumper the page Backup.  <br>
-2.  Copy the path, that stands behind entry in crondump.pl for $absolute_path_of_configdir:  <br>
-3. open the file "crondump.pl" in the editor <br>
-4. paste the copied path there with absolute_path_of_configdir (no blanks) <br>
-5.  Save crondump.pl <br>
-
-6. chmod 755 to the scripts.  <br> 
-6b. If the ending cgi is desired, change the ending of all 3 files  pl - > cgi (rename)  <br>
-(ev. 10b+11 from above) <br><br>
-
-
-Windowsuser must change the first line of all Perlscripts, to the path of Perl.  <br><br>
-
-Example:  <br>
-
-instead of:  #!/usr/bin/perl w <br>
-now #!C:\perl\bin\perl.exe w<br>
-
-<h4>Operating</h4><ul>
-
-<h6>Menu</h6>
-In the select box above you choose your database.<br>
-All actions refer to this database.
-
-<h6>Home</h6>
-Here you get information about your system, the version numbers and details about the configured databases.<br>
-If you click on a database in the table, you get a list of tables with record counts, size and last update stamp.
-
-<h6>Configuration</h6>
-Here you can edit your configuration, save it or load the default settings.
-<ul>
-	<li><a name="conf1"><strong>Configured Databases:</strong> list of configured databases. The active database is in bold.</li>
-	<li><a name="conf2"><strong>Table-Prefix:</strong> you can choose a prefix for each database seperated. The prefix is a filter, which only handle the tables in a dump, that start with this prefix (e.g. all tables starting with "phpBB_"). If you don't want to use it, leave this field empty.</li>
-	<li><a name="conf3"><strong>GZip-Compression:</strong> Here you can activate the compression. It is recommended to work with compression because of the smaller size of files, netherless disk space is ever rarely.</li>
-	<li><a name="conf19"></a><strong>Records count for backup:</strong> These are the number of records which are being read simultaneously while the backup, before the script makes the callback. For slow server you can reduce this parameter to prevent timeouts.</li>
-	<li><a name="conf20"></a><strong>Records count for restore:</strong> These are the number of records which are being read simultaneously while the backup, before the script makes the callback. For slow server you can reduce this parameter to prevent timeouts.</li>
-	<li><a name="conf4"></a><strong>Directory for Backup files:</strong> choose your directory for the backup files. If you choose a new one, the script will create it for you. You can use relative or absolute paths.</li>
-	<li><a name="conf5"></a><strong>Send dumpfile as email:</strong> When this option is enabled, the script will automatically send the finished backup file as an email with an attachment (be careful!, you should use compression with this option because the dumpfile may be too large for email!)</li>
-	<li><a name="conf6"></a><strong>Email address:</strong> Recipient's email address</li>
-	<li><a name="conf7"></a><strong>Email subject:</strong> The subject of the email</li>
-	<li><a name="conf13"></a><strong>FTP-Transfer: </strong>When this option is enabled, the script will automatically send the finished backup file via FTP.</li>
-	<li><a name="conf14"><strong>FTP Server: </strong>the Address of the FTP-Servers (e.g. ftp.mybackups.de)</li>
-	<li><a name="conf15"></a><strong>FTP Server Port: </strong>the Port for the FTP-Server (normally 21)</li>
-	<li><a name="conf16"></a><strong>FTP User: </strong>the username for the FTP-Account</li>
-	<li><a name="conf17"></a><strong>FTP Passwort: </strong>the password for the FTP-Account</li>
-	<li><a name="conf18"></a><strong>FTP Upload-Ordner: </strong>the folder for saving the backup file (there must be Upload-Rights!)</li>
-	
-	<li><a name="conf8"></a><strong>automatic deletion of backups:</strong> When you activate this options, backup files will be deleted automatically by the following rules.</li>
-	<li><a name="conf10"></a><strong>Delete by number of files:</strong> A Value > 0 deletes all files except the given value</li>
-	<li><a name="conf11"></a><strong>Langauge:</strong> choose your language for the interface.</li>
-</ul>
-
-<h6>Management</h6>
-All the actions are listed here.<br>
-You see all files in the backup directory.
-For the actions "Restore" and "Delete" you have to select a file first.
-<UL>
-	<li><strong>Restore:</strong> you restore the database with the records of the selected backupfile.</li>
-	<li><strong>Delete:</strong> you can delete the selected backup file.</li>
-	<li><strong>Start new Dump:</strong> here you  start a new backup (dump) with your configured parameters.</li>
-</UL>
-
-<h6>Log</h6>
-You can read the Log entries and delete them.
-
-<h6>Credits / Help</h6>
-This page.
-</ul>
\ No newline at end of file
diff --git a/msd/language/ar/lang.php b/msd/language/ar/lang.php
index 0821863c..7449fec8 100644
--- a/msd/language/ar/lang.php
+++ b/msd/language/ar/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="نعم";
-$lang['L_TO']="الى";
-$lang['L_ACTIVATED']="تفعيل";
-$lang['L_NOT_ACTIVATED']="لم يتم التفعيل";
-$lang['L_ERROR']="خطأ";
-$lang['L_OF']="من ";
-$lang['L_ADDED']="اضافة";
-$lang['L_DB']="قاعدة بيانات";
-$lang['L_DBS']="قواعد بيانات";
-$lang['L_TABLES']="جداول";
-$lang['L_TABLE']="جدول";
-$lang['L_RECORDS']="سجلات";
-$lang['L_COMPRESSED']="ضغط (gz)";
-$lang['L_NOTCOMPRESSED']="الوضع العادي (uncompressed)";
-$lang['L_GENERAL']="عام";
-$lang['L_COMMENT']="تعليق";
-$lang['L_FILESIZE']="حجم الملف";
-$lang['L_ALL']="الكل";
-$lang['L_NONE']="لا شيئ";
-$lang['L_WITH']=" مع ";
-$lang['L_DIR']="دليل";
-$lang['L_RECHTE']="الرخصة";
-$lang['L_STATUS']="الحالة";
-$lang['L_FINISHED']="انتهى";
-$lang['L_FILE']="ملف";
-$lang['L_FIELDS']="الحقول";
-$lang['L_NEW']="جديد";
-$lang['L_CHARSET']="Charset";
-$lang['L_COLLATION']="ترتيب";
-$lang['L_CHANGE']="التغيير";
-$lang['L_IN']="في";
-$lang['L_DO']="تنفيذ";
-$lang['L_VIEW']="عرض";
-$lang['L_EXISTING']="القائمة";
-$lang['L_BACK']="للخلف";
-$lang['L_DB_HOST']="اسم المضيف";
-$lang['L_DB_USER']="اسم قاعدة البيانات";
-$lang['L_DB_PASS']="كلمة مرور مستخدم قاعدة البيانات";
-$lang['L_INFO_SCRIPTDIR']="دليل مخطوطةMySQLDumper";
-$lang['L_INFO_ACTDB']="قاعدة البيانات الفعلية";
-$lang['L_WRONGCONNECTIONPARS']="مشكلة او لا يوجد ربط !";
-$lang['L_CONN_NOT_POSSIBLE']="الاتصال غير ممكن !";
-$lang['L_SERVERCAPTION']="عرض الخادم";
-$lang['L_HELP_SERVERCAPTION']="عند استخدام MySQLDumper على مختلف المجالات أو الخدمة ، فإنه يمكن أن يكون مفيدا لعرض المجال / اسم الخادم في أعلى الشاشة.";
-$lang['L_ACTIVATE_MULTIDUMP']="تفعيل كافة القوالب";
-$lang['L_SAVE']="حفظ";
-$lang['L_RESET']="تراجع";
-$lang['L_PRAEFIX']="قبل تحديد الجداول";
-$lang['L_AUTODELETE']="حذف ملفات الباك اوب اتوماتيكا";
-$lang['L_MAX_BACKUP_FILES_EACH2']="بالنسبة لكل قاعدة بيانات";
-$lang['L_SAVING_DB_FORM']="قاعدة البيانات";
-$lang['L_TESTCONNECTION']="اختبار الاتصال";
-$lang['L_BACK_TO_MINISQL']="تحرير قاعدة البيانات";
-$lang['L_CREATE']="انشاء";
-$lang['L_VARIABELN']="المتغيرات";
-$lang['L_STATUSINFORMATIONEN']="معلومات عامة";
-$lang['L_VERSIONSINFORMATIONEN']="معلومات النسخة";
-$lang['L_MSD_INFO']="MyOOS [Dumper] معلومات";
-$lang['L_BACKUPFILESANZAHL']="حجم وعدد الملفات في دليل الاسناد ";
-$lang['L_LASTBACKUP']="الاسناد الاخير";
-$lang['L_NOTAVAIL']="<em>غير متوفر</em>";
-$lang['L_VOM']="في";
-$lang['L_MYSQLVARS']="MySQL متغيرات";
-$lang['L_MYSQLSYS']="MySQL اوامر";
-$lang['L_STATUS']="الحالة";
-$lang['L_PROZESSE']="العمليات";
-$lang['L_INFO_NOVARS']="لا متغيرات متوفره";
-$lang['L_INHALT']="القيمة";
-$lang['L_INFO_NOSTATUS']="لا توجد نتائج متوفره";
-$lang['L_INFO_NOPROCESSES']="لا توجد عمليات جارية";
-$lang['L_FM_FREESPACE']="المساحة الخالية على الخادم";
-$lang['L_LOAD_DATABASE']="اعد تحميل قواعد البيانات";
-$lang['L_HOME']="الرئيسة";
-$lang['L_CONFIG']="اعدادات";
-$lang['L_DUMP']="انشاء نسخة من قاعدة البيانات";
-$lang['L_RESTORE']="استعادة قاعدة البيانات";
-$lang['L_FILE_MANAGE']="مدير الملفات";
-$lang['L_LOG']="السجل";
-$lang['L_CHOOSE_DB']="اختر قاعدة البيانات";
-$lang['L_CREDITS']="المعلومات / الدعم";
-$lang['L_MULTI_PART']="تعدد النسخ الاحتياطي";
-$lang['L_LOGFILENOTWRITABLE']="لا يستطيع الكتابة الى ملف السجل !";
-$lang['L_SQL_ERROR1']="خطأ في الاستعلام:";
-$lang['L_SQL_ERROR2']="MySQL وصف الحاله:";
-$lang['L_UNKNOWN']="غير معروف";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="غير معروف";
-$lang['L_OK']="موافق";
-$lang['L_CRON_COMPLETELOG']="ناتج السجل الكامل";
-$lang['L_NO']="لا";
-$lang['L_CREATE_DATABASE']="انشاء قاعدة بيانات جديده";
-$lang['L_EXPORTFINISHED']="الصيغة النهائية.";
-$lang['L_SQL_BROWSER']="SQL-استعرض";
-$lang['L_SERVER']="الخادم";
-$lang['L_MYSQL_CONNECTION_ENCODING']="معيار الترميز القياسي في MySQL-Server";
-$lang['L_TITLE_SHOW_DATA']="Show data";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="إلغاء الأمر";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="النسخ الاحتياطي";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'نعم';
+$lang['L_TO'] = 'الى';
+$lang['L_ACTIVATED'] = 'تفعيل';
+$lang['L_NOT_ACTIVATED'] = 'لم يتم التفعيل';
+$lang['L_ERROR'] = 'خطأ';
+$lang['L_OF'] = 'من ';
+$lang['L_ADDED'] = 'اضافة';
+$lang['L_DB'] = 'قاعدة بيانات';
+$lang['L_DBS'] = 'قواعد بيانات';
+$lang['L_TABLES'] = 'جداول';
+$lang['L_TABLE'] = 'جدول';
+$lang['L_RECORDS'] = 'سجلات';
+$lang['L_COMPRESSED'] = 'ضغط (gz)';
+$lang['L_NOTCOMPRESSED'] = 'الوضع العادي (uncompressed)';
+$lang['L_COMMENT'] = 'تعليق';
+$lang['L_FILESIZE'] = 'حجم الملف';
+$lang['L_ALL'] = 'الكل';
+$lang['L_NONE'] = 'لا شيئ';
+$lang['L_WITH'] = ' مع ';
+$lang['L_DIR'] = 'دليل';
+$lang['L_RECHTE'] = 'الرخصة';
+$lang['L_STATUS'] = 'الحالة';
+$lang['L_FINISHED'] = 'انتهى';
+$lang['L_FILE'] = 'ملف';
+$lang['L_FIELDS'] = 'الحقول';
+$lang['L_NEW'] = 'جديد';
+$lang['L_CHARSET'] = 'Charset';
+$lang['L_COLLATION'] = 'ترتيب';
+$lang['L_CHANGE'] = 'التغيير';
+$lang['L_IN'] = 'في';
+$lang['L_DO'] = 'تنفيذ';
+$lang['L_VIEW'] = 'عرض';
+$lang['L_EXISTING'] = 'القائمة';
+$lang['L_BACK'] = 'للخلف';
+$lang['L_DB_HOST'] = 'اسم المضيف';
+$lang['L_DB_USER'] = 'اسم قاعدة البيانات';
+$lang['L_DB_PASS'] = 'كلمة مرور مستخدم قاعدة البيانات';
+$lang['L_INFO_SCRIPTDIR'] = 'دليل مخطوطةMyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'قاعدة البيانات الفعلية';
+$lang['L_WRONGCONNECTIONPARS'] = 'مشكلة او لا يوجد ربط !';
+$lang['L_CONN_NOT_POSSIBLE'] = 'الاتصال غير ممكن !';
+$lang['L_SERVERCAPTION'] = 'عرض الخادم';
+$lang['L_HELP_SERVERCAPTION'] = 'عند استخدام MyOOS [Dumper] على مختلف المجالات أو الخدمة ، فإنه يمكن أن يكون مفيدا لعرض المجال / اسم الخادم في أعلى الشاشة.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'تفعيل كافة القوالب';
+$lang['L_SAVE'] = 'حفظ';
+$lang['L_RESET'] = 'تراجع';
+$lang['L_PRAEFIX'] = 'قبل تحديد الجداول';
+$lang['L_AUTODELETE'] = 'حذف ملفات الباك اوب اتوماتيكا';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'بالنسبة لكل قاعدة بيانات';
+$lang['L_SAVING_DB_FORM'] = 'قاعدة البيانات';
+$lang['L_TESTCONNECTION'] = 'اختبار الاتصال';
+$lang['L_BACK_TO_MINISQL'] = 'تحرير قاعدة البيانات';
+$lang['L_CREATE'] = 'انشاء';
+$lang['L_VARIABELN'] = 'المتغيرات';
+$lang['L_STATUSINFORMATIONEN'] = 'معلومات عامة';
+$lang['L_VERSIONSINFORMATIONEN'] = 'معلومات النسخة';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] معلومات';
+$lang['L_BACKUPFILESANZAHL'] = 'حجم وعدد الملفات في دليل الاسناد ';
+$lang['L_LASTBACKUP'] = 'الاسناد الاخير';
+$lang['L_NOTAVAIL'] = '<em>غير متوفر</em>';
+$lang['L_VOM'] = 'في';
+$lang['L_MYSQLVARS'] = 'MySQL متغيرات';
+$lang['L_MYSQLSYS'] = 'MySQL اوامر';
+$lang['L_STATUS'] = 'الحالة';
+$lang['L_PROZESSE'] = 'العمليات';
+$lang['L_INFO_NOVARS'] = 'لا متغيرات متوفره';
+$lang['L_INHALT'] = 'القيمة';
+$lang['L_INFO_NOSTATUS'] = 'لا توجد نتائج متوفره';
+$lang['L_INFO_NOPROCESSES'] = 'لا توجد عمليات جارية';
+$lang['L_FM_FREESPACE'] = 'المساحة الخالية على الخادم';
+$lang['L_LOAD_DATABASE'] = 'اعد تحميل قواعد البيانات';
+$lang['L_HOME'] = 'الرئيسة';
+$lang['L_CONFIG'] = 'اعدادات';
+$lang['L_DUMP'] = 'انشاء نسخة من قاعدة البيانات';
+$lang['L_RESTORE'] = 'استعادة قاعدة البيانات';
+$lang['L_FILE_MANAGE'] = 'مدير الملفات';
+$lang['L_LOG'] = 'السجل';
+$lang['L_CHOOSE_DB'] = 'اختر قاعدة البيانات';
+$lang['L_CREDITS'] = 'المعلومات / الدعم';
+$lang['L_MULTI_PART'] = 'تعدد النسخ الاحتياطي';
+$lang['L_LOGFILENOTWRITABLE'] = 'لا يستطيع الكتابة الى ملف السجل !';
+$lang['L_SQL_ERROR1'] = 'خطأ في الاستعلام:';
+$lang['L_SQL_ERROR2'] = 'MySQL وصف الحاله:';
+$lang['L_UNKNOWN'] = 'غير معروف';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'غير معروف';
+$lang['L_OK'] = 'موافق';
+$lang['L_CRON_COMPLETELOG'] = 'ناتج السجل الكامل';
+$lang['L_NO'] = 'لا';
+$lang['L_CREATE_DATABASE'] = 'انشاء قاعدة بيانات جديده';
+$lang['L_EXPORTFINISHED'] = 'الصيغة النهائية.';
+$lang['L_SQL_BROWSER'] = 'SQL-استعرض';
+$lang['L_SERVER'] = 'الخادم';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'معيار الترميز القياسي في MySQL-Server';
+$lang['L_TITLE_SHOW_DATA'] = 'Show data';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'إلغاء الأمر';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'النسخ الاحتياطي';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/ar/lang_config_overview.php b/msd/language/ar/lang_config_overview.php
index 705d2f79..533fd651 100644
--- a/msd/language/ar/lang_config_overview.php
+++ b/msd/language/ar/lang_config_overview.php
@@ -1,111 +1,129 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="اعدادات";
-$lang['L_SAVE_SUCCESS']=" حفظ الاعدادات.";
-$lang['L_CONFIG_LOADED']="تهيئة \"%s\" تم استيرادها بنجاح.";
-$lang['L_SAVE_ERROR']="خطأ - غير قادر على حفظ الاعدادات!";
-$lang['L_CONFIG_EMAIL']="تبليغ بالبريد الالكتروني ";
-$lang['L_CONFIG_AUTODELETE']="حذف تلقائي";
-$lang['L_CONFIG_INTERFACE']="اللغة والسمات";
-$lang['L_MULTI_PART_GROESSE']="الحجم الاقصى للملف";
-$lang['L_HELP_MULTIPART']="وإذا كان وضع النسخ الاحتياطي متعدد ،  النسخ الاحتياطي سوف يكون متعدد ، مع الحد الأقصى للحجم الذي تحدده في الاعدادات أدناه";
-$lang['L_HELP_MULTIPARTGROESSE']="الحد الأقصى لحجم ملفات النسخ الاحتياطي هو مجموعة هنا ، إذا متعدد قم بتفعيله";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="حذف الجداول قبل تنفيذ عملية الاستعادة";
-$lang['L_ALLPARS']="كل الاعدادات";
-$lang['L_CRON_EXTENDER']="امتداد المف";
-$lang['L_CRON_SAVEPATH']="تهيئة الملف";
-$lang['L_CRON_PRINTOUT']="طباعة النتائج على الشاشة.";
-$lang['L_CONFIG_CRONPERL']="اعدادت Crondump Perl في  المخطوطة";
-$lang['L_CRON_MAILPRG']="برنامج البريد";
-$lang['L_OPTIMIZE']="تحسين الجداول قبل عملية النسخ الاحتياطي";
-$lang['L_HELP_OPTIMIZE']="وإذا قمت بتفعيل هذا الخيار  ، كل الجداول كل الجداول سوف يتم تحسينها قبل بدء عملية النسخ الاحتياطي";
-$lang['L_HELP_FTPTIMEOUT']="سوف يتم اعادة الاعدادات الافتراضية خلال 90 ثانية.";
-$lang['L_FTP_TIMEOUT']="انتهاء الفترة الزمنية";
-$lang['L_HELP_FTPSSL']="اختر الاتصال الذي تم تأسيسه بواسطة  via SSL.";
-$lang['L_CONFIG_ASKLOAD']="هل تريد استعادة الإعدادات الفعليه  والإعدادات الافتراضية?";
-$lang['L_LOAD']="استعادة الاعدادات الافتراضية";
-$lang['L_LOAD_SUCCESS']="تمت استعادة الاعدادات الافتراضيه.";
-$lang['L_CRON_CRONDBINDEX']="Database";
-$lang['L_WITHATTACH']="ارفاق تعليق";
-$lang['L_WITHOUTATTACH']=" بدون تعليق";
-$lang['L_MULTIDUMPCONF']="=تهيئة متعدده=";
-$lang['L_MULTIDUMPALL']="=كل قواعد البيانات=";
-$lang['L_GZIP']="GZip ضغط ";
-$lang['L_SEND_MAIL_FORM']="ارسال تقرير بالبريد الالكتروني";
-$lang['L_SEND_MAIL_DUMP']="ارفاق الاسناد";
-$lang['L_EMAIL_ADRESS']="عنوان البريد الالكتروني";
-$lang['L_EMAIL_SENDER']="عنوان مرسل البريد الالكتروني";
-$lang['L_EMAIL_MAXSIZE']="الحجم الاقصى للمرفقات";
-$lang['L_NUMBER_OF_FILES_FORM']="احذف الملفات بعد";
-$lang['L_LANGUAGE']="اللغة";
-$lang['L_LIST_DB']="تشكيل قواعد البيانات :";
-$lang['L_CONFIG_FTP']="FTP نقل ملفات الاسناد بواسطة برنامج";
-$lang['L_FTP_TRANSFER']="FTP نقل بواسطة برنامج";
-$lang['L_FTP_SERVER']="الخادم";
-$lang['L_FTP_PORT']="المنفذ";
-$lang['L_FTP_USER']="اسم المستخدم";
-$lang['L_FTP_PASS']="كلمة المرور";
-$lang['L_FTP_DIR']="رفع الى الدليل";
-$lang['L_FTP_SSL']="اتصال SSL FTP الآمن";
-$lang['L_FTP_USESSL']="استخدام اتصال SSL الآمن";
-$lang['L_SQLBOXHEIGHT']="ارتفاع الصندوق  SQL-Box";
-$lang['L_SQLLIMIT']="احصاء السجلات لكل صفحة";
-$lang['L_BBPARAMS']="تهيئة كود - BB";
-$lang['L_BBTEXTCOLOR']="لون النص";
-$lang['L_HELP_COMMANDS']="يمكنك تنفيذ الاوامر قبل وبعد عملية النسخ الاحتياطي.
-هذه الاوامر يمكن ان تكون عن طريق  SQL-او عن طريق الاوامر (e.g. a script)";
-$lang['L_COMMAND']="امر";
-$lang['L_WRONG_CONNECTIONPARS']="معايير الاتصال خاطئه !";
-$lang['L_CONNECTIONPARS']="تم الاتصال";
-$lang['L_EXTENDEDPARS']="امتداد Parameter";
-$lang['L_FADE_IN_OUT']="عرض فتح/اغلاق";
-$lang['L_DB_BACKUPPARS']="اسناد قواعد البيانات Parameter";
-$lang['L_GENERAL']="عام";
-$lang['L_MAXSIZE']="الاقصى. الحجم";
-$lang['L_ERRORHANDLING_RESTORE']="حدث خطأ اثناء المعالجة";
-$lang['L_EHRESTORE_CONTINUE']="تابع وقم بتسجيل الاخطاء";
-$lang['L_EHRESTORE_STOP']="ايقاف";
-$lang['L_IN_MAINFRAME']="في الإطار الرئيسي";
-$lang['L_IN_LEFTFRAME']="في يسار الاطار";
-$lang['L_WIDTH']="العرض";
-$lang['L_SQL_BEFEHLE']="SQL اوامر";
-$lang['L_DOWNLOAD_LANGUAGES']="تحميل لغات اخرى";
-$lang['L_DOWNLOAD_STYLES']="تحميل سمات اخرى";
-$lang['L_CONNECT_TO']="Connect to";
-$lang['L_CHANGEDIR']="تغيير الى الدليل";
-$lang['L_CHANGEDIRERROR']="لا يمكن تغيير الدليل!";
-$lang['L_FTP_OK']="تم الاتصال بنجاح.";
-$lang['L_INSTALL']="تركيب";
-$lang['L_NOFTPPOSSIBLE']="FTP لا تتوفر لديك وظائف نقل الملفات بواسطة برتوكول  !";
-$lang['L_FOUND_DB']="العثور على قاعدة بيانات";
-$lang['L_FTP_CHOOSE_MODE']="FTP وضع نقل الملفات";
-$lang['L_FTP_PASSIVE']="استخدام الوضع السلبي";
-$lang['L_HELP_FTP_MODE']="اختر الوضع السلبي وعند مواجهة المشاكل استخدم اسلوب الوضع النشط .";
-$lang['L_DB_IN_LIST']="قاعدة البيانات '%s' لايمكن اضافتها ضمن القائمة لانها غير جاهزة. ";
-$lang['L_ADD_DB_MANUALLY']="اضف قاعدة البيانات يدويا";
-$lang['L_DB_MANUAL_ERROR']="اسف, لا يمكن الوصول لقاعدة البيانات '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="خطأ الملف: لا يستطيع ادخال قاعدة البيانات '%s'!";
-$lang['L_NO_DB_FOUND']="لم استطع العثور على قاعدة البيانات تلقائيا!
-مع مزيد من التفاصيل أدخل اسم قاعدة البيانات يدويا.";
-$lang['L_CONFIGFILES']="تهيئة الملفات";
-$lang['L_CONFIGFILE']="تهيئة الملف";
-$lang['L_MYSQL_DATA']="MySQL-بيانات";
-$lang['L_CONFIGURATIONS']="الاعدادات";
-$lang['L_ACTION']="العمل";
-$lang['L_FTP_SEND_TO']="من <strong>%s</strong><br> الى <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="نسخة كربونية-الى المستلم";
-$lang['L_NAME']="الاسم";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="هل تريد حذف ملف التهيئة فعلا %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="خطا: لا يستطيع حذف ملف التهيئة %s!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="ملف التهيئة %s تم حذفه بنجاح.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="ملف التهيئة %s تم انشاؤه بنجاح.";
-$lang['L_ERROR_CONFIGFILE_NAME']="الملف بإسم \"%s\" يحتوي على احرف غير صحيحه.";
-$lang['L_CREATE_CONFIGFILE']="انشاء تهيئة جديده للملف";
-$lang['L_ERROR_LOADING_CONFIGFILE']="لا يستطيع تحميل ملف التهيئة \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="قواعدة البيانات الى النسخ الاحتياطي (PHP)";
-$lang['L_BACKUP_DBS_PERL']="قواعد البيانات الى النسخ الاحتياطي (PERL)";
-$lang['L_CRON_COMMENT']="ادخل تعليقا";
-$lang['L_AUTODETECT']="auto detect";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'اعدادات';
+$lang['L_SAVE_SUCCESS'] = ' حفظ الاعدادات.';
+$lang['L_CONFIG_LOADED'] = 'تهيئة "%s" تم استيرادها بنجاح.';
+$lang['L_SAVE_ERROR'] = 'خطأ - غير قادر على حفظ الاعدادات!';
+$lang['L_EMAIL_NOTIFICATION'] = 'تبليغ بالبريد الالكتروني ';
+$lang['L_CONFIG_AUTODELETE'] = 'حذف تلقائي';
+$lang['L_CONFIG_INTERFACE'] = 'اللغة والسمات';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'الحجم الاقصى للملف';
+$lang['L_HELP_MULTIPART'] = 'وإذا كان وضع النسخ الاحتياطي متعدد ،  النسخ الاحتياطي سوف يكون متعدد ، مع الحد الأقصى للحجم الذي تحدده في الاعدادات أدناه';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'الحد الأقصى لحجم ملفات النسخ الاحتياطي هو مجموعة هنا ، إذا متعدد قم بتفعيله';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'حذف الجداول قبل تنفيذ عملية الاستعادة';
+$lang['L_ALLPARS'] = 'كل الاعدادات';
+$lang['L_CRON_EXTENDER'] = 'امتداد المف';
+$lang['L_CRON_SAVEPATH'] = 'تهيئة الملف';
+$lang['L_CRON_PRINTOUT'] = 'طباعة النتائج على الشاشة.';
+$lang['L_CONFIG_CRONPERL'] = 'اعدادت Crondump Perl في  المخطوطة';
+$lang['L_CRON_MAILPRG'] = 'برنامج البريد';
+$lang['L_OPTIMIZE'] = 'تحسين الجداول قبل عملية النسخ الاحتياطي';
+$lang['L_HELP_OPTIMIZE'] = 'وإذا قمت بتفعيل هذا الخيار  ، كل الجداول كل الجداول سوف يتم تحسينها قبل بدء عملية النسخ الاحتياطي';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'سوف يتم اعادة الاعدادات الافتراضية خلال 90 ثانية.';
+$lang['L_FTP_TIMEOUT'] = 'انتهاء الفترة الزمنية';
+$lang['L_HELP_FTPSSL'] = 'اختر الاتصال الذي تم تأسيسه بواسطة  via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'انتهاء الفترة الزمنية';
+$lang['L_HELP_SFTPSSL'] = 'اختر الاتصال الذي تم تأسيسه بواسطة  via SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'هل تريد استعادة الإعدادات الفعليه  والإعدادات الافتراضية?';
+$lang['L_LOAD'] = 'استعادة الاعدادات الافتراضية';
+$lang['L_LOAD_SUCCESS'] = 'تمت استعادة الاعدادات الافتراضيه.';
+$lang['L_CRON_CRONDBINDEX'] = 'Database';
+$lang['L_WITHATTACH'] = 'ارفاق تعليق';
+$lang['L_WITHOUTATTACH'] = ' بدون تعليق';
+$lang['L_MULTIDUMPCONF'] = '=تهيئة متعدده=';
+$lang['L_MULTIDUMPALL'] = '=كل قواعد البيانات=';
+$lang['L_GZIP'] = 'GZip ضغط ';
+$lang['L_SEND_MAIL_FORM'] = 'ارسال تقرير بالبريد الالكتروني';
+$lang['L_SEND_MAIL_DUMP'] = 'ارفاق الاسناد';
+$lang['L_EMAIL_ADRESS'] = 'عنوان البريد الالكتروني';
+$lang['L_EMAIL_SENDER'] = 'عنوان مرسل البريد الالكتروني';
+$lang['L_EMAIL_MAXSIZE'] = 'الحجم الاقصى للمرفقات';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'احذف الملفات بعد';
+$lang['L_LANGUAGE'] = 'اللغة';
+$lang['L_LIST_DB'] = 'تشكيل قواعد البيانات :';
+$lang['L_CONFIG_FTP'] = 'FTP نقل ملفات الاسناد بواسطة برنامج';
+$lang['L_FTP_TRANSFER'] = 'FTP نقل بواسطة برنامج';
+$lang['L_FTP_SERVER'] = 'الخادم';
+$lang['L_FTP_PORT'] = 'المنفذ';
+$lang['L_FTP_USER'] = 'اسم المستخدم';
+$lang['L_FTP_PASS'] = 'كلمة المرور';
+$lang['L_FTP_DIR'] = 'رفع الى الدليل';
+$lang['L_FTP_SSL'] = 'اتصال SSL FTP الآمن';
+$lang['L_FTP_USESSL'] = 'استخدام اتصال SSL الآمن';
+$lang['L_CONFIG_SFTP'] = 'SFTP نقل ملفات الاسناد بواسطة برنامج';
+$lang['L_SFTP_TRANSFER'] = 'SFTP نقل بواسطة برنامج';
+$lang['L_SFTP_SERVER'] = 'الخادم';
+$lang['L_SFTP_PORT'] = 'المنفذ';
+$lang['L_SFTP_USER'] = 'اسم المستخدم';
+$lang['L_SFTP_PASS'] = 'كلمة المرور';
+$lang['L_SFTP_DIR'] = 'رفع الى الدليل';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'ارتفاع الصندوق  SQL-Box';
+$lang['L_SQLLIMIT'] = 'احصاء السجلات لكل صفحة';
+$lang['L_BBPARAMS'] = 'تهيئة كود - BB';
+$lang['L_BBTEXTCOLOR'] = 'لون النص';
+$lang['L_HELP_COMMANDS'] = 'يمكنك تنفيذ الاوامر قبل وبعد عملية النسخ الاحتياطي.
+هذه الاوامر يمكن ان تكون عن طريق  SQL-او عن طريق الاوامر (e.g. a script)';
+$lang['L_COMMAND'] = 'امر';
+$lang['L_WRONG_CONNECTIONPARS'] = 'معايير الاتصال خاطئه !';
+$lang['L_CONNECTIONPARS'] = 'تم الاتصال';
+$lang['L_EXTENDEDPARS'] = 'امتداد Parameter';
+$lang['L_FADE_IN_OUT'] = 'عرض فتح/اغلاق';
+$lang['L_DB_BACKUPPARS'] = 'اسناد قواعد البيانات Parameter';
+$lang['L_GENERAL'] = 'عام';
+$lang['L_MAXSIZE'] = 'الاقصى. الحجم';
+$lang['L_ERRORHANDLING_RESTORE'] = 'حدث خطأ اثناء المعالجة';
+$lang['L_EHRESTORE_CONTINUE'] = 'تابع وقم بتسجيل الاخطاء';
+$lang['L_EHRESTORE_STOP'] = 'ايقاف';
+$lang['L_IN_MAINFRAME'] = 'في الإطار الرئيسي';
+$lang['L_IN_LEFTFRAME'] = 'في يسار الاطار';
+$lang['L_WIDTH'] = 'العرض';
+$lang['L_SQL_BEFEHLE'] = 'SQL اوامر';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'تحميل لغات اخرى';
+$lang['L_DOWNLOAD_STYLES'] = 'تحميل سمات اخرى';
+$lang['L_CONNECT_TO'] = 'Connect to';
+$lang['L_CHANGEDIR'] = 'تغيير الى الدليل';
+$lang['L_CHANGEDIRERROR'] = 'لا يمكن تغيير الدليل!';
+$lang['L_FTP_OK'] = 'تم الاتصال بنجاح.';
+$lang['L_SFTP_OK'] = 'تم الاتصال بنجاح.';
+$lang['L_INSTALL'] = 'تركيب';
+$lang['L_NOFTPPOSSIBLE'] = 'FTP لا تتوفر لديك وظائف نقل الملفات بواسطة برتوكول  !';
+$lang['L_FOUND_DB'] = 'العثور على قاعدة بيانات';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP وضع نقل الملفات';
+$lang['L_FTP_PASSIVE'] = 'استخدام الوضع السلبي';
+$lang['L_HELP_FTP_MODE'] = 'اختر الوضع السلبي وعند مواجهة المشاكل استخدم اسلوب الوضع النشط .';
+$lang['L_SFTP_PASSIVE'] = 'استخدام الوضع السلبي';
+$lang['L_DB_IN_LIST'] = "قاعدة البيانات '%s' لايمكن اضافتها ضمن القائمة لانها غير جاهزة. ";
+$lang['L_ADD_DB_MANUALLY'] = 'اضف قاعدة البيانات يدويا';
+$lang['L_DB_MANUAL_ERROR'] = "اسف, لا يمكن الوصول لقاعدة البيانات '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "خطأ الملف: لا يستطيع ادخال قاعدة البيانات '%s'!";
+$lang['L_NO_DB_FOUND'] = 'لم استطع العثور على قاعدة البيانات تلقائيا!
+مع مزيد من التفاصيل أدخل اسم قاعدة البيانات يدويا.';
+$lang['L_CONFIGFILES'] = 'تهيئة الملفات';
+$lang['L_CONFIGFILE'] = 'تهيئة الملف';
+$lang['L_MYSQL_DATA'] = 'MySQL-بيانات';
+$lang['L_CONFIGURATIONS'] = 'الاعدادات';
+$lang['L_ACTION'] = 'العمل';
+$lang['L_FTP_SEND_TO'] = 'من <strong>%s</strong><br> الى <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'من <strong>%s</strong><br> الى <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'نسخة كربونية-الى المستلم';
+$lang['L_NAME'] = 'الاسم';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'هل تريد حذف ملف التهيئة فعلا %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'خطا: لا يستطيع حذف ملف التهيئة %s!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'ملف التهيئة %s تم حذفه بنجاح.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'ملف التهيئة %s تم انشاؤه بنجاح.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'الملف بإسم "%s" يحتوي على احرف غير صحيحه.';
+$lang['L_CREATE_CONFIGFILE'] = 'انشاء تهيئة جديده للملف';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'لا يستطيع تحميل ملف التهيئة "%s".';
+$lang['L_BACKUP_DBS_PHP'] = 'قواعدة البيانات الى النسخ الاحتياطي (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'قواعد البيانات الى النسخ الاحتياطي (PERL)';
+$lang['L_CRON_COMMENT'] = 'ادخل تعليقا';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/ar/lang_dump.php b/msd/language/ar/lang_dump.php
index 433a0cb3..59f38c73 100644
--- a/msd/language/ar/lang_dump.php
+++ b/msd/language/ar/lang_dump.php
@@ -1,61 +1,62 @@
 <?php
-$lang['L_DUMP_HEADLINE']="انشاء نسخة احتياطية ...";
-$lang['L_GZIP_COMPRESSION']="GZip ضغط ";
-$lang['L_SAVING_TABLE']="حفظ الجدول ";
-$lang['L_OF']="مغلق";
-$lang['L_ACTUAL_TABLE']="الجدول الفعلي";
-$lang['L_PROGRESS_TABLE']="وصف متقدم للجدول";
-$lang['L_PROGRESS_OVER_ALL']="الوصف الشامل ا";
-$lang['L_ENTRY']="ادخال";
-$lang['L_DONE']="تم!";
-$lang['L_DUMP_SUCCESSFUL']=" تمت الاضافة بنجاح.";
-$lang['L_UPTO']="رفع الى";
-$lang['L_EMAIL_WAS_SEND']="البريد الالكتروني ارسل بنجاح الى ";
-$lang['L_BACK_TO_CONTROL']="استمر";
-$lang['L_BACK_TO_OVERVIEW']="تفاصيل عامة لقاعدة البيانات";
-$lang['L_DUMP_FILENAME']="ملف النسخ الاحتياطي: ";
-$lang['L_WITHPRAEFIX']="بالبادئة";
-$lang['L_DUMP_NOTABLES']="لم يتم العثور على جداول في قاعدة البيانات `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="محتويات الملف <b>%s</b> مع الجداول <b>%s</b> السجلات.<br>";
-$lang['L_MAILERROR']="فشل ارسال البريد الالكتروني!";
-$lang['L_EMAILBODY_ATTACH']="المرفق يحتوي على ملف النسخ الاحتياطي لقاعدة البيانات MySQL.<br>نسخ احتياطي لقاعدة البيانات `%s`
-<br><br>تم انشاء الملف التالي:<br><br>%s <br><br>حظا موفقا  <br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="تم انشاء النسخ الاحتياطي المتعدد.<br>ملفات النسخ الاحتياطي لا يمكن ارسالها البريد الالكتروني!<br>النسخ الاحتياطي لقاعدة البيانات `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'انشاء نسخة احتياطية ...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip ضغط ';
+$lang['L_SAVING_TABLE'] = 'حفظ الجدول ';
+$lang['L_OF'] = 'مغلق';
+$lang['L_ACTUAL_TABLE'] = 'الجدول الفعلي';
+$lang['L_PROGRESS_TABLE'] = 'وصف متقدم للجدول';
+$lang['L_PROGRESS_OVER_ALL'] = 'الوصف الشامل ا';
+$lang['L_ENTRY'] = 'ادخال';
+$lang['L_DONE'] = 'تم!';
+$lang['L_DUMP_SUCCESSFUL'] = ' تمت الاضافة بنجاح.';
+$lang['L_UPTO'] = 'رفع الى';
+$lang['L_EMAIL_WAS_SEND'] = 'البريد الالكتروني ارسل بنجاح الى ';
+$lang['L_BACK_TO_CONTROL'] = 'استمر';
+$lang['L_BACK_TO_OVERVIEW'] = 'تفاصيل عامة لقاعدة البيانات';
+$lang['L_DUMP_FILENAME'] = 'ملف النسخ الاحتياطي: ';
+$lang['L_WITHPRAEFIX'] = 'بالبادئة';
+$lang['L_DUMP_NOTABLES'] = 'لم يتم العثور على جداول في قاعدة البيانات `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = 'محتويات الملف <b>%s</b> مع الجداول <b>%s</b> السجلات.<br>';
+$lang['L_MAILERROR'] = 'فشل ارسال البريد الالكتروني!';
+$lang['L_EMAILBODY_ATTACH'] = 'المرفق يحتوي على ملف النسخ الاحتياطي لقاعدة البيانات MySQL.<br>نسخ احتياطي لقاعدة البيانات `%s`
+<br><br>تم انشاء الملف التالي:<br><br>%s <br><br>حظا موفقا  <br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'تم انشاء النسخ الاحتياطي المتعدد.<br>ملفات النسخ الاحتياطي لا يمكن ارسالها البريد الالكتروني!<br>النسخ الاحتياطي لقاعدة البيانات `%s`
 <br><br>الملفات التالية تم انشئت:<br><br>%s
-<br><br>حظا موفقا<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="تم انشاء النسخ الاحتياطي المتعدد.<br>فواصل بين ملفات النسخ الاحتياطي عند ارسالها بالبريد الالكتروني.<br>النسخ الاحتياطي لقاعدة البيانات `%s`
-<br><br>الملفات التالية انشئت:<br><br>%s <br><br>حظا موفقا<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="`<br><br>حظا موفقا<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="الحجم الاقصى للملف تجاوز الحد المسموح به %s لا يمكن ارسال المرفقات الى البريد الالكتروني  .<br>النسخ الاحتياطي لقاعدة البيانات  `%s`
+<br><br>حظا موفقا<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'تم انشاء النسخ الاحتياطي المتعدد.<br>فواصل بين ملفات النسخ الاحتياطي عند ارسالها بالبريد الالكتروني.<br>النسخ الاحتياطي لقاعدة البيانات `%s`
+<br><br>الملفات التالية انشئت:<br><br>%s <br><br>حظا موفقا<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '`<br><br>حظا موفقا<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'الحجم الاقصى للملف تجاوز الحد المسموح به %s لا يمكن ارسال المرفقات الى البريد الالكتروني  .<br>النسخ الاحتياطي لقاعدة البيانات  `%s`
 <br><br>الملفات التالية انشئت:<br><br>%s
-<br><br>حظا موفقا<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="الملفات لايمكن ارسالها بالبريد الالكتروني!<br>النسخ الاحتياطي لقاعدة البيانات `%s`
+<br><br>حظا موفقا<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'الملفات لايمكن ارسالها بالبريد الالكتروني!<br>النسخ الاحتياطي لقاعدة البيانات `%s`
 <br><br>الملفات التالية انشئت:<br><br>%s
-<br><br>حظا موفقا<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... المرفقات فقط.";
-$lang['L_TABLESELECTION']="تحديد جدول";
-$lang['L_SELECTALL']="تحديد الكل";
-$lang['L_DESELECTALL']="الغاء تحديد الكل";
-$lang['L_STARTDUMP']="بدء النسخ الاحتياطي";
-$lang['L_LASTBUFROM']="من اخر تحديث";
-$lang['L_NOT_SUPPORTED']="النسخ الاحتياطي هذا لا يدعم هذه الوظيفة.";
-$lang['L_MULTIDUMP']="متعدد dump: النسخ الاحتياطي لـ <b>%d</b> لقاعدة البيانات انتهى.";
-$lang['L_FILESENDFTP']="ارسال الملف عن طريق  via FTP... رجاء كن صبورا. ";
-$lang['L_FTPCONNERROR']=" لم يتم تأسيسه FTP اتصال مع ! الاتصال مع ";
-$lang['L_FTPCONNERROR1']=" اسم مستخدم ";
-$lang['L_FTPCONNERROR2']=" غير ممكن";
-$lang['L_FTPCONNERROR3']="FTP الارسال فشل! ";
-$lang['L_FTPCONNECTED1']="الربط مع ";
-$lang['L_FTPCONNECTED2']=" مفتوح ";
-$lang['L_FTPCONNECTED3']=" تمت عملية النقل بنجاح";
-$lang['L_NR_TABLES_SELECTED']="- مع %s اختر الجداول";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s تم اصلاح وتحسين الجداول.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s حدثت اخطاء: <a href=\"log.php?r=3\">عرض</a></p>
+<br><br>حظا موفقا<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... المرفقات فقط.';
+$lang['L_TABLESELECTION'] = 'تحديد جدول';
+$lang['L_SELECTALL'] = 'تحديد الكل';
+$lang['L_DESELECTALL'] = 'الغاء تحديد الكل';
+$lang['L_STARTDUMP'] = 'بدء النسخ الاحتياطي';
+$lang['L_LASTBUFROM'] = 'من اخر تحديث';
+$lang['L_NOT_SUPPORTED'] = 'النسخ الاحتياطي هذا لا يدعم هذه الوظيفة.';
+$lang['L_MULTIDUMP'] = 'متعدد dump: النسخ الاحتياطي لـ <b>%d</b> لقاعدة البيانات انتهى.';
+$lang['L_FILESENDFTP'] = 'ارسال الملف عن طريق  via FTP... رجاء كن صبورا. ';
+$lang['L_FTPCONNERROR'] = ' لم يتم تأسيسه FTP اتصال مع ! الاتصال مع ';
+$lang['L_FTPCONNERROR1'] = ' اسم مستخدم ';
+$lang['L_FTPCONNERROR2'] = ' غير ممكن';
+$lang['L_FTPCONNERROR3'] = 'FTP الارسال فشل! ';
+$lang['L_FTPCONNECTED1'] = 'الربط مع ';
+$lang['L_FTPCONNECTED2'] = ' مفتوح ';
+$lang['L_FTPCONNECTED3'] = ' تمت عملية النقل بنجاح';
+$lang['L_FILESENDSFTP'] = 'ارسال الملف عن طريق  via FTP... رجاء كن صبورا. ';
+$lang['L_SFTPCONNERROR'] = ' لم يتم تأسيسه FTP اتصال مع ! الاتصال مع ';
+$lang['L_NR_TABLES_SELECTED'] = '- مع %s اختر الجداول';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s تم اصلاح وتحسين الجداول.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s حدثت اخطاء: <a href="log.php?r=3">عرض</a></p>
 
 
-";
-$lang['L_FATAL_ERROR_DUMP']="خطأ فادح: انشاء - بيانات من الجدول '%s' في قاعدة البيانات '%s' لا يمكن القراءة!<br>
+';
+$lang['L_FATAL_ERROR_DUMP'] = "خطأ فادح: انشاء - بيانات من الجدول '%s' في قاعدة البيانات '%s' لا يمكن القراءة!<br>
 قم بفحص المشاكل في هذا الجدول.";
-
-
-?>
\ No newline at end of file
diff --git a/msd/language/ar/lang_filemanagement.php b/msd/language/ar/lang_filemanagement.php
index f04e517e..d7c2bedd 100644
--- a/msd/language/ar/lang_filemanagement.php
+++ b/msd/language/ar/lang_filemanagement.php
@@ -1,80 +1,80 @@
 <?php
-$lang['L_CONVERT_START']="بداية التحويل";
-$lang['L_CONVERT_TITLE']="تحويل قاعدة البيانات الى صيغة MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="خطأ parameters!  التحويل غير محتمل.";
-$lang['L_FM_UPLOADFILEREQUEST']="من فضلك اختر ملف.";
-$lang['L_FM_UPLOADNOTALLOWED1']="هذا النوع من الملفات غير مدعوم.";
-$lang['L_FM_UPLOADNOTALLOWED2']="الصيغ المدعومه هي: *.gz و *.sql-ملفات";
-$lang['L_FM_UPLOADMOVEERROR']="الملف المحدد الذي تم تحديده لا يمكن نقله الى دليل الارسال.";
-$lang['L_FM_UPLOADFAILED']="عملية الارسال فشلت!";
-$lang['L_FM_UPLOADFILEEXISTS']="يوجد ملف بنفس الاسم بالفعل !";
-$lang['L_FM_NOFILE']="انت لم تقم بإختيار اي ملف!";
-$lang['L_FM_DELETE1']="الملف ";
-$lang['L_FM_DELETE2']=" تم الحذف بنجاح.";
-$lang['L_FM_DELETE3']=" لا يستطيع الحذف!";
-$lang['L_FM_CHOOSE_FILE']="اختر ملف:";
-$lang['L_FM_FILESIZE']="حجم الملف";
-$lang['L_FM_FILEDATE']="تأريخ الملف";
-$lang['L_FM_NOFILESFOUND']="الملف غير موجود.";
-$lang['L_FM_TABLES']="الجداول";
-$lang['L_FM_RECORDS']="السجلات";
-$lang['L_FM_ALL_BU']="كل النسخ الاحتياطي";
-$lang['L_FM_ANZ_BU']="النسخ الاحتياطي";
-$lang['L_FM_LAST_BU']="النسخ الاحتياطي الاخير";
-$lang['L_FM_TOTALSIZE']="الحجم الكلي";
-$lang['L_FM_SELECTTABLES']="تحديد الجداول";
-$lang['L_FM_COMMENT']="ادخل تعليقا";
-$lang['L_FM_RESTORE']="استعادة";
-$lang['L_FM_ALERTRESTORE1']="هل تريد تنفيذ هذاالاجراء على قاعدة البيانات";
-$lang['L_FM_ALERTRESTORE2']="استعادة الجداول والسجلات من الملف";
-$lang['L_FM_ALERTRESTORE3']=" ?";
-$lang['L_FM_DELETE']="حذف";
-$lang['L_FM_ASKDELETE1']="هل تريد تنفيذ هذا الاجراء على الملف ";
-$lang['L_FM_ASKDELETE2']="وحذف الملف فعلا?";
-$lang['L_FM_ASKDELETE3']="هل تريد تمكين الحذف التلقائي وتهيئة قواعد البانات الآن?";
-$lang['L_FM_ASKDELETE4']="هل تريد حذف جميع ملفات النسخ الاحتياطي?";
-$lang['L_FM_ASKDELETE5']="هل تريد حذف جميع ملفات النسخ الاحتياطي مع ";
-$lang['L_FM_ASKDELETE5_2']="_* ?";
-$lang['L_FM_DELETEAUTO']="تمكين الحذف التلقائي يدويا";
-$lang['L_FM_DELETEALL']="
-حذف جميع ملفات النسخ الاحتياطي";
-$lang['L_FM_DELETEALLFILTER']="حذف الكل مع ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="بدء نسخ احتياطي جديد";
-$lang['L_FM_FILEUPLOAD']="ارسال ملف";
-$lang['L_FM_DBNAME']="اسم قاعدة البيانات";
-$lang['L_FM_FILES1']="قاعدة بيانات النسخ الاحتياطي";
-$lang['L_FM_FILES2']="تراكيب قاعدة البيانات";
-$lang['L_FM_AUTODEL1']="الحذف التلقائي: الملفات التالية تم حذفها لتجاوزها الحد الاقصى المسموح به :";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="تهيئة في المخطوطه";
-$lang['L_FM_OLDBACKUP']="(غير معروف)";
-$lang['L_FM_RESTORE_HEADER']="استعادة من قاعدة البيانات \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="نسخ احتياطي";
-$lang['L_DOCRONBUTTON']="تشغيل Perl Cron في المخطوطه";
-$lang['L_DOPERLTEST']="فحص وحدات Perl ";
-$lang['L_DOSIMPLETEST']="فحص Perl";
-$lang['L_PERLOUTPUT1']="الدخول في  crondump.pl مسموح_عن طريق_التهيئة في الدليل";
-$lang['L_PERLOUTPUT2']="عنوان المتصفح او المشغل الخارجي لوظائف Cron ";
-$lang['L_PERLOUTPUT3']="سطر الاوامر في الشل  او علامة التبويب Cron";
-$lang['L_RESTORE_OF_TABLES']="اختر الجداول التي تريد استعادتها";
-$lang['L_CONVERTER']="تحويل النسخ الاحتياطي";
-$lang['L_CONVERT_FILE']="الملف المحول";
-$lang['L_CONVERT_FILENAME']="اسم الملف الوجهة (بدون الامتداد)";
-$lang['L_CONVERTING']="تحويل";
-$lang['L_CONVERT_FILEREAD']="قراءة الملف '%s'";
-$lang['L_CONVERT_FINISHED']="التحويل انتهى, '%s' تم التحويل بنجاح.";
-$lang['L_NO_MSD_BACKUPFILE']="النسخ الاحتياطي لمخطوطات اخرى";
-$lang['L_MAX_UPLOAD_SIZE']="الحد الاقصى لحجم الملف";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="إذا كان ملف النسخ الاحتياطي هو اكبر من الحد المسموح به أعلاه ، يجب عليك ارساله عبر برامج  بروتوكول نقل الملفات اف تي بي إلى دليل \"work/backup\".
-بعد ذلك يمكنك تحديد ملف الاستعادة ومشاهدة بداية التقدم. ";
-$lang['L_ENCODING']="الترميز";
-$lang['L_FM_CHOOSE_ENCODING']="اختر ترميز لملف النسخ الاحتياطي";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper لا يمكن الكشف عن الترميز تلقائيالملف النسخ الاحتياطي.
+
+$lang['L_CONVERT_START'] = 'بداية التحويل';
+$lang['L_CONVERT_TITLE'] = 'تحويل قاعدة البيانات الى صيغة MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'خطأ parameters!  التحويل غير محتمل.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'من فضلك اختر ملف.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'هذا النوع من الملفات غير مدعوم.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'الصيغ المدعومه هي: *.gz و *.sql-ملفات';
+$lang['L_FM_UPLOADMOVEERROR'] = 'الملف المحدد الذي تم تحديده لا يمكن نقله الى دليل الارسال.';
+$lang['L_FM_UPLOADFAILED'] = 'عملية الارسال فشلت!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'يوجد ملف بنفس الاسم بالفعل !';
+$lang['L_FM_NOFILE'] = 'انت لم تقم بإختيار اي ملف!';
+$lang['L_FM_DELETE1'] = 'الملف ';
+$lang['L_FM_DELETE2'] = ' تم الحذف بنجاح.';
+$lang['L_FM_DELETE3'] = ' لا يستطيع الحذف!';
+$lang['L_FM_CHOOSE_FILE'] = 'اختر ملف:';
+$lang['L_FM_FILESIZE'] = 'حجم الملف';
+$lang['L_FM_FILEDATE'] = 'تأريخ الملف';
+$lang['L_FM_NOFILESFOUND'] = 'الملف غير موجود.';
+$lang['L_FM_TABLES'] = 'الجداول';
+$lang['L_FM_RECORDS'] = 'السجلات';
+$lang['L_FM_ALL_BU'] = 'كل النسخ الاحتياطي';
+$lang['L_FM_ANZ_BU'] = 'النسخ الاحتياطي';
+$lang['L_FM_LAST_BU'] = 'النسخ الاحتياطي الاخير';
+$lang['L_FM_TOTALSIZE'] = 'الحجم الكلي';
+$lang['L_FM_SELECTTABLES'] = 'تحديد الجداول';
+$lang['L_FM_COMMENT'] = 'ادخل تعليقا';
+$lang['L_FM_RESTORE'] = 'استعادة';
+$lang['L_FM_ALERTRESTORE1'] = 'هل تريد تنفيذ هذاالاجراء على قاعدة البيانات';
+$lang['L_FM_ALERTRESTORE2'] = 'استعادة الجداول والسجلات من الملف';
+$lang['L_FM_ALERTRESTORE3'] = ' ?';
+$lang['L_FM_DELETE'] = 'حذف';
+$lang['L_FM_ASKDELETE1'] = 'هل تريد تنفيذ هذا الاجراء على الملف ';
+$lang['L_FM_ASKDELETE2'] = 'وحذف الملف فعلا?';
+$lang['L_FM_ASKDELETE3'] = 'هل تريد تمكين الحذف التلقائي وتهيئة قواعد البانات الآن?';
+$lang['L_FM_ASKDELETE4'] = 'هل تريد حذف جميع ملفات النسخ الاحتياطي?';
+$lang['L_FM_ASKDELETE5'] = 'هل تريد حذف جميع ملفات النسخ الاحتياطي مع ';
+$lang['L_FM_ASKDELETE5_2'] = '_* ?';
+$lang['L_FM_DELETEAUTO'] = 'تمكين الحذف التلقائي يدويا';
+$lang['L_FM_DELETEALL'] = '
+حذف جميع ملفات النسخ الاحتياطي';
+$lang['L_FM_DELETEALLFILTER'] = 'حذف الكل مع ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'بدء نسخ احتياطي جديد';
+$lang['L_FM_FILEUPLOAD'] = 'ارسال ملف';
+$lang['L_FM_DBNAME'] = 'اسم قاعدة البيانات';
+$lang['L_FM_FILES1'] = 'قاعدة بيانات النسخ الاحتياطي';
+$lang['L_FM_FILES2'] = 'تراكيب قاعدة البيانات';
+$lang['L_FM_AUTODEL1'] = 'الحذف التلقائي: الملفات التالية تم حذفها لتجاوزها الحد الاقصى المسموح به :';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'تهيئة في المخطوطه';
+$lang['L_FM_OLDBACKUP'] = '(غير معروف)';
+$lang['L_FM_RESTORE_HEADER'] = 'استعادة من قاعدة البيانات "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'نسخ احتياطي';
+$lang['L_DOCRONBUTTON'] = 'تشغيل Perl Cron في المخطوطه';
+$lang['L_DOPERLTEST'] = 'فحص وحدات Perl ';
+$lang['L_DOSIMPLETEST'] = 'فحص Perl';
+$lang['L_PERLOUTPUT1'] = 'الدخول في  crondump.pl مسموح_عن طريق_التهيئة في الدليل';
+$lang['L_PERLOUTPUT2'] = 'عنوان المتصفح او المشغل الخارجي لوظائف Cron ';
+$lang['L_PERLOUTPUT3'] = 'سطر الاوامر في الشل  او علامة التبويب Cron';
+$lang['L_RESTORE_OF_TABLES'] = 'اختر الجداول التي تريد استعادتها';
+$lang['L_CONVERTER'] = 'تحويل النسخ الاحتياطي';
+$lang['L_CONVERT_FILE'] = 'الملف المحول';
+$lang['L_CONVERT_FILENAME'] = 'اسم الملف الوجهة (بدون الامتداد)';
+$lang['L_CONVERTING'] = 'تحويل';
+$lang['L_CONVERT_FILEREAD'] = "قراءة الملف '%s'";
+$lang['L_CONVERT_FINISHED'] = "التحويل انتهى, '%s' تم التحويل بنجاح.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'النسخ الاحتياطي لمخطوطات اخرى';
+$lang['L_MAX_UPLOAD_SIZE'] = 'الحد الاقصى لحجم الملف';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'إذا كان ملف النسخ الاحتياطي هو اكبر من الحد المسموح به أعلاه ، يجب عليك ارساله عبر برامج  بروتوكول نقل الملفات اف تي بي إلى دليل "work/backup".
+بعد ذلك يمكنك تحديد ملف الاستعادة ومشاهدة بداية التقدم. ';
+$lang['L_ENCODING'] = 'الترميز';
+$lang['L_FM_CHOOSE_ENCODING'] = 'اختر ترميز لملف النسخ الاحتياطي';
+$lang['L_CHOOSE_CHARSET'] = 'MyOOS [Dumper] لا يمكن الكشف عن الترميز تلقائيالملف النسخ الاحتياطي.
 <br>يجب عليك اختيار الاحرف التي تم حفظ النسخ الاحتياطي بها.
 <br>اذا واجهت اي مشكلة مع بعض الاحرف في الاستعادة يمكنك تكرار عملية النسخ الاحتياطي واختيار مجموعة اخرى.
-<br>حظا موفقا. ;)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+<br>حظا موفقا. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/ar/lang_help.php b/msd/language/ar/lang_help.php
index 0e38e593..be9083b2 100644
--- a/msd/language/ar/lang_help.php
+++ b/msd/language/ar/lang_help.php
@@ -1,33 +1,37 @@
 <?php
-$lang['L_HELP_DB']="This is the list of all Databases";
-$lang['L_HELP_PRAEFIX']="the prefix is a string at the beginning of a table name, which works as a filter.";
-$lang['L_HELP_ZIP']="Compression with GZip - recommended state is 'activated'";
-$lang['L_HELP_MEMORYLIMIT']="The max. amount of memory in Bytes for the script\n0 = deactivated";
-$lang['L_MEMORY_LIMIT']="Memory limit";
-$lang['L_HELP_AD1']="If activated, then backup files will be deleted automatically.";
-$lang['L_HELP_AD3']="the maximum number of backup files (for autodelete)
-0 = deactivated";
-$lang['L_HELP_LANG']="select your language";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="To eliminate useless data you can instruct to empty the database before restore";
-$lang['L_HELP_CRONEXTENDER']="The extension of the Perl scripts, default is '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="The name of the configuration file for the Perl script";
-$lang['L_HELP_CRONPRINTOUT']="If deactivated the output will not be printed on screen.
-It is independant from the printing in the logfile.";
-$lang['L_HELP_CRONSAMEDB']="Use same database in Cron job like configured under Database?";
-$lang['L_HELP_CRONDBINDEX']="choose the database for Cron job";
-$lang['L_HELP_FTPTRANSFER']="if activated, file will be sent via FTP.";
-$lang['L_HELP_FTPSERVER']="Address of the FTP-Server";
-$lang['L_HELP_FTPPORT']="Port of the FTP-Server, standard: 21";
-$lang['L_HELP_FTPUSER']="enter username for FTP";
-$lang['L_HELP_FTPPASS']="enter password for FTP";
-$lang['L_HELP_FTPDIR']="where is the upload-dir? enter path!";
-$lang['L_HELP_SPEED']="Minimum and maximum speed, default is 50 to 5000";
-$lang['L_SPEED']="Speed control";
-$lang['L_HELP_CRONEXECPATH']="The place of the Perl scripts.\nStarting Point is the HTTP-Address (like Addresses in the Browser)\nAllowed are absolute or relative entries.";
-$lang['L_CRON_EXECPATH']="Path of Perl scripts";
-$lang['L_HELP_CRONCOMPLETELOG']="When activated the complete output is written in the complete_log-file.
-This is independent from text printing";
-$lang['L_HELP_FTP_MODE']="When problems occur while transfering via FTP, try to use the passive mode. ";
 
-
-?>
\ No newline at end of file
+$lang['L_HELP_DB'] = 'This is the list of all Databases';
+$lang['L_HELP_PRAEFIX'] = 'the prefix is a string at the beginning of a table name, which works as a filter.';
+$lang['L_HELP_ZIP'] = "Compression with GZip - recommended state is 'activated'";
+$lang['L_HELP_MEMORYLIMIT'] = "The max. amount of memory in Bytes for the script\n0 = deactivated";
+$lang['L_MEMORY_LIMIT'] = 'Memory limit';
+$lang['L_HELP_AD1'] = 'If activated, then backup files will be deleted automatically.';
+$lang['L_HELP_AD3'] = 'the maximum number of backup files (for autodelete)
+0 = deactivated';
+$lang['L_HELP_LANG'] = 'select your language';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'To eliminate useless data you can instruct to empty the database before restore';
+$lang['L_HELP_CRONEXTENDER'] = "The extension of the Perl scripts, default is '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'The name of the configuration file for the Perl script';
+$lang['L_HELP_CRONPRINTOUT'] = 'If deactivated the output will not be printed on screen.
+It is independant from the printing in the logfile.';
+$lang['L_HELP_CRONSAMEDB'] = 'Use same database in Cron job like configured under Database?';
+$lang['L_HELP_CRONDBINDEX'] = 'choose the database for Cron job';
+$lang['L_HELP_FTPTRANSFER'] = 'if activated, file will be sent via FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Address of the FTP-Server';
+$lang['L_HELP_FTPPORT'] = 'Port of the FTP-Server, standard: 21';
+$lang['L_HELP_FTPUSER'] = 'enter username for FTP';
+$lang['L_HELP_FTPPASS'] = 'enter password for FTP';
+$lang['L_HELP_FTPDIR'] = 'where is the upload-dir? enter path!';
+$lang['L_HELP_SFTPTRANSFER'] = 'if activated, file will be sent via SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Address of the SFTP-Server';
+$lang['L_HELP_SFTPPORT'] = 'Port of the SFTP-Server, standard: 22';
+$lang['L_HELP_SFTPUSER'] = 'enter username for SFTP';
+$lang['L_HELP_SFTPPASS'] = 'enter password for SFTP';
+$lang['L_HELP_SFTPDIR'] = 'where is the upload-dir? enter path!';
+$lang['L_HELP_SPEED'] = 'Minimum and maximum speed, default is 50 to 5000';
+$lang['L_SPEED'] = 'Speed control';
+$lang['L_HELP_CRONEXECPATH'] = "The place of the Perl scripts.\nStarting Point is the HTTP-Address (like Addresses in the Browser)\nAllowed are absolute or relative entries.";
+$lang['L_CRON_EXECPATH'] = 'Path of Perl scripts';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'When activated the complete output is written in the complete_log-file.
+This is independent from text printing';
+$lang['L_HELP_FTP_MODE'] = 'When problems occur while transfering via FTP, try to use the passive mode. ';
diff --git a/msd/language/ar/lang_install.php b/msd/language/ar/lang_install.php
index fe5b35e0..0567e66c 100644
--- a/msd/language/ar/lang_install.php
+++ b/msd/language/ar/lang_install.php
@@ -1,94 +1,93 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>تم اكتمال التركيب  --> <a href=\"index.php\">ابدأ MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="عوده الى القائمة الرئيسة";
-$lang['L_INSTALLMENU']="القائمة الرئيسة";
-$lang['L_STEP']="خطوة ";
-$lang['L_INSTALL']="التركيب";
-$lang['L_UNINSTALL']="مسح";
-$lang['L_TOOLS']="الادوات";
-$lang['L_EDITCONF']="تعديل الدليل";
-$lang['L_OSWEITER']="مواصلة بدون حفظ";
-$lang['L_ERRORMAN']="<strong>خطأ اثناء عملية حفظ البيانات!</strong><br>الرجاء تعديل الملف ";
-$lang['L_MANUELL']="يدوي";
-$lang['L_CREATEDIRS']="انشاء الادلة";
-$lang['L_INSTALL_CONTINUE']="استمر بعملية التركيب";
-$lang['L_CONNECTTOMYSQL']="ربط الى MySQL ";
-$lang['L_DBPARAMETER']="قاعدة البيانات Parameters";
-$lang['L_CONFIGNOTWRITABLE']="لا يمكن الكتابة للملف \"config.php\".
-الرجاء استخدام برامج بروتوكول نقل الملفات الخاصة بك واعط الملف التصريح0777.";
-$lang['L_DBCONNECTION']="الاتصال بقاعدة البيانات";
-$lang['L_CONNECTIONERROR']="خطأ غير قادر على الربط.";
-$lang['L_CONNECTION_OK']="تم تأسيس الاتصال بقاعدة البيانات.";
-$lang['L_SAVEANDCONTINUE']="حفظ ومتابعة التركيب";
-$lang['L_CONFBASIC']="اساسي Parameter";
-$lang['L_INSTALL_STEP2FINISHED']="تم الوصول الى قاعدة البيانات بنجاح.";
-$lang['L_INSTALL_STEP2_1']="متابعة التركيب بالإعدادات الافتراضية";
-$lang['L_LASTSTEP']="انتهى التركيب";
-$lang['L_FTPMODE']="انشاء ادلة ضرورية في النمط الآمن";
-$lang['L_IDOMANUAL']="انشاء الدليل الخاص بي";
-$lang['L_DOFROM']="بداية من";
-$lang['L_FTPMODE2']="تهيئة  مع بروتوكول نقل الملفات FTP:";
-$lang['L_CONNECT']="ربط";
-$lang['L_DIRS_CREATED']="انشاء الادلة بشكل صحيح.";
-$lang['L_CONNECT_TO']="ربط الى";
-$lang['L_CHANGEDIR']="تغيير مياشر";
-$lang['L_CHANGEDIRERROR']=" لا يمكن التغيير مباشرة ";
-$lang['L_FTP_OK']="FTPيفضل برتكول ";
-$lang['L_CREATEDIRS2']="انشاء الادلة";
-$lang['L_FTP_NOTCONNECTED']="FTP لم يتم انشاء برتكول نقل الملفات!";
-$lang['L_CONNWITH']="اتصال مع";
-$lang['L_ASUSER']="اسم المستخدم";
-$lang['L_NOTPOSSIBLE']="غير ممكن";
-$lang['L_DIRCR1']="انشاء في دليل العمل";
-$lang['L_DIRCR2']="انشاء في دليل الاسناد";
-$lang['L_DIRCR4']="انشاء في السجل";
-$lang['L_DIRCR5']="انشاء في  configurationdir";
-$lang['L_INDIR']="الآن في ";
-$lang['L_CHECK_DIRS']="فحص الادلة";
-$lang['L_DISABLEDFUNCTIONS']="الوظائف المعطلة";
-$lang['L_NOFTPPOSSIBLE']="لا يجد لديك وظائف بروتوكول نقل الملفات FTP  !";
-$lang['L_NOGZPOSSIBLE']="لا يوجد لديك وظائف ضغط الملفات  !";
-$lang['L_UI1']="جميع أدلة العمل التي يمكن أن تحتوي النسخ الاحتياطي سيتم حذفها.";
-$lang['L_UI2']="هل انت موافق على عمل ذلك?";
-$lang['L_UI3']="لا, الغاء العملية";
-$lang['L_UI4']="نعم ، من فضلك تابع";
-$lang['L_UI5']="حذف ادلة العمل";
-$lang['L_UI6']="تم حذف الجميع بنجاح.";
-$lang['L_UI7']="رجاء احذف الدليل من المخطوطه";
-$lang['L_UI8']="المستوى الاول الاعلى";
-$lang['L_UI9']="حدث خطأ ، لم يكن من الممكن الحذف</p>خطأ بالدليل";
-$lang['L_IMPORT']="استيراد الوظائف";
-$lang['L_IMPORT3']="تحميل القوائم ...";
-$lang['L_IMPORT4']="تم حفظ القوائم.";
-$lang['L_IMPORT5']="ابدأ MySQLDumper";
-$lang['L_IMPORT6']="تركيب القائمة";
-$lang['L_IMPORT7']="ارسال القوائم";
-$lang['L_IMPORT8']="عودة الى الرفع";
-$lang['L_IMPORT9']="هذا ليس دليل اسناد !";
-$lang['L_IMPORT10']="تم رفع القوائم بنجاح ...";
-$lang['L_IMPORT11']="<strong>خطا: </strong>كانت هناك مشكلة في الكتابة الى sql_statements";
-$lang['L_IMPORT12']="<strong>خطأ: </strong>كانت هناك مشكلة في الكتابة الى config.php";
-$lang['L_INSTALL_HELP_PORT']="(empty = Default Port)";
-$lang['L_INSTALL_HELP_SOCKET']="(empty = Default Socket)";
-$lang['L_TRYAGAIN']="حاول مرة اخرى";
-$lang['L_SOCKET']="توصيل";
-$lang['L_PORT']="منفذ";
-$lang['L_FOUND_DB']="العثور على قاعدة بيانات";
-$lang['L_FM_FILEUPLOAD']="رفع ملف";
-$lang['L_PASS']="كلمة المرور";
-$lang['L_NO_DB_FOUND_INFO']="تم الاتصال بقاعدة البيانات بنجاح.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>تم اكتمال التركيب  --> <a href="index.php">ابدأ MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'عوده الى القائمة الرئيسة';
+$lang['L_INSTALLMENU'] = 'القائمة الرئيسة';
+$lang['L_STEP'] = 'خطوة ';
+$lang['L_INSTALL'] = 'التركيب';
+$lang['L_UNINSTALL'] = 'مسح';
+$lang['L_TOOLS'] = 'الادوات';
+$lang['L_EDITCONF'] = 'تعديل الدليل';
+$lang['L_OSWEITER'] = 'مواصلة بدون حفظ';
+$lang['L_ERRORMAN'] = '<strong>خطأ اثناء عملية حفظ البيانات!</strong><br>الرجاء تعديل الملف ';
+$lang['L_MANUELL'] = 'يدوي';
+$lang['L_CREATEDIRS'] = 'انشاء الادلة';
+$lang['L_INSTALL_CONTINUE'] = 'استمر بعملية التركيب';
+$lang['L_CONNECTTOMYSQL'] = 'ربط الى MySQL ';
+$lang['L_DBPARAMETER'] = 'قاعدة البيانات Parameters';
+$lang['L_CONFIGNOTWRITABLE'] = 'لا يمكن الكتابة للملف "config.php".
+الرجاء استخدام برامج بروتوكول نقل الملفات الخاصة بك واعط الملف التصريح0777.';
+$lang['L_DBCONNECTION'] = 'الاتصال بقاعدة البيانات';
+$lang['L_CONNECTIONERROR'] = 'خطأ غير قادر على الربط.';
+$lang['L_CONNECTION_OK'] = 'تم تأسيس الاتصال بقاعدة البيانات.';
+$lang['L_SAVEANDCONTINUE'] = 'حفظ ومتابعة التركيب';
+$lang['L_CONFBASIC'] = 'اساسي Parameter';
+$lang['L_INSTALL_STEP2FINISHED'] = 'تم الوصول الى قاعدة البيانات بنجاح.';
+$lang['L_INSTALL_STEP2_1'] = 'متابعة التركيب بالإعدادات الافتراضية';
+$lang['L_LASTSTEP'] = 'انتهى التركيب';
+$lang['L_FTPMODE'] = 'انشاء ادلة ضرورية في النمط الآمن';
+$lang['L_IDOMANUAL'] = 'انشاء الدليل الخاص بي';
+$lang['L_DOFROM'] = 'بداية من';
+$lang['L_FTPMODE2'] = 'تهيئة  مع بروتوكول نقل الملفات FTP:';
+$lang['L_CONNECT'] = 'ربط';
+$lang['L_DIRS_CREATED'] = 'انشاء الادلة بشكل صحيح.';
+$lang['L_CONNECT_TO'] = 'ربط الى';
+$lang['L_CHANGEDIR'] = 'تغيير مياشر';
+$lang['L_CHANGEDIRERROR'] = ' لا يمكن التغيير مباشرة ';
+$lang['L_FTP_OK'] = 'FTPيفضل برتكول ';
+$lang['L_SFTP_OK'] = 'FTPيفضل برتكول ';
+$lang['L_CREATEDIRS2'] = 'انشاء الادلة';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP لم يتم انشاء برتكول نقل الملفات!';
+$lang['L_CONNWITH'] = 'اتصال مع';
+$lang['L_ASUSER'] = 'اسم المستخدم';
+$lang['L_NOTPOSSIBLE'] = 'غير ممكن';
+$lang['L_DIRCR1'] = 'انشاء في دليل العمل';
+$lang['L_DIRCR2'] = 'انشاء في دليل الاسناد';
+$lang['L_DIRCR4'] = 'انشاء في السجل';
+$lang['L_DIRCR5'] = 'انشاء في  configurationdir';
+$lang['L_INDIR'] = 'الآن في ';
+$lang['L_CHECK_DIRS'] = 'فحص الادلة';
+$lang['L_DISABLEDFUNCTIONS'] = 'الوظائف المعطلة';
+$lang['L_NOFTPPOSSIBLE'] = 'لا يجد لديك وظائف بروتوكول نقل الملفات FTP  !';
+$lang['L_NOGZPOSSIBLE'] = 'لا يوجد لديك وظائف ضغط الملفات  !';
+$lang['L_UI1'] = 'جميع أدلة العمل التي يمكن أن تحتوي النسخ الاحتياطي سيتم حذفها.';
+$lang['L_UI2'] = 'هل انت موافق على عمل ذلك?';
+$lang['L_UI3'] = 'لا, الغاء العملية';
+$lang['L_UI4'] = 'نعم ، من فضلك تابع';
+$lang['L_UI5'] = 'حذف ادلة العمل';
+$lang['L_UI6'] = 'تم حذف الجميع بنجاح.';
+$lang['L_UI7'] = 'رجاء احذف الدليل من المخطوطه';
+$lang['L_UI8'] = 'المستوى الاول الاعلى';
+$lang['L_UI9'] = 'حدث خطأ ، لم يكن من الممكن الحذف</p>خطأ بالدليل';
+$lang['L_IMPORT'] = 'استيراد الوظائف';
+$lang['L_IMPORT3'] = 'تحميل القوائم ...';
+$lang['L_IMPORT4'] = 'تم حفظ القوائم.';
+$lang['L_IMPORT5'] = 'ابدأ MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'تركيب القائمة';
+$lang['L_IMPORT7'] = 'ارسال القوائم';
+$lang['L_IMPORT8'] = 'عودة الى الرفع';
+$lang['L_IMPORT9'] = 'هذا ليس دليل اسناد !';
+$lang['L_IMPORT10'] = 'تم رفع القوائم بنجاح ...';
+$lang['L_IMPORT11'] = '<strong>خطا: </strong>كانت هناك مشكلة في الكتابة الى sql_statements';
+$lang['L_IMPORT12'] = '<strong>خطأ: </strong>كانت هناك مشكلة في الكتابة الى config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(empty = Default Port)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(empty = Default Socket)';
+$lang['L_TRYAGAIN'] = 'حاول مرة اخرى';
+$lang['L_SOCKET'] = 'توصيل';
+$lang['L_PORT'] = 'منفذ';
+$lang['L_FOUND_DB'] = 'العثور على قاعدة بيانات';
+$lang['L_FM_FILEUPLOAD'] = 'رفع ملف';
+$lang['L_PASS'] = 'كلمة المرور';
+$lang['L_NO_DB_FOUND_INFO'] = 'تم الاتصال بقاعدة البيانات بنجاح.<br>
 تم قبول بيانات المستخدم الخصة بك لـ MySQL-Server.<br>
 لم يستطيع العثور على اية قاعدة بيانات.<br>
 البحث التلقائي لا يمكن من قبل الخادم.<br>
 انت يجب أن تدخل اسم قاعدة البيانات يدويا بعد الانتهاء من التركيب.
-اضغط هنا \"configuration\" \"Connection Parameter - display\" وتدخل اسم قاعدة البيانات هناك.
+اضغط هنا "configuration" "Connection Parameter - display" وتدخل اسم قاعدة البيانات هناك.
 
-";
-$lang['L_SAFEMODEDESC']="السبب PHP يعمل في الوضع الآمن فأنت تحتاج لإنشاء الادلة التالية يدويا بأستخدام برامج نقل الملفات  FTP-Programms:
+';
+$lang['L_SAFEMODEDESC'] = 'السبب PHP يعمل في الوضع الآمن فأنت تحتاج لإنشاء الادلة التالية يدويا بأستخدام برامج نقل الملفات  FTP-Programms:
 
 
-";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/ar/lang_log.php b/msd/language/ar/lang_log.php
index 9df1a055..b0a7d2ae 100644
--- a/msd/language/ar/lang_log.php
+++ b/msd/language/ar/lang_log.php
@@ -1,11 +1,9 @@
 <?php
-$lang['L_LOG_DELETE']="حذف مدخلات السجل";
-$lang['L_LOGFILEFORMAT']="تفاصيل الملف في السجل";
-$lang['L_LOGFILENOTWRITABLE']="لا يمكن الكتابة الى ملف السجل !";
-$lang['L_NOREVERSE']="بيانات الدخول الاقدم";
-$lang['L_REVERSE']="بيانات الدخول الاخيره
 
-";
+$lang['L_LOG_DELETE'] = 'حذف مدخلات السجل';
+$lang['L_LOGFILEFORMAT'] = 'تفاصيل الملف في السجل';
+$lang['L_LOGFILENOTWRITABLE'] = 'لا يمكن الكتابة الى ملف السجل !';
+$lang['L_NOREVERSE'] = 'بيانات الدخول الاقدم';
+$lang['L_REVERSE'] = 'بيانات الدخول الاخيره
 
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/ar/lang_main.php b/msd/language/ar/lang_main.php
index ed5e4527..91bd9276 100644
--- a/msd/language/ar/lang_main.php
+++ b/msd/language/ar/lang_main.php
@@ -1,81 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="لم يكن لديك وظائف بروتوكول نقل الملفات !";
-$lang['L_INFO_LOCATION']="الموقع الخاص بك هو ";
-$lang['L_INFO_DATABASES']="قاعدة البيانات التالية (s) على الخادم الخاص بك:";
-$lang['L_INFO_NODB']="قاعدة البيانات غير موجوده.";
-$lang['L_INFO_DBDETAIL']="معلومات تفصيلية لقاعدة البيانات ";
-$lang['L_INFO_DBEMPTY']="قاعدة البيانات فارغة !";
-$lang['L_INFO_RECORDS']="سجلات";
-$lang['L_INFO_SIZE']="الحجم";
-$lang['L_INFO_LASTUPDATE']="اخر تحديث";
-$lang['L_INFO_SUM']="المجموع";
-$lang['L_INFO_OPTIMIZED']="الافضل";
-$lang['L_OPTIMIZE_DATABASES']="افضل الجداول";
-$lang['L_CHECK_TABLES']="فحص الجداول";
-$lang['L_CLEAR_DATABASE']="تنظيف قاعدة البيانات";
-$lang['L_DELETE_DATABASE']="حذف قاعدة البيانات";
-$lang['L_INFO_CLEARED']="تأكيد حذف القاعدة";
-$lang['L_INFO_DELETED']="تم حذف القاعدة";
-$lang['L_INFO_EMPTYDB1']=" هل انت متأكد انك تريد حذف قاعدة البيانات ";
-$lang['L_INFO_EMPTYDB2']=" افراغ? (تحذير : جميع البيانات سوف تضيع الى الابد!)";
-$lang['L_INFO_KILLDB']=" حذف? (تحذير : جميع البيانات سوف تضيع الى الابد!)";
-$lang['L_PROCESSKILL1']="المخطوطة تحاول افشال العملية ";
-$lang['L_PROCESSKILL2']="فشلت.";
-$lang['L_PROCESSKILL3']="المخطوطة تحاول منذ  ";
-$lang['L_PROCESSKILL4']=" دقائق.لافشال العملية ";
-$lang['L_HTACC_CREATE']="انشاء اسم مستخدم وكلمة مرور لحماية الدليل ";
-$lang['L_ENCRYPTION_TYPE']="نوع التشفير";
-$lang['L_HTACC_CRYPT']="Crypt (Linux and Unix-Systems)";
-$lang['L_HTACC_MD5']="MD5 (Linux and Unix-Systems)";
-$lang['L_HTACC_NO_ENCRYPTION']="plain text, no cryption (Windows)";
-$lang['L_HTACCESS8']="تم الحصول على حماية الدليل. اذا قمت بإنشاء مستخدم جديد البيانات الاقدم سوف تكتب !";
-$lang['L_HTACC_NO_USERNAME']="انت يجب ان تدخل المستخدم !";
-$lang['L_PASSWORDS_UNEQUAL']="كلمات السر ليست متطابقة او فارغة !";
-$lang['L_HTACC_CONFIRM_DELETE']="يجب كتابة البيانات لحماية الدليل ?";
-$lang['L_HTACC_CREATED']="تم انشاء بيانات حماية الدليل.";
-$lang['L_HTACC_CONTENT']="محتويات الملف";
-$lang['L_HTACC_CREATE_ERROR']="حدث خطأ أثناء إنشاء دليل حماية !<br>يرجى كتابة وتهيئة الملفات التالية يدويا في المحتوى";
-$lang['L_HTACC_PROPOSED']="موصي به بشدة وللأهمية القصوي";
-$lang['L_HTACC_EDIT']="تحرير .htaccess";
-$lang['L_HTACCESS18']="انشاء في .htaccess  ";
-$lang['L_HTACCESS19']="اعد التحميل ";
-$lang['L_HTACCESS20']="تنفيذ البرنامج النصي";
-$lang['L_HTACCESS21']="اضف عملية";
-$lang['L_HTACCESS22']="اجعلها قابله للتنفيذ";
-$lang['L_HTACCESS23']="اداراجها في الدليل";
-$lang['L_HTACCESS24']="انشاء وثيقة للخطأ";
-$lang['L_HTACCESS25']="تفعيل اعادة الكتابة";
-$lang['L_HTACCESS26']="تعطيل / سماح";
-$lang['L_HTACCESS27']="اعادة توجيه";
-$lang['L_HTACCESS28']="خطا السجل";
-$lang['L_HTACCESS29']="امثلة وتفاصيل اكثر";
-$lang['L_HTACCESS30']="مقدمه";
-$lang['L_HTACCESS31']="عام";
-$lang['L_HTACCESS32']="انتبه! فإن. htaccess يؤثر بشكل مباشر على المتصفح .<br>مع وجود محتوى غير صحيح ، هذه الصفحات قد لا تكون متاحة.";
-$lang['L_PHPBUG']="مشكلة في zlib ! عملية الضغط غير ممكنه!";
-$lang['L_DISABLEDFUNCTIONS']="الوظائف المعطلة";
-$lang['L_NOGZPOSSIBLE']="Zlib لم يتم تركيبها  ، لا يمكنك استخدام - GZip وظائف!";
-$lang['L_DELETE_HTACCESS']="إزالة الحماية من الدليل (delete .htaccess)";
-$lang['L_WRONG_RIGHTS']="الملف او الدليل '%s' لايمكن الكتابة فيه.<br>
+
+$lang['L_NOFTPPOSSIBLE'] = 'لم يكن لديك وظائف بروتوكول نقل الملفات !';
+$lang['L_INFO_LOCATION'] = 'الموقع الخاص بك هو ';
+$lang['L_INFO_DATABASES'] = 'قاعدة البيانات التالية (s) على الخادم الخاص بك:';
+$lang['L_INFO_NODB'] = 'قاعدة البيانات غير موجوده.';
+$lang['L_INFO_DBDETAIL'] = 'معلومات تفصيلية لقاعدة البيانات ';
+$lang['L_INFO_DBEMPTY'] = 'قاعدة البيانات فارغة !';
+$lang['L_INFO_RECORDS'] = 'سجلات';
+$lang['L_INFO_SIZE'] = 'الحجم';
+$lang['L_INFO_LASTUPDATE'] = 'اخر تحديث';
+$lang['L_INFO_SUM'] = 'المجموع';
+$lang['L_INFO_OPTIMIZED'] = 'الافضل';
+$lang['L_OPTIMIZE_DATABASES'] = 'افضل الجداول';
+$lang['L_CHECK_TABLES'] = 'فحص الجداول';
+$lang['L_CLEAR_DATABASE'] = 'تنظيف قاعدة البيانات';
+$lang['L_DELETE_DATABASE'] = 'حذف قاعدة البيانات';
+$lang['L_INFO_CLEARED'] = 'تأكيد حذف القاعدة';
+$lang['L_INFO_DELETED'] = 'تم حذف القاعدة';
+$lang['L_INFO_EMPTYDB1'] = ' هل انت متأكد انك تريد حذف قاعدة البيانات ';
+$lang['L_INFO_EMPTYDB2'] = ' افراغ? (تحذير : جميع البيانات سوف تضيع الى الابد!)';
+$lang['L_INFO_KILLDB'] = ' حذف? (تحذير : جميع البيانات سوف تضيع الى الابد!)';
+$lang['L_PROCESSKILL1'] = 'المخطوطة تحاول افشال العملية ';
+$lang['L_PROCESSKILL2'] = 'فشلت.';
+$lang['L_PROCESSKILL3'] = 'المخطوطة تحاول منذ  ';
+$lang['L_PROCESSKILL4'] = ' دقائق.لافشال العملية ';
+$lang['L_HTACC_CREATE'] = 'انشاء اسم مستخدم وكلمة مرور لحماية الدليل ';
+$lang['L_ENCRYPTION_TYPE'] = 'نوع التشفير';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'تم الحصول على حماية الدليل. اذا قمت بإنشاء مستخدم جديد البيانات الاقدم سوف تكتب !';
+$lang['L_HTACC_NO_USERNAME'] = 'انت يجب ان تدخل المستخدم !';
+$lang['L_PASSWORDS_UNEQUAL'] = 'كلمات السر ليست متطابقة او فارغة !';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'يجب كتابة البيانات لحماية الدليل ?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'تم انشاء بيانات حماية الدليل.';
+$lang['L_HTACC_CONTENT'] = 'محتويات الملف';
+$lang['L_HTACC_CREATE_ERROR'] = 'حدث خطأ أثناء إنشاء دليل حماية !<br>يرجى كتابة وتهيئة الملفات التالية يدويا في المحتوى';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'موصي به بشدة وللأهمية القصوي';
+$lang['L_HTACC_EDIT'] = 'تحرير .htaccess';
+$lang['L_HTACCESS18'] = 'انشاء في .htaccess  ';
+$lang['L_HTACCESS19'] = 'اعد التحميل ';
+$lang['L_HTACCESS20'] = 'تنفيذ البرنامج النصي';
+$lang['L_HTACCESS21'] = 'اضف عملية';
+$lang['L_HTACCESS22'] = 'اجعلها قابله للتنفيذ';
+$lang['L_HTACCESS23'] = 'اداراجها في الدليل';
+$lang['L_HTACCESS24'] = 'انشاء وثيقة للخطأ';
+$lang['L_HTACCESS25'] = 'تفعيل اعادة الكتابة';
+$lang['L_HTACCESS26'] = 'تعطيل / سماح';
+$lang['L_HTACCESS27'] = 'اعادة توجيه';
+$lang['L_HTACCESS28'] = 'خطا السجل';
+$lang['L_HTACCESS29'] = 'امثلة وتفاصيل اكثر';
+$lang['L_HTACCESS30'] = 'مقدمه';
+$lang['L_HTACCESS31'] = 'عام';
+$lang['L_HTACCESS32'] = 'انتبه! فإن. htaccess يؤثر بشكل مباشر على المتصفح .<br>مع وجود محتوى غير صحيح ، هذه الصفحات قد لا تكون متاحة.';
+$lang['L_DISABLEDFUNCTIONS'] = 'الوظائف المعطلة';
+$lang['L_NOGZPOSSIBLE'] = 'Zlib لم يتم تركيبها  ، لا يمكنك استخدام - GZip وظائف!';
+$lang['L_DELETE_HTACCESS'] = 'إزالة الحماية من الدليل (delete .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "الملف او الدليل '%s' لايمكن الكتابة فيه.<br>
 الحقوق (chmod)ليست المجموعة  او ان المكلية غير صحيحة.<br>
 استخدم برامج بروتكول  FTP-لنقل ملفاتك.<br>
 الملف او الدليل من الضروري ان يستعدا %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Couldn' لا يستطيع انشاء '%s'. 
-من فضلك استخدم برامج برتكول FTP-لنقل الملفات.
-
-
-";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="لا يستطيع ايجاد الملف";
-
-
-?>
\ No newline at end of file
+$lang['L_CANT_CREATE_DIR'] = "Couldn' لا يستطيع انشاء '%s'.
+من فضلك استخدم برامج برتكول FTP-لنقل الملفات.";
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'لا يستطيع ايجاد الملف';
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/ar/lang_restore.php b/msd/language/ar/lang_restore.php
index 28e0369d..4b959cbc 100644
--- a/msd/language/ar/lang_restore.php
+++ b/msd/language/ar/lang_restore.php
@@ -1,23 +1,21 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="البدء لآن <b>%d</b> تم انشاء الجداول.";
-$lang['L_FILE_MISSING']="لا يستطيع ايجاد الملف";
-$lang['L_RESTORE_DB']="قاعدة البيانات '<b>%s</b>' على '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> انشاء الجداول.";
-$lang['L_RESTORE_RUN1']="<br>البدء لآن  <b>%s</b> of <b>%s</b> تمت الاضافة بنجاح.";
-$lang['L_RESTORE_RUN2']="<br>ابدأ الجداول  '<b>%s</b>'اعادة.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> ادراج سجلات.";
-$lang['L_RESTORE_TABLES_COMPLETED']="البدء لآن <b>%d</b> of <b>%d</b> تم انشاء الجداول.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>تهانينا.</b><br><br>تمت الان استعادة قاعدة البيانات.<br>تم استعادة جميع ملفات النسخ الاحتياطي.<br><br>انتهت العملية. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>مشكلة:<br>حدد قاعدة البيانات <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> فشل!";
-$lang['L_FILE_OPEN_ERROR']="خطأ: لا يمكن فتح الملف.";
-$lang['L_PROGRESS_OVER_ALL']="التقدم الشامل";
-$lang['L_BACK_TO_OVERVIEW']="تفاصيل عامة لقاعدة البيانات";
-$lang['L_RESTORE_RUN0']="<br>البدء لآن<b>%s</b> تمت اضافة السجلات بنجاح.";
-$lang['L_UNKNOWN_SQLCOMMAND']="مجهول SQL-امر";
-$lang['L_NOTICES']="ملاحظات
 
-";
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'البدء لآن <b>%d</b> تم انشاء الجداول.';
+$lang['L_FILE_MISSING'] = 'لا يستطيع ايجاد الملف';
+$lang['L_RESTORE_DB'] = "قاعدة البيانات '<b>%s</b>' على '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> انشاء الجداول.';
+$lang['L_RESTORE_RUN1'] = '<br>البدء لآن  <b>%s</b> of <b>%s</b> تمت الاضافة بنجاح.';
+$lang['L_RESTORE_RUN2'] = "<br>ابدأ الجداول  '<b>%s</b>'اعادة.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> ادراج سجلات.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'البدء لآن <b>%d</b> of <b>%d</b> تم انشاء الجداول.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>تهانينا.</b><br><br>تمت الان استعادة قاعدة البيانات.<br>تم استعادة جميع ملفات النسخ الاحتياطي.<br><br>انتهت العملية. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>مشكلة:<br>حدد قاعدة البيانات <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> فشل!';
+$lang['L_FILE_OPEN_ERROR'] = 'خطأ: لا يمكن فتح الملف.';
+$lang['L_PROGRESS_OVER_ALL'] = 'التقدم الشامل';
+$lang['L_BACK_TO_OVERVIEW'] = 'تفاصيل عامة لقاعدة البيانات';
+$lang['L_RESTORE_RUN0'] = '<br>البدء لآن<b>%s</b> تمت اضافة السجلات بنجاح.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'مجهول SQL-امر';
+$lang['L_NOTICES'] = 'ملاحظات
 
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/ar/lang_sql.php b/msd/language/ar/lang_sql.php
index fe02cc52..227450f6 100644
--- a/msd/language/ar/lang_sql.php
+++ b/msd/language/ar/lang_sql.php
@@ -1,197 +1,190 @@
 <?php
-$lang['L_COMMAND']="الاوامر";
-$lang['L_IMPORT_NOTABLE']="لا يوجد جداول في  التحديد المستورد!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="تنفيذ اوامر SQL يمكن ان يتم معالجة البيانات والتلاعب بها . انتبه لذلك ! المبرمجون لا يتحملون اي مسؤلية جراء فقدان او تلف اي ملفات .";
-$lang['L_SQL_EXEC']=" SQLتنفيذ بيانات  ";
-$lang['L_SQL_DATAVIEW']="عرض البيانات";
-$lang['L_SQL_TABLEVIEW']="عرض الجدول";
-$lang['L_SQL_VONINS']="الجميع";
-$lang['L_SQL_NODATA']="لا سجلات";
-$lang['L_SQL_RECORDUPDATED']="تم تحديث السجل";
-$lang['L_SQL_RECORDINSERTED']="تمت اصافة السجل";
-$lang['L_SQL_BACKDBOVERVIEW']="عودة الى نظرة عامة";
-$lang['L_SQL_RECORDDELETED']="تم حذف السجل";
-$lang['L_ASKTABLEEMPTY']="فارغة `%s` تأكد ان جميع الجداول?";
-$lang['L_SQL_RECORDEDIT']="تحرير السجل";
-$lang['L_SQL_RECORDNEW']="سجل جديد";
-$lang['L_ASKDELETERECORD']="هل انت متأكد انك تريد حذف هذا السجل?";
-$lang['L_ASKDELETETABLE']="حذف الجداول `%s` تاكد انه تم ?";
-$lang['L_SQL_BEFEHLE']="اوامر SQL ";
-$lang['L_SQL_BEFEHLNEU']="امر جديد";
-$lang['L_SQL_BEFEHLSAVED1']="SQL امر";
-$lang['L_SQL_BEFEHLSAVED2']="تمت الاضافة";
-$lang['L_SQL_BEFEHLSAVED3']="تم الحفظ";
-$lang['L_SQL_BEFEHLSAVED4']="تم النقل للاعلى";
-$lang['L_SQL_BEFEHLSAVED5']="تم الحذف";
-$lang['L_SQL_QUERYENTRY']="الاستعلام يتضمن";
-$lang['L_SQL_COLUMNS']="الاعمدة";
-$lang['L_ASKDBDELETE']="بالمحتوى `%s` هل تريد حذف قاعدة البيانات?";
-$lang['L_ASKDBEMPTY']="هل تريد افراغ قاعدة البيانات `%s` ?";
-$lang['L_ASKDBCOPY']=" `%s` هل تريد نسخ قاعدة البيانات  `%s`الى قاعدة البيانات ?";
-$lang['L_SQL_TABLENEW']="تحرير الجداول";
-$lang['L_SQL_OUTPUT']="SQL ناتج";
-$lang['L_DO_NOW']="ابدأ الآن";
-$lang['L_SQL_NAMEDEST_MISSING']="اسم الوجهة مفقود !";
-$lang['L_ASKDELETEFIELD']="هل انت متأكد انك تريد حذف هذا الحقل?";
-$lang['L_SQL_COMMANDS_IN']=" في الخطوط ";
-$lang['L_SQL_COMMANDS_IN2']="  sec. parsed.";
-$lang['L_SQL_OUT1']="تنفيذ ";
-$lang['L_SQL_OUT2']="الاوامر";
-$lang['L_SQL_OUT3']="It had ";
-$lang['L_SQL_OUT4']="التعليقات";
-$lang['L_SQL_OUT5']="اذا كان الناتج يحتوي على أكثر من 5000 من الخطوط فلن يتم عرضها.";
-$lang['L_SQL_SELECDB']="حدد قاعدة البيانات";
-$lang['L_SQL_TABLESOFDB']="الجداول في قاعدة البيانات";
-$lang['L_SQL_EDIT']="تعديل";
-$lang['L_SQL_NOFIELDDELETE']="الحذف غير ممكن لان الجداول يجب ان تحتوي على حقل واحد على الاقل.";
-$lang['L_SQL_FIELDDELETE1']="الحقل";
-$lang['L_SQL_DELETED']="تم الحذف";
-$lang['L_SQL_CHANGED']="تم التعديل.";
-$lang['L_SQL_CREATED']="تمت الاضافة.";
-$lang['L_SQL_NODEST_COPY']="لايمكن النسخ بدون تحديد الاتجاه !";
-$lang['L_SQL_DESTTABLE_EXISTS']="اتجاه الجدول موجود !";
-$lang['L_SQL_SCOPY']=" `%s` اعمدة الجدول `%s`تم نسخها الى الجدول.";
-$lang['L_SQL_TCOPY']=" `%s` بيانات الجدول `%s`تم نسخها الى الجدول.";
-$lang['L_SQL_TABLENONAME']="الجدول يحتاج الى اسم!";
-$lang['L_SQL_TBLNAMEEMPTY']="اسم الجدول لا يمكن ان يكون فارغا!";
-$lang['L_SQL_COLLATENOTMATCH']="البيانات والترتيب لا تتطابق مع بعضها!";
-$lang['L_SQL_FIELDNAMENOTVALID']="خطأ: اسم الحقل غير صحيح";
-$lang['L_SQL_CREATETABLE']="انشاء جدول";
-$lang['L_SQL_COPYTABLE']="نسخ جدول";
-$lang['L_SQL_STRUCTUREONLY']="فقط الاعمدة";
-$lang['L_SQL_STRUCTUREDATA']="الاعمدة والبيانات";
-$lang['L_SQL_NOTABLESINDB']="لا توجد اي جداول في قاعدة البيانات التي حددتها";
-$lang['L_SQL_SELECTTABLE']="select table";
-$lang['L_SQL_SHOWDATATABLE']="Show Data of Table";
-$lang['L_SQL_TBLPROPSOF']="Table properties of";
-$lang['L_SQL_EDITFIELD']="Edit field";
-$lang['L_SQL_NEWFIELD']="New field";
-$lang['L_SQL_INDEXES']="Indices";
-$lang['L_SQL_ATPOSITION']="insert at position";
-$lang['L_SQL_FIRST']="first";
-$lang['L_SQL_AFTER']="after";
-$lang['L_SQL_CHANGEFIELD']="change field";
-$lang['L_SQL_INSERTFIELD']="insert field";
-$lang['L_SQL_INSERTNEWFIELD']="insert new field";
-$lang['L_SQL_TABLEINDEXES']="Indexes of table";
-$lang['L_SQL_ALLOWDUPS']="Duplicates allowed";
-$lang['L_SQL_CARDINALITY']="Cardinality";
-$lang['L_SQL_TABLENOINDEXES']="No Indexes in Table";
-$lang['L_SQL_CREATEINDEX']="create new index";
-$lang['L_SQL_WASEMPTIED']="was emptied";
-$lang['L_SQL_RENAMEDTO']="was renamed to";
-$lang['L_SQL_DBCOPY']="The Content of Database `%s` was copied in Database `%s`.";
-$lang['L_SQL_DBSCOPY']="The Structure of Database `%s` was copied in Database `%s`.";
-$lang['L_SQL_WASCREATED']="تم الانشاء";
-$lang['L_SQL_RENAMEDB']="تغيير اسم قاعدة البيانات";
-$lang['L_SQL_ACTIONS']="الاجراءات";
-$lang['L_SQL_CHOOSEACTION']="اختر اجراء";
-$lang['L_SQL_DELETEDB']="حذف قاعدة البيانات";
-$lang['L_SQL_EMPTYDB']="افراغ قاعدة البيانات";
-$lang['L_SQL_COPYDATADB']="نسخة كاملة لقاعدة البيانات الى";
-$lang['L_SQL_COPYSDB']="نسخة من اعمدة قاعدة البيانات";
-$lang['L_SQL_IMEXPORT']="تصدير-استيراد";
-$lang['L_INFO_RECORDS']="السجلات";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="هل انت متأكد من من تفريغ الجدول  `%s` واعادة الفهارس ?";
-$lang['L_EDIT']="تحرير";
-$lang['L_DELETE']="حذف";
-$lang['L_EMPTY']="افراغ";
-$lang['L_EMPTYKEYS']="تفريغ واعادة الادلة";
-$lang['L_SQL_TABLEEMPTIED']="الجدول `%s` تم حذفه.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="الجدول `%s` تم حذفه وتمت اعادة الفهارس.";
-$lang['L_SQL_LIBRARY']="SQL معلومات";
-$lang['L_SQL_ATTRIBUTES']="الصفات";
-$lang['L_SQL_UPLOADEDFILE']="تنزيل ملف: ";
-$lang['L_SQL_IMPORT']=" `%s`استيراد من قاعدة البيانات ";
-$lang['L_EXPORT']="تصدير";
-$lang['L_IMPORT']="استيراد";
-$lang['L_IMPORTOPTIONS']="خيارات الاستيراد";
-$lang['L_CSVOPTIONS']="CSV خيارات";
-$lang['L_IMPORTTABLE']="استيراد من جدول";
-$lang['L_NEWTABLE']="جدول جديد";
-$lang['L_IMPORTSOURCE']="مصدر الاستيراد";
-$lang['L_FROMTEXTBOX']="صندوق النص";
-$lang['L_FROMFILE']="ملف";
-$lang['L_EMPTYTABLEBEFORE']="قبل افراغ الجدول";
-$lang['L_CREATEAUTOINDEX']="اضف تلقائيا الى دليل-Index";
-$lang['L_CSV_NAMEFIRSTLINE']="اسماء الحقول في الخط الاول";
-$lang['L_CSV_FIELDSEPERATE']="الحقول فصلت";
-$lang['L_CSV_FIELDSENCLOSED']="تم ارفاق الحقول بواسطة";
-$lang['L_CSV_FIELDSESCAPE']="تضمين الحقول مع";
-$lang['L_CSV_EOL']="خطوط منفصلة";
-$lang['L_CSV_NULL']="استبدال NULL ";
-$lang['L_CSV_FILEOPEN']="ملف CSVفتح";
-$lang['L_IMPORTIEREN']="استيراد";
-$lang['L_SQL_EXPORT']="تصدير من قاعدة البيانات `%s`";
-$lang['L_EXPORTOPTIONS']="خيارات التصدير";
-$lang['L_EXCEL2003']="Excel fromاكسل  2003";
-$lang['L_SHOWRESULT']="عرض النتائج";
-$lang['L_SENDRESULTASFILE']="ارسال نتيجة الملف";
-$lang['L_EXPORTLINES']="<قوي>%s</strong> تم تصدير الخطوط";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="احصاء الحقول لا يتطابق مع بيانات الاستيراد (%d بدلا من %d).";
-$lang['L_CSV_FIELDSLINES']="%d الحقول معروفه, كليا %d خطوط";
-$lang['L_CSV_ERRORCREATETABLE']=" `%s` حدث خطأ عند القيام بإنشاء الجدول !";
-$lang['L_FM_UPLOADFILEREQUEST']="رجاء اختر الملف.";
-$lang['L_CSV_NODATA']="لا توجد بيانات للاستيراد!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="الوظائف العامة";
-$lang['L_SQLLIB_RESETAUTO']="اعادة تلقائية-للزيادة";
-$lang['L_SQLLIB_BOARDS']="القوائم";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="تعطيل قائمة";
-$lang['L_SQLLIB_ACTIVATEBOARD']="تمكين قائمة";
-$lang['L_SQL_NOTABLESSELECTED']="لم يتم اختيار اي جداول !";
-$lang['L_TOOLS']="اداوات";
-$lang['L_TOOLS_TOOLBOX']=" اختيار قاعدة البيانات /  مهام / استيراد - تصدير قاعدة بيانات ";
-$lang['L_SQL_OPENFILE']="فتح SQL-ملف";
-$lang['L_SQL_OPENFILE_BUTTON']="ارسال";
-$lang['L_MAX_UPLOAD_SIZE']="الحجم الاقصى للملف";
-$lang['L_SQL_SEARCH']="بحث";
-$lang['L_SQL_SEARCHWORDS']="كلمة البحث(s)";
-$lang['L_START_SQL_SEARCH']="بداية البحث";
-$lang['L_RESET_SEARCHWORDS']="اعد كتابة كلمات البحث";
-$lang['L_SEARCH_OPTIONS']="خيارات البحث";
-$lang['L_SEARCH_RESULTS']="عملية البحث \"<b>%s</b>\" في الجدول \"<b>%s</b>\" جلبت النتائج التالية";
-$lang['L_SEARCH_NO_RESULTS']="عملية البحث \"<b>%s</b>\" في الجدول \"<b>%s</b>\" لم تجلب اي نتائج!";
-$lang['L_NO_ENTRIES']="الجدول \"<b>%s</b>\" فارغ او انه لايمكن الوصل اليه.";
-$lang['L_SEARCH_ACCESS_KEYS']=" استعرض واستخدم المفاتيح التالية : forwardللامام =ALT+V, backwardsالتراجع للخلف=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="يجب ان يحتوي العمود على احدى كلمات البحث (او-بحث)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="الصف يجب ان يحتوي على كل كلمات البحث ولكن يمكن ان يكونوا في اي عمود(يمكن ان يستغرق بعض الوقت)";
-$lang['L_SEARCH_OPTIONS_AND']="العمود يجب ان يحتوي على جميع كلمات البحث  (و-البحث)";
-$lang['L_SEARCH_IN_TABLE']="بحث في الجدول";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="تحرير اعمدة الجدول";
-$lang['L_DEFAULT_CHARSET']="الاعدادات الاصلية
 
-
-";
-$lang['L_TITLE_KEY_PRIMARY']="المفتاح الاساسي";
-$lang['L_TITLE_KEY_UNIQUE']="مفتاح فريد";
-$lang['L_TITLE_INDEX']="الرئيسة";
-$lang['L_TITLE_KEY_FULLTEXT']="مفتاح النص الكامل";
-$lang['L_TITLE_NOKEY']="لا مفتاح";
-$lang['L_TITLE_SEARCH']="بحث";
-$lang['L_TITLE_MYSQL_HELP']="MySQl وثائق";
-$lang['L_TITLE_UPLOAD']="ارسال ملف SQL
-
-
-";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="الحجم";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
-
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'الاوامر';
+$lang['L_IMPORT_NOTABLE'] = 'لا يوجد جداول في  التحديد المستورد!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'تنفيذ اوامر SQL يمكن ان يتم معالجة البيانات والتلاعب بها . انتبه لذلك ! المبرمجون لا يتحملون اي مسؤلية جراء فقدان او تلف اي ملفات .';
+$lang['L_SQL_EXEC'] = ' SQLتنفيذ بيانات  ';
+$lang['L_SQL_DATAVIEW'] = 'عرض البيانات';
+$lang['L_SQL_TABLEVIEW'] = 'عرض الجدول';
+$lang['L_SQL_VONINS'] = 'الجميع';
+$lang['L_SQL_NODATA'] = 'لا سجلات';
+$lang['L_SQL_RECORDUPDATED'] = 'تم تحديث السجل';
+$lang['L_SQL_RECORDINSERTED'] = 'تمت اصافة السجل';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'عودة الى نظرة عامة';
+$lang['L_SQL_RECORDDELETED'] = 'تم حذف السجل';
+$lang['L_ASKTABLEEMPTY'] = 'فارغة `%s` تأكد ان جميع الجداول?';
+$lang['L_SQL_RECORDEDIT'] = 'تحرير السجل';
+$lang['L_SQL_RECORDNEW'] = 'سجل جديد';
+$lang['L_ASKDELETERECORD'] = 'هل انت متأكد انك تريد حذف هذا السجل?';
+$lang['L_ASKDELETETABLE'] = 'حذف الجداول `%s` تاكد انه تم ?';
+$lang['L_SQL_BEFEHLE'] = 'اوامر SQL ';
+$lang['L_SQL_BEFEHLNEU'] = 'امر جديد';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL امر';
+$lang['L_SQL_BEFEHLSAVED2'] = 'تمت الاضافة';
+$lang['L_SQL_BEFEHLSAVED3'] = 'تم الحفظ';
+$lang['L_SQL_BEFEHLSAVED4'] = 'تم النقل للاعلى';
+$lang['L_SQL_BEFEHLSAVED5'] = 'تم الحذف';
+$lang['L_SQL_QUERYENTRY'] = 'الاستعلام يتضمن';
+$lang['L_SQL_COLUMNS'] = 'الاعمدة';
+$lang['L_ASKDBDELETE'] = 'بالمحتوى `%s` هل تريد حذف قاعدة البيانات?';
+$lang['L_ASKDBEMPTY'] = 'هل تريد افراغ قاعدة البيانات `%s` ?';
+$lang['L_ASKDBCOPY'] = ' `%s` هل تريد نسخ قاعدة البيانات  `%s`الى قاعدة البيانات ?';
+$lang['L_SQL_TABLENEW'] = 'تحرير الجداول';
+$lang['L_SQL_OUTPUT'] = 'SQL ناتج';
+$lang['L_DO_NOW'] = 'ابدأ الآن';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'اسم الوجهة مفقود !';
+$lang['L_ASKDELETEFIELD'] = 'هل انت متأكد انك تريد حذف هذا الحقل?';
+$lang['L_SQL_COMMANDS_IN'] = ' في الخطوط ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sec. parsed.';
+$lang['L_SQL_OUT1'] = 'تنفيذ ';
+$lang['L_SQL_OUT2'] = 'الاوامر';
+$lang['L_SQL_OUT3'] = 'It had ';
+$lang['L_SQL_OUT4'] = 'التعليقات';
+$lang['L_SQL_OUT5'] = 'اذا كان الناتج يحتوي على أكثر من 5000 من الخطوط فلن يتم عرضها.';
+$lang['L_SQL_SELECDB'] = 'حدد قاعدة البيانات';
+$lang['L_SQL_TABLESOFDB'] = 'الجداول في قاعدة البيانات';
+$lang['L_SQL_EDIT'] = 'تعديل';
+$lang['L_SQL_NOFIELDDELETE'] = 'الحذف غير ممكن لان الجداول يجب ان تحتوي على حقل واحد على الاقل.';
+$lang['L_SQL_FIELDDELETE1'] = 'الحقل';
+$lang['L_SQL_DELETED'] = 'تم الحذف';
+$lang['L_SQL_CHANGED'] = 'تم التعديل.';
+$lang['L_SQL_CREATED'] = 'تمت الاضافة.';
+$lang['L_SQL_NODEST_COPY'] = 'لايمكن النسخ بدون تحديد الاتجاه !';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'اتجاه الجدول موجود !';
+$lang['L_SQL_SCOPY'] = ' `%s` اعمدة الجدول `%s`تم نسخها الى الجدول.';
+$lang['L_SQL_TCOPY'] = ' `%s` بيانات الجدول `%s`تم نسخها الى الجدول.';
+$lang['L_SQL_TABLENONAME'] = 'الجدول يحتاج الى اسم!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'اسم الجدول لا يمكن ان يكون فارغا!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'البيانات والترتيب لا تتطابق مع بعضها!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'خطأ: اسم الحقل غير صحيح';
+$lang['L_SQL_CREATETABLE'] = 'انشاء جدول';
+$lang['L_SQL_COPYTABLE'] = 'نسخ جدول';
+$lang['L_SQL_STRUCTUREONLY'] = 'فقط الاعمدة';
+$lang['L_SQL_STRUCTUREDATA'] = 'الاعمدة والبيانات';
+$lang['L_SQL_NOTABLESINDB'] = 'لا توجد اي جداول في قاعدة البيانات التي حددتها';
+$lang['L_SQL_SELECTTABLE'] = 'select table';
+$lang['L_SQL_SHOWDATATABLE'] = 'Show Data of Table';
+$lang['L_SQL_TBLPROPSOF'] = 'Table properties of';
+$lang['L_SQL_EDITFIELD'] = 'Edit field';
+$lang['L_SQL_NEWFIELD'] = 'New field';
+$lang['L_SQL_INDEXES'] = 'Indices';
+$lang['L_SQL_ATPOSITION'] = 'insert at position';
+$lang['L_SQL_FIRST'] = 'first';
+$lang['L_SQL_AFTER'] = 'after';
+$lang['L_SQL_CHANGEFIELD'] = 'change field';
+$lang['L_SQL_INSERTFIELD'] = 'insert field';
+$lang['L_SQL_INSERTNEWFIELD'] = 'insert new field';
+$lang['L_SQL_TABLEINDEXES'] = 'Indexes of table';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplicates allowed';
+$lang['L_SQL_CARDINALITY'] = 'Cardinality';
+$lang['L_SQL_TABLENOINDEXES'] = 'No Indexes in Table';
+$lang['L_SQL_CREATEINDEX'] = 'create new index';
+$lang['L_SQL_WASEMPTIED'] = 'was emptied';
+$lang['L_SQL_RENAMEDTO'] = 'was renamed to';
+$lang['L_SQL_DBCOPY'] = 'The Content of Database `%s` was copied in Database `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'The Structure of Database `%s` was copied in Database `%s`.';
+$lang['L_SQL_WASCREATED'] = 'تم الانشاء';
+$lang['L_SQL_RENAMEDB'] = 'تغيير اسم قاعدة البيانات';
+$lang['L_SQL_ACTIONS'] = 'الاجراءات';
+$lang['L_SQL_CHOOSEACTION'] = 'اختر اجراء';
+$lang['L_SQL_DELETEDB'] = 'حذف قاعدة البيانات';
+$lang['L_SQL_EMPTYDB'] = 'افراغ قاعدة البيانات';
+$lang['L_SQL_COPYDATADB'] = 'نسخة كاملة لقاعدة البيانات الى';
+$lang['L_SQL_COPYSDB'] = 'نسخة من اعمدة قاعدة البيانات';
+$lang['L_SQL_IMEXPORT'] = 'تصدير-استيراد';
+$lang['L_INFO_RECORDS'] = 'السجلات';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'هل انت متأكد من من تفريغ الجدول  `%s` واعادة الفهارس ?';
+$lang['L_EDIT'] = 'تحرير';
+$lang['L_DELETE'] = 'حذف';
+$lang['L_EMPTY'] = 'افراغ';
+$lang['L_EMPTYKEYS'] = 'تفريغ واعادة الادلة';
+$lang['L_SQL_TABLEEMPTIED'] = 'الجدول `%s` تم حذفه.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'الجدول `%s` تم حذفه وتمت اعادة الفهارس.';
+$lang['L_SQL_LIBRARY'] = 'SQL معلومات';
+$lang['L_SQL_ATTRIBUTES'] = 'الصفات';
+$lang['L_SQL_UPLOADEDFILE'] = 'تنزيل ملف: ';
+$lang['L_SQL_IMPORT'] = ' `%s`استيراد من قاعدة البيانات ';
+$lang['L_EXPORT'] = 'تصدير';
+$lang['L_IMPORT'] = 'استيراد';
+$lang['L_IMPORTOPTIONS'] = 'خيارات الاستيراد';
+$lang['L_CSVOPTIONS'] = 'CSV خيارات';
+$lang['L_IMPORTTABLE'] = 'استيراد من جدول';
+$lang['L_NEWTABLE'] = 'جدول جديد';
+$lang['L_IMPORTSOURCE'] = 'مصدر الاستيراد';
+$lang['L_FROMTEXTBOX'] = 'صندوق النص';
+$lang['L_FROMFILE'] = 'ملف';
+$lang['L_EMPTYTABLEBEFORE'] = 'قبل افراغ الجدول';
+$lang['L_CREATEAUTOINDEX'] = 'اضف تلقائيا الى دليل-Index';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'اسماء الحقول في الخط الاول';
+$lang['L_CSV_FIELDSEPERATE'] = 'الحقول فصلت';
+$lang['L_CSV_FIELDSENCLOSED'] = 'تم ارفاق الحقول بواسطة';
+$lang['L_CSV_FIELDSESCAPE'] = 'تضمين الحقول مع';
+$lang['L_CSV_EOL'] = 'خطوط منفصلة';
+$lang['L_CSV_NULL'] = 'استبدال NULL ';
+$lang['L_CSV_FILEOPEN'] = 'ملف CSVفتح';
+$lang['L_IMPORTIEREN'] = 'استيراد';
+$lang['L_SQL_EXPORT'] = 'تصدير من قاعدة البيانات `%s`';
+$lang['L_EXPORTOPTIONS'] = 'خيارات التصدير';
+$lang['L_EXCEL2003'] = 'Excel fromاكسل  2003';
+$lang['L_SHOWRESULT'] = 'عرض النتائج';
+$lang['L_SENDRESULTASFILE'] = 'ارسال نتيجة الملف';
+$lang['L_EXPORTLINES'] = '<قوي>%s</strong> تم تصدير الخطوط';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'احصاء الحقول لا يتطابق مع بيانات الاستيراد (%d بدلا من %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d الحقول معروفه, كليا %d خطوط';
+$lang['L_CSV_ERRORCREATETABLE'] = ' `%s` حدث خطأ عند القيام بإنشاء الجدول !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'رجاء اختر الملف.';
+$lang['L_CSV_NODATA'] = 'لا توجد بيانات للاستيراد!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'الوظائف العامة';
+$lang['L_SQLLIB_RESETAUTO'] = 'اعادة تلقائية-للزيادة';
+$lang['L_SQLLIB_BOARDS'] = 'القوائم';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'تعطيل قائمة';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'تمكين قائمة';
+$lang['L_SQL_NOTABLESSELECTED'] = 'لم يتم اختيار اي جداول !';
+$lang['L_TOOLS'] = 'اداوات';
+$lang['L_TOOLS_TOOLBOX'] = ' اختيار قاعدة البيانات /  مهام / استيراد - تصدير قاعدة بيانات ';
+$lang['L_SQL_OPENFILE'] = 'فتح SQL-ملف';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'ارسال';
+$lang['L_MAX_UPLOAD_SIZE'] = 'الحجم الاقصى للملف';
+$lang['L_SQL_SEARCH'] = 'بحث';
+$lang['L_SQL_SEARCHWORDS'] = 'كلمة البحث(s)';
+$lang['L_START_SQL_SEARCH'] = 'بداية البحث';
+$lang['L_RESET_SEARCHWORDS'] = 'اعد كتابة كلمات البحث';
+$lang['L_SEARCH_OPTIONS'] = 'خيارات البحث';
+$lang['L_SEARCH_RESULTS'] = 'عملية البحث "<b>%s</b>" في الجدول "<b>%s</b>" جلبت النتائج التالية';
+$lang['L_SEARCH_NO_RESULTS'] = 'عملية البحث "<b>%s</b>" في الجدول "<b>%s</b>" لم تجلب اي نتائج!';
+$lang['L_NO_ENTRIES'] = 'الجدول "<b>%s</b>" فارغ او انه لايمكن الوصل اليه.';
+$lang['L_SEARCH_ACCESS_KEYS'] = ' استعرض واستخدم المفاتيح التالية : forwardللامام =ALT+V, backwardsالتراجع للخلف=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'يجب ان يحتوي العمود على احدى كلمات البحث (او-بحث)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'الصف يجب ان يحتوي على كل كلمات البحث ولكن يمكن ان يكونوا في اي عمود(يمكن ان يستغرق بعض الوقت)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'العمود يجب ان يحتوي على جميع كلمات البحث  (و-البحث)';
+$lang['L_SEARCH_IN_TABLE'] = 'بحث في الجدول';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'تحرير اعمدة الجدول';
+$lang['L_DEFAULT_CHARSET'] = 'الاعدادات الاصلية';
+$lang['L_TITLE_KEY_PRIMARY'] = 'المفتاح الاساسي';
+$lang['L_TITLE_KEY_UNIQUE'] = 'مفتاح فريد';
+$lang['L_TITLE_INDEX'] = 'الرئيسة';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'مفتاح النص الكامل';
+$lang['L_TITLE_NOKEY'] = 'لا مفتاح';
+$lang['L_TITLE_SEARCH'] = 'بحث';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQl وثائق';
+$lang['L_TITLE_UPLOAD'] = 'ارسال ملف SQL';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'الحجم';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/ch/help.html b/msd/language/ch/help.html
new file mode 100644
index 00000000..4fbd2929
--- /dev/null
+++ b/msd/language/ch/help.html
@@ -0,0 +1,146 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/ch/help.php b/msd/language/ch/help.php
deleted file mode 100644
index d749ee06..00000000
--- a/msd/language/ch/help.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-
-<h3>Über das Projäkt</h3>
-D Idee für das Projäkt isch vom Daniel Schlichtholz cho.<p>Er hät 2004 das Forum <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a>, eröffnet und scho bald händ sich Hobby-Programmierer, wo neui Skripts schribe und diä vom Daniel erwiteret händ, iigfunde.<br>I kürzischter Ziit isch us däm chline Backupskript es stattlichs Projäkt entschtande.<p>Wänn Du Vorschläg zur Verbesserig häsch, dänn wänd Di as MySQLDumper-Forum <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>Mir wünsched Dir vill Vergnüege mit däm Projäkt.<br><p><h4>S MySQLDumper-Team</h4>
-
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
-
-<h3>MySQLDumper Hilf</h3>
-
-<h4>Download</h4>
-Das Script chömed Ihr uf de Homepage vom MySQLDumper über.<br>
-Es wäri guet, diä Homepage regelmässig zbsueche, für Updates und
-Hilfschtellige zübercho.<br>
-D Adrässe isch: <a href="http://www.mysqldumper.de" target="_blank">
-http://www.mysqldumper.de</a>
-
-<h4>Syschtemvorussetzig</h4>
-S Script schaffet uf jedem Server (Windows, Linux, ...) <br>
-mit PHP >= Version 4.3.4 mit GZip-Unterstützig, MySQL (ab Version 3.23), JavaScript (mues aktiviert sii).
-
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
-D Installation isch ganz eifach.
-Entpacked s Archiv imene beliebige Ordner.<br>
-Ladet alli Dateie uf Eure Webserver ufe. (z. B. i di underschti Ebeni in [Server Webverzeichnis/]MySQLDumper)<br>
-... fertig!<br>
-Ihr chönd MySQLDumper ez im Webbrowser dur "http://mein-webserver/MySQLDumper" ufrüefe,<br>
-zum d Installation abschlüsse. Halted Eu eifach ad Instruktione.<br>
-<br><b>Hinwiis:</b><br><i>Falls uf Eurem Server de PHP-Safemode igschalte isch, dörf s Script keini
-Verzeichniss mache.<br>
-Das müender dänn vo Hand nahole, will MySqlDump diä Date gordnet i
-Verzeichniss ableit.<br> 
-S Script bricht mit ere entsprächende Aawisig ab!<br>
-Wänn Ihr diä Verzeichniss (em Hiwiis entsprächend) gmacht händ, laufts normal und ohni Iischränkige.</i>
-
-<a name="perl"></a><h4>Perlskript Aaleitig</h4>
-Di Meischte händ es cgi-bin Verzeichnis, wo drin Perl ausgfüert wärde cha. <br>
-Das isch meischtens per Browser über http://www.domain.de/cgi-bin/ erreichbar. <br>
-<br>
-Für dä Fall bitte folgendi Schritt durefüere:<br><br>
-
-1. Rüef im MySQLDumper d Siite Backup uf und klick uf "Backup Perl". <br>
-2. Kopier de Pfad, wo hinder em Iitrag im crondump.pl für $absolute_path_of_configdir: schtaht. <br>
-3. Mach diä Datei "crondump.pl" im Editor uuf.<br>
-4. Träg de kopierti Pfad det bi absolute_path_of_configdir ii (kei Läärzeiche).<br>
-5. Spichere crondump.pl .<br>
-6. Kopier crondump.pl, perltest.pl und simpletest.pl is cgi-bin-Verzeichnis (Ascii-Modus im FTP).<br>
-7. Gib de Dateie d Rächt 755. <br>
-7b. Wänn d Endig cgi gwünscht isch, ändere bi allne 3 Dateie d Endig vo pl -> cgi (umbenänne). <br>
-8. Rüef d Konfiguration im MySQLDumper uf.<br>
-9. Wähl d Siite Cronscript. <br>
-10. Ändere Perl Uusfüerigspfad i /cgi-bin/ .<br>
-10b. Wänn d Scripts .pl händ, ändere diä Dateiendig uf .cgi .<br>
-11. Spichere d Konfiguration. <br><br>
-
-Fertig, diä Skripts lönd sich vo ez aa uf de Backupsiite aufrüefe.<br><br>
-
-Wär Perl i allne Verzeichnis ausfüere cha, däm langet folgendi Schritt:<br><br>
-
-1. Rüef im MySQLDumper d Siite Backup uf. <br>
-2. Kopier de Pfad, wo hinder em Iitrag im crondump.pl für $absolute_path_of_configdir: schtaht. <br>
-3. Mach d Datei "crondump.pl" im Editor uuf. <br>
-4. Träg de kopierti Pfad det bi absolute_path_of_configdir ii (kei Läärzeiche). <br>
-5. Spichere crondump.pl .<br>
-6. Gib de Dateie d Rächt 755. <br>
-6b. Wänn d Endig cgi gwünscht isch, ändere bi allne 3 Dateie d Endung von pl -> cgi (umbenänne). <br>
-(ev. 10b+11 von oben)<br>
-<br>
-
-Windowsuser müend bi allne Scripts di erscht Ziile ändere, det schtaht de Pfad vo Perl. Bispiil: <br>
-statt: #!/usr/bin/perl -w <br>
-jetzt: #!C:\perl\bin\perl.exe -w <br>
-
-<h4>Bedienig</h4><ul>
-
-<h6>Menü</h6>
-I de obige Auswahllischte stellet Ihr d Datenbank ii.<br>
-Alli Aktione beziend sich uf diä da igschtellti Datenbank.
-
-<h6>an Aafang</h6>
-Da erfahred Ihr Einiges über Eues System, di verschidene, installierte
-Versione und Details über di konfigurierte Datebanke.<br>
-Wänn Ihr uf de Datebankname klicked, so gsehnd Ihr en Uflischtig vo de Tabälle
-mit de Aazahl vo de Iiträg, vo de Grössi und sletschte Aktualisierigsdatum.
-
-<h6>Konfiguration</h6>
-Da chönd Ihr Eueri Konfiguration bearbeite, abspichere oder d Uusgangskonfiguration
-wieder mache.
-<ul><br>
-	<li><a name="conf1"></a><strong>Konfigurierti Datebanke:</strong> d Uuflischtig vo de konfigurierte Datebanke. Di aktivi Datebank wird in <b>bold</b> gelistet. </li>
-	<li><a name="conf2"></a><strong>Tabellen-Präfix:</strong> da chönd Ihr (für jedi Datebank) en Präfix aagäh. Das isch en Filter, wo bi Dumps nur diä Tabälle berücksichtigt, wo mit däm Präfix aafanged (z.B. alli Tabälle, wo mit "phpBB_" aafanged). Wänn alli Tabälle vo dere Datebank gspicheret wärden sölled, 
-lönd eifach s Fäld läär.</li>
-	<li><a name="conf3"></a><strong>GZip-Kompression:</strong> Da cha d Kompression aktiviert wärde. Empfehlenswert isch d Aktivierig, will d Dateie  wesentlich chliner wärdet und Spicherplatz immer rar isch.</li>
-	<li><a name="conf5"></a><strong>Email mit Dumpfile:</strong> Isch diä Option aktiviert,  wird nach em abgschlossne Backup en Email mit dem Dump als Aahang verschickt (Vorsicht, Kompression sötti umbedingt aa sii, susch wird dr Aahang zgross und cha evtl. nöd verschickt wärde!).</li>
-	<li><a name="conf6"></a><strong>Email-Adrässe:</strong> Empfängeradrässe für d Email.</li>
-	<li><a name="conf7"></a><strong>Absänder vo de Email:</strong> diä Adrässe taucht als Absänder i de Email uf.</li>
-	<li><a name="conf13"></a><strong>FTP-Transfer: </strong>Isch diä Option aktiviert, wird nach em abgschlossne Backup d Backupdatei per FTP verschickt.</li>
-	<li><a name="conf14"></a><strong>FTP Server: </strong>D Adrässe vom FTP-Server (z. B. ftp.mybackups.de).</li>
-	<li><a name="conf15"></a><strong>FTP Server Port: </strong>Der Port vom FTP-Server (i de Regle 21).</li>
-	<li><a name="conf16"></a><strong>FTP User: </strong>Der Benutzername des FTP-Accounts. </li>
-	<li><a name="conf17"></a><strong>FTP Passwort: </strong>Das Passwort des FTP-Accounts. </li>
-	<li><a name="conf18"></a><strong>FTP Upload-Ordner: </strong>Das Verzeichnis, wo diä Backupdatei häre söll (es müend Upload-Berechtigunge beschtah!).</li>
-	<li><a name="conf8"></a><strong>Automatisches Lösche vo de Backups:</strong> Wänn diä Option aktiviert isch, wärdet älteri Backups nach de folgende Regle automatisch gelöscht.</li>
-	<li><a name="conf10"></a><strong>Aazahl vo Backupdateie:</strong> En Wert > 0 löscht alli Backupdateie, bis uf diä da agebni Zahl.</li>
-	<li><a name="conf11"></a><strong>Sprach:</strong> Da legsch d Sprach fürs Interface fescht.</li>
-</ul>
-
-<h6>Verwaltig</h6>
-Da wärdet di eigetliche Aktionen duregfüert.<br>
-Es wärdet Dir alli Dateie im Backup-Verzeichnis aazeiget.
-Für d Aktione "Restore" und "Delete" mues e Datei selektiert sii.
-<UL>
-	<li><strong>Restore:</strong> Da demit wird d Datenbank mit de usgwählte Backupdatei aktualisiert.</li>
-	<li><strong>Delete:</strong> Da demit chasch Du di selektierti Backupdatei lösche.</li>
-	<li><strong>Neues Backup starten:</strong> Da schtartisch es neus Backup (Dump) nach de iigschtellte Parametern i de Konfiguration.</li>
-</UL>
-
-<h6>Log</h6>
-Da chasch d Logiiträg aaluege und lösche.
-<h6>Credits / Hilfe</h6>
-diese Seite.
-</ul>
\ No newline at end of file
diff --git a/msd/language/ch/lang.php b/msd/language/ch/lang.php
index 7651885c..f704eb6c 100644
--- a/msd/language/ch/lang.php
+++ b/msd/language/ch/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="jo";
-$lang['L_TO']="bis";
-$lang['L_ACTIVATED']="aktiviärt";
-$lang['L_NOT_ACTIVATED']="nöd aktiviert";
-$lang['L_ERROR']="Fähler";
-$lang['L_OF']="vo";
-$lang['L_ADDED']="dezue gfüegt";
-$lang['L_DB']="Datebank";
-$lang['L_DBS']="Datebanke";
-$lang['L_TABLES']="Tabälle";
-$lang['L_TABLE']="Tabälle";
-$lang['L_RECORDS']="Datesätz";
-$lang['L_COMPRESSED']="komprimiert (gz)";
-$lang['L_NOTCOMPRESSED']="normal (nöd komprimiert)";
-$lang['L_GENERAL']="allgemein";
-$lang['L_COMMENT']="Kommentar";
-$lang['L_FILESIZE']="Dateigrössi";
-$lang['L_ALL']="alli";
-$lang['L_NONE']="keini";
-$lang['L_WITH']="mit";
-$lang['L_DIR']="Verzeichnis";
-$lang['L_RECHTE']="Rächt";
-$lang['L_STATUS']="Status";
-$lang['L_FINISHED']="fertig gmacht";
-$lang['L_FILE']="Datei";
-$lang['L_FIELDS']="Fälder";
-$lang['L_NEW']="neu";
-$lang['L_CHARSET']="Zeichesatz";
-$lang['L_COLLATION']="Sortierig";
-$lang['L_CHANGE']="ändere";
-$lang['L_IN']="in";
-$lang['L_DO']="machs!";
-$lang['L_VIEW']="aaluege";
-$lang['L_EXISTING']="häts";
-$lang['L_BACK']="zrugg";
-$lang['L_DB_HOST']="Datebank- Hoschtname";
-$lang['L_DB_USER']="Datebank- Nutzer";
-$lang['L_DB_PASS']="Datebank- Passwort";
-$lang['L_INFO_SCRIPTDIR']="Verzeichnis vom MySQLDumper";
-$lang['L_INFO_ACTDB']="Aktuelli Datebank";
-$lang['L_WRONGCONNECTIONPARS']="Falschi oder kei Verbindigsparameter";
-$lang['L_CONN_NOT_POSSIBLE']="Verbindig nöd mögli!";
-$lang['L_SERVERCAPTION']="Aazeig vom Server";
-$lang['L_HELP_SERVERCAPTION']="Bi Nutzig uf verschidene Syschtem, chas hilfriich si, d'Serveradrässe farblich kännzeichnet iizblende";
-$lang['L_ACTIVATE_MULTIDUMP']="Multidump aktivierä";
-$lang['L_SAVE']="Speichere";
-$lang['L_RESET']="zruggsetze";
-$lang['L_PRAEFIX']="Tabälle-Präfix";
-$lang['L_AUTODELETE']="automatisch lösche vo de Backups";
-$lang['L_MAX_BACKUP_FILES_EACH2']="für jedi Datebank";
-$lang['L_SAVING_DB_FORM']="Datebank";
-$lang['L_TESTCONNECTION']="Verbindig teschte";
-$lang['L_BACK_TO_MINISQL']="Datebank bearbeite";
-$lang['L_CREATE']="aalegge";
-$lang['L_VARIABELN']="Variable";
-$lang['L_STATUSINFORMATIONEN']="Statusinformatione";
-$lang['L_VERSIONSINFORMATIONEN']="Versionsinformatione";
-$lang['L_MSD_INFO']="MyOOS [Dumper] Informatione";
-$lang['L_BACKUPFILESANZAHL']="Im Backupverzeichnis häts";
-$lang['L_LASTBACKUP']="sletschti Backup";
-$lang['L_NOTAVAIL']="<em>nöd verfüegbar</em>";
-$lang['L_VOM']="vo";
-$lang['L_MYSQLVARS']="MySQL-Variable";
-$lang['L_MYSQLSYS']="MySQL-Befähl";
-$lang['L_STATUS']="Status";
-$lang['L_PROZESSE']="Prozäss";
-$lang['L_INFO_NOVARS']="kei Variable verfüegbar";
-$lang['L_INHALT']="Inhalt";
-$lang['L_INFO_NOSTATUS']="kei Status verfüegbar";
-$lang['L_INFO_NOPROCESSES']="kei laufendi Prozäss";
-$lang['L_FM_FREESPACE']="Freie Speicher uf em Server";
-$lang['L_LOAD_DATABASE']="Datebank neu lade";
-$lang['L_HOME']="an Aafang";
-$lang['L_CONFIG']="Konfiguration";
-$lang['L_DUMP']="Backup mache";
-$lang['L_RESTORE']="Reschtauriere";
-$lang['L_FILE_MANAGE']="Verwaltig";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Datebank uswähle";
-$lang['L_CREDITS']="Kredits und Hilf";
-$lang['L_MULTI_PART']="Multipart-Backup";
-$lang['L_LOGFILENOTWRITABLE']="s'Logfile cha nöd gschribe wärde";
-$lang['L_SQL_ERROR1']="Fähler bi de Aafrag:";
-$lang['L_SQL_ERROR2']="MySQL mäldet:";
-$lang['L_UNKNOWN']="ubekannt";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="ubekannt";
-$lang['L_OK']="ok";
-$lang['L_CRON_COMPLETELOG']="Kompletti Usgab logge";
-$lang['L_NO']="nei";
-$lang['L_CREATE_DATABASE']="Neui Datebank aalegge";
-$lang['L_EXPORTFINISHED']="Export fertig gmacht";
-$lang['L_SQL_BROWSER']="SQL-Browser";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Standardkodierig vom MySQL-Server";
-$lang['L_TITLE_SHOW_DATA']="Date aazeige";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="Cancel";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Backups";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'jo';
+$lang['L_TO'] = 'bis';
+$lang['L_ACTIVATED'] = 'aktiviärt';
+$lang['L_NOT_ACTIVATED'] = 'nöd aktiviert';
+$lang['L_ERROR'] = 'Fähler';
+$lang['L_OF'] = 'vo';
+$lang['L_ADDED'] = 'dezue gfüegt';
+$lang['L_DB'] = 'Datebank';
+$lang['L_DBS'] = 'Datebanke';
+$lang['L_TABLES'] = 'Tabälle';
+$lang['L_TABLE'] = 'Tabälle';
+$lang['L_RECORDS'] = 'Datesätz';
+$lang['L_COMPRESSED'] = 'komprimiert (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (nöd komprimiert)';
+$lang['L_COMMENT'] = 'Kommentar';
+$lang['L_FILESIZE'] = 'Dateigrössi';
+$lang['L_ALL'] = 'alli';
+$lang['L_NONE'] = 'keini';
+$lang['L_WITH'] = 'mit';
+$lang['L_DIR'] = 'Verzeichnis';
+$lang['L_RECHTE'] = 'Rächt';
+$lang['L_STATUS'] = 'Status';
+$lang['L_FINISHED'] = 'fertig gmacht';
+$lang['L_FILE'] = 'Datei';
+$lang['L_FIELDS'] = 'Fälder';
+$lang['L_NEW'] = 'neu';
+$lang['L_CHARSET'] = 'Zeichesatz';
+$lang['L_COLLATION'] = 'Sortierig';
+$lang['L_CHANGE'] = 'ändere';
+$lang['L_IN'] = 'in';
+$lang['L_DO'] = 'machs!';
+$lang['L_VIEW'] = 'aaluege';
+$lang['L_EXISTING'] = 'häts';
+$lang['L_BACK'] = 'zrugg';
+$lang['L_DB_HOST'] = 'Datebank- Hoschtname';
+$lang['L_DB_USER'] = 'Datebank- Nutzer';
+$lang['L_DB_PASS'] = 'Datebank- Passwort';
+$lang['L_INFO_SCRIPTDIR'] = 'Verzeichnis vom MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Aktuelli Datebank';
+$lang['L_WRONGCONNECTIONPARS'] = 'Falschi oder kei Verbindigsparameter';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Verbindig nöd mögli!';
+$lang['L_SERVERCAPTION'] = 'Aazeig vom Server';
+$lang['L_HELP_SERVERCAPTION'] = "Bi Nutzig uf verschidene Syschtem, chas hilfriich si, d'Serveradrässe farblich kännzeichnet iizblende";
+$lang['L_ACTIVATE_MULTIDUMP'] = 'Multidump aktivierä';
+$lang['L_SAVE'] = 'Speichere';
+$lang['L_RESET'] = 'zruggsetze';
+$lang['L_PRAEFIX'] = 'Tabälle-Präfix';
+$lang['L_AUTODELETE'] = 'automatisch lösche vo de Backups';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'für jedi Datebank';
+$lang['L_SAVING_DB_FORM'] = 'Datebank';
+$lang['L_TESTCONNECTION'] = 'Verbindig teschte';
+$lang['L_BACK_TO_MINISQL'] = 'Datebank bearbeite';
+$lang['L_CREATE'] = 'aalegge';
+$lang['L_VARIABELN'] = 'Variable';
+$lang['L_STATUSINFORMATIONEN'] = 'Statusinformatione';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versionsinformatione';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] Informatione';
+$lang['L_BACKUPFILESANZAHL'] = 'Im Backupverzeichnis häts';
+$lang['L_LASTBACKUP'] = 'sletschti Backup';
+$lang['L_NOTAVAIL'] = '<em>nöd verfüegbar</em>';
+$lang['L_VOM'] = 'vo';
+$lang['L_MYSQLVARS'] = 'MySQL-Variable';
+$lang['L_MYSQLSYS'] = 'MySQL-Befähl';
+$lang['L_STATUS'] = 'Status';
+$lang['L_PROZESSE'] = 'Prozäss';
+$lang['L_INFO_NOVARS'] = 'kei Variable verfüegbar';
+$lang['L_INHALT'] = 'Inhalt';
+$lang['L_INFO_NOSTATUS'] = 'kei Status verfüegbar';
+$lang['L_INFO_NOPROCESSES'] = 'kei laufendi Prozäss';
+$lang['L_FM_FREESPACE'] = 'Freie Speicher uf em Server';
+$lang['L_LOAD_DATABASE'] = 'Datebank neu lade';
+$lang['L_HOME'] = 'an Aafang';
+$lang['L_CONFIG'] = 'Konfiguration';
+$lang['L_DUMP'] = 'Backup mache';
+$lang['L_RESTORE'] = 'Reschtauriere';
+$lang['L_FILE_MANAGE'] = 'Verwaltig';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Datebank uswähle';
+$lang['L_CREDITS'] = 'Kredits und Hilf';
+$lang['L_MULTI_PART'] = 'Multipart-Backup';
+$lang['L_LOGFILENOTWRITABLE'] = "s'Logfile cha nöd gschribe wärde";
+$lang['L_SQL_ERROR1'] = 'Fähler bi de Aafrag:';
+$lang['L_SQL_ERROR2'] = 'MySQL mäldet:';
+$lang['L_UNKNOWN'] = 'ubekannt';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'ubekannt';
+$lang['L_OK'] = 'ok';
+$lang['L_CRON_COMPLETELOG'] = 'Kompletti Usgab logge';
+$lang['L_NO'] = 'nei';
+$lang['L_CREATE_DATABASE'] = 'Neui Datebank aalegge';
+$lang['L_EXPORTFINISHED'] = 'Export fertig gmacht';
+$lang['L_SQL_BROWSER'] = 'SQL-Browser';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Standardkodierig vom MySQL-Server';
+$lang['L_TITLE_SHOW_DATA'] = 'Date aazeige';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'Cancel';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Backups';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/ch/lang_config_overview.php b/msd/language/ch/lang_config_overview.php
index 16a3f943..6ecf14be 100644
--- a/msd/language/ch/lang_config_overview.php
+++ b/msd/language/ch/lang_config_overview.php
@@ -1,109 +1,125 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Konfiguration";
-$lang['L_SAVE_SUCCESS']="D Iischtellige sind erfolgriich i de Konfigurationsdatei \"%s\" gspeicheret worde.";
-$lang['L_CONFIG_LOADED']="D Konfiguration \"%s\" isch erfolgriich glade worde.";
-$lang['L_SAVE_ERROR']="D Iischtellige händ nöd chöne gschpeicheret wärde!";
-$lang['L_CONFIG_EMAIL']="E-Mail-Benachrichtigung";
-$lang['L_CONFIG_AUTODELETE']="automatisches Lösche";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="maximali Dateigrössi";
-$lang['L_HELP_MULTIPART']="Bi iigschaltetem Multipart wärdet mehreri Backup-Dateie gmacht, dere irni Maximalgrössi sich nach de undere Iischtellige richtet.";
-$lang['L_HELP_MULTIPARTGROESSE']="D maximali Grössi vo de einzelne Backup-Dateie chan do bi iigschaltetem Multipart bestimmt wärde.";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Datebank vor Reschtaurierig lösche";
-$lang['L_ALLPARS']="ali Parameter";
-$lang['L_CRON_EXTENDER']="Dateiändig vom Skript";
-$lang['L_CRON_SAVEPATH']="Konfigurationsdatei";
-$lang['L_CRON_PRINTOUT']="Textuusgab";
-$lang['L_CONFIG_CRONPERL']="Crondump-Iischtellige fürs Perlscript";
-$lang['L_CRON_MAILPRG']="Mailprogramm";
-$lang['L_OPTIMIZE']="Tabälle vorem Backup optimiere";
-$lang['L_HELP_OPTIMIZE']="Wänn die Option aktiviert isch, wärdet vor jedem Backup ali Tabälle optimiert.";
-$lang['L_HELP_FTPTIMEOUT']="D Ziit, wo bi keiner Überträgig zum Timeout füert, Default = 90 Sekunde";
-$lang['L_FTP_TIMEOUT']="Verbindigs-Timeout";
-$lang['L_HELP_FTPSSL']="Git a, ob en sicheri SSL-Verbindig für d Überträgig brucht wärde söll.";
-$lang['L_CONFIG_ASKLOAD']="Sölled die Iischtellige würkli mit de Aafangsiischtellige überschribe wärde?";
-$lang['L_LOAD']="Afangsiischtellige lade";
-$lang['L_LOAD_SUCCESS']="D Afangsiischtellige sind glade worde.";
-$lang['L_CRON_CRONDBINDEX']="Datenbank";
-$lang['L_WITHATTACH']="mit Aahang";
-$lang['L_WITHOUTATTACH']="ohni Aahang";
-$lang['L_MULTIDUMPCONF']="=Multidump Iischtellige=";
-$lang['L_MULTIDUMPALL']="=alli Datenbanke=";
-$lang['L_GZIP']="GZip-Kompression";
-$lang['L_SEND_MAIL_FORM']="E-Mail schicke";
-$lang['L_SEND_MAIL_DUMP']="Backup aahänke";
-$lang['L_EMAIL_ADRESS']="Empfänger";
-$lang['L_EMAIL_SENDER']="Absänder vo dr E-Mail";
-$lang['L_EMAIL_MAXSIZE']="maximali Grössi vom Aahang";
-$lang['L_NUMBER_OF_FILES_FORM']="Aazahl vo Backup-Dateie";
-$lang['L_LANGUAGE']="Sprach";
-$lang['L_LIST_DB']="Konfigurierti Datenbanke:";
-$lang['L_CONFIG_FTP']="FTP-Transfer vo de Backup-Datei";
-$lang['L_FTP_TRANSFER']="FTP-Transfer";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="User";
-$lang['L_FTP_PASS']="Passwort";
-$lang['L_FTP_DIR']="Upload-Ordner";
-$lang['L_FTP_SSL']="sicheri SSL-FTP-Verbindig";
-$lang['L_FTP_USESSL']="bruch SSL-Verbindig";
-$lang['L_SQLBOXHEIGHT']="Höchi vo de SQL-Box";
-$lang['L_SQLLIMIT']="Aazahl Datesätz pro Siite";
-$lang['L_BBPARAMS']="Ischtellige für BB-Code";
-$lang['L_BBTEXTCOLOR']="Textfarb";
-$lang['L_HELP_COMMANDS']="Me cha vor und nachem Backup en Befähl usführe laa. Das chan en SQL-Aawisig sii oder en Systembefähl (z. B. es Script)";
-$lang['L_COMMAND']="Befähl";
-$lang['L_WRONG_CONNECTIONPARS']="Verbindigsparameter stimmed nöd!";
-$lang['L_CONNECTIONPARS']="Verbindigsparameter";
-$lang['L_EXTENDEDPARS']="erwiitereti Parameter";
-$lang['L_FADE_IN_OUT']="ii-/usblände";
-$lang['L_DB_BACKUPPARS']="Datenbanke Backup-Iischtellige";
-$lang['L_GENERAL']="generell";
-$lang['L_MAXSIZE']="maximali Grössi";
-$lang['L_ERRORHANDLING_RESTORE']="Fählerbehandlig bi de Reschtaurierig";
-$lang['L_EHRESTORE_CONTINUE']="wiitermache und Fähler protokoliere";
-$lang['L_EHRESTORE_STOP']="aahalte";
-$lang['L_IN_MAINFRAME']="im Hauptframe";
-$lang['L_IN_LEFTFRAME']="im linke Frame";
-$lang['L_WIDTH']="Breiti";
-$lang['L_SQL_BEFEHLE']="SQL-Befähl";
-$lang['L_DOWNLOAD_LANGUAGES']="anderi Sprache abelade";
-$lang['L_DOWNLOAD_STYLES']="anderi Theme abelade";
-$lang['L_CONNECT_TO']="Verbind mit";
-$lang['L_CHANGEDIR']="Wächsle zum Verzeichnis";
-$lang['L_CHANGEDIRERROR']="Es hät nid chöne is Verzeichnis gwächslet werde!";
-$lang['L_FTP_OK']="d Verbindig isch erfolgriich gsi";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="Es stönd kei FTP-Funktione zur Verfüegig!";
-$lang['L_FOUND_DB']="gfundeni DB: ";
-$lang['L_FTP_CHOOSE_MODE']="FTP-Überträgigsmodus";
-$lang['L_FTP_PASSIVE']="passive Überträgigsmodus bruche";
-$lang['L_HELP_FTP_MODE']="Git de FTP-Überträgigsmodus a.Wänn Problem im aktive Modus ufträtet, sötti in passive Modus umgschaltet wärde.";
-$lang['L_DB_IN_LIST']="D Datenbank '%s' hät nöd chöne gmacht werde, wils die scho git.";
-$lang['L_ADD_DB_MANUALLY']="Datebank vo Hand dezue tue";
-$lang['L_DB_MANUAL_ERROR']="D Verbindig zur Datenbank '%s' isch fählgschlage!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Dateifähler: ha d Datenbank '%s' nöd chöne iträge!";
-$lang['L_NO_DB_FOUND']="Es isch kei Datebank gfunde worde. Bländet Si d Verbindigsparameter ii und gänd Si de Name vo de Datebank vo Hand ii!";
-$lang['L_CONFIGFILES']="Konfigurationsdateie";
-$lang['L_CONFIGFILE']="Konfigurationsdatei";
-$lang['L_MYSQL_DATA']="MySQL-Date";
-$lang['L_CONFIGURATIONS']="Ischtellige";
-$lang['L_ACTION']="Aktion";
-$lang['L_FTP_SEND_TO']="an <strong>%s</strong><br>in <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Empfänger";
-$lang['L_NAME']="Name";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Söll d Konfigurationsdatei %s würkli glöscht werde?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Fähler: d Konfigurationsdatei %s hät nöd chöne glöscht wärde!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="D Konfigurationsdatei %s isch erfolgriich glöscht worde.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="D Konfigurationsdatei %s isch erfolgriich aagleit worde.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Im Dateiname \"%s\" häts ungültigi Zeiche.";
-$lang['L_CREATE_CONFIGFILE']="E neui Konfigurationsdatei aalegge";
-$lang['L_ERROR_LOADING_CONFIGFILE']="D Konfigurationsdatei \"%s\" hät nöd chöne glade wärde.";
-$lang['L_BACKUP_DBS_PHP']="DBs zum Sichere (Perl)";
-$lang['L_BACKUP_DBS_PERL']="DBs zum Sichere (Perl)";
-$lang['L_CRON_COMMENT']="Kommentar iigää";
-$lang['L_AUTODETECT']="auto detect";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Konfiguration';
+$lang['L_SAVE_SUCCESS'] = 'D Iischtellige sind erfolgriich i de Konfigurationsdatei "%s" gspeicheret worde.';
+$lang['L_CONFIG_LOADED'] = 'D Konfiguration "%s" isch erfolgriich glade worde.';
+$lang['L_SAVE_ERROR'] = 'D Iischtellige händ nöd chöne gschpeicheret wärde!';
+$lang['L_EMAIL_NOTIFICATION'] = 'E-Mail-Benachrichtigung';
+$lang['L_CONFIG_AUTODELETE'] = 'automatisches Lösche';
+$lang['L_CONFIG_INTERFACE'] = 'Interface';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'maximali Dateigrössi';
+$lang['L_HELP_MULTIPART'] = 'Bi iigschaltetem Multipart wärdet mehreri Backup-Dateie gmacht, dere irni Maximalgrössi sich nach de undere Iischtellige richtet.';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'D maximali Grössi vo de einzelne Backup-Dateie chan do bi iigschaltetem Multipart bestimmt wärde.';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Datebank vor Reschtaurierig lösche';
+$lang['L_ALLPARS'] = 'ali Parameter';
+$lang['L_CRON_EXTENDER'] = 'Dateiändig vom Skript';
+$lang['L_CRON_SAVEPATH'] = 'Konfigurationsdatei';
+$lang['L_CRON_PRINTOUT'] = 'Textuusgab';
+$lang['L_CONFIG_CRONPERL'] = 'Crondump-Iischtellige fürs Perlscript';
+$lang['L_CRON_MAILPRG'] = 'Mailprogramm';
+$lang['L_OPTIMIZE'] = 'Tabälle vorem Backup optimiere';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['L_HELP_OPTIMIZE'] = 'Wänn die Option aktiviert isch, wärdet vor jedem Backup ali Tabälle optimiert.';
+$lang['SFTP'] = 'D Ziit, wo bi keiner Überträgig zum Timeout füert, Default = 90 Sekunde';
+$lang['L_FTP_TIMEOUT'] = 'Verbindigs-Timeout';
+$lang['L_HELP_FTPSSL'] = 'Git a, ob en sicheri SSL-Verbindig für d Überträgig brucht wärde söll.';
+$lang['L_SFTP_TIMEOUT'] = 'Verbindigs-Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Git a, ob en sicheri SSL-Verbindig für d Überträgig brucht wärde söll.';
+$lang['L_CONFIG_ASKLOAD'] = 'Sölled die Iischtellige würkli mit de Aafangsiischtellige überschribe wärde?';
+$lang['L_LOAD'] = 'Afangsiischtellige lade';
+$lang['L_LOAD_SUCCESS'] = 'D Afangsiischtellige sind glade worde.';
+$lang['L_CRON_CRONDBINDEX'] = 'Datenbank';
+$lang['L_WITHATTACH'] = 'mit Aahang';
+$lang['L_WITHOUTATTACH'] = 'ohni Aahang';
+$lang['L_MULTIDUMPCONF'] = '=Multidump Iischtellige=';
+$lang['L_MULTIDUMPALL'] = '=alli Datenbanke=';
+$lang['L_GZIP'] = 'GZip-Kompression';
+$lang['L_SEND_MAIL_FORM'] = 'E-Mail schicke';
+$lang['L_SEND_MAIL_DUMP'] = 'Backup aahänke';
+$lang['L_EMAIL_ADRESS'] = 'Empfänger';
+$lang['L_EMAIL_SENDER'] = 'Absänder vo dr E-Mail';
+$lang['L_EMAIL_MAXSIZE'] = 'maximali Grössi vom Aahang';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Aazahl vo Backup-Dateie';
+$lang['L_LANGUAGE'] = 'Sprach';
+$lang['L_LIST_DB'] = 'Konfigurierti Datenbanke:';
+$lang['L_CONFIG_FTP'] = 'FTP-Transfer vo de Backup-Datei';
+$lang['L_FTP_TRANSFER'] = 'FTP-Transfer';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'User';
+$lang['L_FTP_PASS'] = 'Passwort';
+$lang['L_FTP_DIR'] = 'Upload-Ordner';
+$lang['L_FTP_SSL'] = 'sicheri SSL-FTP-Verbindig';
+$lang['L_FTP_USESSL'] = 'bruch SSL-Verbindig';
+$lang['L_CONFIG_SFTP'] = 'SFTP-Transfer vo de Backup-Datei';
+$lang['L_SFTP_TRANSFER'] = 'SFTP-Transfer';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'User';
+$lang['L_SFTP_PASS'] = 'Passwort';
+$lang['L_SFTP_DIR'] = 'Upload-Ordner';
+$lang['L_SQLBOXHEIGHT'] = 'Höchi vo de SQL-Box';
+$lang['L_SQLLIMIT'] = 'Aazahl Datesätz pro Siite';
+$lang['L_BBPARAMS'] = 'Ischtellige für BB-Code';
+$lang['L_BBTEXTCOLOR'] = 'Textfarb';
+$lang['L_HELP_COMMANDS'] = 'Me cha vor und nachem Backup en Befähl usführe laa. Das chan en SQL-Aawisig sii oder en Systembefähl (z. B. es Script)';
+$lang['L_COMMAND'] = 'Befähl';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Verbindigsparameter stimmed nöd!';
+$lang['L_CONNECTIONPARS'] = 'Verbindigsparameter';
+$lang['L_EXTENDEDPARS'] = 'erwiitereti Parameter';
+$lang['L_FADE_IN_OUT'] = 'ii-/usblände';
+$lang['L_DB_BACKUPPARS'] = 'Datenbanke Backup-Iischtellige';
+$lang['L_GENERAL'] = 'generell';
+$lang['L_MAXSIZE'] = 'maximali Grössi';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Fählerbehandlig bi de Reschtaurierig';
+$lang['L_EHRESTORE_CONTINUE'] = 'wiitermache und Fähler protokoliere';
+$lang['L_EHRESTORE_STOP'] = 'aahalte';
+$lang['L_IN_MAINFRAME'] = 'im Hauptframe';
+$lang['L_IN_LEFTFRAME'] = 'im linke Frame';
+$lang['L_WIDTH'] = 'Breiti';
+$lang['L_SQL_BEFEHLE'] = 'SQL-Befähl';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'anderi Sprache abelade';
+$lang['L_DOWNLOAD_STYLES'] = 'anderi Theme abelade';
+$lang['L_CONNECT_TO'] = 'Verbind mit';
+$lang['L_CHANGEDIR'] = 'Wächsle zum Verzeichnis';
+$lang['L_CHANGEDIRERROR'] = 'Es hät nid chöne is Verzeichnis gwächslet werde!';
+$lang['L_FTP_OK'] = 'd Verbindig isch erfolgriich gsi';
+$lang['L_SFTP_OK'] = 'd Verbindig isch erfolgriich gsi';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = 'Es stönd kei FTP-Funktione zur Verfüegig!';
+$lang['L_FOUND_DB'] = 'gfundeni DB: ';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP-Überträgigsmodus';
+$lang['L_FTP_PASSIVE'] = 'passive Überträgigsmodus bruche';
+$lang['L_HELP_FTP_MODE'] = 'Git de FTP-Überträgigsmodus a.Wänn Problem im aktive Modus ufträtet, sötti in passive Modus umgschaltet wärde.';
+$lang['L_SFTP_PASSIVE'] = 'passive Überträgigsmodus bruche';
+$lang['L_DB_IN_LIST'] = "D Datenbank '%s' hät nöd chöne gmacht werde, wils die scho git.";
+$lang['L_ADD_DB_MANUALLY'] = 'Datebank vo Hand dezue tue';
+$lang['L_DB_MANUAL_ERROR'] = "D Verbindig zur Datenbank '%s' isch fählgschlage!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Dateifähler: ha d Datenbank '%s' nöd chöne iträge!";
+$lang['L_NO_DB_FOUND'] = 'Es isch kei Datebank gfunde worde. Bländet Si d Verbindigsparameter ii und gänd Si de Name vo de Datebank vo Hand ii!';
+$lang['L_CONFIGFILES'] = 'Konfigurationsdateie';
+$lang['L_CONFIGFILE'] = 'Konfigurationsdatei';
+$lang['L_MYSQL_DATA'] = 'MySQL-Date';
+$lang['L_CONFIGURATIONS'] = 'Ischtellige';
+$lang['L_ACTION'] = 'Aktion';
+$lang['L_FTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_SFTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Empfänger';
+$lang['L_NAME'] = 'Name';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Söll d Konfigurationsdatei %s würkli glöscht werde?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Fähler: d Konfigurationsdatei %s hät nöd chöne glöscht wärde!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'D Konfigurationsdatei %s isch erfolgriich glöscht worde.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'D Konfigurationsdatei %s isch erfolgriich aagleit worde.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Im Dateiname "%s" häts ungültigi Zeiche.';
+$lang['L_CREATE_CONFIGFILE'] = 'E neui Konfigurationsdatei aalegge';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'D Konfigurationsdatei "%s" hät nöd chöne glade wärde.';
+$lang['L_BACKUP_DBS_PHP'] = 'DBs zum Sichere (Perl)';
+$lang['L_BACKUP_DBS_PERL'] = 'DBs zum Sichere (Perl)';
+$lang['L_CRON_COMMENT'] = 'Kommentar iigää';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/ch/lang_dump.php b/msd/language/ch/lang_dump.php
index 3f82692d..5d59f423 100644
--- a/msd/language/ch/lang_dump.php
+++ b/msd/language/ch/lang_dump.php
@@ -1,49 +1,50 @@
 <?php
-$lang['L_DUMP_HEADLINE']="bi am backup mache..";
-$lang['L_GZIP_COMPRESSION']="GZip-Kompression";
-$lang['L_SAVING_TABLE']="Spichere Tabälle";
-$lang['L_OF']="vo";
-$lang['L_ACTUAL_TABLE']="Aktuelli Tabälle";
-$lang['L_PROGRESS_TABLE']="Fortschritt Tabälle";
-$lang['L_PROGRESS_OVER_ALL']="Fortschritt gsamt";
-$lang['L_ENTRY']="Itrag";
-$lang['L_DONE']="Alls gmacht!";
-$lang['L_DUMP_SUCCESSFUL']="isch erfolgriich erstellt worde.";
-$lang['L_UPTO']="bis";
-$lang['L_EMAIL_WAS_SEND']="D E-Mail isch erfolriich verschickt worde an";
-$lang['L_BACK_TO_CONTROL']="wiiter";
-$lang['L_BACK_TO_OVERVIEW']="zrugg zur Übersicht";
-$lang['L_DUMP_FILENAME']="Backup-Datei:";
-$lang['L_WITHPRAEFIX']="mit Präfix";
-$lang['L_DUMP_NOTABLES']="Es händ kei Tabällen i de Datenbank `<b>%s</b>` chöne gfunde werde.";
-$lang['L_DUMP_ENDERGEBNIS']="Es sind <b>%s</b> Tabälle mit zäme <b>%s</b> Datesätz gsicheret worde.<br>";
-$lang['L_MAILERROR']="Leider isch bim Verschicke vo de E-Mail en Fähler underloffe!";
-$lang['L_EMAILBODY_ATTACH']="Im Aahang finded Si d Sicherig vo Ihrer MySQL-Datenbank.<br>Sicherig vo de Datenbank `%s` <br><br>Folgende Datei wurde erzeugt:<br><br>%s <br><br>Fründlichi Grüess<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Es isch e Multipart-Sicherig erstellt worde.<br>Die Sicherige werdet nöd als Aahang mitglieferet!<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Dateie sind erzügt worde:<br><br>%s<br><br><br>Fründlichi Grüess<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Es isch e Multipart-Sicherig erstellt worde.<br>D Sicherige werdet i separate E-Mails als Anhang glieferet!<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Dateie sind erzügt worde:<br><br>%s<br><br><br>Fründlichi Grüess<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Fründlichi Grüess<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="D Sicherig überschriitet d Maximalgrössi von %s und isch drum nöd aagehänkt worde.<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Datei isch erzügt worde:<br><br>%s <br><br>Fründlichi Grüess<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="S Backup isch nöd aaghänkt worde.<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Datei isch erzügt worde:<br><br>%s <br><br>Fründlichi Grüess<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']="... nume dr Aahang";
-$lang['L_TABLESELECTION']="Tabälleuswahl";
-$lang['L_SELECTALL']="ali uuswähle";
-$lang['L_DESELECTALL']="Uswahl ufhebä";
-$lang['L_STARTDUMP']="Backup starte";
-$lang['L_LASTBUFROM']="sletschti Update vom";
-$lang['L_NOT_SUPPORTED']="Das Backup cha diä Funktion nöd.";
-$lang['L_MULTIDUMP']="Multidump: Es sind <b>%d</b> Datenbanke gesicheret worde.";
-$lang['L_FILESENDFTP']="verschicke grad File via FTP... heb bitte e chli Geduld.";
-$lang['L_FTPCONNERROR']="FTP-Verbindig nöd hergstellt! Verbindig mit";
-$lang['L_FTPCONNERROR1']="als User";
-$lang['L_FTPCONNERROR2']="nöd mögli";
-$lang['L_FTPCONNERROR3']="FTP-Upload isch fählerhaft gsi!";
-$lang['L_FTPCONNECTED1']="Verbunde mit";
-$lang['L_FTPCONNECTED2']="uf";
-$lang['L_FTPCONNECTED3']="gschribe";
-$lang['L_NR_TABLES_SELECTED']="- mit %s gewählte Tabälle";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s Tabälle sind optimiert worde.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s Fähler ufträte: <a href=\"log.php?r=3\">aaluege</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Fatale Fähler: d CREATE-Aawiisig vo de Tabelle '%s' i de Datenbank '%s' hät nöd chöne gläse werde!";
 
-
-?>
\ No newline at end of file
+$lang['L_DUMP_HEADLINE'] = 'bi am backup mache..';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip-Kompression';
+$lang['L_SAVING_TABLE'] = 'Spichere Tabälle';
+$lang['L_OF'] = 'vo';
+$lang['L_ACTUAL_TABLE'] = 'Aktuelli Tabälle';
+$lang['L_PROGRESS_TABLE'] = 'Fortschritt Tabälle';
+$lang['L_PROGRESS_OVER_ALL'] = 'Fortschritt gsamt';
+$lang['L_ENTRY'] = 'Itrag';
+$lang['L_DONE'] = 'Alls gmacht!';
+$lang['L_DUMP_SUCCESSFUL'] = 'isch erfolgriich erstellt worde.';
+$lang['L_UPTO'] = 'bis';
+$lang['L_EMAIL_WAS_SEND'] = 'D E-Mail isch erfolriich verschickt worde an';
+$lang['L_BACK_TO_CONTROL'] = 'wiiter';
+$lang['L_BACK_TO_OVERVIEW'] = 'zrugg zur Übersicht';
+$lang['L_DUMP_FILENAME'] = 'Backup-Datei:';
+$lang['L_WITHPRAEFIX'] = 'mit Präfix';
+$lang['L_DUMP_NOTABLES'] = 'Es händ kei Tabällen i de Datenbank `<b>%s</b>` chöne gfunde werde.';
+$lang['L_DUMP_ENDERGEBNIS'] = 'Es sind <b>%s</b> Tabälle mit zäme <b>%s</b> Datesätz gsicheret worde.<br>';
+$lang['L_MAILERROR'] = 'Leider isch bim Verschicke vo de E-Mail en Fähler underloffe!';
+$lang['L_EMAILBODY_ATTACH'] = 'Im Aahang finded Si d Sicherig vo Ihrer MySQL-Datenbank.<br>Sicherig vo de Datenbank `%s` <br><br>Folgende Datei wurde erzeugt:<br><br>%s <br><br>Fründlichi Grüess<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Es isch e Multipart-Sicherig erstellt worde.<br>Die Sicherige werdet nöd als Aahang mitglieferet!<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Dateie sind erzügt worde:<br><br>%s<br><br><br>Fründlichi Grüess<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Es isch e Multipart-Sicherig erstellt worde.<br>D Sicherige werdet i separate E-Mails als Anhang glieferet!<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Dateie sind erzügt worde:<br><br>%s<br><br><br>Fründlichi Grüess<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Fründlichi Grüess<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'D Sicherig überschriitet d Maximalgrössi von %s und isch drum nöd aagehänkt worde.<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Datei isch erzügt worde:<br><br>%s <br><br>Fründlichi Grüess<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'S Backup isch nöd aaghänkt worde.<br>Sicherig vo de Datenbank `%s` <br><br>Folgendi Datei isch erzügt worde:<br><br>%s <br><br>Fründlichi Grüess<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = '... nume dr Aahang';
+$lang['L_TABLESELECTION'] = 'Tabälleuswahl';
+$lang['L_SELECTALL'] = 'ali uuswähle';
+$lang['L_DESELECTALL'] = 'Uswahl ufhebä';
+$lang['L_STARTDUMP'] = 'Backup starte';
+$lang['L_LASTBUFROM'] = 'sletschti Update vom';
+$lang['L_NOT_SUPPORTED'] = 'Das Backup cha diä Funktion nöd.';
+$lang['L_MULTIDUMP'] = 'Multidump: Es sind <b>%d</b> Datenbanke gesicheret worde.';
+$lang['L_FILESENDFTP'] = 'verschicke grad File via FTP... heb bitte e chli Geduld.';
+$lang['L_FTPCONNERROR'] = 'FTP-Verbindig nöd hergstellt! Verbindig mit';
+$lang['L_FTPCONNERROR1'] = 'als User';
+$lang['L_FTPCONNERROR2'] = 'nöd mögli';
+$lang['L_FTPCONNERROR3'] = 'FTP-Upload isch fählerhaft gsi!';
+$lang['L_FTPCONNECTED1'] = 'Verbunde mit';
+$lang['L_FTPCONNECTED2'] = 'uf';
+$lang['L_FTPCONNECTED3'] = 'gschribe';
+$lang['L_FILESENDSFTP'] = 'verschicke grad File via SFTP... heb bitte e chli Geduld.';
+$lang['L_SFTPCONNERROR'] = 'SFTP-Verbindig nöd hergstellt! Verbindig mit';
+$lang['L_NR_TABLES_SELECTED'] = '- mit %s gewählte Tabälle';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s Tabälle sind optimiert worde.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s Fähler ufträte: <a href="log.php?r=3">aaluege</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Fatale Fähler: d CREATE-Aawiisig vo de Tabelle '%s' i de Datenbank '%s' hät nöd chöne gläse werde!";
diff --git a/msd/language/ch/lang_filemanagement.php b/msd/language/ch/lang_filemanagement.php
index ca83c74e..e75af21c 100644
--- a/msd/language/ch/lang_filemanagement.php
+++ b/msd/language/ch/lang_filemanagement.php
@@ -1,75 +1,75 @@
 <?php
-$lang['L_CONVERT_START']="Konvertierig starte";
-$lang['L_CONVERT_TITLE']="Konvertiere Dump is MSD-Format";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Falschi Parameter! Konvertierig isch nöd mögli.";
-$lang['L_FM_UPLOADFILEREQUEST']="Gänd Si bitte e Datei a.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Dä Dateityp isch nöd erlaubt.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Gültigi Type sind: *.gz und *.sql-Dateie";
-$lang['L_FM_UPLOADMOVEERROR']="Dia ufeglade Datei hät nöd chöne in richtige Order verschobe wärde.";
-$lang['L_FM_UPLOADFAILED']="Dr Upload isch leider fählgschlage!";
-$lang['L_FM_UPLOADFILEEXISTS']="Es git scho e Datei mit däm Name!";
-$lang['L_FM_NOFILE']="Si händ gar kei Datei usgwählt!";
-$lang['L_FM_DELETE1']="Diä Datei";
-$lang['L_FM_DELETE2']=" isch erfolgriich glöscht worde.";
-$lang['L_FM_DELETE3']="hät nöd chöne glöscht wärde!";
-$lang['L_FM_CHOOSE_FILE']="gwählti Datei:";
-$lang['L_FM_FILESIZE']="Dateigrössi";
-$lang['L_FM_FILEDATE']="Datum";
-$lang['L_FM_NOFILESFOUND']="Kei Datei gfunde.";
-$lang['L_FM_TABLES']="Tabälle";
-$lang['L_FM_RECORDS']="Iiträg";
-$lang['L_FM_ALL_BU']="alli Backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="sletschte Backup";
-$lang['L_FM_TOTALSIZE']="Gsamtgrössi";
-$lang['L_FM_SELECTTABLES']="Uswahl vo bestimmte Tabälle";
-$lang['L_FM_COMMENT']="Kommentar iigäh";
-$lang['L_FM_RESTORE']="Reschtauriere";
-$lang['L_FM_ALERTRESTORE1']="Söll diä Datenbank";
-$lang['L_FM_ALERTRESTORE2']="mit de Inhält vo dere Datei";
-$lang['L_FM_ALERTRESTORE3']="reschtauriert wärde?";
-$lang['L_FM_DELETE']="usgwählti Dateie lösche";
-$lang['L_FM_ASKDELETE1']="Wänd Si diä Datei";
-$lang['L_FM_ASKDELETE2']="würkli lösche?";
-$lang['L_FM_ASKDELETE3']="Wänd Sie Autodelete nach de iigschtellte Regle jetzt usfüere?";
-$lang['L_FM_ASKDELETE4']="Wänd Si alli Backup-Dateie jetzt lösche?";
-$lang['L_FM_ASKDELETE5']="Wänd Si alli Backup-Dateie mit";
-$lang['L_FM_ASKDELETE5_2']="_* jetzt lösche?";
-$lang['L_FM_DELETEAUTO']="Autodelete vo Hand ausfüere";
-$lang['L_FM_DELETEALL']="alli Backup-Dateie lösche";
-$lang['L_FM_DELETEALLFILTER']="alli lösche mit";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Neus Backup starte";
-$lang['L_FM_FILEUPLOAD']="Datei ufelade";
-$lang['L_FM_DBNAME']="Datebankname";
-$lang['L_FM_FILES1']="Datebank-Backups";
-$lang['L_FM_FILES2']="Datebank-Strukture";
-$lang['L_FM_AUTODEL1']="Autodelete: Folgendi Dateie sind ufgrund vo de maximale Dateiaazahl gelöscht worde:";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="Iischtellige fürs Backup";
-$lang['L_FM_OLDBACKUP']="(unbekannt)";
-$lang['L_FM_RESTORE_HEADER']="Reschtaurierig vo de Datebank \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Perl-Cronscript usfüere";
-$lang['L_DOPERLTEST']="Perl-Module teschte";
-$lang['L_DOSIMPLETEST']="Perl teschte";
-$lang['L_PERLOUTPUT1']="Iitrag in crondump.pl für absolute_path_of_con";
-$lang['L_PERLOUTPUT2']="Ufruef im Browser oder für externe Cronjob";
-$lang['L_PERLOUTPUT3']="Ufruef i de Shell oder für d Crontab";
-$lang['L_RESTORE_OF_TABLES']="Reschtauriere vo bestimmte Tabälle";
-$lang['L_CONVERTER']="Backup-Konverter";
-$lang['L_CONVERT_FILE']="z konvertierendi Datei";
-$lang['L_CONVERT_FILENAME']="Name vo de Zieldatei (ohni Endig)";
-$lang['L_CONVERTING']="Konvertierig";
-$lang['L_CONVERT_FILEREAD']="Datei '%s' wird eingläse";
-$lang['L_CONVERT_FINISHED']="Konvertierig abgschlosse, '%s' isch erzügt worde.";
-$lang['L_NO_MSD_BACKUPFILE']="Dateie vo andere Programm";
-$lang['L_MAX_UPLOAD_SIZE']="Maximali Dateigrössi";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Wänn Ihri Backup-Datei grösser als das agebne Limit isch, müend Si diä per FTP in \"work/backup\"-Ordner ufelade. Dänn wird diä Datei, do i de Verwaltig aazeigt und laht sich dänn für en Reschtaurierig uswähle.";
-$lang['L_ENCODING']="Kodierig";
-$lang['L_FM_CHOOSE_ENCODING']="Kodierig vo de Backupdatei wähle";
-$lang['L_CHOOSE_CHARSET']="Leider hät nöd chöne automatich ermittlet mit welem Zeichesatz diä Backupdatei sinerziit aagleit worde isch.<br> Sie müend diä Kodierig, i dere Zeichechette i dere Datei sind, vo Hand aagäh.<br>Dänn stellt MySQLDumper diä Verbindigskännig zum MySQL-Server uf de usgwählti Zeichesatz und fangt mit de Reschtaurierig vo de Date a.>br>Sötted Si nach de Reschtaurierig Problem mit Sonderzeiche ha, chönd Si probiere, das Backup mit ere andere Zeichesatzuswahl z reschtauriere.<br> Vill Glück. ;)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+
+$lang['L_CONVERT_START'] = 'Konvertierig starte';
+$lang['L_CONVERT_TITLE'] = 'Konvertiere Dump is MOD-Format';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Falschi Parameter! Konvertierig isch nöd mögli.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Gänd Si bitte e Datei a.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Dä Dateityp isch nöd erlaubt.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Gültigi Type sind: *.gz und *.sql-Dateie';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Dia ufeglade Datei hät nöd chöne in richtige Order verschobe wärde.';
+$lang['L_FM_UPLOADFAILED'] = 'Dr Upload isch leider fählgschlage!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Es git scho e Datei mit däm Name!';
+$lang['L_FM_NOFILE'] = 'Si händ gar kei Datei usgwählt!';
+$lang['L_FM_DELETE1'] = 'Diä Datei';
+$lang['L_FM_DELETE2'] = ' isch erfolgriich glöscht worde.';
+$lang['L_FM_DELETE3'] = 'hät nöd chöne glöscht wärde!';
+$lang['L_FM_CHOOSE_FILE'] = 'gwählti Datei:';
+$lang['L_FM_FILESIZE'] = 'Dateigrössi';
+$lang['L_FM_FILEDATE'] = 'Datum';
+$lang['L_FM_NOFILESFOUND'] = 'Kei Datei gfunde.';
+$lang['L_FM_TABLES'] = 'Tabälle';
+$lang['L_FM_RECORDS'] = 'Iiträg';
+$lang['L_FM_ALL_BU'] = 'alli Backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'sletschte Backup';
+$lang['L_FM_TOTALSIZE'] = 'Gsamtgrössi';
+$lang['L_FM_SELECTTABLES'] = 'Uswahl vo bestimmte Tabälle';
+$lang['L_FM_COMMENT'] = 'Kommentar iigäh';
+$lang['L_FM_RESTORE'] = 'Reschtauriere';
+$lang['L_FM_ALERTRESTORE1'] = 'Söll diä Datenbank';
+$lang['L_FM_ALERTRESTORE2'] = 'mit de Inhält vo dere Datei';
+$lang['L_FM_ALERTRESTORE3'] = 'reschtauriert wärde?';
+$lang['L_FM_DELETE'] = 'usgwählti Dateie lösche';
+$lang['L_FM_ASKDELETE1'] = 'Wänd Si diä Datei';
+$lang['L_FM_ASKDELETE2'] = 'würkli lösche?';
+$lang['L_FM_ASKDELETE3'] = 'Wänd Sie Autodelete nach de iigschtellte Regle jetzt usfüere?';
+$lang['L_FM_ASKDELETE4'] = 'Wänd Si alli Backup-Dateie jetzt lösche?';
+$lang['L_FM_ASKDELETE5'] = 'Wänd Si alli Backup-Dateie mit';
+$lang['L_FM_ASKDELETE5_2'] = '_* jetzt lösche?';
+$lang['L_FM_DELETEAUTO'] = 'Autodelete vo Hand ausfüere';
+$lang['L_FM_DELETEALL'] = 'alli Backup-Dateie lösche';
+$lang['L_FM_DELETEALLFILTER'] = 'alli lösche mit';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Neus Backup starte';
+$lang['L_FM_FILEUPLOAD'] = 'Datei ufelade';
+$lang['L_FM_DBNAME'] = 'Datebankname';
+$lang['L_FM_FILES1'] = 'Datebank-Backups';
+$lang['L_FM_FILES2'] = 'Datebank-Strukture';
+$lang['L_FM_AUTODEL1'] = 'Autodelete: Folgendi Dateie sind ufgrund vo de maximale Dateiaazahl gelöscht worde:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'Iischtellige fürs Backup';
+$lang['L_FM_OLDBACKUP'] = '(unbekannt)';
+$lang['L_FM_RESTORE_HEADER'] = 'Reschtaurierig vo de Datebank "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Perl-Cronscript usfüere';
+$lang['L_DOPERLTEST'] = 'Perl-Module teschte';
+$lang['L_DOSIMPLETEST'] = 'Perl teschte';
+$lang['L_PERLOUTPUT1'] = 'Iitrag in crondump.pl für absolute_path_of_con';
+$lang['L_PERLOUTPUT2'] = 'Ufruef im Browser oder für externe Cronjob';
+$lang['L_PERLOUTPUT3'] = 'Ufruef i de Shell oder für d Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Reschtauriere vo bestimmte Tabälle';
+$lang['L_CONVERTER'] = 'Backup-Konverter';
+$lang['L_CONVERT_FILE'] = 'z konvertierendi Datei';
+$lang['L_CONVERT_FILENAME'] = 'Name vo de Zieldatei (ohni Endig)';
+$lang['L_CONVERTING'] = 'Konvertierig';
+$lang['L_CONVERT_FILEREAD'] = "Datei '%s' wird eingläse";
+$lang['L_CONVERT_FINISHED'] = "Konvertierig abgschlosse, '%s' isch erzügt worde.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Dateie vo andere Programm';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximali Dateigrössi';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Wänn Ihri Backup-Datei grösser als das agebne Limit isch, müend Si diä per FTP in "work/backup"-Ordner ufelade. Dänn wird diä Datei, do i de Verwaltig aazeigt und laht sich dänn für en Reschtaurierig uswähle.';
+$lang['L_ENCODING'] = 'Kodierig';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Kodierig vo de Backupdatei wähle';
+$lang['L_CHOOSE_CHARSET'] = 'Leider hät nöd chöne automatich ermittlet mit welem Zeichesatz diä Backupdatei sinerziit aagleit worde isch.<br> Sie müend diä Kodierig, i dere Zeichechette i dere Datei sind, vo Hand aagäh.<br>Dänn stellt MyOOS [Dumper] diä Verbindigskännig zum MySQL-Server uf de usgwählti Zeichesatz und fangt mit de Reschtaurierig vo de Date a.>br>Sötted Si nach de Reschtaurierig Problem mit Sonderzeiche ha, chönd Si probiere, das Backup mit ere andere Zeichesatzuswahl z reschtauriere.<br> Vill Glück. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/ch/lang_help.php b/msd/language/ch/lang_help.php
index 7ecde9f7..c084c72b 100644
--- a/msd/language/ch/lang_help.php
+++ b/msd/language/ch/lang_help.php
@@ -1,30 +1,34 @@
 <?php
-$lang['L_HELP_DB']="Das isch d Lischte vo de vorhandene Datebanke.";
-$lang['L_HELP_PRAEFIX']="Dr Präfix isch e Zeichefolg für d Aafang vo Tabälle, wo als Filter fungiert.";
-$lang['L_HELP_ZIP']="Kompression mit GZip - emfohle isch 'aktiviert'.";
-$lang['L_HELP_MEMORYLIMIT']="Das isch di maximali Grössi i Bytes, wo das Skript a Speicher überchunnt. 0 = deaktiviert";
-$lang['L_MEMORY_LIMIT']="Spiichergränze";
-$lang['L_HELP_AD1']="Wänn aktiviert, dänn werdet automatisch Backup-Dateie glöscht.";
-$lang['L_HELP_AD3']="Di maximali Aazahl vo Dateie, wo im Backup-Verzeichnis sii dörfed (für Autodelete). 0 = deaktiviert";
-$lang['L_HELP_LANG']="Stellt uf di gwünschti Sprach.";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Zum überflüssigi Date eliminiere, cha me anwiise, d Datebank vor de Reschtaurierig komplett z lääre.";
-$lang['L_HELP_CRONEXTENDER']="D Endig vom Perlscript, Standard isch '.pl'.";
-$lang['L_HELP_CRONSAVEPATH']="De Name vo de Konfigurationsdatei fürs Perlskript.";
-$lang['L_HELP_CRONPRINTOUT']="Wänn d Textuusgab abgschaltet isch, wird kei Text meh ausgeh. Diä Funktion isch unabhängig vo de Log-Uusgab.";
-$lang['L_HELP_CRONSAMEDB']="Söll di gliichi Datebank für de Cronjob wiä i de Iischtellige brucht wärde?";
-$lang['L_HELP_CRONDBINDEX']="Wähl d Datebank für de Cronjob";
-$lang['L_HELP_FTPTRANSFER']="Wänn aktiviert, wird nachem Backup diä Datei per FTP gschickt.";
-$lang['L_HELP_FTPSERVER']="D Adrässe vom FTP-Server.";
-$lang['L_HELP_FTPPORT']="Port vom FTP-Server. Standard: 21";
-$lang['L_HELP_FTPUSER']="Gib de Benutzername vo de FTP-Verbindig a.";
-$lang['L_HELP_FTPPASS']="Gibs s Passwort vo de FTP-Verbindig a.";
-$lang['L_HELP_FTPDIR']="Wohäre söll diä Datei gschickt wärde?";
-$lang['L_HELP_SPEED']="Minimali und maximali Gschwindigkeit. Standard isch 50 bis 5000. (Z höchi Gschwindigkeite chönned zu Timeouts führe!)";
-$lang['L_SPEED']="Gschwindigkeitskontrolle";
-$lang['L_HELP_CRONEXECPATH']="Dr Ort, wo die Perlskripts ligged. Usgangspunkt isch d HTTP-Adresse (also im Browser). Erlaubt sind absoluti und relativi Pfadaagabe.";
-$lang['L_CRON_EXECPATH']="Pfad vo de Perlskripts";
-$lang['L_HELP_CRONCOMPLETELOG']="Wänn diä Funktion aktiviert isch, wird di kompletti Usgab im complete_log gschribe. Diä Funtion isch unabhängig vo de Textusgab.";
-$lang['L_HELP_FTP_MODE']="Wänn Problem bi de FTP-Überträgig uftauched, versueched Si de passivi FTP-Modus";
 
-
-?>
\ No newline at end of file
+$lang['L_HELP_DB'] = 'Das isch d Lischte vo de vorhandene Datebanke.';
+$lang['L_HELP_PRAEFIX'] = 'Dr Präfix isch e Zeichefolg für d Aafang vo Tabälle, wo als Filter fungiert.';
+$lang['L_HELP_ZIP'] = "Kompression mit GZip - emfohle isch 'aktiviert'.";
+$lang['L_HELP_MEMORYLIMIT'] = 'Das isch di maximali Grössi i Bytes, wo das Skript a Speicher überchunnt. 0 = deaktiviert';
+$lang['L_MEMORY_LIMIT'] = 'Spiichergränze';
+$lang['L_HELP_AD1'] = 'Wänn aktiviert, dänn werdet automatisch Backup-Dateie glöscht.';
+$lang['L_HELP_AD3'] = 'Di maximali Aazahl vo Dateie, wo im Backup-Verzeichnis sii dörfed (für Autodelete). 0 = deaktiviert';
+$lang['L_HELP_LANG'] = 'Stellt uf di gwünschti Sprach.';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Zum überflüssigi Date eliminiere, cha me anwiise, d Datebank vor de Reschtaurierig komplett z lääre.';
+$lang['L_HELP_CRONEXTENDER'] = "D Endig vom Perlscript, Standard isch '.pl'.";
+$lang['L_HELP_CRONSAVEPATH'] = 'De Name vo de Konfigurationsdatei fürs Perlskript.';
+$lang['L_HELP_CRONPRINTOUT'] = 'Wänn d Textuusgab abgschaltet isch, wird kei Text meh ausgeh. Diä Funktion isch unabhängig vo de Log-Uusgab.';
+$lang['L_HELP_CRONSAMEDB'] = 'Söll di gliichi Datebank für de Cronjob wiä i de Iischtellige brucht wärde?';
+$lang['L_HELP_CRONDBINDEX'] = 'Wähl d Datebank für de Cronjob';
+$lang['L_HELP_FTPTRANSFER'] = 'Wänn aktiviert, wird nachem Backup diä Datei per FTP gschickt.';
+$lang['L_HELP_FTPSERVER'] = 'D Adrässe vom FTP-Server.';
+$lang['L_HELP_FTPPORT'] = 'Port vom FTP-Server. Standard: 21';
+$lang['L_HELP_FTPUSER'] = 'Gib de Benutzername vo de FTP-Verbindig a.';
+$lang['L_HELP_FTPPASS'] = 'Gibs s Passwort vo de FTP-Verbindig a.';
+$lang['L_HELP_FTPDIR'] = 'Wohäre söll diä Datei gschickt wärde?';
+$lang['L_HELP_SFTPTRANSFER'] = 'Wänn aktiviert, wird nachem Backup diä Datei per SFTP gschickt.';
+$lang['L_HELP_SFTPSERVER'] = 'D Adrässe vom SFTP-Server.';
+$lang['L_HELP_SFTPPORT'] = 'Port vom SFTP-Server. Standard: 22';
+$lang['L_HELP_SFTPUSER'] = 'Gib de Benutzername vo de SFTP-Verbindig a.';
+$lang['L_HELP_SFTPPASS'] = 'Gibs s Passwort vo de SFTP-Verbindig a.';
+$lang['L_HELP_SFTPDIR'] = 'Wohäre söll diä Datei gschickt wärde?';
+$lang['L_HELP_SPEED'] = 'Minimali und maximali Gschwindigkeit. Standard isch 50 bis 5000. (Z höchi Gschwindigkeite chönned zu Timeouts führe!)';
+$lang['L_SPEED'] = 'Gschwindigkeitskontrolle';
+$lang['L_HELP_CRONEXECPATH'] = 'Dr Ort, wo die Perlskripts ligged. Usgangspunkt isch d HTTP-Adresse (also im Browser). Erlaubt sind absoluti und relativi Pfadaagabe.';
+$lang['L_CRON_EXECPATH'] = 'Pfad vo de Perlskripts';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Wänn diä Funktion aktiviert isch, wird di kompletti Usgab im complete_log gschribe. Diä Funtion isch unabhängig vo de Textusgab.';
+$lang['L_HELP_FTP_MODE'] = 'Wänn Problem bi de FTP-Überträgig uftauched, versueched Si de passivi FTP-Modus';
diff --git a/msd/language/ch/lang_install.php b/msd/language/ch/lang_install.php
index 9fb19001..69802df7 100644
--- a/msd/language/ch/lang_install.php
+++ b/msd/language/ch/lang_install.php
@@ -1,83 +1,80 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>d Installation isch abgschlosse --> <a href=\"index.php\">starte MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="zum Hauptmenü";
-$lang['L_INSTALLMENU']="Hauptmenü";
-$lang['L_STEP']="Schritt";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Uninstall";
-$lang['L_TOOLS']="Tools";
-$lang['L_EDITCONF']="Konfiguration bearbeite";
-$lang['L_OSWEITER']="ohni Spiichere wiiter";
-$lang['L_ERRORMAN']="<strong>Fähler bim Schriibe vo de Konfiguration!</strong><br>Bitte editiered Si diä Datei";
-$lang['L_MANUELL']="vo Hand";
-$lang['L_CREATEDIRS']="mache Verzeichnis";
-$lang['L_INSTALL_CONTINUE']="mit de Installation wiitermache";
-$lang['L_CONNECTTOMYSQL']="zu MySQL verbinde";
-$lang['L_DBPARAMETER']="Datebank-Parameter";
-$lang['L_CONFIGNOTWRITABLE']="Diä Datei \"config.php\" ist nöd beschriibbar. Gänd Si ire miteme FTP-Programm entsprächende Rächt, z. B. de CHMod-Wert 0777.";
-$lang['L_DBCONNECTION']="Datebank-Verbindig";
-$lang['L_CONNECTIONERROR']="Fähler: Es hät kei Verbindig chöne gmacht wärde.";
-$lang['L_CONNECTION_OK']="Datebankverbindig isch gmacht worde.";
-$lang['L_SAVEANDCONTINUE']="spiichere und wiitermache mit de Installation";
-$lang['L_CONFBASIC']="Grundiischtellige";
-$lang['L_INSTALL_STEP2FINISHED']="D Iischtellige sind erfolgriich gsicheret worde";
-$lang['L_INSTALL_STEP2_1']="Installation mit de Standardkonfiguration wiitermache";
-$lang['L_LASTSTEP']="Abschluss vo de Installation";
-$lang['L_FTPMODE']="Verzeichniss per FTP erzüge (safe_mode)";
-$lang['L_IDOMANUAL']="Ich mache diä Verzeichniss vo Hand";
-$lang['L_DOFROM']="usgehend vo";
-$lang['L_FTPMODE2']="Mache diä Verzeichniss per FTP:";
-$lang['L_CONNECT']="verbinde";
-$lang['L_DIRS_CREATED']="D Verzeichniss sind ordnigsgmäss gmacht worde.";
-$lang['L_CONNECT_TO']="verbinde zu";
-$lang['L_CHANGEDIR']="Wächsel is Verzeichnis";
-$lang['L_CHANGEDIRERROR']="Wächsel is Verzeichnis nöd mögli";
-$lang['L_FTP_OK']="FTP-Parameter sind ok";
-$lang['L_CREATEDIRS2']="Verzeichnis mache";
-$lang['L_FTP_NOTCONNECTED']="FTP-Verbindig nöd gmacht!";
-$lang['L_CONNWITH']="Verbindig mit";
-$lang['L_ASUSER']="als User";
-$lang['L_NOTPOSSIBLE']="nöd mögli";
-$lang['L_DIRCR1']="mache es Arbetsverzeichnis";
-$lang['L_DIRCR2']="mache es Backup-Verzeichnis";
-$lang['L_DIRCR4']="mache es Log-Verzeichnis";
-$lang['L_DIRCR5']="mache es Konfigurationsverzeichnis";
-$lang['L_INDIR']="bi im Verzeichnis";
-$lang['L_CHECK_DIRS']="überprüefe";
-$lang['L_DISABLEDFUNCTIONS']="Abgschalteti Funktionen";
-$lang['L_NOFTPPOSSIBLE']="Es hät kei FTP-Funktionen zur Verfüegig!";
-$lang['L_NOGZPOSSIBLE']="Es hät kei Kompressions-Funktione zur Verfüegig!";
-$lang['L_UI1']="Es werded alli Arbetsverzeichnis mit allne Backups wo drin sind glöscht.";
-$lang['L_UI2']="Sind Si sicher, dass Si das wänd?";
-$lang['L_UI3']="Nei, sofort abbräche";
-$lang['L_UI4']="jo, bitte wiitermache";
-$lang['L_UI5']="lösche Arbetsverzeichnis";
-$lang['L_UI6']="alls isch erfolgriich glöscht worde";
-$lang['L_UI7']="Lösched Si bitte das Skriptverzeichnis";
-$lang['L_UI8']="en Ebeni nach obe";
-$lang['L_UI9']="Es hät en Fähler gäh, Lösche isch nöd mögli gsi<p>Fähler bi Verzeichnis";
-$lang['L_IMPORT']="Konfiguration importiere";
-$lang['L_IMPORT3']="D Konfiguration isch glade...";
-$lang['L_IMPORT4']="D Konfiguration isch gsicheret.";
-$lang['L_IMPORT5']="MySQLDumper starte";
-$lang['L_IMPORT6']="Installations-Menü";
-$lang['L_IMPORT7']="Konfiguration ufelade";
-$lang['L_IMPORT8']="zrugg zum Upload";
-$lang['L_IMPORT9']="Das isch kei Konfigurationssicherig!";
-$lang['L_IMPORT10']="D Konfiguration isch erfolgriich ufeglade worde.";
-$lang['L_IMPORT11']="<strong>Fähler: </strong>Es hät Problem gäh bim Schriibe vo de  sql_statements.";
-$lang['L_IMPORT12']="<strong>Fähler: </strong>Es hät Problem gäh bim Schriibe vo de config.php.";
-$lang['L_INSTALL_HELP_PORT']="(läär = Standardport)";
-$lang['L_INSTALL_HELP_SOCKET']="(läär = Standardsocket)";
-$lang['L_TRYAGAIN']="namal versueche";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="gfundeni DB:";
-$lang['L_FM_FILEUPLOAD']="Datei ufelade";
-$lang['L_PASS']="Passwort";
-$lang['L_NO_DB_FOUND_INFO']="D Verbindig zur Datebank isch erfolgriich gsi.<br>Ihri Zuegangsdate sind gültig und sind vom MySQL-Server akzeptiert worde.<br>Leider hät de MySQLDumper kei Datebank gfunde.<br>Di automatischi Erkännig isch bi mänge Hoschter gschpeert.<br>Si müend Ihri Datebank nachem Abschluss vo de Installation under em Menüpunkt \"Konfiguration\" \"Verbindigsparameter iiblände\" agäh.<br>Gönd Si bitte sofort nach em Abschluss vo de Installation det hii und träged Si de Name vo Irer Datebank det ii.";
-$lang['L_SAFEMODEDESC']="Will PHP uf däm Server mit de Option \"safe_mode=on\" usgfuert wird, müend folgendi Verzeichnis vo Hand aagleit wärde (Si chönd das mit Irem FTP-Programm erlegige):";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
 
-
-?>
\ No newline at end of file
+$lang['L_INSTALLFINISHED'] = '<br>d Installation isch abgschlosse --> <a href="index.php">starte MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'zum Hauptmenü';
+$lang['L_INSTALLMENU'] = 'Hauptmenü';
+$lang['L_STEP'] = 'Schritt';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Uninstall';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_EDITCONF'] = 'Konfiguration bearbeite';
+$lang['L_OSWEITER'] = 'ohni Spiichere wiiter';
+$lang['L_ERRORMAN'] = '<strong>Fähler bim Schriibe vo de Konfiguration!</strong><br>Bitte editiered Si diä Datei';
+$lang['L_MANUELL'] = 'vo Hand';
+$lang['L_CREATEDIRS'] = 'mache Verzeichnis';
+$lang['L_INSTALL_CONTINUE'] = 'mit de Installation wiitermache';
+$lang['L_CONNECTTOMYSQL'] = 'zu MySQL verbinde';
+$lang['L_DBPARAMETER'] = 'Datebank-Parameter';
+$lang['L_CONFIGNOTWRITABLE'] = 'Diä Datei "config.php" ist nöd beschriibbar. Gänd Si ire miteme FTP-Programm entsprächende Rächt, z. B. de CHMod-Wert 0777.';
+$lang['L_DBCONNECTION'] = 'Datebank-Verbindig';
+$lang['L_CONNECTIONERROR'] = 'Fähler: Es hät kei Verbindig chöne gmacht wärde.';
+$lang['L_CONNECTION_OK'] = 'Datebankverbindig isch gmacht worde.';
+$lang['L_SAVEANDCONTINUE'] = 'spiichere und wiitermache mit de Installation';
+$lang['L_CONFBASIC'] = 'Grundiischtellige';
+$lang['L_INSTALL_STEP2FINISHED'] = 'D Iischtellige sind erfolgriich gsicheret worde';
+$lang['L_INSTALL_STEP2_1'] = 'Installation mit de Standardkonfiguration wiitermache';
+$lang['L_LASTSTEP'] = 'Abschluss vo de Installation';
+$lang['L_IDOMANUAL'] = 'Ich mache diä Verzeichniss vo Hand';
+$lang['L_DOFROM'] = 'usgehend vo';
+$lang['L_FTPMODE2'] = 'Mache diä Verzeichniss per FTP:';
+$lang['L_CONNECT'] = 'verbinde';
+$lang['L_DIRS_CREATED'] = 'D Verzeichniss sind ordnigsgmäss gmacht worde.';
+$lang['L_CONNECT_TO'] = 'verbinde zu';
+$lang['L_CHANGEDIR'] = 'Wächsel is Verzeichnis';
+$lang['L_CHANGEDIRERROR'] = 'Wächsel is Verzeichnis nöd mögli';
+$lang['L_FTP_OK'] = 'FTP-Parameter sind ok';
+$lang['L_SFTP_OK'] = 'FTP-Parameter sind ok';
+$lang['L_CREATEDIRS2'] = 'Verzeichnis mache';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP-Verbindig nöd gmacht!';
+$lang['L_CONNWITH'] = 'Verbindig mit';
+$lang['L_ASUSER'] = 'als User';
+$lang['L_NOTPOSSIBLE'] = 'nöd mögli';
+$lang['L_DIRCR1'] = 'mache es Arbetsverzeichnis';
+$lang['L_DIRCR2'] = 'mache es Backup-Verzeichnis';
+$lang['L_DIRCR4'] = 'mache es Log-Verzeichnis';
+$lang['L_DIRCR5'] = 'mache es Konfigurationsverzeichnis';
+$lang['L_INDIR'] = 'bi im Verzeichnis';
+$lang['L_CHECK_DIRS'] = 'überprüefe';
+$lang['L_DISABLEDFUNCTIONS'] = 'Abgschalteti Funktionen';
+$lang['L_NOFTPPOSSIBLE'] = 'Es hät kei FTP-Funktionen zur Verfüegig!';
+$lang['L_NOGZPOSSIBLE'] = 'Es hät kei Kompressions-Funktione zur Verfüegig!';
+$lang['L_UI1'] = 'Es werded alli Arbetsverzeichnis mit allne Backups wo drin sind glöscht.';
+$lang['L_UI2'] = 'Sind Si sicher, dass Si das wänd?';
+$lang['L_UI3'] = 'Nei, sofort abbräche';
+$lang['L_UI4'] = 'jo, bitte wiitermache';
+$lang['L_UI5'] = 'lösche Arbetsverzeichnis';
+$lang['L_UI6'] = 'alls isch erfolgriich glöscht worde';
+$lang['L_UI7'] = 'Lösched Si bitte das Skriptverzeichnis';
+$lang['L_UI8'] = 'en Ebeni nach obe';
+$lang['L_UI9'] = 'Es hät en Fähler gäh, Lösche isch nöd mögli gsi<p>Fähler bi Verzeichnis';
+$lang['L_IMPORT'] = 'Konfiguration importiere';
+$lang['L_IMPORT3'] = 'D Konfiguration isch glade...';
+$lang['L_IMPORT4'] = 'D Konfiguration isch gsicheret.';
+$lang['L_IMPORT5'] = 'MyOOS [Dumper] starte';
+$lang['L_IMPORT6'] = 'Installations-Menü';
+$lang['L_IMPORT7'] = 'Konfiguration ufelade';
+$lang['L_IMPORT8'] = 'zrugg zum Upload';
+$lang['L_IMPORT9'] = 'Das isch kei Konfigurationssicherig!';
+$lang['L_IMPORT10'] = 'D Konfiguration isch erfolgriich ufeglade worde.';
+$lang['L_IMPORT11'] = '<strong>Fähler: </strong>Es hät Problem gäh bim Schriibe vo de  sql_statements.';
+$lang['L_IMPORT12'] = '<strong>Fähler: </strong>Es hät Problem gäh bim Schriibe vo de config.php.';
+$lang['L_INSTALL_HELP_PORT'] = '(läär = Standardport)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(läär = Standardsocket)';
+$lang['L_TRYAGAIN'] = 'namal versueche';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'gfundeni DB:';
+$lang['L_FM_FILEUPLOAD'] = 'Datei ufelade';
+$lang['L_PASS'] = 'Passwort';
+$lang['L_NO_DB_FOUND_INFO'] = 'D Verbindig zur Datebank isch erfolgriich gsi.<br>Ihri Zuegangsdate sind gültig und sind vom MySQL-Server akzeptiert worde.<br>Leider hät de MyOOS [Dumper] kei Datebank gfunde.<br>Di automatischi Erkännig isch bi mänge Hoschter gschpeert.<br>Si müend Ihri Datebank nachem Abschluss vo de Installation under em Menüpunkt "Konfiguration" "Verbindigsparameter iiblände" agäh.<br>Gönd Si bitte sofort nach em Abschluss vo de Installation det hii und träged Si de Name vo Irer Datebank det ii.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/ch/lang_log.php b/msd/language/ch/lang_log.php
index 42756eee..102cf125 100644
--- a/msd/language/ch/lang_log.php
+++ b/msd/language/ch/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Log lösche";
-$lang['L_LOGFILEFORMAT']="Log-Dateiformat";
-$lang['L_LOGFILENOTWRITABLE']="Log-Datei cha nöd gschribe wärde!";
-$lang['L_NOREVERSE']="ältischte Iitrag zerscht";
-$lang['L_REVERSE']="neuschte Iitrag zerscht";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Log lösche';
+$lang['L_LOGFILEFORMAT'] = 'Log-Dateiformat';
+$lang['L_LOGFILENOTWRITABLE'] = 'Log-Datei cha nöd gschribe wärde!';
+$lang['L_NOREVERSE'] = 'ältischte Iitrag zerscht';
+$lang['L_REVERSE'] = 'neuschte Iitrag zerscht';
diff --git a/msd/language/ch/lang_main.php b/msd/language/ch/lang_main.php
index 6e620270..698ef467 100644
--- a/msd/language/ch/lang_main.php
+++ b/msd/language/ch/lang_main.php
@@ -1,74 +1,85 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Es schtönd kei FTP-Funktione zur Verfüegig!";
-$lang['L_INFO_LOCATION']="Si sind uf";
-$lang['L_INFO_DATABASES']="Folgendi Datebank(e) sind ufem MySql-Server:";
-$lang['L_INFO_NODB']="Datebank gits nöd";
-$lang['L_INFO_DBDETAIL']="Detail-Information vo de Datnbank";
-$lang['L_INFO_DBEMPTY']="Diä Datnbank isch läär!";
-$lang['L_INFO_RECORDS']="Datesätz";
-$lang['L_INFO_SIZE']="Grössi";
-$lang['L_INFO_LASTUPDATE']="sletscht Update";
-$lang['L_INFO_SUM']="total";
-$lang['L_INFO_OPTIMIZED']="optimiert";
-$lang['L_OPTIMIZE_DATABASES']="Tabälle optimiere";
-$lang['L_CHECK_TABLES']="Tabälle überprüefe";
-$lang['L_CLEAR_DATABASE']="Datebank lääre";
-$lang['L_DELETE_DATABASE']="Datebank lösche";
-$lang['L_INFO_CLEARED']="isch gläärt worde";
-$lang['L_INFO_DELETED']="isch glöscht worde";
-$lang['L_INFO_EMPTYDB1']="Söll diä Datebank";
-$lang['L_INFO_EMPTYDB2']="würkli gläärt wärde? (Achtung! Alli Date sind für ewig verlore)";
-$lang['L_INFO_KILLDB']="würkli glöscht wärde? (Achtung! Alli Date sind für ewig verlore)";
-$lang['L_PROCESSKILL1']="Es wird versuecht, Prozess";
-$lang['L_PROCESSKILL2']="z beände";
-$lang['L_PROCESSKILL3']="Es wird sit";
-$lang['L_PROCESSKILL4']="Sekunde versuecht, Prozess";
-$lang['L_HTACC_CREATE']="Verzeichnisschutz mache";
-$lang['L_ENCRYPTION_TYPE']="Verschlüsseligsart";
-$lang['L_HTACC_CRYPT']="Crypt (Linux und Unix-System)";
-$lang['L_HTACC_MD5']="MD5 (Linux und Unix-System)";
-$lang['L_HTACC_NO_ENCRYPTION']="unverschlüsslet (Windows)";
-$lang['L_HTACCESS8']="Es hät scho en Verzeichnisschutz. Wänn Si en neue mached, wird de alti überschribe!";
-$lang['L_HTACC_NO_USERNAME']="Si müend en Name iigäh!";
-$lang['L_PASSWORDS_UNEQUAL']="Diä Passwörter sind nöd identisch oder läär!";
-$lang['L_HTACC_CONFIRM_DELETE']="Söll de Verzeichnisschutz jetzt gmacht wärde?";
-$lang['L_HTACC_CREATED']="De Verzeichnisschutz isch gmacht.";
-$lang['L_HTACC_CONTENT']="Inhalt vo de Datei";
-$lang['L_HTACC_CREATE_ERROR']="Es isch en Fähler bim Verzeichnisschutz mache passiert!<br> Mached Si bitte vo Hand e Datei mit folgendem Inhalt";
-$lang['L_HTACC_PROPOSED']="Dringend empfohle";
-$lang['L_HTACC_EDIT']=".htaccess editiere";
-$lang['L_HTACCESS18']=".htaccess mache in";
-$lang['L_HTACCESS19']="neu lade";
-$lang['L_HTACCESS20']="Skript ausfüere";
-$lang['L_HTACCESS21']="Handler zuefüege";
-$lang['L_HTACCESS22']="Usfüerbar mache";
-$lang['L_HTACCESS23']="Verzeichnis-Listing";
-$lang['L_HTACCESS24']="Error-Dokument";
-$lang['L_HTACCESS25']="Rewrite aktiviere";
-$lang['L_HTACCESS26']="Deny / Allow";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Error-Log";
-$lang['L_HTACCESS29']="wiiteri Bischpiel und Dokumentation";
-$lang['L_HTACCESS30']="Provider";
-$lang['L_HTACCESS31']="generell";
-$lang['L_HTACCESS32']="Achtung! Diä .htaccess hät e diräkti Uswirkig uf de Browser.<br>Bi falscher Anwendig sind diä Siite nüme erreichbar.";
-$lang['L_PHPBUG']="Bug in zlib! Kei Kompression mögli!";
-$lang['L_DISABLEDFUNCTIONS']="Abgschalteti Funktione";
-$lang['L_NOGZPOSSIBLE']="Will zlib nöd inschtalliert isch, schtönd kei GZip-Funktione zur Verfüegig!";
-$lang['L_DELETE_HTACCESS']="Verzeichnisschutz wägmache (.htaccess lösche)";
-$lang['L_WRONG_RIGHTS']="Diä Datei oder das Verzeichnis '%s' isch für mi nöd beschriibbar.<br> Entweder hät si de falschi Besitzer (Owner) oder di falsche Rächt (Chmod).<br> Bitte setzed Si diä richtige Attribut mit Irem FTP-Programm. <br> Diä Datei oder das Verzeichnis brucht diä Rächt %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Ha s Verzeichnis '%s' nöd chöne mache. Mached Si s bitte mit Irem FTP-Programm";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="Han diä Datei nöd gfunde";
 
-
-?>
\ No newline at end of file
+$lang['L_NOFTPPOSSIBLE'] = 'Es schtönd kei FTP-Funktione zur Verfüegig!';
+$lang['L_INFO_LOCATION'] = 'Si sind uf';
+$lang['L_INFO_DATABASES'] = 'Folgendi Datebank(e) sind ufem MySql-Server:';
+$lang['L_INFO_NODB'] = 'Datebank gits nöd';
+$lang['L_INFO_DBDETAIL'] = 'Detail-Information vo de Datnbank';
+$lang['L_INFO_DBEMPTY'] = 'Diä Datnbank isch läär!';
+$lang['L_INFO_RECORDS'] = 'Datesätz';
+$lang['L_INFO_SIZE'] = 'Grössi';
+$lang['L_INFO_LASTUPDATE'] = 'sletscht Update';
+$lang['L_INFO_SUM'] = 'total';
+$lang['L_INFO_OPTIMIZED'] = 'optimiert';
+$lang['L_OPTIMIZE_DATABASES'] = 'Tabälle optimiere';
+$lang['L_CHECK_TABLES'] = 'Tabälle überprüefe';
+$lang['L_CLEAR_DATABASE'] = 'Datebank lääre';
+$lang['L_DELETE_DATABASE'] = 'Datebank lösche';
+$lang['L_INFO_CLEARED'] = 'isch gläärt worde';
+$lang['L_INFO_DELETED'] = 'isch glöscht worde';
+$lang['L_INFO_EMPTYDB1'] = 'Söll diä Datebank';
+$lang['L_INFO_EMPTYDB2'] = 'würkli gläärt wärde? (Achtung! Alli Date sind für ewig verlore)';
+$lang['L_INFO_KILLDB'] = 'würkli glöscht wärde? (Achtung! Alli Date sind für ewig verlore)';
+$lang['L_PROCESSKILL1'] = 'Es wird versuecht, Prozess';
+$lang['L_PROCESSKILL2'] = 'z beände';
+$lang['L_PROCESSKILL3'] = 'Es wird sit';
+$lang['L_PROCESSKILL4'] = 'Sekunde versuecht, Prozess';
+$lang['L_HTACC_CREATE'] = 'Verzeichnisschutz mache';
+$lang['L_ENCRYPTION_TYPE'] = 'Verschlüsseligsart';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Es hät scho en Verzeichnisschutz. Wänn Si en neue mached, wird de alti überschribe!';
+$lang['L_HTACC_NO_USERNAME'] = 'Si müend en Name iigäh!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Diä Passwörter sind nöd identisch oder läär!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Söll de Verzeichnisschutz jetzt gmacht wärde?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'De Verzeichnisschutz isch gmacht.';
+$lang['L_HTACC_CONTENT'] = 'Inhalt vo de Datei';
+$lang['L_HTACC_CREATE_ERROR'] = 'Es isch en Fähler bim Verzeichnisschutz mache passiert!<br> Mached Si bitte vo Hand e Datei mit folgendem Inhalt';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = '.htaccess editiere';
+$lang['L_HTACCESS18'] = '.htaccess mache in';
+$lang['L_HTACCESS19'] = 'neu lade';
+$lang['L_HTACCESS20'] = 'Skript ausfüere';
+$lang['L_HTACCESS21'] = 'Handler zuefüege';
+$lang['L_HTACCESS22'] = 'Usfüerbar mache';
+$lang['L_HTACCESS23'] = 'Verzeichnis-Listing';
+$lang['L_HTACCESS24'] = 'Error-Dokument';
+$lang['L_HTACCESS25'] = 'Rewrite aktiviere';
+$lang['L_HTACCESS26'] = 'Deny / Allow';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Error-Log';
+$lang['L_HTACCESS29'] = 'wiiteri Bischpiel und Dokumentation';
+$lang['L_HTACCESS30'] = 'Provider';
+$lang['L_HTACCESS31'] = 'generell';
+$lang['L_HTACCESS32'] = 'Achtung! Diä .htaccess hät e diräkti Uswirkig uf de Browser.<br>Bi falscher Anwendig sind diä Siite nüme erreichbar.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Abgschalteti Funktione';
+$lang['L_NOGZPOSSIBLE'] = 'Will zlib nöd inschtalliert isch, schtönd kei GZip-Funktione zur Verfüegig!';
+$lang['L_DELETE_HTACCESS'] = 'Verzeichnisschutz wägmache (.htaccess lösche)';
+$lang['L_WRONG_RIGHTS'] = "Diä Datei oder das Verzeichnis '%s' isch für mi nöd beschriibbar.<br> Entweder hät si de falschi Besitzer (Owner) oder di falsche Rächt (Chmod).<br> Bitte setzed Si diä richtige Attribut mit Irem FTP-Programm. <br> Diä Datei oder das Verzeichnis brucht diä Rächt %s.<br>";
+$lang['L_CANT_CREATE_DIR'] = "Ha s Verzeichnis '%s' nöd chöne mache. Mached Si s bitte mit Irem FTP-Programm";
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'Han diä Datei nöd gfunde';
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/ch/lang_restore.php b/msd/language/ch/lang_restore.php
index 7d519467..1d9332e5 100644
--- a/msd/language/ch/lang_restore.php
+++ b/msd/language/ch/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Es sind bis ez <b>%d</b> Tabälle agleit worde.";
-$lang['L_FILE_MISSING']="Han diä Datei nöd gfunde";
-$lang['L_RESTORE_DB']="Datebank '<b>%s</b>' uf Server '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> Tabälle sind angleit worde.";
-$lang['L_RESTORE_RUN1']="<br>Es sind bis ez <b>%s</b> vo <b>%s</b> Datesätz erfolgriich iitreit worde.";
-$lang['L_RESTORE_RUN2']="<br>Momentan werdet Date vo de Tabälle '<b>%s</b>' analysiert.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> Datesätz sind iitreit worde.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Es sind bis ez <b>%d</b> vo <b>%d</b> Tabälle agleit worde.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Herzliche Glückwunsch.</b><br><br>Diä Datenbank isch komplett reschtauriert worde.<br>Alli Date us de Backup-Datei sind erfolgriich i diä Datebank itreit worde.<br><br>Alls fertig. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Fähler:<br>Uuswahl vo de Datebank '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' abverheit!";
-$lang['L_FILE_OPEN_ERROR']="Fähler: Diä Datei hät nöd chöne ufgmacht wärde";
-$lang['L_PROGRESS_OVER_ALL']="Fortschritt total";
-$lang['L_BACK_TO_OVERVIEW']="Datebank-Übersicht";
-$lang['L_RESTORE_RUN0']="<br>Es sind bis ez <b>%s</b> Datesätz erfolgriich iitreit worde.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Unbekannte SQL-Befehl:";
-$lang['L_NOTICES']="Hiiwis";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Es sind bis ez <b>%d</b> Tabälle agleit worde.';
+$lang['L_FILE_MISSING'] = 'Han diä Datei nöd gfunde';
+$lang['L_RESTORE_DB'] = "Datebank '<b>%s</b>' uf Server '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> Tabälle sind angleit worde.';
+$lang['L_RESTORE_RUN1'] = '<br>Es sind bis ez <b>%s</b> vo <b>%s</b> Datesätz erfolgriich iitreit worde.';
+$lang['L_RESTORE_RUN2'] = "<br>Momentan werdet Date vo de Tabälle '<b>%s</b>' analysiert.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> Datesätz sind iitreit worde.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Es sind bis ez <b>%d</b> vo <b>%d</b> Tabälle agleit worde.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Herzliche Glückwunsch.</b><br><br>Diä Datenbank isch komplett reschtauriert worde.<br>Alli Date us de Backup-Datei sind erfolgriich i diä Datebank itreit worde.<br><br>Alls fertig. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Fähler:<br>Uuswahl vo de Datebank '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' abverheit!";
+$lang['L_FILE_OPEN_ERROR'] = 'Fähler: Diä Datei hät nöd chöne ufgmacht wärde';
+$lang['L_PROGRESS_OVER_ALL'] = 'Fortschritt total';
+$lang['L_BACK_TO_OVERVIEW'] = 'Datebank-Übersicht';
+$lang['L_RESTORE_RUN0'] = '<br>Es sind bis ez <b>%s</b> Datesätz erfolgriich iitreit worde.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Unbekannte SQL-Befehl:';
+$lang['L_NOTICES'] = 'Hiiwis';
diff --git a/msd/language/ch/lang_sql.php b/msd/language/ch/lang_sql.php
index 6855da50..40c55cb1 100644
--- a/msd/language/ch/lang_sql.php
+++ b/msd/language/ch/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Befähl";
-$lang['L_IMPORT_NOTABLE']="Es isch kei Tabälle für de Import ausgwählt!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="D Uusfüerig vo SQL-Befähl cha Date manipuliere! Dr Autor übernimmt kei Haftig bi Dateverlüscht.";
-$lang['L_SQL_EXEC']="SQL-Befähl usfüere";
-$lang['L_SQL_DATAVIEW']="Daten-Aasicht";
-$lang['L_SQL_TABLEVIEW']="Tabälle-Aasicht";
-$lang['L_SQL_VONINS']="vo total";
-$lang['L_SQL_NODATA']="kei Datesätz";
-$lang['L_SQL_RECORDUPDATED']="Datesatz isch gändert worde";
-$lang['L_SQL_RECORDINSERTED']="Datesatz isch gspeicheret worde";
-$lang['L_SQL_BACKDBOVERVIEW']="zrugg zur Datebank-Übersicht";
-$lang['L_SQL_RECORDDELETED']="Datesatz isch gelöscht worde";
-$lang['L_ASKTABLEEMPTY']="Söll diä Tabälle `%s` geläärt wärde?";
-$lang['L_SQL_RECORDEDIT']="editiere Datesatz";
-$lang['L_SQL_RECORDNEW']="Datesatz iifüege";
-$lang['L_ASKDELETERECORD']="Söll dä Datesatz glöscht wärde?";
-$lang['L_ASKDELETETABLE']="Söll diä Tabelle `%s` glöscht wärde?";
-$lang['L_SQL_BEFEHLE']="SQL-Befähl";
-$lang['L_SQL_BEFEHLNEU']="neue Befähl";
-$lang['L_SQL_BEFEHLSAVED1']="SQL-Befähl";
-$lang['L_SQL_BEFEHLSAVED2']="isch zuegfüegt worde";
-$lang['L_SQL_BEFEHLSAVED3']="isch gschpeicheret worde";
-$lang['L_SQL_BEFEHLSAVED4']="isch nach obe bracht worde";
-$lang['L_SQL_BEFEHLSAVED5']="isch glöscht worde";
-$lang['L_SQL_QUERYENTRY']="D Abfrag hät";
-$lang['L_SQL_COLUMNS']="Spalte";
-$lang['L_ASKDBDELETE']="Söll diä Datebank `%s` samt em Inhalt würkli glöscht wärde?";
-$lang['L_ASKDBEMPTY']="Söll diä Datebank `%s` würkli gläärt wärde?";
-$lang['L_ASKDBCOPY']="Söll de Inhalt vo de Datenbank `%s` i diä Datebank `%s` kopiert wärde?";
-$lang['L_SQL_TABLENEW']="Tabälle bearbeite";
-$lang['L_SQL_OUTPUT']="SQL-Uusgab";
-$lang['L_DO_NOW']="jetzt usfüere";
-$lang['L_SQL_NAMEDEST_MISSING']="Name für d Zieldatebank fählt!";
-$lang['L_ASKDELETEFIELD']="Söll das Feld glöscht wärde?";
-$lang['L_SQL_COMMANDS_IN']="Ziile i";
-$lang['L_SQL_COMMANDS_IN2']="Sekunde(n) abgschafft.";
-$lang['L_SQL_OUT1']="Es wurden";
-$lang['L_SQL_OUT2']="Befähl usgfüert";
-$lang['L_SQL_OUT3']="Es gab";
-$lang['L_SQL_OUT4']="Kommentar";
-$lang['L_SQL_OUT5']="Will d Uusgab über 5000 Ziile hät, wird si nöd aazeigt.";
-$lang['L_SQL_SELECDB']="Datebank uswähle";
-$lang['L_SQL_TABLESOFDB']="Tabälle vo de Datebank";
-$lang['L_SQL_EDIT']="bearbeite";
-$lang['L_SQL_NOFIELDDELETE']="Lösche nöd mögli, will e Tabälle mindischtens 1 Fäld ha mues.";
-$lang['L_SQL_FIELDDELETE1']="Das Fäld";
-$lang['L_SQL_DELETED']="isch glöscht worde";
-$lang['L_SQL_CHANGED']="isch gänderet worde";
-$lang['L_SQL_CREATED']="isch aagleit worde";
-$lang['L_SQL_NODEST_COPY']="Ohni Ziel cha nöd kopiert wärde!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Zieltabälle existiert scho!";
-$lang['L_SQL_SCOPY']="Tabällestruktur vo `%s` isch i Tabelle `%s` kopiert worde.";
-$lang['L_SQL_TCOPY']="Tabälle `%s` isch mit Date in Tabälle `%s` kopiert worde.";
-$lang['L_SQL_TABLENONAME']="Tabälle brucht en Namen!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tabällename dörf nöd läär sii!";
-$lang['L_SQL_COLLATENOTMATCH']="Zeichesatz und Sortierig passed nöd zäme!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Fähler: Kei gültige Fäldname";
-$lang['L_SQL_CREATETABLE']="Tabälle aalegge";
-$lang['L_SQL_COPYTABLE']="Tabälle kopiere";
-$lang['L_SQL_STRUCTUREONLY']="nume Struktur";
-$lang['L_SQL_STRUCTUREDATA']="Struktur und Date";
-$lang['L_SQL_NOTABLESINDB']="Es hät kei Tabälle i de Datebank";
-$lang['L_SQL_SELECTTABLE']="Tabälle uswähle";
-$lang['L_SQL_SHOWDATATABLE']="Date vo de Tabälle aazeige";
-$lang['L_SQL_TBLPROPSOF']="Tabälleeigeschafte vo";
-$lang['L_SQL_EDITFIELD']="Editiere Fäld";
-$lang['L_SQL_NEWFIELD']="neus Fäld";
-$lang['L_SQL_INDEXES']="Indizes";
-$lang['L_SQL_ATPOSITION']="a Position iifüege";
-$lang['L_SQL_FIRST']="zerscht";
-$lang['L_SQL_AFTER']="nach";
-$lang['L_SQL_CHANGEFIELD']="Fäld ändere";
-$lang['L_SQL_INSERTFIELD']="Fäld iifüege";
-$lang['L_SQL_INSERTNEWFIELD']="neus Fäld iifüege";
-$lang['L_SQL_TABLEINDEXES']="Indizes vo de Tabälle";
-$lang['L_SQL_ALLOWDUPS']="Duplikat erlaubt";
-$lang['L_SQL_CARDINALITY']="Kardinalität";
-$lang['L_SQL_TABLENOINDEXES']="Diä Tabälle hät kei Indizes";
-$lang['L_SQL_CREATEINDEX']="neue Index mache";
-$lang['L_SQL_WASEMPTIED']="isch gläärt worde";
-$lang['L_SQL_RENAMEDTO']="isch unbenännt worde i";
-$lang['L_SQL_DBCOPY']="De Inhalt vo de Datebank `%s` isch i d Datenbank `%s` kopiert worde.";
-$lang['L_SQL_DBSCOPY']="D Struktur vo de Datebank `%s` isch i d Datebank `%s` kopiert worde.";
-$lang['L_SQL_WASCREATED']="isch gmacht worde";
-$lang['L_SQL_RENAMEDB']="Datesatz umbenänne";
-$lang['L_SQL_ACTIONS']="Aktione";
-$lang['L_SQL_CHOOSEACTION']="Aktion wähle";
-$lang['L_SQL_DELETEDB']="Datebank lösche";
-$lang['L_SQL_EMPTYDB']="Datebank lääre";
-$lang['L_SQL_COPYDATADB']="Inhalt i Datebank kopiere";
-$lang['L_SQL_COPYSDB']="Struktur i Datebank kopiere";
-$lang['L_SQL_IMEXPORT']="Im-/Export";
-$lang['L_INFO_RECORDS']="Datesätz";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="Sölled diä Tabälle `%s` geläärt und diä Indizes zrugggsetzt wärde?";
-$lang['L_EDIT']="editiere";
-$lang['L_DELETE']="lösche";
-$lang['L_EMPTY']="lääre";
-$lang['L_EMPTYKEYS']="lääre und Indizes zruggsetze";
-$lang['L_SQL_TABLEEMPTIED']="Tabälle `%s` isch gläärt worde.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Tabälle `%s` isch gläärt worde, und d Indizes sind zrugggsetzt worde.";
-$lang['L_SQL_LIBRARY']="SQL-Bibliothek";
-$lang['L_SQL_ATTRIBUTES']="Attribut";
-$lang['L_SQL_UPLOADEDFILE']="gladeni Datei:";
-$lang['L_SQL_IMPORT']="Import i Datebank `%s`";
-$lang['L_EXPORT']="Export";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Import-Optione";
-$lang['L_CSVOPTIONS']="CSV-Optione";
-$lang['L_IMPORTTABLE']="Import i Tabälle";
-$lang['L_NEWTABLE']="neui Tabälle";
-$lang['L_IMPORTSOURCE']="Import-Quälle";
-$lang['L_FROMTEXTBOX']="usem Textfäld";
-$lang['L_FROMFILE']="us de Datei";
-$lang['L_EMPTYTABLEBEFORE']="Tabälle vorhär lääre";
-$lang['L_CREATEAUTOINDEX']="Auto-Index mache";
-$lang['L_CSV_NAMEFIRSTLINE']="Fäldname i di erschti Ziile";
-$lang['L_CSV_FIELDSEPERATE']="Fälder trännt mit";
-$lang['L_CSV_FIELDSENCLOSED']="Fälder igschlosse vo";
-$lang['L_CSV_FIELDSESCAPE']="Fälder \"escaped\" vo";
-$lang['L_CSV_EOL']="Ziile trännt mit";
-$lang['L_CSV_NULL']="Ersetz NULL dur";
-$lang['L_CSV_FILEOPEN']="CSV-Datei ufmache";
-$lang['L_IMPORTIEREN']="importiere";
-$lang['L_SQL_EXPORT']="Export us Datebank `%s`";
-$lang['L_EXPORTOPTIONS']="Export-Optione";
-$lang['L_EXCEL2003']="Excel ab 2003";
-$lang['L_SHOWRESULT']="Ergebnis aazeige";
-$lang['L_SENDRESULTASFILE']="Ergebnis als Datei schicke";
-$lang['L_EXPORTLINES']="<strong>%s</strong> Ziile exportiert";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="D Aazahl vo de Tabällefelder schtimmed nöd mit de date vo de z importierende Date überii (%d statt %d).";
-$lang['L_CSV_FIELDSLINES']="%d Fälder ermittlet, total %d Ziile";
-$lang['L_CSV_ERRORCREATETABLE']="Fähler bim Mache vo de Tabälle `%s`!";
-$lang['L_FM_UPLOADFILEREQUEST']="Gänd Si bitte e Datei aa.";
-$lang['L_CSV_NODATA']="Kei Date zum Importiere gfunde!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="allgemeini Funktione";
-$lang['L_SQLLIB_RESETAUTO']="Auto-Wert zruggsetze";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="Board deaktiviere";
-$lang['L_SQLLIB_ACTIVATEBOARD']="Board aktiviere";
-$lang['L_SQL_NOTABLESSELECTED']="Es sind kei Tabälle usgwählt!";
-$lang['L_TOOLS']="Tools";
-$lang['L_TOOLS_TOOLBOX']="Datebank uswähle / Datebankfunktionen / Im- und Export";
-$lang['L_SQL_OPENFILE']="SQL-Datei ufmache";
-$lang['L_SQL_OPENFILE_BUTTON']="Ufelade";
-$lang['L_MAX_UPLOAD_SIZE']="Maximali Dateigrössi";
-$lang['L_SQL_SEARCH']="Suechi";
-$lang['L_SQL_SEARCHWORDS']="Suechbegriff";
-$lang['L_START_SQL_SEARCH']="Suechi starte";
-$lang['L_RESET_SEARCHWORDS']="Iigab zruggsetze";
-$lang['L_SEARCH_OPTIONS']="Suechoptione";
-$lang['L_SEARCH_RESULTS']="D Suech nach \"<b>%s</b>\" i de Tabälle \"<b>%s</b>\" liferet folgendi Träffer";
-$lang['L_SEARCH_NO_RESULTS']="D Suech nach \"<b>%s</b>\" i de Tabälle \"<b>%s</b>\" lieferet kei Ergebniss!";
-$lang['L_NO_ENTRIES']="Diä Tabälle \"<b>%s</b>\" ist läär und hät keine Iiträg.";
-$lang['L_SEARCH_ACCESS_KEYS']="Blättere: vürschi=ALT+V, zrugg=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="e Spalte mues mindeschtens ein Suechbegriff enthalte (ODER-Suche)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="en Datesatz mues alli Suechbegriffe enthalte, diä chöned aber i beliebige Spalte sii (Recheintensiv!)";
-$lang['L_SEARCH_OPTIONS_AND']="e Spalte mues alli Suechbegriff enthalte (UND-Suche)";
-$lang['L_SEARCH_IN_TABLE']="Suech i de Tabälle";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Tabällestruktur bearbeite";
-$lang['L_DEFAULT_CHARSET']="Standardzeichesatz";
-$lang['L_TITLE_KEY_PRIMARY']="Primärschlüssel";
-$lang['L_TITLE_KEY_UNIQUE']="Eidütige Schlüssel";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Volltextschlüssel";
-$lang['L_TITLE_NOKEY']="Kei Schlüssel ";
-$lang['L_TITLE_SEARCH']="Suechi";
-$lang['L_TITLE_MYSQL_HELP']="MySQL Dokumentation ";
-$lang['L_TITLE_UPLOAD']="SQL-Datei ufelade ";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="Grössi";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Befähl';
+$lang['L_IMPORT_NOTABLE'] = 'Es isch kei Tabälle für de Import ausgwählt!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'D Uusfüerig vo SQL-Befähl cha Date manipuliere! Dr Autor übernimmt kei Haftig bi Dateverlüscht.';
+$lang['L_SQL_EXEC'] = 'SQL-Befähl usfüere';
+$lang['L_SQL_DATAVIEW'] = 'Daten-Aasicht';
+$lang['L_SQL_TABLEVIEW'] = 'Tabälle-Aasicht';
+$lang['L_SQL_VONINS'] = 'vo total';
+$lang['L_SQL_NODATA'] = 'kei Datesätz';
+$lang['L_SQL_RECORDUPDATED'] = 'Datesatz isch gändert worde';
+$lang['L_SQL_RECORDINSERTED'] = 'Datesatz isch gspeicheret worde';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'zrugg zur Datebank-Übersicht';
+$lang['L_SQL_RECORDDELETED'] = 'Datesatz isch gelöscht worde';
+$lang['L_ASKTABLEEMPTY'] = 'Söll diä Tabälle `%s` geläärt wärde?';
+$lang['L_SQL_RECORDEDIT'] = 'editiere Datesatz';
+$lang['L_SQL_RECORDNEW'] = 'Datesatz iifüege';
+$lang['L_ASKDELETERECORD'] = 'Söll dä Datesatz glöscht wärde?';
+$lang['L_ASKDELETETABLE'] = 'Söll diä Tabelle `%s` glöscht wärde?';
+$lang['L_SQL_BEFEHLE'] = 'SQL-Befähl';
+$lang['L_SQL_BEFEHLNEU'] = 'neue Befähl';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL-Befähl';
+$lang['L_SQL_BEFEHLSAVED2'] = 'isch zuegfüegt worde';
+$lang['L_SQL_BEFEHLSAVED3'] = 'isch gschpeicheret worde';
+$lang['L_SQL_BEFEHLSAVED4'] = 'isch nach obe bracht worde';
+$lang['L_SQL_BEFEHLSAVED5'] = 'isch glöscht worde';
+$lang['L_SQL_QUERYENTRY'] = 'D Abfrag hät';
+$lang['L_SQL_COLUMNS'] = 'Spalte';
+$lang['L_ASKDBDELETE'] = 'Söll diä Datebank `%s` samt em Inhalt würkli glöscht wärde?';
+$lang['L_ASKDBEMPTY'] = 'Söll diä Datebank `%s` würkli gläärt wärde?';
+$lang['L_ASKDBCOPY'] = 'Söll de Inhalt vo de Datenbank `%s` i diä Datebank `%s` kopiert wärde?';
+$lang['L_SQL_TABLENEW'] = 'Tabälle bearbeite';
+$lang['L_SQL_OUTPUT'] = 'SQL-Uusgab';
+$lang['L_DO_NOW'] = 'jetzt usfüere';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Name für d Zieldatebank fählt!';
+$lang['L_ASKDELETEFIELD'] = 'Söll das Feld glöscht wärde?';
+$lang['L_SQL_COMMANDS_IN'] = 'Ziile i';
+$lang['L_SQL_COMMANDS_IN2'] = 'Sekunde(n) abgschafft.';
+$lang['L_SQL_OUT1'] = 'Es wurden';
+$lang['L_SQL_OUT2'] = 'Befähl usgfüert';
+$lang['L_SQL_OUT3'] = 'Es gab';
+$lang['L_SQL_OUT4'] = 'Kommentar';
+$lang['L_SQL_OUT5'] = 'Will d Uusgab über 5000 Ziile hät, wird si nöd aazeigt.';
+$lang['L_SQL_SELECDB'] = 'Datebank uswähle';
+$lang['L_SQL_TABLESOFDB'] = 'Tabälle vo de Datebank';
+$lang['L_SQL_EDIT'] = 'bearbeite';
+$lang['L_SQL_NOFIELDDELETE'] = 'Lösche nöd mögli, will e Tabälle mindischtens 1 Fäld ha mues.';
+$lang['L_SQL_FIELDDELETE1'] = 'Das Fäld';
+$lang['L_SQL_DELETED'] = 'isch glöscht worde';
+$lang['L_SQL_CHANGED'] = 'isch gänderet worde';
+$lang['L_SQL_CREATED'] = 'isch aagleit worde';
+$lang['L_SQL_NODEST_COPY'] = 'Ohni Ziel cha nöd kopiert wärde!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Zieltabälle existiert scho!';
+$lang['L_SQL_SCOPY'] = 'Tabällestruktur vo `%s` isch i Tabelle `%s` kopiert worde.';
+$lang['L_SQL_TCOPY'] = 'Tabälle `%s` isch mit Date in Tabälle `%s` kopiert worde.';
+$lang['L_SQL_TABLENONAME'] = 'Tabälle brucht en Namen!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tabällename dörf nöd läär sii!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Zeichesatz und Sortierig passed nöd zäme!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Fähler: Kei gültige Fäldname';
+$lang['L_SQL_CREATETABLE'] = 'Tabälle aalegge';
+$lang['L_SQL_COPYTABLE'] = 'Tabälle kopiere';
+$lang['L_SQL_STRUCTUREONLY'] = 'nume Struktur';
+$lang['L_SQL_STRUCTUREDATA'] = 'Struktur und Date';
+$lang['L_SQL_NOTABLESINDB'] = 'Es hät kei Tabälle i de Datebank';
+$lang['L_SQL_SELECTTABLE'] = 'Tabälle uswähle';
+$lang['L_SQL_SHOWDATATABLE'] = 'Date vo de Tabälle aazeige';
+$lang['L_SQL_TBLPROPSOF'] = 'Tabälleeigeschafte vo';
+$lang['L_SQL_EDITFIELD'] = 'Editiere Fäld';
+$lang['L_SQL_NEWFIELD'] = 'neus Fäld';
+$lang['L_SQL_INDEXES'] = 'Indizes';
+$lang['L_SQL_ATPOSITION'] = 'a Position iifüege';
+$lang['L_SQL_FIRST'] = 'zerscht';
+$lang['L_SQL_AFTER'] = 'nach';
+$lang['L_SQL_CHANGEFIELD'] = 'Fäld ändere';
+$lang['L_SQL_INSERTFIELD'] = 'Fäld iifüege';
+$lang['L_SQL_INSERTNEWFIELD'] = 'neus Fäld iifüege';
+$lang['L_SQL_TABLEINDEXES'] = 'Indizes vo de Tabälle';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplikat erlaubt';
+$lang['L_SQL_CARDINALITY'] = 'Kardinalität';
+$lang['L_SQL_TABLENOINDEXES'] = 'Diä Tabälle hät kei Indizes';
+$lang['L_SQL_CREATEINDEX'] = 'neue Index mache';
+$lang['L_SQL_WASEMPTIED'] = 'isch gläärt worde';
+$lang['L_SQL_RENAMEDTO'] = 'isch unbenännt worde i';
+$lang['L_SQL_DBCOPY'] = 'De Inhalt vo de Datebank `%s` isch i d Datenbank `%s` kopiert worde.';
+$lang['L_SQL_DBSCOPY'] = 'D Struktur vo de Datebank `%s` isch i d Datebank `%s` kopiert worde.';
+$lang['L_SQL_WASCREATED'] = 'isch gmacht worde';
+$lang['L_SQL_RENAMEDB'] = 'Datesatz umbenänne';
+$lang['L_SQL_ACTIONS'] = 'Aktione';
+$lang['L_SQL_CHOOSEACTION'] = 'Aktion wähle';
+$lang['L_SQL_DELETEDB'] = 'Datebank lösche';
+$lang['L_SQL_EMPTYDB'] = 'Datebank lääre';
+$lang['L_SQL_COPYDATADB'] = 'Inhalt i Datebank kopiere';
+$lang['L_SQL_COPYSDB'] = 'Struktur i Datebank kopiere';
+$lang['L_SQL_IMEXPORT'] = 'Im-/Export';
+$lang['L_INFO_RECORDS'] = 'Datesätz';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Sölled diä Tabälle `%s` geläärt und diä Indizes zrugggsetzt wärde?';
+$lang['L_EDIT'] = 'editiere';
+$lang['L_DELETE'] = 'lösche';
+$lang['L_EMPTY'] = 'lääre';
+$lang['L_EMPTYKEYS'] = 'lääre und Indizes zruggsetze';
+$lang['L_SQL_TABLEEMPTIED'] = 'Tabälle `%s` isch gläärt worde.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Tabälle `%s` isch gläärt worde, und d Indizes sind zrugggsetzt worde.';
+$lang['L_SQL_LIBRARY'] = 'SQL-Bibliothek';
+$lang['L_SQL_ATTRIBUTES'] = 'Attribut';
+$lang['L_SQL_UPLOADEDFILE'] = 'gladeni Datei:';
+$lang['L_SQL_IMPORT'] = 'Import i Datebank `%s`';
+$lang['L_EXPORT'] = 'Export';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = 'Import-Optione';
+$lang['L_CSVOPTIONS'] = 'CSV-Optione';
+$lang['L_IMPORTTABLE'] = 'Import i Tabälle';
+$lang['L_NEWTABLE'] = 'neui Tabälle';
+$lang['L_IMPORTSOURCE'] = 'Import-Quälle';
+$lang['L_FROMTEXTBOX'] = 'usem Textfäld';
+$lang['L_FROMFILE'] = 'us de Datei';
+$lang['L_EMPTYTABLEBEFORE'] = 'Tabälle vorhär lääre';
+$lang['L_CREATEAUTOINDEX'] = 'Auto-Index mache';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Fäldname i di erschti Ziile';
+$lang['L_CSV_FIELDSEPERATE'] = 'Fälder trännt mit';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Fälder igschlosse vo';
+$lang['L_CSV_FIELDSESCAPE'] = 'Fälder "escaped" vo';
+$lang['L_CSV_EOL'] = 'Ziile trännt mit';
+$lang['L_CSV_NULL'] = 'Ersetz NULL dur';
+$lang['L_CSV_FILEOPEN'] = 'CSV-Datei ufmache';
+$lang['L_IMPORTIEREN'] = 'importiere';
+$lang['L_SQL_EXPORT'] = 'Export us Datebank `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Export-Optione';
+$lang['L_EXCEL2003'] = 'Excel ab 2003';
+$lang['L_SHOWRESULT'] = 'Ergebnis aazeige';
+$lang['L_SENDRESULTASFILE'] = 'Ergebnis als Datei schicke';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> Ziile exportiert';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'D Aazahl vo de Tabällefelder schtimmed nöd mit de date vo de z importierende Date überii (%d statt %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d Fälder ermittlet, total %d Ziile';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Fähler bim Mache vo de Tabälle `%s`!';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Gänd Si bitte e Datei aa.';
+$lang['L_CSV_NODATA'] = 'Kei Date zum Importiere gfunde!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'allgemeini Funktione';
+$lang['L_SQLLIB_RESETAUTO'] = 'Auto-Wert zruggsetze';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'Board deaktiviere';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'Board aktiviere';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Es sind kei Tabälle usgwählt!';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_TOOLS_TOOLBOX'] = 'Datebank uswähle / Datebankfunktionen / Im- und Export';
+$lang['L_SQL_OPENFILE'] = 'SQL-Datei ufmache';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Ufelade';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximali Dateigrössi';
+$lang['L_SQL_SEARCH'] = 'Suechi';
+$lang['L_SQL_SEARCHWORDS'] = 'Suechbegriff';
+$lang['L_START_SQL_SEARCH'] = 'Suechi starte';
+$lang['L_RESET_SEARCHWORDS'] = 'Iigab zruggsetze';
+$lang['L_SEARCH_OPTIONS'] = 'Suechoptione';
+$lang['L_SEARCH_RESULTS'] = 'D Suech nach "<b>%s</b>" i de Tabälle "<b>%s</b>" liferet folgendi Träffer';
+$lang['L_SEARCH_NO_RESULTS'] = 'D Suech nach "<b>%s</b>" i de Tabälle "<b>%s</b>" lieferet kei Ergebniss!';
+$lang['L_NO_ENTRIES'] = 'Diä Tabälle "<b>%s</b>" ist läär und hät keine Iiträg.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Blättere: vürschi=ALT+V, zrugg=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'e Spalte mues mindeschtens ein Suechbegriff enthalte (ODER-Suche)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'en Datesatz mues alli Suechbegriffe enthalte, diä chöned aber i beliebige Spalte sii (Recheintensiv!)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'e Spalte mues alli Suechbegriff enthalte (UND-Suche)';
+$lang['L_SEARCH_IN_TABLE'] = 'Suech i de Tabälle';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Tabällestruktur bearbeite';
+$lang['L_DEFAULT_CHARSET'] = 'Standardzeichesatz';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primärschlüssel';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Eidütige Schlüssel';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Volltextschlüssel';
+$lang['L_TITLE_NOKEY'] = 'Kei Schlüssel ';
+$lang['L_TITLE_SEARCH'] = 'Suechi';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQL Dokumentation ';
+$lang['L_TITLE_UPLOAD'] = 'SQL-Datei ufelade ';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'Grössi';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/da/help.html b/msd/language/da/help.html
new file mode 100644
index 00000000..64a1411b
--- /dev/null
+++ b/msd/language/da/help.html
@@ -0,0 +1,147 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/da/help.php b/msd/language/da/help.php
deleted file mode 100644
index fc522acb..00000000
--- a/msd/language/da/help.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Om dette projekt</h3>
-Idéen til dette projekt kommer fra Daniel Schlichtholz.<p>I 2004 skabte han et forum kaldet <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> og programmører af andre programmer supplementerede Daniel's scripts.<br>I løbet af kort tid blomstrede det lille backup-script til et langt større projekt.<p>Hvis du har forslag til forbedringer kan du besøge MySQLDumper-Forum: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>God fornøjelse med at bruge systemet.<br><br><h4>MySQLDumper-Teamet</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz<br>
-Dansk oversættelse - AlleyKat
-</td></tr></table>
-
-<h3>MySQLDumper Hjælp</h3>
-
-<h4>Download</h4>
-Dette Script er tilgængeligt på MySQLDumper's hjemmeside.<br>
-Det anbefales at du regelmæssigt besøger siden for seneste information, opdateringer og hjælp.<br>
-Adressen er <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>Systemkrav</h4>
-Scriptet virker med stort set alle typer servere (Windows, Linux, ...) <br>
-og PHP >= Version 4.3.4 med GZip-Library, MySQL (>= 3.23), JavaScript (skal være slået til).
-
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
-Installationen er meget nem.
-Udpak arkivet i enhver folder der er tilgængelig fra webserveren<br>
-(f.eks. i rod-folderen [Server rootdir/]MySQLDumper)<br>
-ændr config.php til chmod 777<br>
-... færdig!<br>
-Du kan starte MySQLDumper i din browser ved at skrive "http://domain.tld/MySQLDumper"
-for at færdiggøre opsætningen, følg blot instruktionerne.
-
-<br><b>Bemærk:</b><br><i>Hvis din webserver kører med indstillingen safemode=ON må MySqlDump ikke oprette foldere.<br>
-Du vil derfor være nødt til at gøre det selv.<br>
-Hvis det er tilfældet afbryder MySqlDump og fortæller dig hvad der skal gøres.<br>
-Efter oprettelse af folderne vil MySqlDump fungere normalt</i><br>
-
-<a name="perl"></a><h4>Hjælp med Perl scriptet</h4>
-
-De fleste har en cgi-bin folder, hvorfra Perl kan udføres. <br>
-Dette er normalt tilgængeligt via f.eks. http://www.domain.tld/cgi-bin/ <br><br>
-
-Hvis dette er tilfældet, følg venligst disse trin.  <br><br>
-
-1.  Åbn i MySQLDumper sidene Backup og klik "Backup Perl"   <br>
-2.  Kopiér stien der står efter entry i crondump.pl for $absolute_path_of_configdir:    <br>
-3. Åbn filen "crondump.pl" i editoren <br>
-4. indsæt den kopierede sti dér i absolute_path_of_configdir (ingen mellemrum) <br>
-5.  Gem crondump.pl <br>
-6. Kopiér crondump.pl, såvel som perltest.pl og simpletest.pl til cgi-bin folderen (ASCII-modus i ftp-klient!) <br>
-7. CHMOD scriptene til 755.  <br>
-7b. Hvis filtypen cgi foretrækkes omdøbes alle 3 filer pl - > cgi (rename)  <br>
-8.  Åbn i MySQLDumper siden Konfiguration<br>
-9. Klik på Cronscript <br>
-10. Ændr Perl udførelsessti til /cgi-bin/<br>
-10b. Hvis Scriptene er omdøbt til *.cgi , ændr Filtype til cgi <br>
-11 Gem Konfigurationen <br><br>
-
-Klar! Scriptene er tilgængelige fra siden "Backup" <br><br>
-
-Hvis du kan udføre Perl overalt, behøves kun følgende trin:  <br><br>
-
-1.  Åbn i MySQLDumper siden Backup.  <br>
-2.  Kopiér stien der står efter entry i crondump.pl for $absolute_path_of_configdir:    <br>
-3. Åbn filen "crondump.pl" i editoren <br>
-4. indsæt den kopierede sti dér i absolute_path_of_configdir (ingen mellemrum) <br>
-5.  Gem crondump.pl <br>
-6. CHMOD scriptene til 755.  <br> 
-6b. Hvis filtypen cgi foretrækkes omdøbes alle 3 filer pl - > cgi (rename)  <br>
-(evt. 10b+11 fra herover) <br><br>
-
-
-Windowsbrugere skal ændre første linie i alle Perlscripts til stien til Perl.  <br><br>
-
-Eksempel:  <br>
-
-i stedet for:  #!/usr/bin/perl w <br>
-bruges: #!C:\perl\bin\perl.exe w<br>
-
-<h4>Brug</h4><ul>
-
-<h6>Menu</h6>
-I den øverste valgboks vælges din database.<br>
-Alle handlinger refererer til denne database.
-
-<h6>Hjem</h6>
-Her ser du information om dit system, versionsnumre og detaljer om de konfigurerede databaser.<br>
-Hvis du klikker på en database i tabellen, får du en liste over tabeller med posttællere, størrelse og senest opdateret-stempel.
-
-<h6>Konfiguration</h6>
-Her kan du redigere din konfiguration, gemme den eller indlæse standardindstillingerne.
-<ul>
-	<li><a name="conf1"><strong>Konfigurerede Databaser:</strong> liste over konfigurerede databaser. Den aktive database er markeret fremhøvet.</li>
-	<li><a name="conf2"><strong>Tabel-Præfiks:</strong> du kan vælge et præfiks for hver database for sig. Præfikset er et filter, der kun håndterer de tabeller i et dump, som starter med dette præfiks (f.eks. alle tabeller startende med "phpBB_"). Hvis du ikke ønsker at bruge det, lad feltet være tomt.</li>
-	<li><a name="conf3"><strong>GZip-komprimering:</strong> Her kan du aktivere komprimering. Det anbefales at bruge komprimering grundet den mindre filstørrelse som dermed sluger mindre diskplads.</li>
-	<li><a name="conf19"></a><strong>Antal poster til backup:</strong> Dette er antallet af poster der læses samtidigt under backup, før scriptet kaldes igen. For langsommere servere kan du reducere dette parameter for at forhindre timeouts.</li>
-	<li><a name="conf20"></a><strong>Antal poster til genetablering:</strong> Dette er antallet af poster der læses samtidigt under backup, før scriptet kaldes igen. For langsommere servere kan du reducere dette parameter for at forhindre timeouts.</li>
-	<li><a name="conf4"></a><strong>Folder for Backupfiler:</strong> vælg din folder til backupfilerne. Hvis du vælger en ny, opretter scriptet den for dig. Du kan bruge relative eller absolutte stier.</li>
-	<li><a name="conf5"></a><strong>Send dumpfil som email:</strong> Når denne indstilling er slået til, vil scriptet automatisk sende den færdige backupfil som en email med vedhæftet fil (Forsigtig!, du bør bruge komprimering med denne indstilling da dumpfilen kan være for stor til email!)</li>
-	<li><a name="conf6"></a><strong>Email-adresse:</strong> Modtagers emailadresse</li>
-	<li><a name="conf7"></a><strong>Email emne:</strong> Emnet på emailen</li>
-	<li><a name="conf13"></a><strong>FTP-overførsel: </strong>Når denne indstilling er slået til sender scriptet automatisk den færdige backupfil via FTP.</li>
-	<li><a name="conf14"><strong>FTP-server: </strong>Adresse på FTP-serveren (e.g. ftp.mybackups.de)</li>
-	<li><a name="conf15"></a><strong>FTP-server port: </strong>port til FTP-serveren (normalt 21)</li>
-	<li><a name="conf16"></a><strong>FTP-bruger: </strong>brugernavnet til FTP-kontoent</li>
-	<li><a name="conf17"></a><strong>FTP-kodeord: </strong>kodeordet til FTP-kontoen</li>
-	<li><a name="conf18"></a><strong>FTP Upload-folder: </strong>folderen hvori backupfilen gemmes (der skal være skrive-rettigheder til folderen!)</li>
-	
-	<li><a name="conf8"></a><strong>Automatisk sletning af backups:</strong> Når du aktiverer denne indstilling, slettes backupfiler automatisk efter følgende regler.</li>
-	<li><a name="conf10"></a><strong>Slet ud fra antal filer:</strong> En værdi > 0 sletter alle filer pånær det givne antal</li>
-	<li><a name="conf11"></a><strong>Sprog:</strong> vælg dit sprog til brugerfladen.</li>
-</ul>
-
-<h6>Administration</h6>
-Alle handlinger listes op hér.<br>
-Du kan se alle filer i backupfolderen.
-For handlingerne "Genetabler" og "Slet" skal du vælge en fil først.
-<UL>
-	<li><strong>Genetabler:</strong> du genetablerer databasen med posterne fra den valgte backupfil.</li>
-	<li><strong>Slet:</strong> du kan slette den valgte backupfil.</li>
-	<li><strong>Start nyt Dump:</strong> her starter du en ny backup (dump) med dine konfigurerede parametre.</li>
-</UL>
-
-<h6>Log</h6>
-Du kan læse Log-indlæg og slette dem.
-
-<h6>Bidragsydere / Hjælp</h6>
-Denne side.
-</ul>
\ No newline at end of file
diff --git a/msd/language/da/lang.php b/msd/language/da/lang.php
index b63f547b..6487e8ff 100644
--- a/msd/language/da/lang.php
+++ b/msd/language/da/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="ja";
-$lang['L_TO']="til";
-$lang['L_ACTIVATED']="aktiveret";
-$lang['L_NOT_ACTIVATED']="ikke aktiveret";
-$lang['L_ERROR']="Fejl";
-$lang['L_OF']=" af ";
-$lang['L_ADDED']="tilføjet";
-$lang['L_DB']="Database";
-$lang['L_DBS']="Databaser";
-$lang['L_TABLES']="Tabeller";
-$lang['L_TABLE']="Tabel";
-$lang['L_RECORDS']="Poster";
-$lang['L_COMPRESSED']="komprimeret (gz)";
-$lang['L_NOTCOMPRESSED']="normal (ukomprimeret)";
-$lang['L_GENERAL']="generelt";
-$lang['L_COMMENT']="Kommentar";
-$lang['L_FILESIZE']="Filstørrelse";
-$lang['L_ALL']="alle";
-$lang['L_NONE']="ingen";
-$lang['L_WITH']=" med ";
-$lang['L_DIR']="Folder";
-$lang['L_RECHTE']="Tilladelser";
-$lang['L_STATUS']="Tilstand";
-$lang['L_FINISHED']="færdig";
-$lang['L_FILE']="Fil";
-$lang['L_FIELDS']="Felter";
-$lang['L_NEW']="ny";
-$lang['L_CHARSET']="Tegnsæt";
-$lang['L_COLLATION']="Kollation";
-$lang['L_CHANGE']="skift";
-$lang['L_IN']="i";
-$lang['L_DO']="Udfør";
-$lang['L_VIEW']="vis";
-$lang['L_EXISTING']="eksisterende";
-$lang['L_BACK']="tilbage";
-$lang['L_DB_HOST']="Hostnavn";
-$lang['L_DB_USER']="Bruger";
-$lang['L_DB_PASS']="Kodeord";
-$lang['L_INFO_SCRIPTDIR']="MySQLDumper folder";
-$lang['L_INFO_ACTDB']="Aktuel Database";
-$lang['L_WRONGCONNECTIONPARS']="Forkerte eller manglende forbindelsesparametre!";
-$lang['L_CONN_NOT_POSSIBLE']="Forbindelse ikke mulig !";
-$lang['L_SERVERCAPTION']="Vis Server";
-$lang['L_HELP_SERVERCAPTION']="Ved brug af MySQLDumper på forskellige domæner eller servere kan det være praktisk at vise domæne/server-navn i toppen af skærmen.";
-$lang['L_ACTIVATE_MULTIDUMP']="aktiver MultiDump";
-$lang['L_SAVE']="Gem";
-$lang['L_RESET']="Nulstil";
-$lang['L_PRAEFIX']="Tabelpræfiks";
-$lang['L_AUTODELETE']="Slet backups automatisk";
-$lang['L_MAX_BACKUP_FILES_EACH2']="For hver database";
-$lang['L_SAVING_DB_FORM']="Database";
-$lang['L_TESTCONNECTION']="Test forbindelse";
-$lang['L_BACK_TO_MINISQL']="Ret Database";
-$lang['L_CREATE']="Opret";
-$lang['L_VARIABELN']="Variabler";
-$lang['L_STATUSINFORMATIONEN']="Statusinformation";
-$lang['L_VERSIONSINFORMATIONEN']="Versionsinformation";
-$lang['L_MSD_INFO']="MyOOS [Dumper] Information";
-$lang['L_BACKUPFILESANZAHL']="I Backup folderen er ";
-$lang['L_LASTBACKUP']="Seneste Backup";
-$lang['L_NOTAVAIL']="<em>ikke tilgængelig</em>";
-$lang['L_VOM']="fra";
-$lang['L_MYSQLVARS']="MySQL Variabler";
-$lang['L_MYSQLSYS']="MySQL Kommandoer";
-$lang['L_STATUS']="Tilstand";
-$lang['L_PROZESSE']="Processer";
-$lang['L_INFO_NOVARS']="ingen variabler tilgængelige";
-$lang['L_INHALT']="Værdi";
-$lang['L_INFO_NOSTATUS']="ingen tilstand tilgængelig";
-$lang['L_INFO_NOPROCESSES']="ingen kørende processer";
-$lang['L_FM_FREESPACE']="Fri plads på Server";
-$lang['L_LOAD_DATABASE']="Genindlæs databaser";
-$lang['L_HOME']="Hjem";
-$lang['L_CONFIG']="Konfiguration";
-$lang['L_DUMP']="Backup";
-$lang['L_RESTORE']="Genetabler";
-$lang['L_FILE_MANAGE']="Fil Administration";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Vælg Database";
-$lang['L_CREDITS']="Bidragydere / Hjælp";
-$lang['L_MULTI_PART']="Multipart Backup";
-$lang['L_LOGFILENOTWRITABLE']="Kan ikke skrive Logfil !";
-$lang['L_SQL_ERROR1']="Fejl i forespørgsel:";
-$lang['L_SQL_ERROR2']="MySQL siger:";
-$lang['L_UNKNOWN']="ukendt";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="ukendt";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Log komplet output";
-$lang['L_NO']="nej";
-$lang['L_CREATE_DATABASE']="Opret ny database";
-$lang['L_EXPORTFINISHED']="Eksport færdiggjort.";
-$lang['L_SQL_BROWSER']="SQL-Browser";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Standard encoding of MySQL-Server";
-$lang['L_TITLE_SHOW_DATA']="Show data";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="Cancel";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Backups";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'ja';
+$lang['L_TO'] = 'til';
+$lang['L_ACTIVATED'] = 'aktiveret';
+$lang['L_NOT_ACTIVATED'] = 'ikke aktiveret';
+$lang['L_ERROR'] = 'Fejl';
+$lang['L_OF'] = ' af ';
+$lang['L_ADDED'] = 'tilføjet';
+$lang['L_DB'] = 'Database';
+$lang['L_DBS'] = 'Databaser';
+$lang['L_TABLES'] = 'Tabeller';
+$lang['L_TABLE'] = 'Tabel';
+$lang['L_RECORDS'] = 'Poster';
+$lang['L_COMPRESSED'] = 'komprimeret (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (ukomprimeret)';
+$lang['L_COMMENT'] = 'Kommentar';
+$lang['L_FILESIZE'] = 'Filstørrelse';
+$lang['L_ALL'] = 'alle';
+$lang['L_NONE'] = 'ingen';
+$lang['L_WITH'] = ' med ';
+$lang['L_DIR'] = 'Folder';
+$lang['L_RECHTE'] = 'Tilladelser';
+$lang['L_STATUS'] = 'Tilstand';
+$lang['L_FINISHED'] = 'færdig';
+$lang['L_FILE'] = 'Fil';
+$lang['L_FIELDS'] = 'Felter';
+$lang['L_NEW'] = 'ny';
+$lang['L_CHARSET'] = 'Tegnsæt';
+$lang['L_COLLATION'] = 'Kollation';
+$lang['L_CHANGE'] = 'skift';
+$lang['L_IN'] = 'i';
+$lang['L_DO'] = 'Udfør';
+$lang['L_VIEW'] = 'vis';
+$lang['L_EXISTING'] = 'eksisterende';
+$lang['L_BACK'] = 'tilbage';
+$lang['L_DB_HOST'] = 'Hostnavn';
+$lang['L_DB_USER'] = 'Bruger';
+$lang['L_DB_PASS'] = 'Kodeord';
+$lang['L_INFO_SCRIPTDIR'] = 'MyOOS [Dumper] folder';
+$lang['L_INFO_ACTDB'] = 'Aktuel Database';
+$lang['L_WRONGCONNECTIONPARS'] = 'Forkerte eller manglende forbindelsesparametre!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Forbindelse ikke mulig !';
+$lang['L_SERVERCAPTION'] = 'Vis Server';
+$lang['L_HELP_SERVERCAPTION'] = 'Ved brug af MyOOS [Dumper] på forskellige domæner eller servere kan det være praktisk at vise domæne/server-navn i toppen af skærmen.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'aktiver MultiDump';
+$lang['L_SAVE'] = 'Gem';
+$lang['L_RESET'] = 'Nulstil';
+$lang['L_PRAEFIX'] = 'Tabelpræfiks';
+$lang['L_AUTODELETE'] = 'Slet backups automatisk';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'For hver database';
+$lang['L_SAVING_DB_FORM'] = 'Database';
+$lang['L_TESTCONNECTION'] = 'Test forbindelse';
+$lang['L_BACK_TO_MINISQL'] = 'Ret Database';
+$lang['L_CREATE'] = 'Opret';
+$lang['L_VARIABELN'] = 'Variabler';
+$lang['L_STATUSINFORMATIONEN'] = 'Statusinformation';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versionsinformation';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] Information';
+$lang['L_BACKUPFILESANZAHL'] = 'I Backup folderen er ';
+$lang['L_LASTBACKUP'] = 'Seneste Backup';
+$lang['L_NOTAVAIL'] = '<em>ikke tilgængelig</em>';
+$lang['L_VOM'] = 'fra';
+$lang['L_MYSQLVARS'] = 'MySQL Variabler';
+$lang['L_MYSQLSYS'] = 'MySQL Kommandoer';
+$lang['L_STATUS'] = 'Tilstand';
+$lang['L_PROZESSE'] = 'Processer';
+$lang['L_INFO_NOVARS'] = 'ingen variabler tilgængelige';
+$lang['L_INHALT'] = 'Værdi';
+$lang['L_INFO_NOSTATUS'] = 'ingen tilstand tilgængelig';
+$lang['L_INFO_NOPROCESSES'] = 'ingen kørende processer';
+$lang['L_FM_FREESPACE'] = 'Fri plads på Server';
+$lang['L_LOAD_DATABASE'] = 'Genindlæs databaser';
+$lang['L_HOME'] = 'Hjem';
+$lang['L_CONFIG'] = 'Konfiguration';
+$lang['L_DUMP'] = 'Backup';
+$lang['L_RESTORE'] = 'Genetabler';
+$lang['L_FILE_MANAGE'] = 'Fil Administration';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Vælg Database';
+$lang['L_CREDITS'] = 'Bidragydere / Hjælp';
+$lang['L_MULTI_PART'] = 'Multipart Backup';
+$lang['L_LOGFILENOTWRITABLE'] = 'Kan ikke skrive Logfil !';
+$lang['L_SQL_ERROR1'] = 'Fejl i forespørgsel:';
+$lang['L_SQL_ERROR2'] = 'MySQL siger:';
+$lang['L_UNKNOWN'] = 'ukendt';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'ukendt';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Log komplet output';
+$lang['L_NO'] = 'nej';
+$lang['L_CREATE_DATABASE'] = 'Opret ny database';
+$lang['L_EXPORTFINISHED'] = 'Eksport færdiggjort.';
+$lang['L_SQL_BROWSER'] = 'SQL-Browser';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Standard encoding of MySQL-Server';
+$lang['L_TITLE_SHOW_DATA'] = 'Show data';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'Cancel';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Backups';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/da/lang_config_overview.php b/msd/language/da/lang_config_overview.php
index 2890e444..fc718256 100644
--- a/msd/language/da/lang_config_overview.php
+++ b/msd/language/da/lang_config_overview.php
@@ -1,110 +1,131 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Konfiguration";
-$lang['L_SAVE_SUCCESS']="Configuration was saved succesfully into configuration file \"%s\".";
-$lang['L_CONFIG_LOADED']="Configuration \"%s\" has been imported successfully.";
-$lang['L_SAVE_ERROR']="Fejl - kunne ikke gemme konfiguration!";
-$lang['L_CONFIG_EMAIL']="Email-notifikation";
-$lang['L_CONFIG_AUTODELETE']="Autoslet";
-$lang['L_CONFIG_INTERFACE']="Brugerflade";
-$lang['L_MULTI_PART_GROESSE']="maksimum Filstørrelse";
-$lang['L_HELP_MULTIPART']="Hvis Multipart er slået til skaber Backup flere Backupfiler, hver med maksimalstørrelsen angivet i konfigurationen herunder";
-$lang['L_HELP_MULTIPARTGROESSE']="Maksimal størrelse på enkelte backupfiler defineres hér, hvis Multipart er slået til";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Slet tabeller før genetablering";
-$lang['L_ALLPARS']="Alle parametre";
-$lang['L_CRON_EXTENDER']="Filtype";
-$lang['L_CRON_SAVEPATH']="Konfigurationsfil";
-$lang['L_CRON_PRINTOUT']="Udskriv output til skærmen.";
-$lang['L_CONFIG_CRONPERL']="Crondump-indstillinger til Perl-script";
-$lang['L_CRON_MAILPRG']="Mailprogram";
-$lang['L_OPTIMIZE']="Optimér tabeller før backup";
-$lang['L_HELP_OPTIMIZE']="Hvis denne indstilling er aktiveret, optimeres alle tabeller før backup";
-$lang['L_HELP_FTPTIMEOUT']="Standardindstilling for Timeout er 90 sekunder.";
-$lang['L_FTP_TIMEOUT']="Forbindelses Timeout";
-$lang['L_HELP_FTPSSL']="Vælg om forbindelsen skal etableres via SSL.";
-$lang['L_CONFIG_ASKLOAD']="Vil du erstatte de nuværende indstillinger med standardindstillingerne?";
-$lang['L_LOAD']="Indlæs standard-indstillinger";
-$lang['L_LOAD_SUCCESS']="Standardindstillingerne blev indlæst.";
-$lang['L_CRON_CRONDBINDEX']="Database";
-$lang['L_WITHATTACH']=" med vedhæftede";
-$lang['L_WITHOUTATTACH']=" uden vedhæftede";
-$lang['L_MULTIDUMPCONF']="=Multidump konfiguration=";
-$lang['L_MULTIDUMPALL']="=alle databaser=";
-$lang['L_GZIP']="GZip-komprimering";
-$lang['L_SEND_MAIL_FORM']="Send email rapport";
-$lang['L_SEND_MAIL_DUMP']="Vedhæft backup";
-$lang['L_EMAIL_ADRESS']="Emailadresse";
-$lang['L_EMAIL_SENDER']="Afsenderadresse på emailen";
-$lang['L_EMAIL_MAXSIZE']="Maksimumstørrelse på vedhæftede";
-$lang['L_NUMBER_OF_FILES_FORM']="Slet ud fra antal filer";
-$lang['L_LANGUAGE']="Sprog";
-$lang['L_LIST_DB']="Konfigurerede databaser:";
-$lang['L_CONFIG_FTP']="FTP-overførsel af Backupfil";
-$lang['L_FTP_TRANSFER']="FTP-overførsel";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="Bruger";
-$lang['L_FTP_PASS']="Kodeord";
-$lang['L_FTP_DIR']="Upload-folder";
-$lang['L_FTP_SSL']="Sikker SSL FTP-forbindelse";
-$lang['L_FTP_USESSL']="brug SSL-forbindelse";
-$lang['L_SQLBOXHEIGHT']="Højde på SQL-Boks";
-$lang['L_SQLLIMIT']="Antal poster pr. side";
-$lang['L_BBPARAMS']="Konfiguration for BB-kode";
-$lang['L_BBTEXTCOLOR']="Tekstfarve";
-$lang['L_HELP_COMMANDS']="Du kan udføre en kommando før og efter backup.
-Denne kommando kan være en SQL-konstruktion eller en Systemkommando (f.eks. et script)";
-$lang['L_COMMAND']="Kommando";
-$lang['L_WRONG_CONNECTIONPARS']="Forbindelsesparametre er forkerte!";
-$lang['L_CONNECTIONPARS']="Forbindelsesparametre";
-$lang['L_EXTENDEDPARS']="Udvidede parametre";
-$lang['L_FADE_IN_OUT']="Visning til/fra";
-$lang['L_DB_BACKUPPARS']="Database backupparametre";
-$lang['L_GENERAL']="Generelt";
-$lang['L_MAXSIZE']="maks. størrelse";
-$lang['L_ERRORHANDLING_RESTORE']="Fejlhandling under genetablering";
-$lang['L_EHRESTORE_CONTINUE']="fortsæt og log fejl";
-$lang['L_EHRESTORE_STOP']="stop";
-$lang['L_IN_MAINFRAME']="i hovedramme";
-$lang['L_IN_LEFTFRAME']="i venstre ramme";
-$lang['L_WIDTH']="Bredde";
-$lang['L_SQL_BEFEHLE']="SQL-kommandoer";
-$lang['L_DOWNLOAD_LANGUAGES']="download andre sprog";
-$lang['L_DOWNLOAD_STYLES']="download andre temaer";
-$lang['L_CONNECT_TO']="forbind med";
-$lang['L_CHANGEDIR']="Skifter til folder";
-$lang['L_CHANGEDIRERROR']="Kunne ikke skifte folder!";
-$lang['L_FTP_OK']="Forbindelse etableret.";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="Du har ingen FTP-funktioner !";
-$lang['L_FOUND_DB']="fundet db";
-$lang['L_FTP_CHOOSE_MODE']="FTP-overførselstilstand";
-$lang['L_FTP_PASSIVE']="brug passiv-tilstand";
-$lang['L_HELP_FTP_MODE']="Vælg passiv tilstand hvis der opstår problemer ved brug af aktiv tilstand.";
-$lang['L_DB_IN_LIST']="Databasen '%s' kunne ikke tilføjes da den allerede findes.";
-$lang['L_ADD_DB_MANUALLY']="Opret manuelt database";
-$lang['L_DB_MANUAL_ERROR']="Beklager, kunne ikke forbinde til database '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Fil-fejl: kunne ikke tilføje database '%s'!";
-$lang['L_NO_DB_FOUND']="kunne ikke automatisk finde nogen database! Åbn forbindelsesparametrene og indtast manuelt navnet på databasen.";
-$lang['L_CONFIGFILES']="Configuration Files";
-$lang['L_CONFIGFILE']="Config File";
-$lang['L_MYSQL_DATA']="MySQL-Data";
-$lang['L_CONFIGURATIONS']="Configurations";
-$lang['L_ACTION']="Action";
-$lang['L_FTP_SEND_TO']="to <strong>%s</strong><br> into <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Receiver";
-$lang['L_NAME']="Name";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Really delete the configuration file %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Error: couldn't delete configuration file %s!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="The configuration file %s has successfully been deleted.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Configuration file %s has successfully been created.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Filename \"%s\" contains invalid characters.";
-$lang['L_CREATE_CONFIGFILE']="Create a new configuration file";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Couldn't load configfile \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="DBs to backup (PHP)";
-$lang['L_BACKUP_DBS_PERL']="DBs to backup (PERL)";
-$lang['L_CRON_COMMENT']="Indtast kommentar";
-$lang['L_AUTODETECT']="auto detect";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Konfiguration';
+$lang['L_SAVE_SUCCESS'] = 'Configuration was saved succesfully into configuration file "%s".';
+$lang['L_CONFIG_LOADED'] = 'Configuration "%s" has been imported successfully.';
+$lang['L_SAVE_ERROR'] = 'Fejl - kunne ikke gemme konfiguration!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Email-notifikation';
+$lang['L_CONFIG_AUTODELETE'] = 'Autoslet';
+$lang['L_CONFIG_INTERFACE'] = 'Brugerflade';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'maksimum Filstørrelse';
+$lang['L_HELP_MULTIPART'] = 'Hvis Multipart er slået til skaber Backup flere Backupfiler, hver med maksimalstørrelsen angivet i konfigurationen herunder';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Maksimal størrelse på enkelte backupfiler defineres hér, hvis Multipart er slået til';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Slet tabeller før genetablering';
+$lang['L_ALLPARS'] = 'Alle parametre';
+$lang['L_CRON_EXTENDER'] = 'Filtype';
+$lang['L_CRON_SAVEPATH'] = 'Konfigurationsfil';
+$lang['L_CRON_PRINTOUT'] = 'Udskriv output til skærmen.';
+$lang['L_CONFIG_CRONPERL'] = 'Crondump-indstillinger til Perl-script';
+$lang['L_CRON_MAILPRG'] = 'Mailprogram';
+$lang['L_OPTIMIZE'] = 'Optimér tabeller før backup';
+$lang['L_HELP_OPTIMIZE'] = 'Hvis denne indstilling er aktiveret, optimeres alle tabeller før backup';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'Standardindstilling for Timeout er 90 sekunder.';
+$lang['L_FTP_TIMEOUT'] = 'Forbindelses Timeout';
+$lang['L_HELP_FTPSSL'] = 'Vælg om forbindelsen skal etableres via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Forbindelses Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Vælg om forbindelsen skal etableres via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Forbindelses Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Vælg om forbindelsen skal etableres via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Forbindelses Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Vælg om forbindelsen skal etableres via SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'Vil du erstatte de nuværende indstillinger med standardindstillingerne?';
+$lang['L_LOAD'] = 'Indlæs standard-indstillinger';
+$lang['L_LOAD_SUCCESS'] = 'Standardindstillingerne blev indlæst.';
+$lang['L_CRON_CRONDBINDEX'] = 'Database';
+$lang['L_WITHATTACH'] = ' med vedhæftede';
+$lang['L_WITHOUTATTACH'] = ' uden vedhæftede';
+$lang['L_MULTIDUMPCONF'] = '=Multidump konfiguration=';
+$lang['L_MULTIDUMPALL'] = '=alle databaser=';
+$lang['L_GZIP'] = 'GZip-komprimering';
+$lang['L_SEND_MAIL_FORM'] = 'Send email rapport';
+$lang['L_SEND_MAIL_DUMP'] = 'Vedhæft backup';
+$lang['L_EMAIL_ADRESS'] = 'Emailadresse';
+$lang['L_EMAIL_SENDER'] = 'Afsenderadresse på emailen';
+$lang['L_EMAIL_MAXSIZE'] = 'Maksimumstørrelse på vedhæftede';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Slet ud fra antal filer';
+$lang['L_LANGUAGE'] = 'Sprog';
+$lang['L_LIST_DB'] = 'Konfigurerede databaser:';
+$lang['L_CONFIG_FTP'] = 'FTP-overførsel af Backupfil';
+$lang['L_FTP_TRANSFER'] = 'FTP-overførsel';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'Bruger';
+$lang['L_FTP_PASS'] = 'Kodeord';
+$lang['L_FTP_DIR'] = 'Upload-folder';
+$lang['L_FTP_SSL'] = 'Sikker SSL FTP-forbindelse';
+$lang['L_FTP_USESSL'] = 'brug SSL-forbindelse';
+$lang['L_CONFIG_SFTP'] = 'SFTP-overførsel af Backupfil';
+$lang['L_SFTP_TRANSFER'] = 'SFTP-overførsel';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'Bruger';
+$lang['L_SFTP_PASS'] = 'Kodeord';
+$lang['L_SFTP_DIR'] = 'Upload-folder';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Højde på SQL-Boks';
+$lang['L_SQLLIMIT'] = 'Antal poster pr. side';
+$lang['L_BBPARAMS'] = 'Konfiguration for BB-kode';
+$lang['L_BBTEXTCOLOR'] = 'Tekstfarve';
+$lang['L_HELP_COMMANDS'] = 'Du kan udføre en kommando før og efter backup.
+Denne kommando kan være en SQL-konstruktion eller en Systemkommando (f.eks. et script)';
+$lang['L_COMMAND'] = 'Kommando';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Forbindelsesparametre er forkerte!';
+$lang['L_CONNECTIONPARS'] = 'Forbindelsesparametre';
+$lang['L_EXTENDEDPARS'] = 'Udvidede parametre';
+$lang['L_FADE_IN_OUT'] = 'Visning til/fra';
+$lang['L_DB_BACKUPPARS'] = 'Database backupparametre';
+$lang['L_GENERAL'] = 'Generelt';
+$lang['L_MAXSIZE'] = 'maks. størrelse';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Fejlhandling under genetablering';
+$lang['L_EHRESTORE_CONTINUE'] = 'fortsæt og log fejl';
+$lang['L_EHRESTORE_STOP'] = 'stop';
+$lang['L_IN_MAINFRAME'] = 'i hovedramme';
+$lang['L_IN_LEFTFRAME'] = 'i venstre ramme';
+$lang['L_WIDTH'] = 'Bredde';
+$lang['L_SQL_BEFEHLE'] = 'SQL-kommandoer';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'download andre sprog';
+$lang['L_DOWNLOAD_STYLES'] = 'download andre temaer';
+$lang['L_CONNECT_TO'] = 'forbind med';
+$lang['L_CHANGEDIR'] = 'Skifter til folder';
+$lang['L_CHANGEDIRERROR'] = 'Kunne ikke skifte folder!';
+$lang['L_FTP_OK'] = 'Forbindelse etableret.';
+$lang['L_SFTP_OK'] = 'Forbindelse etableret.';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = 'Du har ingen FTP-funktioner !';
+$lang['L_FOUND_DB'] = 'fundet db';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP-overførselstilstand';
+$lang['L_FTP_PASSIVE'] = 'brug passiv-tilstand';
+$lang['L_HELP_FTP_MODE'] = 'Vælg passiv tilstand hvis der opstår problemer ved brug af aktiv tilstand.';
+$lang['L_SFTP_PASSIVE'] = 'brug passiv-tilstand';
+$lang['L_DB_IN_LIST'] = "Databasen '%s' kunne ikke tilføjes da den allerede findes.";
+$lang['L_ADD_DB_MANUALLY'] = 'Opret manuelt database';
+$lang['L_DB_MANUAL_ERROR'] = "Beklager, kunne ikke forbinde til database '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Fil-fejl: kunne ikke tilføje database '%s'!";
+$lang['L_NO_DB_FOUND'] = 'kunne ikke automatisk finde nogen database! Åbn forbindelsesparametrene og indtast manuelt navnet på databasen.';
+$lang['L_CONFIGFILES'] = 'Configuration Files';
+$lang['L_CONFIGFILE'] = 'Config File';
+$lang['L_MYSQL_DATA'] = 'MySQL-Data';
+$lang['L_CONFIGURATIONS'] = 'Configurations';
+$lang['L_ACTION'] = 'Action';
+$lang['L_FTP_SEND_TO'] = 'to <strong>%s</strong><br> into <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Receiver';
+$lang['L_NAME'] = 'Name';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Really delete the configuration file %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = "Error: couldn't delete configuration file %s!";
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'The configuration file %s has successfully been deleted.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Configuration file %s has successfully been created.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Filename "%s" contains invalid characters.';
+$lang['L_CREATE_CONFIGFILE'] = 'Create a new configuration file';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = "Couldn't load configfile \"%s\".";
+$lang['L_BACKUP_DBS_PHP'] = 'DBs to backup (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'DBs to backup (PERL)';
+$lang['L_CRON_COMMENT'] = 'Indtast kommentar';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/da/lang_dump.php b/msd/language/da/lang_dump.php
index 46c14ab9..a8a958a4 100644
--- a/msd/language/da/lang_dump.php
+++ b/msd/language/da/lang_dump.php
@@ -1,60 +1,61 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Lav backup...";
-$lang['L_GZIP_COMPRESSION']="GZip-komprimering";
-$lang['L_SAVING_TABLE']="Gemmer tabel ";
-$lang['L_OF']="af";
-$lang['L_ACTUAL_TABLE']="Aktuel tabel";
-$lang['L_PROGRESS_TABLE']="Fremskridt i tabel";
-$lang['L_PROGRESS_OVER_ALL']="Samlet fremskridt";
-$lang['L_ENTRY']="Indlæg";
-$lang['L_DONE']="Færdig!";
-$lang['L_DUMP_SUCCESSFUL']=" blev fremstillet korrekt.";
-$lang['L_UPTO']="op til";
-$lang['L_EMAIL_WAS_SEND']="Email blev korrekt sendt til ";
-$lang['L_BACK_TO_CONTROL']="Fortsæt";
-$lang['L_BACK_TO_OVERVIEW']="Databaseoversigt";
-$lang['L_DUMP_FILENAME']="Backup Fil: ";
-$lang['L_WITHPRAEFIX']="med præfiks";
-$lang['L_DUMP_NOTABLES']="Ingen tabeller fundet i database `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="Filen indeholder <b>%s</b> tabeller med <b>%s</b> poster.<br>";
-$lang['L_MAILERROR']="Afsendelse af email slog fejl!";
-$lang['L_EMAILBODY_ATTACH']="Den vedhæftede fil indeholder backup af din MySQL-Database.<br>Backup af Database `%s`
-<br><br>Følgende fil blev oprettet:<br><br>%s <br><br>Venlig hilsen<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="En Multipart Backup blev oprettet.<br>Backupfilerne er ikke vedhæftet denne email!<br>Backup af Database `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'Lav backup...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip-komprimering';
+$lang['L_SAVING_TABLE'] = 'Gemmer tabel ';
+$lang['L_OF'] = 'af';
+$lang['L_ACTUAL_TABLE'] = 'Aktuel tabel';
+$lang['L_PROGRESS_TABLE'] = 'Fremskridt i tabel';
+$lang['L_PROGRESS_OVER_ALL'] = 'Samlet fremskridt';
+$lang['L_ENTRY'] = 'Indlæg';
+$lang['L_DONE'] = 'Færdig!';
+$lang['L_DUMP_SUCCESSFUL'] = ' blev fremstillet korrekt.';
+$lang['L_UPTO'] = 'op til';
+$lang['L_EMAIL_WAS_SEND'] = 'Email blev korrekt sendt til ';
+$lang['L_BACK_TO_CONTROL'] = 'Fortsæt';
+$lang['L_BACK_TO_OVERVIEW'] = 'Databaseoversigt';
+$lang['L_DUMP_FILENAME'] = 'Backup Fil: ';
+$lang['L_WITHPRAEFIX'] = 'med præfiks';
+$lang['L_DUMP_NOTABLES'] = 'Ingen tabeller fundet i database `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = 'Filen indeholder <b>%s</b> tabeller med <b>%s</b> poster.<br>';
+$lang['L_MAILERROR'] = 'Afsendelse af email slog fejl!';
+$lang['L_EMAILBODY_ATTACH'] = 'Den vedhæftede fil indeholder backup af din MySQL-Database.<br>Backup af Database `%s`
+<br><br>Følgende fil blev oprettet:<br><br>%s <br><br>Venlig hilsen<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'En Multipart Backup blev oprettet.<br>Backupfilerne er ikke vedhæftet denne email!<br>Backup af Database `%s`
 <br><br>Følgende filer blev oprettet:<br><br>%s
-<br><br>Venlig hilsen<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="En Multipart Backup er blevet oprettet.<br>Backupfilerne er vedhæftet separate emails.<br>Backup af Database `%s`
-<br><br>Følgende filer blev oprettet:<br><br>%s <br><br>Med venlig hilsen<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br>Venlig hilsen<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="Backupfilen oversteg maksimumstørrelsen på %s og blev ikke vedhæftet denne email.<br>Backup sf Database `%s`
+<br><br>Venlig hilsen<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'En Multipart Backup er blevet oprettet.<br>Backupfilerne er vedhæftet separate emails.<br>Backup af Database `%s`
+<br><br>Følgende filer blev oprettet:<br><br>%s <br><br>Med venlig hilsen<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br>Venlig hilsen<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Backupfilen oversteg maksimumstørrelsen på %s og blev ikke vedhæftet denne email.<br>Backup sf Database `%s`
 <br><br>Følgende fil blev oprettet:<br><br>%s
-<br><br>Venlig hilsen<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Filer er ikke vedhæftet denne email!<br>Backup af Database `%s`
+<br><br>Venlig hilsen<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Filer er ikke vedhæftet denne email!<br>Backup af Database `%s`
 <br><br>Følgende fil blev oprettet:<br><br>%s
-<br><br>Venlig hilsen<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... kun vedhæftet.";
-$lang['L_TABLESELECTION']="Tabelvælg";
-$lang['L_SELECTALL']="Vælg alle";
-$lang['L_DESELECTALL']="Fravælg alle";
-$lang['L_STARTDUMP']="Start Backup";
-$lang['L_LASTBUFROM']="sidst opdateret fra";
-$lang['L_NOT_SUPPORTED']="Denne backup understøtter ikke denne funktion.";
-$lang['L_MULTIDUMP']="Multidump: Backup af <b>%d</b> Databaser færdige.";
-$lang['L_FILESENDFTP']="send fil via FTP... vær venligst tålmodig. ";
-$lang['L_FTPCONNERROR']="FTP-forbindelse ikke etableret! Forbind med ";
-$lang['L_FTPCONNERROR1']=" som bruger ";
-$lang['L_FTPCONNERROR2']=" ikke muligt";
-$lang['L_FTPCONNERROR3']="FTP-upload fejlede! ";
-$lang['L_FTPCONNECTED1']="Forbundet med ";
-$lang['L_FTPCONNECTED2']=" på ";
-$lang['L_FTPCONNECTED3']=" overførsel korrekt gennemført";
-$lang['L_NR_TABLES_SELECTED']="- med %s valgte tabeller";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tabeller er blevet optimeret.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s fejl optrådte: <a href=\"log.php?r=3\">se log</a></p>
+<br><br>Venlig hilsen<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... kun vedhæftet.';
+$lang['L_TABLESELECTION'] = 'Tabelvælg';
+$lang['L_SELECTALL'] = 'Vælg alle';
+$lang['L_DESELECTALL'] = 'Fravælg alle';
+$lang['L_STARTDUMP'] = 'Start Backup';
+$lang['L_LASTBUFROM'] = 'sidst opdateret fra';
+$lang['L_NOT_SUPPORTED'] = 'Denne backup understøtter ikke denne funktion.';
+$lang['L_MULTIDUMP'] = 'Multidump: Backup af <b>%d</b> Databaser færdige.';
+$lang['L_FILESENDFTP'] = 'send fil via FTP... vær venligst tålmodig. ';
+$lang['L_FTPCONNERROR'] = 'FTP-forbindelse ikke etableret! Forbind med ';
+$lang['L_FTPCONNERROR1'] = ' som bruger ';
+$lang['L_FTPCONNERROR2'] = ' ikke muligt';
+$lang['L_FTPCONNERROR3'] = 'FTP-upload fejlede! ';
+$lang['L_FTPCONNECTED1'] = 'Forbundet med ';
+$lang['L_FTPCONNECTED2'] = ' på ';
+$lang['L_FTPCONNECTED3'] = ' overførsel korrekt gennemført';
+$lang['L_FILESENDSFTP'] = 'send fil via SFTP... vær venligst tålmodig. ';
+$lang['L_SFTPCONNERROR'] = 'SFTP-forbindelse ikke etableret! Forbind med ';
+$lang['L_NR_TABLES_SELECTED'] = '- med %s valgte tabeller';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tabeller er blevet optimeret.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s fejl optrådte: <a href="log.php?r=3">se log</a></p>
 
 
-";
-$lang['L_FATAL_ERROR_DUMP']="Fatal error: the CREATE-Statement of table '%s' in database '%s' couldn't be read!";
-
-
-?>
\ No newline at end of file
+';
+$lang['L_FATAL_ERROR_DUMP'] = "Fatal error: the CREATE-Statement of table '%s' in database '%s' couldn't be read!";
diff --git a/msd/language/da/lang_filemanagement.php b/msd/language/da/lang_filemanagement.php
index 1deacca5..9c2f122d 100644
--- a/msd/language/da/lang_filemanagement.php
+++ b/msd/language/da/lang_filemanagement.php
@@ -1,79 +1,79 @@
 <?php
-$lang['L_CONVERT_START']="Start konvertering";
-$lang['L_CONVERT_TITLE']="Konvertér dump til MSD-format";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Forkerte parametre!  Konvertering er ikke muligt.";
-$lang['L_FM_UPLOADFILEREQUEST']="vælg venligst en fil.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Denne filtype understøttes ikke.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Gyldige typer er: *.gz og *.sql-filer";
-$lang['L_FM_UPLOADMOVEERROR']="Kunne ikke flytte valgte fil til upload folderen.";
-$lang['L_FM_UPLOADFAILED']="Upload slog fejl!";
-$lang['L_FM_UPLOADFILEEXISTS']="Der findes allerede en fil med samme navn!";
-$lang['L_FM_NOFILE']="Du valgte ikke en fil!";
-$lang['L_FM_DELETE1']="Filen ";
-$lang['L_FM_DELETE2']=" blev slettet korrekt.";
-$lang['L_FM_DELETE3']=" kunne ikke slettes!";
-$lang['L_FM_CHOOSE_FILE']="Valgt fil:";
-$lang['L_FM_FILESIZE']="Filstørrelse";
-$lang['L_FM_FILEDATE']="Fildato";
-$lang['L_FM_NOFILESFOUND']="Ingen fil fundet.";
-$lang['L_FM_TABLES']="Tabeller";
-$lang['L_FM_RECORDS']="Poster";
-$lang['L_FM_ALL_BU']="Alle backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="Seneste backup";
-$lang['L_FM_TOTALSIZE']="Total størrelse";
-$lang['L_FM_SELECTTABLES']="Vælg tabeller";
-$lang['L_FM_COMMENT']="Indtast kommentar";
-$lang['L_FM_RESTORE']="Genetabler";
-$lang['L_FM_ALERTRESTORE1']="Skal databasen";
-$lang['L_FM_ALERTRESTORE2']="genetableres med posterne fra filen";
-$lang['L_FM_ALERTRESTORE3']=" ?";
-$lang['L_FM_DELETE']="Slet";
-$lang['L_FM_ASKDELETE1']="Skal filen ";
-$lang['L_FM_ASKDELETE2']="virkelig slettes?";
-$lang['L_FM_ASKDELETE3']="Vil du køre autoslet med de konfigurerede regler nu?";
-$lang['L_FM_ASKDELETE4']="Vil du slette alle backupfiler?";
-$lang['L_FM_ASKDELETE5']="Vil du slette alle backupfiler med ";
-$lang['L_FM_ASKDELETE5_2']="_* ?";
-$lang['L_FM_DELETEAUTO']="Kør autoslet manuelt";
-$lang['L_FM_DELETEALL']="Slette alle backupfiler";
-$lang['L_FM_DELETEALLFILTER']="Slet alle med ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Start ny backup";
-$lang['L_FM_FILEUPLOAD']="Upload fil";
-$lang['L_FM_DBNAME']="Databasenavn";
-$lang['L_FM_FILES1']="Databasebackups";
-$lang['L_FM_FILES2']="Databasestrukturer";
-$lang['L_FM_AUTODEL1']="Autoslet: følgende filer blev slettet grundet maksimalt antal filer-indstillingen:";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="Konfiguration for Perl Cron scriptet";
-$lang['L_FM_OLDBACKUP']="(ukendt)";
-$lang['L_FM_RESTORE_HEADER']="Genetablering af Database \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Kør Perl Cron scriptet";
-$lang['L_DOPERLTEST']="Test Perl-moduler";
-$lang['L_DOSIMPLETEST']="Test Perl";
-$lang['L_PERLOUTPUT1']="Linie i crondump.pl for absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="URL for browseren eller for eksternt Cron job";
-$lang['L_PERLOUTPUT3']="Kommandolinie i Shell eller for Crontab";
-$lang['L_RESTORE_OF_TABLES']="Choose tables to be restored";
-$lang['L_CONVERTER']="Backupkonvertering";
-$lang['L_CONVERT_FILE']="Fil der skal konverteres";
-$lang['L_CONVERT_FILENAME']="Navn på destinationsfilen (uden filtype)";
-$lang['L_CONVERTING']="Konverterer";
-$lang['L_CONVERT_FILEREAD']="Læs fil '%s'";
-$lang['L_CONVERT_FINISHED']="Konvertering afsluttet, '%s' blev skrevet korrekt.";
-$lang['L_NO_MSD_BACKUPFILE']="Backups af andre scripts";
-$lang['L_MAX_UPLOAD_SIZE']="Maksimal filstørrelse";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Hvis din Dumpfil er større end den ovennævnte grænse, skal du uploade den via FTP til folderen \"work/backup\".
-Derefter kan du vælge den og begynde genetableringsprocessen.";
-$lang['L_ENCODING']="encoding";
-$lang['L_FM_CHOOSE_ENCODING']="Choose encoding of backup file";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper couldn't detect the encoding of the backup file automatically.
+
+$lang['L_CONVERT_START'] = 'Start konvertering';
+$lang['L_CONVERT_TITLE'] = 'Konvertér dump til MOD-format';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Forkerte parametre!  Konvertering er ikke muligt.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'vælg venligst en fil.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Denne filtype understøttes ikke.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Gyldige typer er: *.gz og *.sql-filer';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Kunne ikke flytte valgte fil til upload folderen.';
+$lang['L_FM_UPLOADFAILED'] = 'Upload slog fejl!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Der findes allerede en fil med samme navn!';
+$lang['L_FM_NOFILE'] = 'Du valgte ikke en fil!';
+$lang['L_FM_DELETE1'] = 'Filen ';
+$lang['L_FM_DELETE2'] = ' blev slettet korrekt.';
+$lang['L_FM_DELETE3'] = ' kunne ikke slettes!';
+$lang['L_FM_CHOOSE_FILE'] = 'Valgt fil:';
+$lang['L_FM_FILESIZE'] = 'Filstørrelse';
+$lang['L_FM_FILEDATE'] = 'Fildato';
+$lang['L_FM_NOFILESFOUND'] = 'Ingen fil fundet.';
+$lang['L_FM_TABLES'] = 'Tabeller';
+$lang['L_FM_RECORDS'] = 'Poster';
+$lang['L_FM_ALL_BU'] = 'Alle backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'Seneste backup';
+$lang['L_FM_TOTALSIZE'] = 'Total størrelse';
+$lang['L_FM_SELECTTABLES'] = 'Vælg tabeller';
+$lang['L_FM_COMMENT'] = 'Indtast kommentar';
+$lang['L_FM_RESTORE'] = 'Genetabler';
+$lang['L_FM_ALERTRESTORE1'] = 'Skal databasen';
+$lang['L_FM_ALERTRESTORE2'] = 'genetableres med posterne fra filen';
+$lang['L_FM_ALERTRESTORE3'] = ' ?';
+$lang['L_FM_DELETE'] = 'Slet';
+$lang['L_FM_ASKDELETE1'] = 'Skal filen ';
+$lang['L_FM_ASKDELETE2'] = 'virkelig slettes?';
+$lang['L_FM_ASKDELETE3'] = 'Vil du køre autoslet med de konfigurerede regler nu?';
+$lang['L_FM_ASKDELETE4'] = 'Vil du slette alle backupfiler?';
+$lang['L_FM_ASKDELETE5'] = 'Vil du slette alle backupfiler med ';
+$lang['L_FM_ASKDELETE5_2'] = '_* ?';
+$lang['L_FM_DELETEAUTO'] = 'Kør autoslet manuelt';
+$lang['L_FM_DELETEALL'] = 'Slette alle backupfiler';
+$lang['L_FM_DELETEALLFILTER'] = 'Slet alle med ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Start ny backup';
+$lang['L_FM_FILEUPLOAD'] = 'Upload fil';
+$lang['L_FM_DBNAME'] = 'Databasenavn';
+$lang['L_FM_FILES1'] = 'Databasebackups';
+$lang['L_FM_FILES2'] = 'Databasestrukturer';
+$lang['L_FM_AUTODEL1'] = 'Autoslet: følgende filer blev slettet grundet maksimalt antal filer-indstillingen:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'Konfiguration for Perl Cron scriptet';
+$lang['L_FM_OLDBACKUP'] = '(ukendt)';
+$lang['L_FM_RESTORE_HEADER'] = 'Genetablering af Database "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Kør Perl Cron scriptet';
+$lang['L_DOPERLTEST'] = 'Test Perl-moduler';
+$lang['L_DOSIMPLETEST'] = 'Test Perl';
+$lang['L_PERLOUTPUT1'] = 'Linie i crondump.pl for absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'URL for browseren eller for eksternt Cron job';
+$lang['L_PERLOUTPUT3'] = 'Kommandolinie i Shell eller for Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Choose tables to be restored';
+$lang['L_CONVERTER'] = 'Backupkonvertering';
+$lang['L_CONVERT_FILE'] = 'Fil der skal konverteres';
+$lang['L_CONVERT_FILENAME'] = 'Navn på destinationsfilen (uden filtype)';
+$lang['L_CONVERTING'] = 'Konverterer';
+$lang['L_CONVERT_FILEREAD'] = "Læs fil '%s'";
+$lang['L_CONVERT_FINISHED'] = "Konvertering afsluttet, '%s' blev skrevet korrekt.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Backups af andre scripts';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maksimal filstørrelse';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Hvis din Dumpfil er større end den ovennævnte grænse, skal du uploade den via FTP til folderen "work/backup".
+Derefter kan du vælge den og begynde genetableringsprocessen.';
+$lang['L_ENCODING'] = 'encoding';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Choose encoding of backup file';
+$lang['L_CHOOSE_CHARSET'] = "MyOOS [Dumper] couldn't detect the encoding of the backup file automatically.
 <br>You must choose the charset with which this backup was saved.
 <br>If you discover any problems with some characters after restoring, you can repeat the backup-progress and then choose another character set.
 <br>Good luck. ;)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/da/lang_help.php b/msd/language/da/lang_help.php
index e802ebba..46b0bd7f 100644
--- a/msd/language/da/lang_help.php
+++ b/msd/language/da/lang_help.php
@@ -1,36 +1,40 @@
 <?php
-$lang['L_HELP_DB']="Dette er listen over alle Databaser";
-$lang['L_HELP_PRAEFIX']="præfikset er en streng i begyndelsen af et tabelnavn, hvilket kan bruges som et filter.";
-$lang['L_HELP_ZIP']="Komprimering med GZip - anbefalet tilstand er 'aktiveret'";
-$lang['L_HELP_MEMORYLIMIT']="Maksimal mængde hukommelse i Bytes for scriptet
-0 = deaktiveret";
-$lang['L_MEMORY_LIMIT']="Hukommelsesgrænse";
-$lang['L_HELP_AD1']="Hvis aktiveret slettes backupfiler automatisk.";
-$lang['L_HELP_AD3']="maksimum antal backupfilet (for autoslet)
-0 = deaktiveret";
-$lang['L_HELP_LANG']="vælg dit sprog";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="For at eliminere nytteløse eller fejlagtige data kan du tømme databasen før genetablering";
-$lang['L_HELP_CRONEXTENDER']="Filtype for Perl scripts, standard er '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="Navn på konfigurationsfilen for Perl scriptet";
-$lang['L_HELP_CRONPRINTOUT']="Hvis deaktiveret skrives output ikke på skærmen.
-Dette er uafhængigt af skrivningen til logfilen.";
-$lang['L_HELP_CRONSAMEDB']="Brug samme database i Cron job som konfigureret under Database?";
-$lang['L_HELP_CRONDBINDEX']="vælg databasen for Cron job";
-$lang['L_HELP_FTPTRANSFER']="hvis aktiveret sendes filen via FTP.";
-$lang['L_HELP_FTPSERVER']="Adresse på FTP-Serveren";
-$lang['L_HELP_FTPPORT']="Port på FTP-Serveren, standard: 21";
-$lang['L_HELP_FTPUSER']="indtast brugernavn for FTP";
-$lang['L_HELP_FTPPASS']="indtast kodeord for FTP";
-$lang['L_HELP_FTPDIR']="hvor er upload-folderen? indtast sti!";
-$lang['L_HELP_SPEED']="Minimum og maksimum hastighed, standard er 50 til 5000 (for høje eller lave hastigheder kan forårsage timeouts!)";
-$lang['L_SPEED']="Hastighedskontrol";
-$lang['L_HELP_CRONEXECPATH']="Placering af Perl scripts.
+
+$lang['L_HELP_DB'] = 'Dette er listen over alle Databaser';
+$lang['L_HELP_PRAEFIX'] = 'præfikset er en streng i begyndelsen af et tabelnavn, hvilket kan bruges som et filter.';
+$lang['L_HELP_ZIP'] = "Komprimering med GZip - anbefalet tilstand er 'aktiveret'";
+$lang['L_HELP_MEMORYLIMIT'] = 'Maksimal mængde hukommelse i Bytes for scriptet
+0 = deaktiveret';
+$lang['L_MEMORY_LIMIT'] = 'Hukommelsesgrænse';
+$lang['L_HELP_AD1'] = 'Hvis aktiveret slettes backupfiler automatisk.';
+$lang['L_HELP_AD3'] = 'maksimum antal backupfilet (for autoslet)
+0 = deaktiveret';
+$lang['L_HELP_LANG'] = 'vælg dit sprog';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'For at eliminere nytteløse eller fejlagtige data kan du tømme databasen før genetablering';
+$lang['L_HELP_CRONEXTENDER'] = "Filtype for Perl scripts, standard er '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'Navn på konfigurationsfilen for Perl scriptet';
+$lang['L_HELP_CRONPRINTOUT'] = 'Hvis deaktiveret skrives output ikke på skærmen.
+Dette er uafhængigt af skrivningen til logfilen.';
+$lang['L_HELP_CRONSAMEDB'] = 'Brug samme database i Cron job som konfigureret under Database?';
+$lang['L_HELP_CRONDBINDEX'] = 'vælg databasen for Cron job';
+$lang['L_HELP_FTPTRANSFER'] = 'hvis aktiveret sendes filen via FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Adresse på FTP-Serveren';
+$lang['L_HELP_FTPPORT'] = 'Port på FTP-Serveren, standard: 21';
+$lang['L_HELP_FTPUSER'] = 'indtast brugernavn for FTP';
+$lang['L_HELP_FTPPASS'] = 'indtast kodeord for FTP';
+$lang['L_HELP_FTPDIR'] = 'hvor er upload-folderen? indtast sti!';
+$lang['L_HELP_SFTPTRANSFER'] = 'hvis aktiveret sendes filen via SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Adresse på SFTP-Serveren';
+$lang['L_HELP_SFTPPORT'] = 'Port på SFTP-Serveren, standard: 22';
+$lang['L_HELP_SFTPUSER'] = 'indtast brugernavn for SFTP';
+$lang['L_HELP_SFTPPASS'] = 'indtast kodeord for SFTP';
+$lang['L_HELP_SFTPDIR'] = 'hvor er upload-folderen? indtast sti!';
+$lang['L_HELP_SPEED'] = 'Minimum og maksimum hastighed, standard er 50 til 5000 (for høje eller lave hastigheder kan forårsage timeouts!)';
+$lang['L_SPEED'] = 'Hastighedskontrol';
+$lang['L_HELP_CRONEXECPATH'] = 'Placering af Perl scripts.
 Startpunkt er HTTP-Adressen (som Adresser i Browseren)
-Tilladt er absolutte eller relative angivelser.";
-$lang['L_CRON_EXECPATH']="Sti til Perl scripts";
-$lang['L_HELP_CRONCOMPLETELOG']="Når aktiveret, skrives det fuldstændige output til complete_log-filen.
-Dette er uafhængigt af tekstudskrifter";
-$lang['L_HELP_FTP_MODE']="Hvis du oplever problemer med FTP-overførsel, brug passiv tilstand.";
-
-
-?>
\ No newline at end of file
+Tilladt er absolutte eller relative angivelser.';
+$lang['L_CRON_EXECPATH'] = 'Sti til Perl scripts';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Når aktiveret, skrives det fuldstændige output til complete_log-filen.
+Dette er uafhængigt af tekstudskrifter';
+$lang['L_HELP_FTP_MODE'] = 'Hvis du oplever problemer med FTP-overførsel, brug passiv tilstand.';
diff --git a/msd/language/da/lang_install.php b/msd/language/da/lang_install.php
index 17aea6f3..8a297f40 100644
--- a/msd/language/da/lang_install.php
+++ b/msd/language/da/lang_install.php
@@ -1,84 +1,82 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Installation gennemført  --> <a href=\"index.php\">start MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Tilbage til hovedmenu";
-$lang['L_INSTALLMENU']="Hovedmenu";
-$lang['L_STEP']="Trin";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Afinstallation";
-$lang['L_TOOLS']="Funktioner";
-$lang['L_EDITCONF']="Ret konfiguration";
-$lang['L_OSWEITER']="Fortsæt uden at gemme";
-$lang['L_ERRORMAN']="<strong>Fejl ved lagring af konfiguration!</strong><br>Redigér venligst filen ";
-$lang['L_MANUELL']="manuelt";
-$lang['L_CREATEDIRS']="Opret foldere";
-$lang['L_INSTALL_CONTINUE']="Fortsæt med installation";
-$lang['L_CONNECTTOMYSQL']="Forbind til MySQL ";
-$lang['L_DBPARAMETER']="Databaseparametre";
-$lang['L_CONFIGNOTWRITABLE']="Kan ikke skrive til fil \"config.php\".
-Brug venligst dit FTP-program og giv denne fil passende rettigheder, f.eks. CHMOD 0777.";
-$lang['L_DBCONNECTION']="Databaseforbindelse";
-$lang['L_CONNECTIONERROR']="Fejl: kan ikke forbinde.";
-$lang['L_CONNECTION_OK']="Databaseforbindelse etableret.";
-$lang['L_SAVEANDCONTINUE']="Gem og fortsæt installation";
-$lang['L_CONFBASIC']="Basisparametre";
-$lang['L_INSTALL_STEP2FINISHED']="Databaseparametre blev gemt.";
-$lang['L_INSTALL_STEP2_1']="Fortsæt installation med standard-indstillingerne";
-$lang['L_LASTSTEP']="Installation afsluttet";
-$lang['L_FTPMODE']="Opret nødvendige foldere i safe-mode";
-$lang['L_IDOMANUAL']="Jeg opretter selv folderne";
-$lang['L_DOFROM']="startende fra";
-$lang['L_FTPMODE2']="Opret folderne med FTP:";
-$lang['L_CONNECT']="forbind";
-$lang['L_DIRS_CREATED']="Folderne er blevet oprettet og har fået tildelt korrekte tilladelser.";
-$lang['L_CONNECT_TO']="forbind til";
-$lang['L_CHANGEDIR']="skift til folder";
-$lang['L_CHANGEDIRERROR']="skift til folder var ikke muligt";
-$lang['L_FTP_OK']="FTP-parameter er ok";
-$lang['L_CREATEDIRS2']="Opret foldere";
-$lang['L_FTP_NOTCONNECTED']="FTP-forbindelse ikke etableret!";
-$lang['L_CONNWITH']="Forbindelse med";
-$lang['L_ASUSER']="som bruger";
-$lang['L_NOTPOSSIBLE']="ikke muligt";
-$lang['L_DIRCR1']="opret arbejdsfolder";
-$lang['L_DIRCR2']="opret backupdir";
-$lang['L_DIRCR4']="opret logdir";
-$lang['L_DIRCR5']="opret configurationdir";
-$lang['L_INDIR']="nu i dir (folder)";
-$lang['L_CHECK_DIRS']="Check mine foldere";
-$lang['L_DISABLEDFUNCTIONS']="Deaktiverede Funktioner";
-$lang['L_NOFTPPOSSIBLE']="Du har ikke adgang til FTP-funktioner!";
-$lang['L_NOGZPOSSIBLE']="Du har ikke adgang til komprimerings-funktioner!";
-$lang['L_UI1']="Alle arbejdsfoldere, hvilke kan indeholde backups, vil blive slettet.";
-$lang['L_UI2']="Er du sikker på at du vil gøre dette?";
-$lang['L_UI3']="nej, afbryd øjeblikkeligt";
-$lang['L_UI4']="ja, fortsæt venligst";
-$lang['L_UI5']="sletter arbejdsfoldere";
-$lang['L_UI6']="alle blev korrekt slettet.";
-$lang['L_UI7']="Slet venligst script folderen";
-$lang['L_UI8']="et niveau op";
-$lang['L_UI9']="Der opstod en fejl, sletning var ikke muligt</p>Fejl med folder ";
-$lang['L_IMPORT']="Import Konfiguration";
-$lang['L_IMPORT3']="Konfiguration blev indlæst ...";
-$lang['L_IMPORT4']="Konfiguration blev gemt.";
-$lang['L_IMPORT5']="Start MySQLDumper";
-$lang['L_IMPORT6']="Installationsmenu";
-$lang['L_IMPORT7']="Upload konfiguration";
-$lang['L_IMPORT8']="tilbage til upload";
-$lang['L_IMPORT9']="Dette er ikke en konfigurationsbackup!";
-$lang['L_IMPORT10']="Konfiguration korrekt uploadet ...";
-$lang['L_IMPORT11']="<strong>Fejl: </strong>Der var problemer med at skrive til sql_statements";
-$lang['L_IMPORT12']="<strong>Fejl: </strong>Der var problemer med at skrive til config.php";
-$lang['L_INSTALL_HELP_PORT']="(tom = Standardport)";
-$lang['L_INSTALL_HELP_SOCKET']="(tom = Standard Socket)";
-$lang['L_TRYAGAIN']="Prøv igen";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="fundet db:";
-$lang['L_FM_FILEUPLOAD']="Upload fil";
-$lang['L_PASS']="Kodeord";
-$lang['L_NO_DB_FOUND_INFO']="Forbindelsen til databasen blev korrekt etableret.<br> Dine brugerdata er gyldige og blev accepteret af MySQL-serveren.<br> Men MySQLDumper kunne ikke finde nogen database.<br> Den automatiske visning af databaser via script er slået fra på visse servere.<br> Du skal indtaste databasenavnet manuelt efter installationen er færdiggjort. Klik på \"konfiguration\" \"Forbindelsesparametr - vis\" og indtast databasenavnet dér.";
-$lang['L_SAFEMODEDESC']="Because PHP is running in safe_mode you need to create the following directories manually using your FTP-Programm:";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
 
-
-?>
\ No newline at end of file
+$lang['L_INSTALLFINISHED'] = '<br>Installation gennemført  --> <a href="index.php">start MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Tilbage til hovedmenu';
+$lang['L_INSTALLMENU'] = 'Hovedmenu';
+$lang['L_STEP'] = 'Trin';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Afinstallation';
+$lang['L_TOOLS'] = 'Funktioner';
+$lang['L_EDITCONF'] = 'Ret konfiguration';
+$lang['L_OSWEITER'] = 'Fortsæt uden at gemme';
+$lang['L_ERRORMAN'] = '<strong>Fejl ved lagring af konfiguration!</strong><br>Redigér venligst filen ';
+$lang['L_MANUELL'] = 'manuelt';
+$lang['L_CREATEDIRS'] = 'Opret foldere';
+$lang['L_INSTALL_CONTINUE'] = 'Fortsæt med installation';
+$lang['L_CONNECTTOMYSQL'] = 'Forbind til MySQL ';
+$lang['L_DBPARAMETER'] = 'Databaseparametre';
+$lang['L_CONFIGNOTWRITABLE'] = 'Kan ikke skrive til fil "config.php".
+Brug venligst dit FTP-program og giv denne fil passende rettigheder, f.eks. CHMOD 0777.';
+$lang['L_DBCONNECTION'] = 'Databaseforbindelse';
+$lang['L_CONNECTIONERROR'] = 'Fejl: kan ikke forbinde.';
+$lang['L_CONNECTION_OK'] = 'Databaseforbindelse etableret.';
+$lang['L_SAVEANDCONTINUE'] = 'Gem og fortsæt installation';
+$lang['L_CONFBASIC'] = 'Basisparametre';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Databaseparametre blev gemt.';
+$lang['L_INSTALL_STEP2_1'] = 'Fortsæt installation med standard-indstillingerne';
+$lang['L_LASTSTEP'] = 'Installation afsluttet';
+$lang['L_FTPMODE'] = 'Opret nødvendige foldere i safe-mode';
+$lang['L_IDOMANUAL'] = 'Jeg opretter selv folderne';
+$lang['L_DOFROM'] = 'startende fra';
+$lang['L_FTPMODE2'] = 'Opret folderne med FTP:';
+$lang['L_CONNECT'] = 'forbind';
+$lang['L_DIRS_CREATED'] = 'Folderne er blevet oprettet og har fået tildelt korrekte tilladelser.';
+$lang['L_CONNECT_TO'] = 'forbind til';
+$lang['L_CHANGEDIR'] = 'skift til folder';
+$lang['L_CHANGEDIRERROR'] = 'skift til folder var ikke muligt';
+$lang['L_FTP_OK'] = 'FTP-parameter er ok';
+$lang['L_SFTP_OK'] = 'FTP-parameter er ok';
+$lang['L_CREATEDIRS2'] = 'Opret foldere';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP-forbindelse ikke etableret!';
+$lang['L_CONNWITH'] = 'Forbindelse med';
+$lang['L_ASUSER'] = 'som bruger';
+$lang['L_NOTPOSSIBLE'] = 'ikke muligt';
+$lang['L_DIRCR1'] = 'opret arbejdsfolder';
+$lang['L_DIRCR2'] = 'opret backupdir';
+$lang['L_DIRCR4'] = 'opret logdir';
+$lang['L_DIRCR5'] = 'opret configurationdir';
+$lang['L_INDIR'] = 'nu i dir (folder)';
+$lang['L_CHECK_DIRS'] = 'Check mine foldere';
+$lang['L_DISABLEDFUNCTIONS'] = 'Deaktiverede Funktioner';
+$lang['L_NOFTPPOSSIBLE'] = 'Du har ikke adgang til FTP-funktioner!';
+$lang['L_NOGZPOSSIBLE'] = 'Du har ikke adgang til komprimerings-funktioner!';
+$lang['L_UI1'] = 'Alle arbejdsfoldere, hvilke kan indeholde backups, vil blive slettet.';
+$lang['L_UI2'] = 'Er du sikker på at du vil gøre dette?';
+$lang['L_UI3'] = 'nej, afbryd øjeblikkeligt';
+$lang['L_UI4'] = 'ja, fortsæt venligst';
+$lang['L_UI5'] = 'sletter arbejdsfoldere';
+$lang['L_UI6'] = 'alle blev korrekt slettet.';
+$lang['L_UI7'] = 'Slet venligst script folderen';
+$lang['L_UI8'] = 'et niveau op';
+$lang['L_UI9'] = 'Der opstod en fejl, sletning var ikke muligt</p>Fejl med folder ';
+$lang['L_IMPORT'] = 'Import Konfiguration';
+$lang['L_IMPORT3'] = 'Konfiguration blev indlæst ...';
+$lang['L_IMPORT4'] = 'Konfiguration blev gemt.';
+$lang['L_IMPORT5'] = 'Start MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Installationsmenu';
+$lang['L_IMPORT7'] = 'Upload konfiguration';
+$lang['L_IMPORT8'] = 'tilbage til upload';
+$lang['L_IMPORT9'] = 'Dette er ikke en konfigurationsbackup!';
+$lang['L_IMPORT10'] = 'Konfiguration korrekt uploadet ...';
+$lang['L_IMPORT11'] = '<strong>Fejl: </strong>Der var problemer med at skrive til sql_statements';
+$lang['L_IMPORT12'] = '<strong>Fejl: </strong>Der var problemer med at skrive til config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(tom = Standardport)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(tom = Standard Socket)';
+$lang['L_TRYAGAIN'] = 'Prøv igen';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'fundet db:';
+$lang['L_FM_FILEUPLOAD'] = 'Upload fil';
+$lang['L_PASS'] = 'Kodeord';
+$lang['L_NO_DB_FOUND_INFO'] = 'Forbindelsen til databasen blev korrekt etableret.<br> Dine brugerdata er gyldige og blev accepteret af MySQL-serveren.<br> Men MyOOS [Dumper] kunne ikke finde nogen database.<br> Den automatiske visning af databaser via script er slået fra på visse servere.<br> Du skal indtaste databasenavnet manuelt efter installationen er færdiggjort. Klik på "konfiguration" "Forbindelsesparametr - vis" og indtast databasenavnet dér.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/da/lang_log.php b/msd/language/da/lang_log.php
index 8147acfc..bcf773a7 100644
--- a/msd/language/da/lang_log.php
+++ b/msd/language/da/lang_log.php
@@ -1,12 +1,10 @@
 <?php
-$lang['L_LOG_DELETE']="slet Log";
-$lang['L_LOGFILEFORMAT']="Logfilformat";
-$lang['L_LOGFILENOTWRITABLE']="Kan <b>ikke</b> skrive Logfil!";
-$lang['L_NOREVERSE']="Ældste indlæg først";
-$lang['L_REVERSE']="Seneste indlæg først
+
+$lang['L_LOG_DELETE'] = 'slet Log';
+$lang['L_LOGFILEFORMAT'] = 'Logfilformat';
+$lang['L_LOGFILENOTWRITABLE'] = 'Kan <b>ikke</b> skrive Logfil!';
+$lang['L_NOREVERSE'] = 'Ældste indlæg først';
+$lang['L_REVERSE'] = 'Seneste indlæg først
 
 
-";
-
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/da/lang_main.php b/msd/language/da/lang_main.php
index 9ca1d703..8a146027 100644
--- a/msd/language/da/lang_main.php
+++ b/msd/language/da/lang_main.php
@@ -1,77 +1,85 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Du har ingen FTP-funktioner til rådighed!";
-$lang['L_INFO_LOCATION']="Din lokation er ";
-$lang['L_INFO_DATABASES']="Følgende database(r) er tilgængelige på din server:";
-$lang['L_INFO_NODB']="database findes ikke.";
-$lang['L_INFO_DBDETAIL']="Detaljeret info om database ";
-$lang['L_INFO_DBEMPTY']="Databasen er tom !";
-$lang['L_INFO_RECORDS']="Poster";
-$lang['L_INFO_SIZE']="Størrelse";
-$lang['L_INFO_LASTUPDATE']="Sidst opdateret";
-$lang['L_INFO_SUM']="total";
-$lang['L_INFO_OPTIMIZED']="optimeret";
-$lang['L_OPTIMIZE_DATABASES']="Optimér tabeller";
-$lang['L_CHECK_TABLES']="Check Tabeller";
-$lang['L_CLEAR_DATABASE']="Tøm database";
-$lang['L_DELETE_DATABASE']="Slet database";
-$lang['L_INFO_CLEARED']="blev tømt";
-$lang['L_INFO_DELETED']="blev slettet";
-$lang['L_INFO_EMPTYDB1']="Skal databasen";
-$lang['L_INFO_EMPTYDB2']=" virkelig tømmes? (Bemærk: Alle data vil være permanent tabt!)";
-$lang['L_INFO_KILLDB']=" virkelig slettes? (Bemærk: Alle data vil være permanent tabt!)";
-$lang['L_PROCESSKILL1']="Scriptet forsøger at dræbe proces ";
-$lang['L_PROCESSKILL2']="at dræbe.";
-$lang['L_PROCESSKILL3']="Scriptet har forsøgt i   ";
-$lang['L_PROCESSKILL4']=" sek. at dræbe processen ";
-$lang['L_HTACC_CREATE']="Opret folderbeskyttelse";
-$lang['L_ENCRYPTION_TYPE']="Krypteringsmetode";
-$lang['L_HTACC_CRYPT']="Crypt (Linux og Unix-systemer)";
-$lang['L_HTACC_MD5']="MD5 (Linux og Unix-systemer)";
-$lang['L_HTACC_NO_ENCRYPTION']="plain text, ingen kryptering (Windows)";
-$lang['L_HTACCESS8']="Der findes allerede en folderbeskyttelse. Hvis du opretter en ny, vil den tidligere blive overskrevet!";
-$lang['L_HTACC_NO_USERNAME']="Du skal indtaste et navn!";
-$lang['L_PASSWORDS_UNEQUAL']="Kodeordene er ikke identiske eller tomme!";
-$lang['L_HTACC_CONFIRM_DELETE']="Skal folderbeskyttelsen gemmes nu?";
-$lang['L_HTACC_CREATED']="Folderbeskyttelsen blev oprettet.";
-$lang['L_HTACC_CONTENT']="Indhold af fil";
-$lang['L_HTACC_CREATE_ERROR']="Der opstod en fejl ved oprettelse af folderbeskyttelsen!<br>Opret venligst de 2 filer manuelt med følgende indhold";
-$lang['L_HTACC_PROPOSED']="Stærkt anbefalet";
-$lang['L_HTACC_EDIT']="Rediger .htaccess";
-$lang['L_HTACCESS18']="Opret .htaccess i ";
-$lang['L_HTACCESS19']="Genindlæs";
-$lang['L_HTACCESS20']="Udfør script";
-$lang['L_HTACCESS21']="Tilføj handler";
-$lang['L_HTACCESS22']="Lav til eksekverbar";
-$lang['L_HTACCESS23']="Folder-indholdslistning";
-$lang['L_HTACCESS24']="Fejl-dokument";
-$lang['L_HTACCESS25']="Aktivér rewrite";
-$lang['L_HTACCESS26']="Deny / Allow";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Error Log";
-$lang['L_HTACCESS29']="Flere eksempler og dokumentation";
-$lang['L_HTACCESS30']="Leverandør";
-$lang['L_HTACCESS31']="Generelt";
-$lang['L_HTACCESS32']="Bemærk! .htaccess påvirker dirkte browserens opførsel.<br>Med forkert indhold kan disse sider blive utilgængelige.";
-$lang['L_PHPBUG']="Fejl i zlib ! Ingen komprimering mulig!";
-$lang['L_DISABLEDFUNCTIONS']="Funktioner slået fra";
-$lang['L_NOGZPOSSIBLE']="Da Zlib ikke er installeret/tilgængeligt, kan du ikke bruge GZip-funktionerne!
 
-
-";
-$lang['L_DELETE_HTACCESS']="Fjern folderbeskyttelse (slet .htaccess)";
-$lang['L_WRONG_RIGHTS']="Kan ikke skrive til filen eller folderen '%s'.<br> Fil-rettighederne (chmod) er ikke sat korrekt eller har den forkerte ejer.<br> Sæt venligst de korrekte attributter via din FTP-klient.<br> Filen eller mappen skal være sat til %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Kunne ikke oprette folderen '%s'. Opret den venligst med en FTP-klient.";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="kunne ikke finde fil";
-
-
-?>
\ No newline at end of file
+$lang['L_NOFTPPOSSIBLE'] = 'Du har ingen FTP-funktioner til rådighed!';
+$lang['L_INFO_LOCATION'] = 'Din lokation er ';
+$lang['L_INFO_DATABASES'] = 'Følgende database(r) er tilgængelige på din server:';
+$lang['L_INFO_NODB'] = 'database findes ikke.';
+$lang['L_INFO_DBDETAIL'] = 'Detaljeret info om database ';
+$lang['L_INFO_DBEMPTY'] = 'Databasen er tom !';
+$lang['L_INFO_RECORDS'] = 'Poster';
+$lang['L_INFO_SIZE'] = 'Størrelse';
+$lang['L_INFO_LASTUPDATE'] = 'Sidst opdateret';
+$lang['L_INFO_SUM'] = 'total';
+$lang['L_INFO_OPTIMIZED'] = 'optimeret';
+$lang['L_OPTIMIZE_DATABASES'] = 'Optimér tabeller';
+$lang['L_CHECK_TABLES'] = 'Check Tabeller';
+$lang['L_CLEAR_DATABASE'] = 'Tøm database';
+$lang['L_DELETE_DATABASE'] = 'Slet database';
+$lang['L_INFO_CLEARED'] = 'blev tømt';
+$lang['L_INFO_DELETED'] = 'blev slettet';
+$lang['L_INFO_EMPTYDB1'] = 'Skal databasen';
+$lang['L_INFO_EMPTYDB2'] = ' virkelig tømmes? (Bemærk: Alle data vil være permanent tabt!)';
+$lang['L_INFO_KILLDB'] = ' virkelig slettes? (Bemærk: Alle data vil være permanent tabt!)';
+$lang['L_PROCESSKILL1'] = 'Scriptet forsøger at dræbe proces ';
+$lang['L_PROCESSKILL2'] = 'at dræbe.';
+$lang['L_PROCESSKILL3'] = 'Scriptet har forsøgt i   ';
+$lang['L_PROCESSKILL4'] = ' sek. at dræbe processen ';
+$lang['L_HTACC_CREATE'] = 'Opret folderbeskyttelse';
+$lang['L_ENCRYPTION_TYPE'] = 'Krypteringsmetode';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Der findes allerede en folderbeskyttelse. Hvis du opretter en ny, vil den tidligere blive overskrevet!';
+$lang['L_HTACC_NO_USERNAME'] = 'Du skal indtaste et navn!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Kodeordene er ikke identiske eller tomme!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Skal folderbeskyttelsen gemmes nu?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'Folderbeskyttelsen blev oprettet.';
+$lang['L_HTACC_CONTENT'] = 'Indhold af fil';
+$lang['L_HTACC_CREATE_ERROR'] = 'Der opstod en fejl ved oprettelse af folderbeskyttelsen!<br>Opret venligst de 2 filer manuelt med følgende indhold';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';;
+$lang['L_HTACC_EDIT'] = 'Rediger .htaccess';
+$lang['L_HTACCESS18'] = 'Opret .htaccess i ';
+$lang['L_HTACCESS19'] = 'Genindlæs';
+$lang['L_HTACCESS20'] = 'Udfør script';
+$lang['L_HTACCESS21'] = 'Tilføj handler';
+$lang['L_HTACCESS22'] = 'Lav til eksekverbar';
+$lang['L_HTACCESS23'] = 'Folder-indholdslistning';
+$lang['L_HTACCESS24'] = 'Fejl-dokument';
+$lang['L_HTACCESS25'] = 'Aktivér rewrite';
+$lang['L_HTACCESS26'] = 'Deny / Allow';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Error Log';
+$lang['L_HTACCESS29'] = 'Flere eksempler og dokumentation';
+$lang['L_HTACCESS30'] = 'Leverandør';
+$lang['L_HTACCESS31'] = 'Generelt';
+$lang['L_HTACCESS32'] = 'Bemærk! .htaccess påvirker dirkte browserens opførsel.<br>Med forkert indhold kan disse sider blive utilgængelige.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Funktioner slået fra';
+$lang['L_NOGZPOSSIBLE'] = 'Da Zlib ikke er installeret/tilgængeligt, kan du ikke bruge GZip-funktionerne!';
+$lang['L_DELETE_HTACCESS'] = 'Fjern folderbeskyttelse (slet .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "Kan ikke skrive til filen eller folderen '%s'.<br> Fil-rettighederne (chmod) er ikke sat korrekt eller har den forkerte ejer.<br> Sæt venligst de korrekte attributter via din FTP-klient.<br> Filen eller mappen skal være sat til %s.<br>";
+$lang['L_CANT_CREATE_DIR'] = "Kunne ikke oprette folderen '%s'. Opret den venligst med en FTP-klient.";
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'Ny version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'En ny version af MyOOS [Dumper] er tilgængelig.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'kunne ikke finde fil';
+$lang['L_INSTALLING_UPDATES'] = 'Installation af opdateringer';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Opdatering vellykket';
+$lang['L_UPDATE_FAILED'] = 'Opdatering mislykkedes';
+$lang['L_UP_TO_DATE'] = 'Den aktuelle version er opdateret';
diff --git a/msd/language/da/lang_restore.php b/msd/language/da/lang_restore.php
index ceb6370f..4119e1ef 100644
--- a/msd/language/da/lang_restore.php
+++ b/msd/language/da/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Foreløbigt er der oprettet <b>%d</b> tabeller.";
-$lang['L_FILE_MISSING']="kunne ikke finde fil";
-$lang['L_RESTORE_DB']="Database '<b>%s</b>' på '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> tabeller oprettet.";
-$lang['L_RESTORE_RUN1']="<br>Foreløbigt er der korrekt tilføjet  <b>%s</b> af <b>%s</b> poster.";
-$lang['L_RESTORE_RUN2']="<br>Tabellen '<b>%s</b>' er under genetablering.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> poster indsat.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Foreløbigt er der oprettet <b>%d</b> af <b>%d</b> tabeller.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Tillykke.</b><br><br>Genetableringen af databasen er færdig.<br>Alle data fra Backupfilen er blevet genetableret.<br><br>Processen er færdig. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Fejl:<br>Valg af database <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> fejlede!";
-$lang['L_FILE_OPEN_ERROR']="Fejl: kunne ikke åbne fil.";
-$lang['L_PROGRESS_OVER_ALL']="Samlede fremskridt";
-$lang['L_BACK_TO_OVERVIEW']="Database-oversigt";
-$lang['L_RESTORE_RUN0']="<br>foreløbigt er der korrekt tilføjet <b>%s</b> poster.";
-$lang['L_UNKNOWN_SQLCOMMAND']="ukendt SQL-kommando";
-$lang['L_NOTICES']="Bemærkninger";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Foreløbigt er der oprettet <b>%d</b> tabeller.';
+$lang['L_FILE_MISSING'] = 'kunne ikke finde fil';
+$lang['L_RESTORE_DB'] = "Database '<b>%s</b>' på '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> tabeller oprettet.';
+$lang['L_RESTORE_RUN1'] = '<br>Foreløbigt er der korrekt tilføjet  <b>%s</b> af <b>%s</b> poster.';
+$lang['L_RESTORE_RUN2'] = "<br>Tabellen '<b>%s</b>' er under genetablering.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> poster indsat.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Foreløbigt er der oprettet <b>%d</b> af <b>%d</b> tabeller.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Tillykke.</b><br><br>Genetableringen af databasen er færdig.<br>Alle data fra Backupfilen er blevet genetableret.<br><br>Processen er færdig. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>Fejl:<br>Valg af database <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> fejlede!';
+$lang['L_FILE_OPEN_ERROR'] = 'Fejl: kunne ikke åbne fil.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Samlede fremskridt';
+$lang['L_BACK_TO_OVERVIEW'] = 'Database-oversigt';
+$lang['L_RESTORE_RUN0'] = '<br>foreløbigt er der korrekt tilføjet <b>%s</b> poster.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'ukendt SQL-kommando';
+$lang['L_NOTICES'] = 'Bemærkninger';
diff --git a/msd/language/da/lang_sql.php b/msd/language/da/lang_sql.php
index 5bc982f4..09286157 100644
--- a/msd/language/da/lang_sql.php
+++ b/msd/language/da/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Kommando";
-$lang['L_IMPORT_NOTABLE']="Ingen tabel valgt til import!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="Udførelse af SQL-sætninger kan manipulere data. PAS PÅ! Forfatterne af dette system påtager sig intet ansvar for beskadigede eller tabte data.";
-$lang['L_SQL_EXEC']="Udfør SQL-sætning";
-$lang['L_SQL_DATAVIEW']="Data Visning";
-$lang['L_SQL_TABLEVIEW']="Tabel-visning";
-$lang['L_SQL_VONINS']="fra totalt";
-$lang['L_SQL_NODATA']="ingen poster";
-$lang['L_SQL_RECORDUPDATED']="Post blev opdateret";
-$lang['L_SQL_RECORDINSERTED']="Post blev tilføjet";
-$lang['L_SQL_BACKDBOVERVIEW']="Tilbage til Oversigt";
-$lang['L_SQL_RECORDDELETED']="Post blev slettet";
-$lang['L_ASKTABLEEMPTY']="Skal tabellen `%s` tømmes?";
-$lang['L_SQL_RECORDEDIT']="rediger post";
-$lang['L_SQL_RECORDNEW']="ny post";
-$lang['L_ASKDELETERECORD']="Er du sikker på at du vil slette denne post?";
-$lang['L_ASKDELETETABLE']="Skal tabellen `%s` slettes?";
-$lang['L_SQL_BEFEHLE']="SQL-kommandoer";
-$lang['L_SQL_BEFEHLNEU']="Ny kommando";
-$lang['L_SQL_BEFEHLSAVED1']="SQL-kommando";
-$lang['L_SQL_BEFEHLSAVED2']="blev tilføjet";
-$lang['L_SQL_BEFEHLSAVED3']="blev gemt";
-$lang['L_SQL_BEFEHLSAVED4']="blev flyttet op";
-$lang['L_SQL_BEFEHLSAVED5']="blev slettet";
-$lang['L_SQL_QUERYENTRY']="Forespørgslen indeholder";
-$lang['L_SQL_COLUMNS']="Kolonner";
-$lang['L_ASKDBDELETE']="Vil du slette databasen `%s` med alt indhold?";
-$lang['L_ASKDBEMPTY']="Vil du tømme databasen `%s` ?";
-$lang['L_ASKDBCOPY']="Vil du kopiere database `%s` til database `%s`?";
-$lang['L_SQL_TABLENEW']="Ret Tabeller";
-$lang['L_SQL_OUTPUT']="SQL-Output";
-$lang['L_DO_NOW']="gør det nu";
-$lang['L_SQL_NAMEDEST_MISSING']="Destinationsnavn mangler!";
-$lang['L_ASKDELETEFIELD']="Vil du slette feltet?";
-$lang['L_SQL_COMMANDS_IN']=" linier i ";
-$lang['L_SQL_COMMANDS_IN2']="  sek. bearbejdet.";
-$lang['L_SQL_OUT1']="Udført ";
-$lang['L_SQL_OUT2']="Kommandoer";
-$lang['L_SQL_OUT3']="Den havde ";
-$lang['L_SQL_OUT4']="Kommentarer";
-$lang['L_SQL_OUT5']="Da outputtet indeholder mere end 5000 linier vises det ikke.";
-$lang['L_SQL_SELECDB']="Vælg Database";
-$lang['L_SQL_TABLESOFDB']="Tabeller i Database";
-$lang['L_SQL_EDIT']="ret";
-$lang['L_SQL_NOFIELDDELETE']="Slet er ikke muligt da tabeller skal indeholde mindst et felt.";
-$lang['L_SQL_FIELDDELETE1']="Feltet";
-$lang['L_SQL_DELETED']="blev slettet";
-$lang['L_SQL_CHANGED']="blev ændret.";
-$lang['L_SQL_CREATED']="blev oprettet.";
-$lang['L_SQL_NODEST_COPY']="Ingen kopiering uden en destination!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Destinationstabel findes allerede!";
-$lang['L_SQL_SCOPY']="Tabelstrukturen fra `%s` blev kopieret ind i Tabel `%s`.";
-$lang['L_SQL_TCOPY']="Tabel `%s` blev kopieret med data ind i Tabel `%s`.";
-$lang['L_SQL_TABLENONAME']="Tabellen skal have et navn!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tabelnavnet kan ikke være tomt!";
-$lang['L_SQL_COLLATENOTMATCH']="Tegnsæt og Kollation passer ikke sammen!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Fejl: Ikke gyldigt feltnavn";
-$lang['L_SQL_CREATETABLE']="opret tabel";
-$lang['L_SQL_COPYTABLE']="kopier tabel";
-$lang['L_SQL_STRUCTUREONLY']="Kun Struktur";
-$lang['L_SQL_STRUCTUREDATA']="Struktur og Data";
-$lang['L_SQL_NOTABLESINDB']="Ingen tabeller fundet i Database";
-$lang['L_SQL_SELECTTABLE']="vælg tabel";
-$lang['L_SQL_SHOWDATATABLE']="Vis Data i Tabel";
-$lang['L_SQL_TBLPROPSOF']="Tabelegenskaber for";
-$lang['L_SQL_EDITFIELD']="Ret felt";
-$lang['L_SQL_NEWFIELD']="Nyt felt";
-$lang['L_SQL_INDEXES']="Indeks";
-$lang['L_SQL_ATPOSITION']="indsæt på position";
-$lang['L_SQL_FIRST']="først";
-$lang['L_SQL_AFTER']="efter";
-$lang['L_SQL_CHANGEFIELD']="ændre felt";
-$lang['L_SQL_INSERTFIELD']="indsæt felt";
-$lang['L_SQL_INSERTNEWFIELD']="indsæt nyt felt";
-$lang['L_SQL_TABLEINDEXES']="Indeks på tabel";
-$lang['L_SQL_ALLOWDUPS']="Dubletter tilladte";
-$lang['L_SQL_CARDINALITY']="Kardinalitet";
-$lang['L_SQL_TABLENOINDEXES']="Ingen indeks i tabel";
-$lang['L_SQL_CREATEINDEX']="opret nyt indeks";
-$lang['L_SQL_WASEMPTIED']="blev tømt";
-$lang['L_SQL_RENAMEDTO']="blev omdøbt til";
-$lang['L_SQL_DBCOPY']="Indholdet af database `%s` blev kopieret til database `%s`.";
-$lang['L_SQL_DBSCOPY']="Database-strukturen fra database `%s` blev kopieret til database `%s`.";
-$lang['L_SQL_WASCREATED']="blev oprettet";
-$lang['L_SQL_RENAMEDB']="Omdøb database";
-$lang['L_SQL_ACTIONS']="Handlinger";
-$lang['L_SQL_CHOOSEACTION']="Vælg handling";
-$lang['L_SQL_DELETEDB']="Slet database";
-$lang['L_SQL_EMPTYDB']="Tøm database";
-$lang['L_SQL_COPYDATADB']="Kopier hele databasen til";
-$lang['L_SQL_COPYSDB']="Kopier database-struktur";
-$lang['L_SQL_IMEXPORT']="Import-Eksport";
-$lang['L_INFO_RECORDS']="poster";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="Skal tabellen `%s` tømmes og indeksene nulstilles?";
-$lang['L_EDIT']="ret";
-$lang['L_DELETE']="slet";
-$lang['L_EMPTY']="tøm";
-$lang['L_EMPTYKEYS']="tøm og nulstil alle indeks";
-$lang['L_SQL_TABLEEMPTIED']="Tabel `%s` blev tømt.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Tabel `%s` blev tømt og indeksene blev nulstillet.";
-$lang['L_SQL_LIBRARY']="SQL-bibliotek";
-$lang['L_SQL_ATTRIBUTES']="Attributter";
-$lang['L_SQL_UPLOADEDFILE']="indlæst fil: ";
-$lang['L_SQL_IMPORT']="Import i Database `%s`";
-$lang['L_EXPORT']="Eksport";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Import-opsætning";
-$lang['L_CSVOPTIONS']="CSV-opsætning";
-$lang['L_IMPORTTABLE']="Import i Tabel";
-$lang['L_NEWTABLE']="Ny tabel";
-$lang['L_IMPORTSOURCE']="Import-kilde";
-$lang['L_FROMTEXTBOX']="fra tekstboks";
-$lang['L_FROMFILE']="fra fil";
-$lang['L_EMPTYTABLEBEFORE']="Tøm tabel før";
-$lang['L_CREATEAUTOINDEX']="Opret Auto-Indeks";
-$lang['L_CSV_NAMEFIRSTLINE']="Feltnavne i første linie";
-$lang['L_CSV_FIELDSEPERATE']="Felter adskilt med";
-$lang['L_CSV_FIELDSENCLOSED']="Felter lukket inde i";
-$lang['L_CSV_FIELDSESCAPE']="Felter escaped med";
-$lang['L_CSV_EOL']="Udskil linier med";
-$lang['L_CSV_NULL']="Erstat NULL med";
-$lang['L_CSV_FILEOPEN']="Åbn CSV-fil";
-$lang['L_IMPORTIEREN']="Import";
-$lang['L_SQL_EXPORT']="Eksport fra Database `%s`";
-$lang['L_EXPORTOPTIONS']="Eksport-opsætning";
-$lang['L_EXCEL2003']="Excel fra 2003";
-$lang['L_SHOWRESULT']="vis resultat";
-$lang['L_SENDRESULTASFILE']="send resultat som fil";
-$lang['L_EXPORTLINES']="<strong>%s</strong> linier eksporteret";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Felt-tælleren stemmer ikke overens med de importerede data (%d i stedet for %d).";
-$lang['L_CSV_FIELDSLINES']="%d felter genkendt, totalt %d linier";
-$lang['L_CSV_ERRORCREATETABLE']="Fejl ved oprettelse af tabel `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="vælg venligst en fil.";
-$lang['L_CSV_NODATA']="Ingen data fundet til import!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="generelle funktioner";
-$lang['L_SQLLIB_RESETAUTO']="nulstil auto-increment (forøgelse)";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="deaktiver Board";
-$lang['L_SQLLIB_ACTIVATEBOARD']="aktiver Board";
-$lang['L_SQL_NOTABLESSELECTED']="Ingen tabeller valgt!";
-$lang['L_TOOLS']="Funktioner";
-$lang['L_TOOLS_TOOLBOX']="Vælg Database / Datebasefunktioner / Import - Eksport";
-$lang['L_SQL_OPENFILE']="Åbn SQL-fil";
-$lang['L_SQL_OPENFILE_BUTTON']="Upload";
-$lang['L_MAX_UPLOAD_SIZE']="Maksimal filstørrelse";
-$lang['L_SQL_SEARCH']="Søg";
-$lang['L_SQL_SEARCHWORDS']="Søgeord";
-$lang['L_START_SQL_SEARCH']="Start søgning";
-$lang['L_RESET_SEARCHWORDS']="nulstil søgeord";
-$lang['L_SEARCH_OPTIONS']="Søgeindstillinger";
-$lang['L_SEARCH_RESULTS']="Søgningen efter \"<b>%s</b>\" i tabellen \"<b>%s</b>\" giver følgende resultater";
-$lang['L_SEARCH_NO_RESULTS']="Søgningen efter \"<b>%s</b>\" i tabel \"<b>%s</b>\" gav ingen rsultater!";
-$lang['L_NO_ENTRIES']="Tabel \"<b>%s</b>\" er tom og indeholder ingen poster.";
-$lang['L_SEARCH_ACCESS_KEYS']="Bladre: fremad=ALT+V, baglæns=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="en kolonne skal indeholde et af søgeordene (ELLER-søgning)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="en række skal indeholde alle søgeordene men kan være i hvilkensomhelst kolonne (kan tage noget tid)";
-$lang['L_SEARCH_OPTIONS_AND']="en kolonne skal indeholde ALLE søgeord (OG-søgning)";
-$lang['L_SEARCH_IN_TABLE']="Søg i tabel";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Edit table structure";
-$lang['L_DEFAULT_CHARSET']="Default character set";
-$lang['L_TITLE_KEY_PRIMARY']="Primary key";
-$lang['L_TITLE_KEY_UNIQUE']="Unique key";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Fulltext key";
-$lang['L_TITLE_NOKEY']="No key";
-$lang['L_TITLE_SEARCH']="Search";
-$lang['L_TITLE_MYSQL_HELP']="MySQl Documentation";
-$lang['L_TITLE_UPLOAD']="Upload SQL file";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="Størrelse";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Kommando';
+$lang['L_IMPORT_NOTABLE'] = 'Ingen tabel valgt til import!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'Udførelse af SQL-sætninger kan manipulere data. PAS PÅ! Forfatterne af dette system påtager sig intet ansvar for beskadigede eller tabte data.';
+$lang['L_SQL_EXEC'] = 'Udfør SQL-sætning';
+$lang['L_SQL_DATAVIEW'] = 'Data Visning';
+$lang['L_SQL_TABLEVIEW'] = 'Tabel-visning';
+$lang['L_SQL_VONINS'] = 'fra totalt';
+$lang['L_SQL_NODATA'] = 'ingen poster';
+$lang['L_SQL_RECORDUPDATED'] = 'Post blev opdateret';
+$lang['L_SQL_RECORDINSERTED'] = 'Post blev tilføjet';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'Tilbage til Oversigt';
+$lang['L_SQL_RECORDDELETED'] = 'Post blev slettet';
+$lang['L_ASKTABLEEMPTY'] = 'Skal tabellen `%s` tømmes?';
+$lang['L_SQL_RECORDEDIT'] = 'rediger post';
+$lang['L_SQL_RECORDNEW'] = 'ny post';
+$lang['L_ASKDELETERECORD'] = 'Er du sikker på at du vil slette denne post?';
+$lang['L_ASKDELETETABLE'] = 'Skal tabellen `%s` slettes?';
+$lang['L_SQL_BEFEHLE'] = 'SQL-kommandoer';
+$lang['L_SQL_BEFEHLNEU'] = 'Ny kommando';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL-kommando';
+$lang['L_SQL_BEFEHLSAVED2'] = 'blev tilføjet';
+$lang['L_SQL_BEFEHLSAVED3'] = 'blev gemt';
+$lang['L_SQL_BEFEHLSAVED4'] = 'blev flyttet op';
+$lang['L_SQL_BEFEHLSAVED5'] = 'blev slettet';
+$lang['L_SQL_QUERYENTRY'] = 'Forespørgslen indeholder';
+$lang['L_SQL_COLUMNS'] = 'Kolonner';
+$lang['L_ASKDBDELETE'] = 'Vil du slette databasen `%s` med alt indhold?';
+$lang['L_ASKDBEMPTY'] = 'Vil du tømme databasen `%s` ?';
+$lang['L_ASKDBCOPY'] = 'Vil du kopiere database `%s` til database `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Ret Tabeller';
+$lang['L_SQL_OUTPUT'] = 'SQL-Output';
+$lang['L_DO_NOW'] = 'gør det nu';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Destinationsnavn mangler!';
+$lang['L_ASKDELETEFIELD'] = 'Vil du slette feltet?';
+$lang['L_SQL_COMMANDS_IN'] = ' linier i ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sek. bearbejdet.';
+$lang['L_SQL_OUT1'] = 'Udført ';
+$lang['L_SQL_OUT2'] = 'Kommandoer';
+$lang['L_SQL_OUT3'] = 'Den havde ';
+$lang['L_SQL_OUT4'] = 'Kommentarer';
+$lang['L_SQL_OUT5'] = 'Da outputtet indeholder mere end 5000 linier vises det ikke.';
+$lang['L_SQL_SELECDB'] = 'Vælg Database';
+$lang['L_SQL_TABLESOFDB'] = 'Tabeller i Database';
+$lang['L_SQL_EDIT'] = 'ret';
+$lang['L_SQL_NOFIELDDELETE'] = 'Slet er ikke muligt da tabeller skal indeholde mindst et felt.';
+$lang['L_SQL_FIELDDELETE1'] = 'Feltet';
+$lang['L_SQL_DELETED'] = 'blev slettet';
+$lang['L_SQL_CHANGED'] = 'blev ændret.';
+$lang['L_SQL_CREATED'] = 'blev oprettet.';
+$lang['L_SQL_NODEST_COPY'] = 'Ingen kopiering uden en destination!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Destinationstabel findes allerede!';
+$lang['L_SQL_SCOPY'] = 'Tabelstrukturen fra `%s` blev kopieret ind i Tabel `%s`.';
+$lang['L_SQL_TCOPY'] = 'Tabel `%s` blev kopieret med data ind i Tabel `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'Tabellen skal have et navn!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tabelnavnet kan ikke være tomt!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Tegnsæt og Kollation passer ikke sammen!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Fejl: Ikke gyldigt feltnavn';
+$lang['L_SQL_CREATETABLE'] = 'opret tabel';
+$lang['L_SQL_COPYTABLE'] = 'kopier tabel';
+$lang['L_SQL_STRUCTUREONLY'] = 'Kun Struktur';
+$lang['L_SQL_STRUCTUREDATA'] = 'Struktur og Data';
+$lang['L_SQL_NOTABLESINDB'] = 'Ingen tabeller fundet i Database';
+$lang['L_SQL_SELECTTABLE'] = 'vælg tabel';
+$lang['L_SQL_SHOWDATATABLE'] = 'Vis Data i Tabel';
+$lang['L_SQL_TBLPROPSOF'] = 'Tabelegenskaber for';
+$lang['L_SQL_EDITFIELD'] = 'Ret felt';
+$lang['L_SQL_NEWFIELD'] = 'Nyt felt';
+$lang['L_SQL_INDEXES'] = 'Indeks';
+$lang['L_SQL_ATPOSITION'] = 'indsæt på position';
+$lang['L_SQL_FIRST'] = 'først';
+$lang['L_SQL_AFTER'] = 'efter';
+$lang['L_SQL_CHANGEFIELD'] = 'ændre felt';
+$lang['L_SQL_INSERTFIELD'] = 'indsæt felt';
+$lang['L_SQL_INSERTNEWFIELD'] = 'indsæt nyt felt';
+$lang['L_SQL_TABLEINDEXES'] = 'Indeks på tabel';
+$lang['L_SQL_ALLOWDUPS'] = 'Dubletter tilladte';
+$lang['L_SQL_CARDINALITY'] = 'Kardinalitet';
+$lang['L_SQL_TABLENOINDEXES'] = 'Ingen indeks i tabel';
+$lang['L_SQL_CREATEINDEX'] = 'opret nyt indeks';
+$lang['L_SQL_WASEMPTIED'] = 'blev tømt';
+$lang['L_SQL_RENAMEDTO'] = 'blev omdøbt til';
+$lang['L_SQL_DBCOPY'] = 'Indholdet af database `%s` blev kopieret til database `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'Database-strukturen fra database `%s` blev kopieret til database `%s`.';
+$lang['L_SQL_WASCREATED'] = 'blev oprettet';
+$lang['L_SQL_RENAMEDB'] = 'Omdøb database';
+$lang['L_SQL_ACTIONS'] = 'Handlinger';
+$lang['L_SQL_CHOOSEACTION'] = 'Vælg handling';
+$lang['L_SQL_DELETEDB'] = 'Slet database';
+$lang['L_SQL_EMPTYDB'] = 'Tøm database';
+$lang['L_SQL_COPYDATADB'] = 'Kopier hele databasen til';
+$lang['L_SQL_COPYSDB'] = 'Kopier database-struktur';
+$lang['L_SQL_IMEXPORT'] = 'Import-Eksport';
+$lang['L_INFO_RECORDS'] = 'poster';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Skal tabellen `%s` tømmes og indeksene nulstilles?';
+$lang['L_EDIT'] = 'ret';
+$lang['L_DELETE'] = 'slet';
+$lang['L_EMPTY'] = 'tøm';
+$lang['L_EMPTYKEYS'] = 'tøm og nulstil alle indeks';
+$lang['L_SQL_TABLEEMPTIED'] = 'Tabel `%s` blev tømt.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Tabel `%s` blev tømt og indeksene blev nulstillet.';
+$lang['L_SQL_LIBRARY'] = 'SQL-bibliotek';
+$lang['L_SQL_ATTRIBUTES'] = 'Attributter';
+$lang['L_SQL_UPLOADEDFILE'] = 'indlæst fil: ';
+$lang['L_SQL_IMPORT'] = 'Import i Database `%s`';
+$lang['L_EXPORT'] = 'Eksport';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = 'Import-opsætning';
+$lang['L_CSVOPTIONS'] = 'CSV-opsætning';
+$lang['L_IMPORTTABLE'] = 'Import i Tabel';
+$lang['L_NEWTABLE'] = 'Ny tabel';
+$lang['L_IMPORTSOURCE'] = 'Import-kilde';
+$lang['L_FROMTEXTBOX'] = 'fra tekstboks';
+$lang['L_FROMFILE'] = 'fra fil';
+$lang['L_EMPTYTABLEBEFORE'] = 'Tøm tabel før';
+$lang['L_CREATEAUTOINDEX'] = 'Opret Auto-Indeks';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Feltnavne i første linie';
+$lang['L_CSV_FIELDSEPERATE'] = 'Felter adskilt med';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Felter lukket inde i';
+$lang['L_CSV_FIELDSESCAPE'] = 'Felter escaped med';
+$lang['L_CSV_EOL'] = 'Udskil linier med';
+$lang['L_CSV_NULL'] = 'Erstat NULL med';
+$lang['L_CSV_FILEOPEN'] = 'Åbn CSV-fil';
+$lang['L_IMPORTIEREN'] = 'Import';
+$lang['L_SQL_EXPORT'] = 'Eksport fra Database `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Eksport-opsætning';
+$lang['L_EXCEL2003'] = 'Excel fra 2003';
+$lang['L_SHOWRESULT'] = 'vis resultat';
+$lang['L_SENDRESULTASFILE'] = 'send resultat som fil';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> linier eksporteret';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Felt-tælleren stemmer ikke overens med de importerede data (%d i stedet for %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d felter genkendt, totalt %d linier';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Fejl ved oprettelse af tabel `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'vælg venligst en fil.';
+$lang['L_CSV_NODATA'] = 'Ingen data fundet til import!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'generelle funktioner';
+$lang['L_SQLLIB_RESETAUTO'] = 'nulstil auto-increment (forøgelse)';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'deaktiver Board';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'aktiver Board';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Ingen tabeller valgt!';
+$lang['L_TOOLS'] = 'Funktioner';
+$lang['L_TOOLS_TOOLBOX'] = 'Vælg Database / Datebasefunktioner / Import - Eksport';
+$lang['L_SQL_OPENFILE'] = 'Åbn SQL-fil';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Upload';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maksimal filstørrelse';
+$lang['L_SQL_SEARCH'] = 'Søg';
+$lang['L_SQL_SEARCHWORDS'] = 'Søgeord';
+$lang['L_START_SQL_SEARCH'] = 'Start søgning';
+$lang['L_RESET_SEARCHWORDS'] = 'nulstil søgeord';
+$lang['L_SEARCH_OPTIONS'] = 'Søgeindstillinger';
+$lang['L_SEARCH_RESULTS'] = 'Søgningen efter "<b>%s</b>" i tabellen "<b>%s</b>" giver følgende resultater';
+$lang['L_SEARCH_NO_RESULTS'] = 'Søgningen efter "<b>%s</b>" i tabel "<b>%s</b>" gav ingen rsultater!';
+$lang['L_NO_ENTRIES'] = 'Tabel "<b>%s</b>" er tom og indeholder ingen poster.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Bladre: fremad=ALT+V, baglæns=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'en kolonne skal indeholde et af søgeordene (ELLER-søgning)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'en række skal indeholde alle søgeordene men kan være i hvilkensomhelst kolonne (kan tage noget tid)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'en kolonne skal indeholde ALLE søgeord (OG-søgning)';
+$lang['L_SEARCH_IN_TABLE'] = 'Søg i tabel';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Edit table structure';
+$lang['L_DEFAULT_CHARSET'] = 'Default character set';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primary key';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Unique key';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Fulltext key';
+$lang['L_TITLE_NOKEY'] = 'No key';
+$lang['L_TITLE_SEARCH'] = 'Search';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQl Documentation';
+$lang['L_TITLE_UPLOAD'] = 'Upload SQL file';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'Størrelse';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/de_du/help.php b/msd/language/de/help.html
similarity index 63%
rename from msd/language/de_du/help.php
rename to msd/language/de/help.html
index c5c1094c..059bfa8f 100644
--- a/msd/language/de_du/help.php
+++ b/msd/language/de/help.html
@@ -1,47 +1,73 @@
 <div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
 
 <h3>Über dieses Projekt</h3>
-Die Idee für dieses Projekt kam von Daniel Schlichtholz.<p>Er eröffnete 2004 das Forum <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a>, und schon bald fanden sich Hobby-Programmierer, die neue Skripte schrieben und die von Daniel erweiterten.<br>Innerhalb kürzester Zeit entstand aus dem kleinen Backupskript ein stattliches Projekt.<p>Wenn Du Vorschläge zur Verbesserung hast, dann wende Dich an das MySQLDumper-Forum <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>Wir wünschen Dir viel Vergnügen mit diesem Projekt.<br><p><h4>Das MySQLDumper-Team</h4>
+<p><strong>MyOOS [Dumper]</strong> ist eine verbesserte Version von MySQLDumper 1.24.4 (24. Januar 2011). Diese Weiterentwicklung berücksichtig die Entwicklung von PHP.</p>
+<p>Vor allem Stabilität, Sicherheit und Handhabung stehen bei <strong>MyOOS [Dumper]</strong> maßgeblich im Vordergrund. Aber auch ein ansprechendes Template wird mitgeliefert, welches beliebig bearbeitet und an eigene Bedürfnisse angepasst werden kann.</p>
 
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
 
-<h3>MySQLDumper Hilfe</h3>
+<p><strong>MyOOS [Dumper]</strong> ist ein Sicherungsprogramm für MySQL-Datenbanken, geschrieben in PHP und Perl. Damit können Sicherungskopien der Daten (Shop, Blog, usw.) erstellt und bei Bedarf auch wieder hergestellt werden. Besonders bei Web-Space ohne Shell-Zugang bietet sich MyOOS [Dumper] als sinnvolle Alternative an.</p> 
+
+<p>Die Idee für MySQLDumper kam von Daniel Schlichtholz. Er eröffnete 2004 das Forum MySQLDumper, woraufhin Programmierer neue Skripte schrieben und bestehende erweiterten.</p>
+
+
+
+<h3>Wunschliste / Künftige Attraktionen</h3>
+<p>Hast du Verbesserungsvorschläge? Zögere nicht, das Entwicklerteam über das Forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a> zu kontaktieren.</p>
+
+
+<h3>Mitwirken</h3>
+<p>Wenn du uns dabei helfen möchtest, das MyOOS Projekt zu verbessern, freuen wir uns hier auf deine Pull Requests via GitHub.</p>
+<a href="https://github.com/r23/MyOOS/" target="_blank">https://github.com/r23/MyOOS/</a>
+
+
+<h3>Finanzielle Unterstützung</h3>
+<p>Man kann mit PayPal Me<br>
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>oder über den QR Code<br>  
+<img src="images/qrcode.png" alt="Finanzielle Unterstützung für MyOOS [Dumper]"></p>
+
+Geld an das MyOOS Projekt senden. <br>
+
+<p>Wir wünschen Dir viel Vergnügen mit diesem Projekt.<br><p><h4>Das MyOOS [Dumper]-Team</h4>
+
+<img src="css/mod/pics/h1_logo.gif" alt="MyOOS [Dumper]"><br>
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+
+<h3>MyOOS [Dumper] Hilfe</h3>
 
 <h4>Download</h4>
-Dieses Script erhaltet Ihr auf der Homepage von MySQLDumper.<br>
-Es empfiehlt sich, die Homepage regelmäßig zu besuchen, um Updates und
-Hilfestellungen zu erlangen.<br>
-Die Adresse lautet: <a href="http://www.mysqldumper.de" target="_blank">
-http://www.mysqldumper.de</a>
+<p>Aktuelle Versionen erhälst du immer über GitHub<br>
+<a href="https://github.com/r23/MyOOS/releases" target="_blank">https://github.com/r23/MyOOS/releases</a></p>
+
 
 <h4>Systemvoraussetzung</h4>
-Das Script arbeitet auf jedem Server (Windows, Linux, ...) <br>
-mit PHP >= Version 4.3.4 mit GZip-Unterstützung, MySQL (ab Version 3.23), JavaScript (muss aktiviert sein).
+<p>Das Script arbeitet auf jedem Server (Windows, Linux, ...) <br>
+mit PHP >= Version 7.4 mit GZip-Unterstützung, MySQL (ab Version 4.1), JavaScript (muss aktiviert sein).</p>
+<p>Aus dem MyOOS Archiv den Ordner mod in einen separaten Arbeitsordner kopieren.</p>
 
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
+<h4>Installation</h4></a>
 Die Installation geht einfach von statten.
-Entpackt das Archiv in einen beliebigen Ordner.<br>
-Ladet alle Dateien auf Euren Webserver hoch. (z. B. in die unterste Ebene in [Server Webverzeichnis/]MySQLDumper)<br>
+<p>Aus dem MyOOS Archiv den Ordner mod in einen beliebigen Ordner kopieren.<br>
+Ladet alle Dateien aus dem ordner mod auf deinen Webserver hoch. (z. B. in die unterste Ebene in [Server Webverzeichnis/]mod)<br>
 ... fertig!<br>
-Ihr könnt MySQLDumper nun im Webbrowser durch "http://mein-webserver/MySQLDumper" aufrufen,<br>
+Du kannst MyOOS [Dumper] nun im Webbrowser durch "https://example.com/mod/" aufrufen,<br>
 um die Installation abzuschließen. Folgt einfach den Instruktionen.<br>
-<br><b>Hinweis:</b><br><i>Falls auf Eurem Server der PHP-Safemode eingeschaltet ist, darf das Script keine
-Verzeichnisse erstellen.<br>
-Dies müsst Ihr dann von Hand nachholen, da MySqlDump die Daten geordnet in
+<br><b>Hinweis:</b><br><i>Falls auf Eurem Server das Script keine Verzeichnisse erstellen darf, <br>
+müsst Ihr dies dann von Hand nachholen, da MyOOS [Dumper] die Daten geordnet in
 Verzeichnissen ablegt.<br> 
 Das Script bricht mit einer entsprechenden Anweisung ab!<br>
 Nachdem Ihr die Verzeichnisse (dem Hinweis entsprechend) erstellt habt, läuft es normal und ohne Einschränkungen.</i>
 
 <a name="perl"></a><h4>Perlskript Anleitung</h4>
 Die Meisten haben ein cgi-bin Verzeichnis, in dem Perl ausgeführt werden kann. <br>
-Dies ist meist per Browser über http://www.domain.de/cgi-bin/ erreichbar. <br>
+Dies ist meist per Browser über http://www.example.com/cgi-bin/ erreichbar. <br>
 <br>
 Für diesen Fall bitte folgende Schritte durchführen:<br><br>
 
-1. Rufe im MySQLDumper die Seite Backup auf und klicke auf "Backup Perl". <br>
+1. Rufe im MyOOS [Dumper] die Seite Backup auf und klicke auf "Backup Perl". <br>
 2. Kopiere den Pfad, der hinter Eintrag in crondump.pl für $absolute_path_of_configdir: steht. <br>
 3. Öffne die Datei "crondump.pl" im Editor.<br>
 4. Trage den kopierten Pfad dort bei absolute_path_of_configdir ein (keine Leerzeichen).<br>
@@ -49,7 +75,7 @@ Für diesen Fall bitte folgende Schritte durchführen:<br><br>
 6. Kopiere crondump.pl, sowie perltest.pl und simpletest.pl ins cgi-bin-Verzeichnis (Ascii-Modus im FTP).<br>
 7. Gebe den Dateien die Rechte 755. <br>
 7b. Wenn die Endung cgi gewünscht ist, ändere bei allen 3 Dateien die Endung von pl -> cgi (umbenennen). <br>
-8. Rufe die Konfiguration im MySQLDumper auf.<br>
+8. Rufe die Konfiguration im MyOOS [Dumper] auf.<br>
 9. Wähle die Seite Cronscript. <br>
 10. Ändere Perl Ausführungspfad in /cgi-bin/ .<br>
 10b. Wenn die Scripte .pl haben, ändere die Dateiendung auf .cgi .<br>
@@ -59,7 +85,7 @@ Fertig, die Skripte lassen sich nun von der Backupseite aufrufen.<br><br>
 
 Wer Perl in allen Verzeichnissen ausführen kann, dem reichen folgende Schritte:<br><br>
 
-1. Rufe im MySQLDumper die Seite Backup auf. <br>
+1. Rufe im MyOOS [Dumper] die Seite Backup auf. <br>
 2. Kopiere den Pfad, der hinter Eintrag in crondump.pl für $absolute_path_of_configdir: steht. <br>
 3. Öffne die Datei "crondump.pl" im Editor. <br>
 4. Trage den kopierten Pfad dort bei absolute_path_of_configdir ein (keine Leerzeichen). <br>
@@ -90,8 +116,7 @@ Hier könnt Ihr eure Konfiguration bearbeiten, abspeichern oder die Ausgangskonf
 wieder herstellen.
 <ul><br>
 	<li><a name="conf1"></a><strong>Konfigurierte Datenbanken:</strong> die Auflistung der konfigurierten Datenbanken. Die aktive Datenbank wird in <b>bold</b> gelistet. </li>
-	<li><a name="conf2"></a><strong>Tabellen-Präfix:</strong> hier könnt Ihr (für jede Datenbank) einen Präfix angeben. Dies ist ein Filter, der bei Dumps nur die Tabellen berücksichtigt, die mit diesem Präfix beginnen (z.B. alle Tabellen, die mit "phpBB_" beginnen). Wenn alle Tabellen dieser Datenbank gespeichert werden sollen, 
-so lasst das Feld einfach leer.</li>
+	<li><a name="conf2"></a><strong>Tabellen-Präfix:</strong> hier könnt Ihr (für jede Datenbank) einen Präfix angeben. Dies ist ein Filter, der bei Dumps nur die Tabellen berücksichtigt, die mit diesem Präfix beginnen (z.B. alle Tabellen, die mit "phpBB_" beginnen). Wenn alle Tabellen dieser Datenbank gespeichert werden sollen, so lasst das Feld einfach leer.</li>
 	<li><a name="conf3"></a><strong>GZip-Kompression:</strong> Hier kann die Kompression aktiviert werden. Empfehlenswert ist die Aktivierung, da die Dateien doch wesentlich kleiner werden und Speicherplatz immer rar ist.</li>
 	<li><a name="conf5"></a><strong>Email mit Dumpfile:</strong> Ist diese Option aktiviert, so wird nach abgeschlossenem Backup eine Email mit dem Dump als Anhang verschickt (Vorsicht, Kompression sollte unbedingt an sein, sonst wird der Anhang zu gross und kann evtl. nicht versandt werden!).</li>
 	<li><a name="conf6"></a><strong>Email-Adresse:</strong> Empfängeradresse für die Email.</li>
diff --git a/msd/language/de/lang.php b/msd/language/de/lang.php
index 6adeac18..9806fefe 100644
--- a/msd/language/de/lang.php
+++ b/msd/language/de/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="ja";
-$lang['L_TO']="bis";
-$lang['L_ACTIVATED']="aktiviert";
-$lang['L_NOT_ACTIVATED']="nicht aktiviert";
-$lang['L_ERROR']="Fehler";
-$lang['L_OF']=" von ";
-$lang['L_ADDED']="hinzugefügt";
-$lang['L_DB']="Datenbank";
-$lang['L_DBS']="Datenbanken";
-$lang['L_TABLES']="Tabellen";
-$lang['L_TABLE']="Tabelle";
-$lang['L_RECORDS']="Datensätze";
-$lang['L_COMPRESSED']="komprimiert (gz)";
-$lang['L_NOTCOMPRESSED']="normal (unkomprimiert)";
-$lang['L_GENERAL']="allgemein";
-$lang['L_COMMENT']="Kommentar";
-$lang['L_FILESIZE']="Dateigröße";
-$lang['L_ALL']="alle";
-$lang['L_NONE']="keine";
-$lang['L_WITH']=" mit ";
-$lang['L_DIR']="Verzeichnis";
-$lang['L_RECHTE']="Rechte";
-$lang['L_STATUS']="Status";
-$lang['L_FINISHED']="fertig";
-$lang['L_FILE']="Datei";
-$lang['L_FIELDS']="Felder";
-$lang['L_NEW']="neu";
-$lang['L_CHARSET']="Zeichensatz";
-$lang['L_COLLATION']="Sortierung";
-$lang['L_CHANGE']="Ändern";
-$lang['L_IN']="in";
-$lang['L_DO']="ausführen";
-$lang['L_VIEW']="ansehen";
-$lang['L_EXISTING']="vorhanden";
-$lang['L_BACK']="zurück";
-$lang['L_DB_HOST']="Datenbank-Hostname";
-$lang['L_DB_USER']="Datenbank-Benutzer";
-$lang['L_DB_PASS']="Datenbank-Passwort";
-$lang['L_INFO_SCRIPTDIR']="Verzeichnis von MySQLDumper";
-$lang['L_INFO_ACTDB']="Aktuelle Datenbank";
-$lang['L_WRONGCONNECTIONPARS']="Falsche oder keine Verbindungsparameter!";
-$lang['L_CONN_NOT_POSSIBLE']="Verbindung nicht möglich!";
-$lang['L_SERVERCAPTION']="Anzeige des Servers";
-$lang['L_HELP_SERVERCAPTION']="Bei Benutzung auf verschieden Systemen kann es hilfreich sein, die Server-Adresse farblich gekennzeichnet einzublenden";
-$lang['L_ACTIVATE_MULTIDUMP']="Multidump aktivieren";
-$lang['L_SAVE']="Speichern";
-$lang['L_RESET']="Zurücksetzen";
-$lang['L_PRAEFIX']="Tabellen-Präfix";
-$lang['L_AUTODELETE']="Automatisches Löschen der Backups";
-$lang['L_MAX_BACKUP_FILES_EACH2']="für jede Datenbank";
-$lang['L_SAVING_DB_FORM']="Datenbank";
-$lang['L_TESTCONNECTION']="Verbindung testen";
-$lang['L_BACK_TO_MINISQL']="Datenbank bearbeiten";
-$lang['L_CREATE']="Anlegen";
-$lang['L_VARIABELN']="Variablen";
-$lang['L_STATUSINFORMATIONEN']="Statusinformationen";
-$lang['L_VERSIONSINFORMATIONEN']="Versionsinformationen";
-$lang['L_MSD_INFO']="MyOOS [Dumper] Informationen";
-$lang['L_BACKUPFILESANZAHL']="Im Backup-Verzeichnis befinden sich";
-$lang['L_LASTBACKUP']="Letztes Backup";
-$lang['L_NOTAVAIL']="<em>nicht verfügbar</em>";
-$lang['L_VOM']="vom";
-$lang['L_MYSQLVARS']="MySQL-Variablen";
-$lang['L_MYSQLSYS']="MySQL-Befehle";
-$lang['L_STATUS']="Status";
-$lang['L_PROZESSE']="Prozesse";
-$lang['L_INFO_NOVARS']="keine Variablen verfügbar";
-$lang['L_INHALT']="Inhalt";
-$lang['L_INFO_NOSTATUS']="kein Status verfügbar";
-$lang['L_INFO_NOPROCESSES']="keine laufenden Prozesse";
-$lang['L_FM_FREESPACE']="Freier Speicher auf Server";
-$lang['L_LOAD_DATABASE']="Datenbanken neu laden";
-$lang['L_HOME']="Home";
-$lang['L_CONFIG']="Konfiguration";
-$lang['L_DUMP']="Backup";
-$lang['L_RESTORE']="Wiederherstellung";
-$lang['L_FILE_MANAGE']="Verwaltung";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Datenbank wählen";
-$lang['L_CREDITS']="Credits / Hilfe";
-$lang['L_MULTI_PART']="Multipart-Backup";
-$lang['L_LOGFILENOTWRITABLE']="Log-File kann nicht geschrieben werden!";
-$lang['L_SQL_ERROR1']="Fehler bei der Anfrage:";
-$lang['L_SQL_ERROR2']="MySQL meldet:";
-$lang['L_UNKNOWN']="unbekannt";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="unbekannt";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Komplette Ausgabe loggen";
-$lang['L_NO']="nein";
-$lang['L_CREATE_DATABASE']="Neue Datenbank anlegen";
-$lang['L_EXPORTFINISHED']="Export beendet.";
-$lang['L_SQL_BROWSER']="SQL-Browser";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Standardkodierung des MySQL-Servers";
-$lang['L_TITLE_SHOW_DATA']="Daten anzeigen";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Primärschlüssel wirklich löschen?";
-$lang['L_SETPRIMARYKEYSFOR']="Setzen neuer Primärschlüssel für die Tabelle";
-$lang['L_PRIMARYKEY_FIELD']="Schlüsselfeld";
-$lang['L_PRIMARYKEYS_SAVE']="Primärschlüssel speichern";
-$lang['L_CANCEL']="Abbruch";
-$lang['L_VISIT_HOMEPAGE']="Besuchen Sie die Homepage";
-$lang['L_SECONDS']="Sekunden";
-$lang['L_BACKUPS']="Sicherungsdateien";
-$lang['L_MINUTES']="Minuten";
-$lang['L_PAGE_REFRESHS']="Seitenaufrufe";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Setzen neuer Indizes für die Tabelle";
-$lang['L_KEY_CONFIRMDELETE']="Index wirklich löschen?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'ja';
+$lang['L_TO'] = 'bis';
+$lang['L_ACTIVATED'] = 'aktiviert';
+$lang['L_NOT_ACTIVATED'] = 'nicht aktiviert';
+$lang['L_ERROR'] = 'Fehler';
+$lang['L_OF'] = ' von ';
+$lang['L_ADDED'] = 'hinzugefügt';
+$lang['L_DB'] = 'Datenbank';
+$lang['L_DBS'] = 'Datenbanken';
+$lang['L_TABLES'] = 'Tabellen';
+$lang['L_TABLE'] = 'Tabelle';
+$lang['L_RECORDS'] = 'Datensätze';
+$lang['L_COMPRESSED'] = 'komprimiert (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (unkomprimiert)';
+$lang['L_COMMENT'] = 'Kommentar';
+$lang['L_FILESIZE'] = 'Dateigröße';
+$lang['L_ALL'] = 'alle';
+$lang['L_NONE'] = 'keine';
+$lang['L_WITH'] = ' mit ';
+$lang['L_DIR'] = 'Verzeichnis';
+$lang['L_RECHTE'] = 'Rechte';
+$lang['L_STATUS'] = 'Status';
+$lang['L_FINISHED'] = 'fertig';
+$lang['L_FILE'] = 'Datei';
+$lang['L_FIELDS'] = 'Felder';
+$lang['L_NEW'] = 'neu';
+$lang['L_CHARSET'] = 'Zeichensatz';
+$lang['L_COLLATION'] = 'Sortierung';
+$lang['L_CHANGE'] = 'Ändern';
+$lang['L_IN'] = 'in';
+$lang['L_DO'] = 'ausführen';
+$lang['L_VIEW'] = 'ansehen';
+$lang['L_EXISTING'] = 'vorhanden';
+$lang['L_BACK'] = 'zurück';
+$lang['L_DB_HOST'] = 'Datenbank-Hostname';
+$lang['L_DB_USER'] = 'Datenbank-Benutzer';
+$lang['L_DB_PASS'] = 'Datenbank-Passwort';
+$lang['L_INFO_SCRIPTDIR'] = 'Verzeichnis von MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Aktuelle Datenbank';
+$lang['L_WRONGCONNECTIONPARS'] = 'Falsche oder keine Verbindungsparameter!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Verbindung nicht möglich!';
+$lang['L_SERVERCAPTION'] = 'Anzeige des Servers';
+$lang['L_HELP_SERVERCAPTION'] = 'Bei Benutzung auf verschieden Systemen kann es hilfreich sein, die Server-Adresse farblich gekennzeichnet einzublenden';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'Multidump aktivieren';
+$lang['L_SAVE'] = 'Speichern';
+$lang['L_RESET'] = 'Zurücksetzen';
+$lang['L_PRAEFIX'] = 'Tabellen-Präfix';
+$lang['L_AUTODELETE'] = 'Automatisches Löschen der Backups';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'für jede Datenbank';
+$lang['L_SAVING_DB_FORM'] = 'Datenbank';
+$lang['L_TESTCONNECTION'] = 'Verbindung testen';
+$lang['L_BACK_TO_MINISQL'] = 'Datenbank bearbeiten';
+$lang['L_CREATE'] = 'Anlegen';
+$lang['L_VARIABELN'] = 'Variablen';
+$lang['L_STATUSINFORMATIONEN'] = 'Statusinformationen';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versionsinformationen';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] Informationen';
+$lang['L_BACKUPFILESANZAHL'] = 'Im Backup-Verzeichnis befinden sich';
+$lang['L_LASTBACKUP'] = 'Letztes Backup';
+$lang['L_NOTAVAIL'] = '<em>nicht verfügbar</em>';
+$lang['L_VOM'] = 'vom';
+$lang['L_MYSQLVARS'] = 'MySQL-Variablen';
+$lang['L_MYSQLSYS'] = 'MySQL-Befehle';
+$lang['L_STATUS'] = 'Status';
+$lang['L_PROZESSE'] = 'Prozesse';
+$lang['L_INFO_NOVARS'] = 'keine Variablen verfügbar';
+$lang['L_INHALT'] = 'Inhalt';
+$lang['L_INFO_NOSTATUS'] = 'kein Status verfügbar';
+$lang['L_INFO_NOPROCESSES'] = 'keine laufenden Prozesse';
+$lang['L_FM_FREESPACE'] = 'Freier Speicher auf Server';
+$lang['L_LOAD_DATABASE'] = 'Datenbanken neu laden';
+$lang['L_HOME'] = 'Startseite';
+$lang['L_CONFIG'] = 'Konfiguration';
+$lang['L_DUMP'] = 'Sicherung';
+$lang['L_RESTORE'] = 'Wiederherstellung';
+$lang['L_FILE_MANAGE'] = 'Verwaltung';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Datenbank wählen';
+$lang['L_CREDITS'] = 'Credits / Hilfe';
+$lang['L_MULTI_PART'] = 'Multipart-Backup';
+$lang['L_LOGFILENOTWRITABLE'] = 'Log-File kann nicht geschrieben werden!';
+$lang['L_SQL_ERROR1'] = 'Fehler bei der Anfrage:';
+$lang['L_SQL_ERROR2'] = 'MySQL meldet:';
+$lang['L_UNKNOWN'] = 'unbekannt';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'unbekannt';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Komplette Ausgabe loggen';
+$lang['L_NO'] = 'nein';
+$lang['L_CREATE_DATABASE'] = 'Neue Datenbank anlegen';
+$lang['L_EXPORTFINISHED'] = 'Export beendet.';
+$lang['L_SQL_BROWSER'] = 'SQL-Browser';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Standardkodierung des MySQL-Servers';
+$lang['L_TITLE_SHOW_DATA'] = 'Daten anzeigen';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Primärschlüssel wirklich löschen?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Setzen neuer Primärschlüssel für die Tabelle';
+$lang['L_PRIMARYKEY_FIELD'] = 'Schlüsselfeld';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Primärschlüssel speichern';
+$lang['L_CANCEL'] = 'Abbruch';
+$lang['L_VISIT_HOMEPAGE'] = 'Besuchen Sie die Homepage';
+$lang['L_SECONDS'] = 'Sekunden';
+$lang['L_BACKUPS'] = 'Sicherungsdateien';
+$lang['L_MINUTES'] = 'Minuten';
+$lang['L_PAGE_REFRESHS'] = 'Seitenaufrufe';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Setzen neuer Indizes für die Tabelle';
+$lang['L_KEY_CONFIRMDELETE'] = 'Index wirklich löschen?';
diff --git a/msd/language/de/lang_config_overview.php b/msd/language/de/lang_config_overview.php
index ddea076e..a2efe9b1 100644
--- a/msd/language/de/lang_config_overview.php
+++ b/msd/language/de/lang_config_overview.php
@@ -1,111 +1,129 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Konfiguration";
-$lang['L_SAVE_SUCCESS']="Die Einstellungen wurden erfolgreich in der Konfigurationsdatei \"%s\" gespeichert.";
-$lang['L_CONFIG_LOADED']="Die Konfiguration \"%s\" wurde erfolgreich geladen.";
-$lang['L_SAVE_ERROR']="Die Einstellungen konnten nicht gespeichert werden!";
-$lang['L_CONFIG_EMAIL']="E-Mail-Benachrichtigung";
-$lang['L_CONFIG_AUTODELETE']="Auto Löschen";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="Maximale Dateigröße";
-$lang['L_HELP_MULTIPART']="Bei eingeschaltetem Multipart werden mehrere Backup-Dateien erzeugt, deren Maximalgröße sich nach der unteren Einstellung richtet";
-$lang['L_HELP_MULTIPARTGROESSE']="Die maximale Größe der einzelnen Backup-Dateien kann hier bei eingeschaltetem Multipart bestimmt werden";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Datenbank vor Wiederherstellung löschen";
-$lang['L_ALLPARS']="alle Parameter";
-$lang['L_CRON_EXTENDER']="Dateiendung des Scripts";
-$lang['L_CRON_SAVEPATH']="Konfigurationsdatei";
-$lang['L_CRON_PRINTOUT']="Textausgabe";
-$lang['L_CONFIG_CRONPERL']="Crondump-Einstellungen für das Perlscript";
-$lang['L_CRON_MAILPRG']="Mailprogramm";
-$lang['L_OPTIMIZE']="Tabellen vor dem Backup optimieren";
-$lang['L_HELP_OPTIMIZE']="Wenn die Option aktiviert ist, werden vor jedem Backup alle Tabellen optimiert";
-$lang['L_HELP_FTPTIMEOUT']="Die Zeit, die bei keiner Übertragung zum Timeout führt, Default = 90 Sekunden.";
-$lang['L_FTP_TIMEOUT']="Verbindungs-Timeout";
-$lang['L_HELP_FTPSSL']="Gibt an, ob eine sichere SSL-Verbindung für die Übertragung benutzt werden soll.";
-$lang['L_CONFIG_ASKLOAD']="Sollen die Einstellungen wirklich mit den Anfangseinstellungen überschrieben werden?";
-$lang['L_LOAD']="Grundeinstellungen";
-$lang['L_LOAD_SUCCESS']="Die Anfangseinstellungen wurden geladen.";
-$lang['L_CRON_CRONDBINDEX']="Datenbank";
-$lang['L_WITHATTACH']=" mit Anhang";
-$lang['L_WITHOUTATTACH']=" ohne Anhang";
-$lang['L_MULTIDUMPCONF']="=Multidump Einstellungen=";
-$lang['L_MULTIDUMPALL']="=alle Datenbanken=";
-$lang['L_GZIP']="GZip-Kompression";
-$lang['L_SEND_MAIL_FORM']="E-Mail senden";
-$lang['L_SEND_MAIL_DUMP']="Backup anhängen";
-$lang['L_EMAIL_ADRESS']="Empfänger";
-$lang['L_EMAIL_SENDER']="Absender der E-Mail";
-$lang['L_EMAIL_MAXSIZE']="Maximale Größe des Anhangs";
-$lang['L_NUMBER_OF_FILES_FORM']="Anzahl von Backup-Dateien pro Datenbank";
-$lang['L_LANGUAGE']="Sprache";
-$lang['L_LIST_DB']="Konfigurierte Datenbanken:";
-$lang['L_CONFIG_FTP']="FTP-Transfer der Backup-Datei";
-$lang['L_FTP_TRANSFER']="FTP-Transfer";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="User";
-$lang['L_FTP_PASS']="Passwort";
-$lang['L_FTP_DIR']="Upload-Ordner";
-$lang['L_FTP_SSL']="Sichere SSL-FTP-Verbindung";
-$lang['L_FTP_USESSL']="benutze SSL-Verbindung";
-$lang['L_SQLBOXHEIGHT']="Höhe der SQL-Box";
-$lang['L_SQLLIMIT']="Anzahl der Datensätze pro Seite";
-$lang['L_BBPARAMS']="Einstellung für BB-Code";
-$lang['L_BBTEXTCOLOR']="Textfarbe";
-$lang['L_HELP_COMMANDS']="Man kann vor und nach dem Backup einen Befehl ausführen lassen.
-Dies kann eine SQL-Anweisung sein oder ein Systembefehl (z. B. ein Script)";
-$lang['L_COMMAND']="Befehl";
-$lang['L_WRONG_CONNECTIONPARS']="Verbindungsparameter stimmen nicht!";
-$lang['L_CONNECTIONPARS']="Verbindungsparameter";
-$lang['L_EXTENDEDPARS']="erweiterte Parameter";
-$lang['L_FADE_IN_OUT']="ein-/ausblenden";
-$lang['L_DB_BACKUPPARS']="Einstellungen";
-$lang['L_GENERAL']="Allgemein";
-$lang['L_MAXSIZE']="maximale Größe";
-$lang['L_ERRORHANDLING_RESTORE']="Fehlerbehandlung bei Wiederherstellung";
-$lang['L_EHRESTORE_CONTINUE']="fortfahren und Fehler protokollieren";
-$lang['L_EHRESTORE_STOP']="anhalten";
-$lang['L_IN_MAINFRAME']="im Hauptframe";
-$lang['L_IN_LEFTFRAME']="im linken Frame";
-$lang['L_WIDTH']="Breite";
-$lang['L_SQL_BEFEHLE']="SQL-Befehle";
-$lang['L_DOWNLOAD_LANGUAGES']="andere Sprachen herunterladen";
-$lang['L_DOWNLOAD_STYLES']="andere Themen herunterladen";
-$lang['L_CONNECT_TO']="Verbinde mit";
-$lang['L_CHANGEDIR']="Wechsle in das Verzeichnis ";
-$lang['L_CHANGEDIRERROR']="Es konnte nicht in das Verzeichnis gewechselt werden!";
-$lang['L_FTP_OK']="Die Verbindung wurde erfolgreich hergestellt.";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="Es stehen keine FTP-Funktionen zur Verfügung!";
-$lang['L_FOUND_DB']="gefundene DB: ";
-$lang['L_FTP_CHOOSE_MODE']="FTP-Übertragungsmodus";
-$lang['L_FTP_PASSIVE']="passiven Übertragungsmodus benutzen";
-$lang['L_HELP_FTP_MODE']="Gibt den FTP-Übertragungsmodus an. Wenn Probleme im aktiven Modus auftreten, sollte in den passiven Modus umgeschaltet werden.";
-$lang['L_DB_IN_LIST']="Die Datenbank '%s' konnte nicht hinzugefügt werden, da sie bereits vorhanden ist.";
-$lang['L_ADD_DB_MANUALLY']="Datenbank manuell hinzufügen";
-$lang['L_DB_MANUAL_ERROR']="Die Verbindung zur Datenbank '%s' ist fehlgeschlagen!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Dateifehler: konnte die Datenbank '%s' nicht eintragen!";
-$lang['L_NO_DB_FOUND']="Es wurde keine Datenbank gefunden.
-Blenden Sie die Verbindungsparameter ein und geben Sie den Namen Ihrer Datenbanken manuell ein! ";
-$lang['L_CONFIGFILES']="Konfigurationsdateien";
-$lang['L_CONFIGFILE']="Konfigurationsdatei";
-$lang['L_MYSQL_DATA']="MySQL-Daten";
-$lang['L_CONFIGURATIONS']="Einstellungen";
-$lang['L_ACTION']="Aktion";
-$lang['L_FTP_SEND_TO']="an <strong>%s</strong><br>in <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Empfänger";
-$lang['L_NAME']="Name";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Soll die Konfigurationsdatei %s wirklich gelöscht werden?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Fehler: die Konfigurationsdatei %s konnte nicht gelöscht werden!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Die Konfigurationsdatei %s wurde erfolgreich gelöscht.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Die Konfigurationsdatei %s wurde erfolgreich angelegt.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Der Dateiname \"%s\" enthält ungültige Zeichen.";
-$lang['L_CREATE_CONFIGFILE']="Eine neue Konfigurationsdatei anlegen";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Die Konfigurationsdatei \"%s\" konnte nicht geladen werden.";
-$lang['L_BACKUP_DBS_PHP']="zu sichernde DBs (PHP)";
-$lang['L_BACKUP_DBS_PERL']="zu sichernde DBs (PERL)";
-$lang['L_CRON_COMMENT']="Kommentar eingeben";
-$lang['L_AUTODETECT']="automatisch ermitteln";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Konfiguration';
+$lang['L_SAVE_SUCCESS'] = 'Die Einstellungen wurden erfolgreich in der Konfigurationsdatei "%s" gespeichert.';
+$lang['L_CONFIG_LOADED'] = 'Die Konfiguration "%s" wurde erfolgreich geladen.';
+$lang['L_SAVE_ERROR'] = 'Die Einstellungen konnten nicht gespeichert werden!';
+$lang['L_EMAIL_NOTIFICATION'] = 'E-Mail-Benachrichtigung';
+$lang['L_CONFIG_AUTODELETE'] = 'Auto Löschen';
+$lang['L_CONFIG_INTERFACE'] = 'Benutzeroberfläche';
+$lang['L_CONFIG_EMAIL'] = 'E-Mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'Maximale Dateigröße';
+$lang['L_HELP_MULTIPART'] = 'Bei eingeschaltetem Multipart werden mehrere Backup-Dateien erzeugt, deren Maximalgröße sich nach der unteren Einstellung richtet';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Die maximale Größe der einzelnen Backup-Dateien kann hier bei eingeschaltetem Multipart bestimmt werden';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Datenbank vor Wiederherstellung löschen';
+$lang['L_ALLPARS'] = 'alle Parameter';
+$lang['L_CRON_EXTENDER'] = 'Dateiendung des Scripts';
+$lang['L_CRON_SAVEPATH'] = 'Konfigurationsdatei';
+$lang['L_CRON_PRINTOUT'] = 'Textausgabe';
+$lang['L_CONFIG_CRONPERL'] = 'Crondump-Einstellungen für das Perlscript';
+$lang['L_CRON_MAILPRG'] = 'Mailprogramm';
+$lang['L_OPTIMIZE'] = 'Tabellen vor dem Backup optimieren';
+$lang['L_HELP_OPTIMIZE'] = 'Wenn die Option aktiviert ist, werden vor jedem Backup alle Tabellen optimiert';
+$lang['L_BINARY'] = 'Exportiere binäre Daten im Hex-Format';
+$lang['L_HELP_BINARY'] = 'Bei aktivierter Option werden binäre Daten im Hex-Format exportiert um Kodierungsprobleme zu vermeiden.';
+$lang['SFTP'] = 'Die Zeit, die bei keiner Übertragung zum Timeout führt, Default = 90 Sekunden.';
+$lang['L_FTP_TIMEOUT'] = 'Verbindungs-Timeout';
+$lang['L_HELP_FTPSSL'] = 'Gibt an, ob eine sichere SSL-Verbindung für die Übertragung benutzt werden soll.';
+$lang['L_SFTP_TIMEOUT'] = 'Verbindungs-Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Gibt an, ob eine sichere SSL-Verbindung für die Übertragung benutzt werden soll.';
+$lang['L_CONFIG_ASKLOAD'] = 'Sollen die Einstellungen wirklich mit den Anfangseinstellungen überschrieben werden?';
+$lang['L_LOAD'] = 'Grundeinstellungen';
+$lang['L_LOAD_SUCCESS'] = 'Die Anfangseinstellungen wurden geladen.';
+$lang['L_CRON_CRONDBINDEX'] = 'Datenbank';
+$lang['L_WITHATTACH'] = ' mit Anhang';
+$lang['L_WITHOUTATTACH'] = ' ohne Anhang';
+$lang['L_MULTIDUMPCONF'] = '=Multidump Einstellungen=';
+$lang['L_MULTIDUMPALL'] = '=alle Datenbanken=';
+$lang['L_GZIP'] = 'GZip-Kompression';
+$lang['L_SEND_MAIL_FORM'] = 'E-Mail senden';
+$lang['L_SEND_MAIL_DUMP'] = 'Backup anhängen';
+$lang['L_EMAIL_ADRESS'] = 'Empfänger';
+$lang['L_EMAIL_SENDER'] = 'Absender der E-Mail';
+$lang['L_EMAIL_MAXSIZE'] = 'Maximale Größe des Anhangs';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Anzahl von Backup-Dateien pro Datenbank';
+$lang['L_LANGUAGE'] = 'Sprache';
+$lang['L_LIST_DB'] = 'Konfigurierte Datenbanken:';
+$lang['L_CONFIG_FTP'] = 'FTP-Transfer der Backup-Datei';
+$lang['L_FTP_TRANSFER'] = 'FTP-Transfer';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'User';
+$lang['L_FTP_PASS'] = 'Passwort';
+$lang['L_FTP_DIR'] = 'Upload-Ordner';
+$lang['L_FTP_SSL'] = 'Sichere SSL-FTP-Verbindung';
+$lang['L_FTP_USESSL'] = 'benutze SSL-Verbindung';
+$lang['L_CONFIG_SFTP'] = 'SFTP-Transfer der Backup-Datei';
+$lang['L_SFTP_TRANSFER'] = 'SFTP-Transfer';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'User';
+$lang['L_SFTP_PASS'] = 'Passwort';
+$lang['L_SFTP_DIR'] = 'Upload-Ordner';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Höhe der SQL-Box';
+$lang['L_SQLLIMIT'] = 'Anzahl der Datensätze pro Seite';
+$lang['L_BBPARAMS'] = 'Einstellung für BB-Code';
+$lang['L_BBTEXTCOLOR'] = 'Textfarbe';
+$lang['L_HELP_COMMANDS'] = 'Man kann vor und nach dem Backup einen Befehl ausführen lassen.
+Dies kann eine SQL-Anweisung sein oder ein Systembefehl (z. B. ein Script)';
+$lang['L_COMMAND'] = 'Befehl';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Verbindungsparameter stimmen nicht!';
+$lang['L_CONNECTIONPARS'] = 'Verbindungsparameter';
+$lang['L_EXTENDEDPARS'] = 'erweiterte Parameter';
+$lang['L_FADE_IN_OUT'] = 'ein-/ausblenden';
+$lang['L_DB_BACKUPPARS'] = 'Einstellungen';
+$lang['L_GENERAL'] = 'Allgemein';
+$lang['L_MAXSIZE'] = 'maximale Größe';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Fehlerbehandlung bei Wiederherstellung';
+$lang['L_EHRESTORE_CONTINUE'] = 'fortfahren und Fehler protokollieren';
+$lang['L_EHRESTORE_STOP'] = 'anhalten';
+$lang['L_IN_MAINFRAME'] = 'im Hauptframe';
+$lang['L_IN_LEFTFRAME'] = 'im linken Frame';
+$lang['L_WIDTH'] = 'Breite';
+$lang['L_SQL_BEFEHLE'] = 'SQL-Befehle';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'andere Sprachen herunterladen';
+$lang['L_DOWNLOAD_STYLES'] = 'andere Themen herunterladen';
+$lang['L_CONNECT_TO'] = 'Verbinde mit';
+$lang['L_CHANGEDIR'] = 'Wechsle in das Verzeichnis ';
+$lang['L_CHANGEDIRERROR'] = 'Es konnte nicht in das Verzeichnis gewechselt werden!';
+$lang['L_FTP_OK'] = 'Die Verbindung wurde erfolgreich hergestellt.';
+$lang['L_SFTP_OK'] = 'Die Verbindung wurde erfolgreich hergestellt.';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = 'Es stehen keine FTP-Funktionen zur Verfügung!';
+$lang['L_FOUND_DB'] = 'gefundene DB: ';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP-Übertragungsmodus';
+$lang['L_FTP_PASSIVE'] = 'passiven Übertragungsmodus benutzen';
+$lang['L_HELP_FTP_MODE'] = 'Gibt den FTP-Übertragungsmodus an. Wenn Probleme im aktiven Modus auftreten, sollte in den passiven Modus umgeschaltet werden.';
+$lang['L_SFTP_PASSIVE'] = 'passiven Übertragungsmodus benutzen';
+$lang['L_DB_IN_LIST'] = "Die Datenbank '%s' konnte nicht hinzugefügt werden, da sie bereits vorhanden ist.";
+$lang['L_ADD_DB_MANUALLY'] = 'Datenbank manuell hinzufügen';
+$lang['L_DB_MANUAL_ERROR'] = "Die Verbindung zur Datenbank '%s' ist fehlgeschlagen!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Dateifehler: konnte die Datenbank '%s' nicht eintragen!";
+$lang['L_NO_DB_FOUND'] = 'Es wurde keine Datenbank gefunden.
+Blenden Sie die Verbindungsparameter ein und geben Sie den Namen Ihrer Datenbanken manuell ein! ';
+$lang['L_CONFIGFILES'] = 'Konfigurationsdateien';
+$lang['L_CONFIGFILE'] = 'Konfigurationsdatei';
+$lang['L_MYSQL_DATA'] = 'MySQL-Daten';
+$lang['L_CONFIGURATIONS'] = 'Einstellungen';
+$lang['L_ACTION'] = 'Aktion';
+$lang['L_FTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Empfänger';
+$lang['L_NAME'] = 'Name';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Soll die Konfigurationsdatei %s wirklich gelöscht werden?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Fehler: die Konfigurationsdatei %s konnte nicht gelöscht werden!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Die Konfigurationsdatei %s wurde erfolgreich gelöscht.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Die Konfigurationsdatei %s wurde erfolgreich angelegt.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Der Dateiname "%s" enthält ungültige Zeichen.';
+$lang['L_CREATE_CONFIGFILE'] = 'Eine neue Konfigurationsdatei anlegen';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Die Konfigurationsdatei "%s" konnte nicht geladen werden.';
+$lang['L_BACKUP_DBS_PHP'] = 'zu sichernde DBs (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'zu sichernde DBs (PERL)';
+$lang['L_CRON_COMMENT'] = 'Kommentar eingeben';
+$lang['L_AUTODETECT'] = 'automatisch ermitteln';
diff --git a/msd/language/de/lang_dump.php b/msd/language/de/lang_dump.php
index 10d03dc5..23a606a4 100644
--- a/msd/language/de/lang_dump.php
+++ b/msd/language/de/lang_dump.php
@@ -1,56 +1,57 @@
 <?php
-$lang['L_DUMP_HEADLINE']="erzeuge Backup...";
-$lang['L_GZIP_COMPRESSION']="GZip-Kompression";
-$lang['L_SAVING_TABLE']="Speichere Tabelle ";
-$lang['L_OF']="von";
-$lang['L_ACTUAL_TABLE']="Aktuelle Tabelle";
-$lang['L_PROGRESS_TABLE']="Fortschritt Tabelle";
-$lang['L_PROGRESS_OVER_ALL']="Fortschritt gesamt";
-$lang['L_ENTRY']="Eintrag";
-$lang['L_DONE']="Fertig!";
-$lang['L_DUMP_SUCCESSFUL']=" wurde erfolgreich erstellt.";
-$lang['L_UPTO']="bis";
-$lang['L_EMAIL_WAS_SEND']="Die E-Mail wurde erfolgreich verschickt an ";
-$lang['L_BACK_TO_CONTROL']="weiter";
-$lang['L_BACK_TO_OVERVIEW']="Datenbank-Übersicht";
-$lang['L_DUMP_FILENAME']="Backup-Datei: ";
-$lang['L_WITHPRAEFIX']="mit Praefix";
-$lang['L_DUMP_NOTABLES']="Es konnten keine Tabellen in der Datenbank `<b>%s</b>` gefunden werden.";
-$lang['L_DUMP_ENDERGEBNIS']="Es wurden <b>%s</b> Tabellen mit insgesamt <b>%s</b> Datensätzen gesichert.<br>";
-$lang['L_MAILERROR']="Leider ist beim Verschicken der E-Mail ein Fehler aufgetreten!";
-$lang['L_EMAILBODY_ATTACH']="In der Anlage finden Sie die Sicherung Ihrer MySQL-Datenbank.<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Datei wurde erzeugt:<br><br>%s <br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden nicht als Anhang mitgeliefert!<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden in separaten E-Mails als Anhang geliefert!<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="Die Sicherung überschreitet die Maximalgröße von %s und wurde daher nicht angehängt.<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Datei wurde erzeugt:<br><br>%s
-<br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Das Backup wurde nicht angehängt.<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Datei wurde erzeugt:<br><br>%s
-<br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... nur der Anhang";
-$lang['L_TABLESELECTION']="Tabellenauswahl";
-$lang['L_SELECTALL']="alle auswählen";
-$lang['L_DESELECTALL']="Auswahl aufheben";
-$lang['L_STARTDUMP']="Backup starten";
-$lang['L_LASTBUFROM']="letztes Update vom";
-$lang['L_NOT_SUPPORTED']="Dieses Backup unterstützt diese Funktion nicht.";
-$lang['L_MULTIDUMP']="Multidump: Es wurden <b>%d</b> Datenbanken gesichert.";
-$lang['L_FILESENDFTP']="versende File via FTP... bitte habe etwas Geduld. ";
-$lang['L_FTPCONNERROR']="FTP-Verbindung nicht hergestellt! Verbindung mit ";
-$lang['L_FTPCONNERROR1']=" als Benutzer ";
-$lang['L_FTPCONNERROR2']=" nicht möglich";
-$lang['L_FTPCONNERROR3']="FTP-Upload war fehlerhaft! ";
-$lang['L_FTPCONNECTED1']="Verbunden mit ";
-$lang['L_FTPCONNECTED2']=" auf ";
-$lang['L_FTPCONNECTED3']=" geschrieben";
-$lang['L_NR_TABLES_SELECTED']="- mit %s gewählten Tabellen";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s Tabellen wurden optimiert.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s Fehler aufgetreten: <a href=\"log.php?r=3\">anzeigen</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Schwerwiegender Fehler: die CREATE-Anweisung der Tabelle '%s' in der Datenbank '%s' konnte nicht gelesen werden! ";
 
-
-?>
\ No newline at end of file
+$lang['L_DUMP_HEADLINE'] = 'erzeuge Backup...';
+$lang['L_DUMP_INFO'] = 'Bitte warten! Die Datenbanktabellen werden vor dem Backup optimiert.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip-Kompression';
+$lang['L_SAVING_TABLE'] = 'Speichere Tabelle ';
+$lang['L_OF'] = 'von';
+$lang['L_ACTUAL_TABLE'] = 'Aktuelle Tabelle';
+$lang['L_PROGRESS_TABLE'] = 'Fortschritt Tabelle';
+$lang['L_PROGRESS_OVER_ALL'] = 'Fortschritt gesamt';
+$lang['L_ENTRY'] = 'Eintrag';
+$lang['L_DONE'] = 'Fertig!';
+$lang['L_DUMP_SUCCESSFUL'] = ' wurde erfolgreich erstellt.';
+$lang['L_UPTO'] = 'bis';
+$lang['L_EMAIL_WAS_SEND'] = 'Die E-Mail wurde erfolgreich verschickt an ';
+$lang['L_BACK_TO_CONTROL'] = 'weiter';
+$lang['L_BACK_TO_OVERVIEW'] = 'Datenbank-Übersicht';
+$lang['L_DUMP_FILENAME'] = 'Backup-Datei: ';
+$lang['L_WITHPRAEFIX'] = 'mit Praefix';
+$lang['L_DUMP_NOTABLES'] = 'Es konnten keine Tabellen in der Datenbank `<b>%s</b>` gefunden werden.';
+$lang['L_DUMP_ENDERGEBNIS'] = 'Es wurden <b>%s</b> Tabellen mit insgesamt <b>%s</b> Datensätzen gesichert.<br>';
+$lang['L_MAILERROR'] = 'Leider ist beim Verschicken der E-Mail ein Fehler aufgetreten!';
+$lang['L_EMAILBODY_ATTACH'] = 'In der Anlage finden Sie die Sicherung Ihrer MySQL-Datenbank.<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Datei wurde erzeugt:<br><br>%s <br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden nicht als Anhang mitgeliefert!<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden in separaten E-Mails als Anhang geliefert!<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Die Sicherung überschreitet die Maximalgröße von %s und wurde daher nicht angehängt.<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Datei wurde erzeugt:<br><br>%s
+<br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Das Backup wurde nicht angehängt.<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Datei wurde erzeugt:<br><br>%s
+<br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... nur der Anhang';
+$lang['L_TABLESELECTION'] = 'Tabellenauswahl';
+$lang['L_SELECTALL'] = 'alle auswählen';
+$lang['L_DESELECTALL'] = 'Auswahl aufheben';
+$lang['L_STARTDUMP'] = 'Backup starten';
+$lang['L_LASTBUFROM'] = 'letztes Update vom';
+$lang['L_NOT_SUPPORTED'] = 'Dieses Backup unterstützt diese Funktion nicht.';
+$lang['L_MULTIDUMP'] = 'Multidump: Es wurden <b>%d</b> Datenbanken gesichert.';
+$lang['L_FILESENDFTP'] = 'versende File via FTP... bitte habe etwas Geduld. ';
+$lang['L_FTPCONNERROR'] = 'FTP-Verbindung nicht hergestellt! Verbindung mit ';
+$lang['L_FTPCONNERROR1'] = ' als Benutzer ';
+$lang['L_FTPCONNERROR2'] = ' nicht möglich';
+$lang['L_FTPCONNERROR3'] = 'FTP-Upload war fehlerhaft! ';
+$lang['L_FTPCONNECTED1'] = 'Verbunden mit ';
+$lang['L_FTPCONNECTED2'] = ' auf ';
+$lang['L_FTPCONNECTED3'] = ' geschrieben';
+$lang['L_FILESENDSFTP'] = 'versende File via SFTP... bitte habe etwas Geduld. ';
+$lang['L_SFTPCONNERROR'] = 'SFTP-Verbindung nicht hergestellt! Verbindung mit ';
+$lang['L_NR_TABLES_SELECTED'] = '- mit %s gewählten Tabellen';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s Tabellen wurden optimiert.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s Fehler aufgetreten: <a href="log.php?r=3">anzeigen</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Schwerwiegender Fehler: die CREATE-Anweisung der Tabelle '%s' in der Datenbank '%s' konnte nicht gelesen werden!";
diff --git a/msd/language/de/lang_filemanagement.php b/msd/language/de/lang_filemanagement.php
index 1c632cc7..4770fc4f 100644
--- a/msd/language/de/lang_filemanagement.php
+++ b/msd/language/de/lang_filemanagement.php
@@ -1,81 +1,80 @@
 <?php
-$lang['L_CONVERT_START']="Konvertierung starten";
-$lang['L_CONVERT_TITLE']="Konvertiere Dump ins MSD-Format";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Falsche Parameter! Konvertierung ist nicht möglich.";
-$lang['L_FM_UPLOADFILEREQUEST']="Geben Sie bitte eine Datei an.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Dieser Dateityp ist nicht erlaubt.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Gültige Typen sind: *.gz und *.sql-Dateien";
-$lang['L_FM_UPLOADMOVEERROR']="Die hochgeladene Datei konnte nicht in den richtigen Ordner verschoben werden.";
-$lang['L_FM_UPLOADFAILED']="Der Upload ist leider fehlgeschlagen!";
-$lang['L_FM_UPLOADFILEEXISTS']="Es existiert bereits eine Datei mit diesem Namen!";
-$lang['L_FM_NOFILE']="Sie haben gar keine Datei ausgewählt!";
-$lang['L_FM_DELETE1']="Die Datei ";
-$lang['L_FM_DELETE2']=" wurde erfolgreich gelöscht.";
-$lang['L_FM_DELETE3']=" konnte nicht gelöscht werden!";
-$lang['L_FM_CHOOSE_FILE']="Gewählte Datei:";
-$lang['L_FM_FILESIZE']="Dateigröße";
-$lang['L_FM_FILEDATE']="Datum";
-$lang['L_FM_NOFILESFOUND']="Keine Datei gefunden.";
-$lang['L_FM_TABLES']="Tabellen";
-$lang['L_FM_RECORDS']="Einträge";
-$lang['L_FM_ALL_BU']="alle Backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="letztes Backup";
-$lang['L_FM_TOTALSIZE']="Gesamtgröße";
-$lang['L_FM_SELECTTABLES']="Auswahl bestimmter Tabellen";
-$lang['L_FM_COMMENT']="Kommentar eingeben";
-$lang['L_FM_RESTORE']="Wiederherstellen";
-$lang['L_FM_ALERTRESTORE1']="Soll die Datenbank ";
-$lang['L_FM_ALERTRESTORE2']="mit den Inhalten der Datei";
-$lang['L_FM_ALERTRESTORE3']="wiederhergestellt werden?";
-$lang['L_FM_DELETE']="Ausgewählte Dateien löschen";
-$lang['L_FM_ASKDELETE1']="Möchten Sie die Datei(en) ";
-$lang['L_FM_ASKDELETE2']="wirklich löschen?";
-$lang['L_FM_ASKDELETE3']="Möchten Sie Autodelete nach den eingestellten Regeln jetzt ausführen?";
-$lang['L_FM_ASKDELETE4']="Möchten Sie alle Backup-Dateien jetzt löschen?";
-$lang['L_FM_ASKDELETE5']="Möchten Sie alle Backup-Dateien mit ";
-$lang['L_FM_ASKDELETE5_2']="_* jetzt löschen?";
-$lang['L_FM_DELETEAUTO']="Autodelete manuell ausführen";
-$lang['L_FM_DELETEALL']="Alle Backup-Dateien löschen";
-$lang['L_FM_DELETEALLFILTER']="Alle löschen mit ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Neues Backup starten";
-$lang['L_FM_FILEUPLOAD']="Datei hochladen";
-$lang['L_FM_DBNAME']="Datenbankname";
-$lang['L_FM_FILES1']="Datenbank-Backups";
-$lang['L_FM_FILES2']="Datenbank-Strukturen";
-$lang['L_FM_AUTODEL1']="Autodelete: Folgende Dateien wurden aufgrund der maximalen Dateianzahl gelöscht:";
-$lang['L_DELETE_FILE_SUCCESS']="Die Datei \"%s\" wurde erfolgreich gelöscht.";
-$lang['L_FM_DUMPSETTINGS']="Einstellungen für das Backup";
-$lang['L_FM_OLDBACKUP']="(unbekannt)";
-$lang['L_FM_RESTORE_HEADER']="Wiederherstellung der Datenbank \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Die Datei \"%s\" konnte nicht gelöscht werden!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Perl-Cronscript ausführen";
-$lang['L_DOPERLTEST']="Perl-Module testen";
-$lang['L_DOSIMPLETEST']="Perl testen";
-$lang['L_PERLOUTPUT1']="Eintrag in crondump.pl für absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Aufruf im Browser oder für externen Cronjob";
-$lang['L_PERLOUTPUT3']="Aufruf in der Shell oder für die Crontab";
-$lang['L_RESTORE_OF_TABLES']="Wiederherstellen bestimmter Tabellen";
-$lang['L_CONVERTER']="Backup-Konverter";
-$lang['L_CONVERT_FILE']="zu konvertierende Datei";
-$lang['L_CONVERT_FILENAME']="Name der Zieldatei (ohne Endung)";
-$lang['L_CONVERTING']="Konvertierung";
-$lang['L_CONVERT_FILEREAD']="Datei '%s' wird eingelesen";
-$lang['L_CONVERT_FINISHED']="Konvertierung abgeschlossen, '%s' wurde erzeugt.";
-$lang['L_NO_MSD_BACKUPFILE']="Dateien anderer Programme";
-$lang['L_MAX_UPLOAD_SIZE']="Maximale Dateigröße";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Wenn Ihre Backup-Datei größer als das angegebene Limit ist, dann müssen Sie diese per FTP in den \"work/backup\"-Ordner hochladen.
-Danach wird diese Datei hier in der Verwaltung angezeigt und lässt sich für eine Wiederherstellung auswählen.";
-$lang['L_ENCODING']="Kodierung";
-$lang['L_FM_CHOOSE_ENCODING']="Kodierung der Backupdatei wählen";
-$lang['L_CHOOSE_CHARSET']="Leider konnte nicht automatisch ermittelt werden mit welchem Zeichensatz diese Backupdatei seinerzeit angelegt wurde.
-<br>Sie müssen die Kodierung, in der Zeichenketten in dieser Datei vorliegen, manuell angeben.
-<br>Danach stellt MySQLDumper die Verbindungskennung zum MySQL-Server auf den ausgewählten Zeichensatz und beginnt mit der Wiederherstellung der Daten.
-<br>Sollten Sie nach der Wiederherstellung Probleme mit Sonderzeichen entdecken, so können Sie versuchen, das Backup mit einer anderen Zeichensatzauswahl wiederherzustellen.
-<br>Viel Glück. ;)";
-$lang['L_DOWNLOAD_FILE']="Datei herunterladen";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "Eine Sicherung der Systemdatenbank `%s` ist nicht möglich!";
 
-?>
\ No newline at end of file
+$lang['L_CONVERT_START'] = 'Konvertierung starten';
+$lang['L_CONVERT_TITLE'] = 'Konvertiere Dump ins MOD-Format';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Falsche Parameter! Konvertierung ist nicht möglich.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Geben Sie bitte eine Datei an.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Dieser Dateityp ist nicht erlaubt.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Gültige Typen sind: *.gz und *.sql-Dateien';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Die hochgeladene Datei konnte nicht in den richtigen Ordner verschoben werden.';
+$lang['L_FM_UPLOADFAILED'] = 'Der Upload ist leider fehlgeschlagen!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Es existiert bereits eine Datei mit diesem Namen!';
+$lang['L_FM_NOFILE'] = 'Sie haben gar keine Datei ausgewählt!';
+$lang['L_FM_DELETE1'] = 'Die Datei ';
+$lang['L_FM_DELETE2'] = ' wurde erfolgreich gelöscht.';
+$lang['L_FM_DELETE3'] = ' konnte nicht gelöscht werden!';
+$lang['L_FM_CHOOSE_FILE'] = 'Gewählte Datei:';
+$lang['L_FM_FILESIZE'] = 'Dateigröße';
+$lang['L_FM_FILEDATE'] = 'Datum';
+$lang['L_FM_NOFILESFOUND'] = 'Keine Datei gefunden.';
+$lang['L_FM_TABLES'] = 'Tabellen';
+$lang['L_FM_RECORDS'] = 'Einträge';
+$lang['L_FM_ALL_BU'] = 'alle Backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'letztes Backup';
+$lang['L_FM_TOTALSIZE'] = 'Gesamtgröße';
+$lang['L_FM_SELECTTABLES'] = 'Auswahl bestimmter Tabellen';
+$lang['L_FM_COMMENT'] = 'Kommentar eingeben';
+$lang['L_FM_RESTORE'] = 'Wiederherstellen';
+$lang['L_FM_ALERTRESTORE1'] = 'Soll die Datenbank ';
+$lang['L_FM_ALERTRESTORE2'] = 'mit den Inhalten der Datei';
+$lang['L_FM_ALERTRESTORE3'] = 'wiederhergestellt werden?';
+$lang['L_FM_DELETE'] = 'Ausgewählte Dateien löschen';
+$lang['L_FM_ASKDELETE1'] = 'Möchten Sie die Datei(en) ';
+$lang['L_FM_ASKDELETE2'] = 'wirklich löschen?';
+$lang['L_FM_ASKDELETE3'] = 'Möchten Sie Autodelete nach den eingestellten Regeln jetzt ausführen?';
+$lang['L_FM_ASKDELETE4'] = 'Möchten Sie alle Backup-Dateien jetzt löschen?';
+$lang['L_FM_ASKDELETE5'] = 'Möchten Sie alle Backup-Dateien mit ';
+$lang['L_FM_ASKDELETE5_2'] = '_* jetzt löschen?';
+$lang['L_FM_DELETEAUTO'] = 'Autodelete manuell ausführen';
+$lang['L_FM_DELETEALL'] = 'Alle Backup-Dateien löschen';
+$lang['L_FM_DELETEALLFILTER'] = 'Alle löschen mit ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Neues Backup starten';
+$lang['L_FM_FILEUPLOAD'] = 'Datei hochladen';
+$lang['L_FM_DBNAME'] = 'Datenbankname';
+$lang['L_FM_FILES1'] = 'Datenbank-Backups';
+$lang['L_FM_FILES2'] = 'Datenbank-Strukturen';
+$lang['L_FM_AUTODEL1'] = 'Autodelete: Folgende Dateien wurden aufgrund der maximalen Dateianzahl gelöscht:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'Die Datei "%s" wurde erfolgreich gelöscht.';
+$lang['L_FM_DUMPSETTINGS'] = 'Einstellungen für das Backup';
+$lang['L_FM_OLDBACKUP'] = '(unbekannt)';
+$lang['L_FM_RESTORE_HEADER'] = 'Wiederherstellung der Datenbank "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Die Datei "%s" konnte nicht gelöscht werden!';
+$lang['L_FM_DUMP_HEADER'] = 'Sicherung';
+$lang['L_DOCRONBUTTON'] = 'Perl-Cronscript ausführen';
+$lang['L_DOPERLTEST'] = 'Perl-Module testen';
+$lang['L_DOSIMPLETEST'] = 'Perl testen';
+$lang['L_PERLOUTPUT1'] = 'Eintrag in crondump.pl für absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Aufruf im Browser oder für externen Cronjob';
+$lang['L_PERLOUTPUT3'] = 'Aufruf in der Shell oder für die Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Wiederherstellen bestimmter Tabellen';
+$lang['L_CONVERTER'] = 'Backup-Konverter';
+$lang['L_CONVERT_FILE'] = 'zu konvertierende Datei';
+$lang['L_CONVERT_FILENAME'] = 'Name der Zieldatei (ohne Endung)';
+$lang['L_CONVERTING'] = 'Konvertierung';
+$lang['L_CONVERT_FILEREAD'] = "Datei '%s' wird eingelesen";
+$lang['L_CONVERT_FINISHED'] = "Konvertierung abgeschlossen, '%s' wurde erzeugt.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Dateien anderer Programme';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximale Dateigröße';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Wenn Ihre Backup-Datei größer als das angegebene Limit ist, dann müssen Sie diese per FTP in den "work/backup"-Ordner hochladen.
+Danach wird diese Datei hier in der Verwaltung angezeigt und lässt sich für eine Wiederherstellung auswählen.';
+$lang['L_ENCODING'] = 'Kodierung';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Kodierung der Backupdatei wählen';
+$lang['L_CHOOSE_CHARSET'] = 'Leider konnte nicht automatisch ermittelt werden mit welchem Zeichensatz diese Backupdatei seinerzeit angelegt wurde.
+<br>Sie müssen die Kodierung, in der Zeichenketten in dieser Datei vorliegen, manuell angeben.
+<br>Danach stellt MyOOS [Dumper] die Verbindungskennung zum MySQL-Server auf den ausgewählten Zeichensatz und beginnt mit der Wiederherstellung der Daten.
+<br>Sollten Sie nach der Wiederherstellung Probleme mit Sonderzeichen entdecken, so können Sie versuchen, das Backup mit einer anderen Zeichensatzauswahl wiederherzustellen.
+<br>Viel Glück. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Datei herunterladen';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'Eine Sicherung der Systemdatenbank `%s` ist nicht möglich!';
diff --git a/msd/language/de/lang_help.php b/msd/language/de/lang_help.php
index ff2bdc0c..2403f658 100644
--- a/msd/language/de/lang_help.php
+++ b/msd/language/de/lang_help.php
@@ -1,40 +1,41 @@
 <?php
-$lang['L_HELP_DB']="Dies ist die Liste der vorhandenen Datenbanken.";
-$lang['L_HELP_PRAEFIX']="Der Präfix ist eine Zeichenfolge für den Anfang von Tabellen, der als Filter fungiert.";
-$lang['L_HELP_ZIP']="Kompression mit GZip - emfohlen ist 'aktiviert'.";
-$lang['L_HELP_MEMORYLIMIT']="Das ist die maximale Größe in Bytes, die das Skript an Speicher bekommt.
-0 = deaktiviert";
-$lang['L_MEMORY_LIMIT']="Speichergrenze";
-$lang['L_HELP_AD1']="Wenn aktiviert, dann werden automatisch Backup-Dateien gelöscht.";
-$lang['L_HELP_AD3']="Die maximale Anzahl von Dateien, die im Backup-Verzeichnis sein dürfen (für Autodelete).
-0 = deaktiviert";
-$lang['L_HELP_LANG']="Stellt auf die gewünschte Sprache.";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Um überflüssige Daten zu eliminieren, kann man anweisen, die Datenbank vor der Wiederherstellung komplett zu leeren.";
-$lang['L_HELP_CRONEXTENDER']="Die Endung des Perlscriptes, Standard ist '.pl'.";
-$lang['L_HELP_CRONSAVEPATH']="Der Name der Konfigurationsdatei für das Perlskript.";
-$lang['L_HELP_CRONPRINTOUT']="Wenn die Textausgabe abgeschaltet ist, wird kein Text mehr ausgegeben.
-Diese Funktion ist unabhängig von der Log-Ausgabe.";
-$lang['L_HELP_CRONSAMEDB']="Soll die gleiche Datenbank für Cronjob wie in den Einstellungen benutzt werden?";
-$lang['L_HELP_CRONDBINDEX']="Wähle die Datenbank für den Cronjob.";
-$lang['L_HELP_FTPTRANSFER']="Wenn aktiviert, wird nach dem Backup die Datei per FTP gesendet.";
-$lang['L_HELP_FTPSERVER']="Adresse des FTP-Servers.";
-$lang['L_HELP_FTPPORT']="Port des FTP-Servers. Standard: 21.";
-$lang['L_HELP_FTPUSER']="Gibt den Benutzernamen der FTP-Verbindung an.";
-$lang['L_HELP_FTPPASS']="Gibt das Passwort der FTP-Verbindung an.";
-$lang['L_HELP_FTPDIR']="Wohin soll die Datei gesendet werden?";
-$lang['L_HELP_SPEED']="Minimale und maximale Geschwindigkeit. Standard ist 50 bis 5000.
-(Zu hohe Geschwindigkeiten können zu Timeouts führen!)";
-$lang['L_SPEED']="Geschwindigkeitskontrolle";
-$lang['L_HELP_CRONEXECPATH']="Der Ort, an dem die Perlskripte liegen.
+
+$lang['L_HELP_DB'] = 'Dies ist die Liste der vorhandenen Datenbanken.';
+$lang['L_HELP_PRAEFIX'] = 'Der Präfix ist eine Zeichenfolge für den Anfang von Tabellen, der als Filter fungiert.';
+$lang['L_HELP_ZIP'] = "Kompression mit GZip - emfohlen ist 'aktiviert'.";
+$lang['L_HELP_MEMORYLIMIT'] = 'Das ist die maximale Größe in Bytes, die das Skript an Speicher bekommt.
+0 = deaktiviert';
+$lang['L_MEMORY_LIMIT'] = 'Speichergrenze';
+$lang['L_HELP_AD1'] = 'Wenn aktiviert, dann werden automatisch Backup-Dateien gelöscht.';
+$lang['L_HELP_AD3'] = 'Die maximale Anzahl von Dateien, die im Backup-Verzeichnis sein dürfen (für Autodelete).
+0 = deaktiviert';
+$lang['L_HELP_LANG'] = 'Stellt auf die gewünschte Sprache.';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Um überflüssige Daten zu eliminieren, kann man anweisen, die Datenbank vor der Wiederherstellung komplett zu leeren.';
+$lang['L_HELP_CRONEXTENDER'] = "Die Endung des Perlscriptes, Standard ist '.pl'.";
+$lang['L_HELP_CRONSAVEPATH'] = 'Der Name der Konfigurationsdatei für das Perlskript.';
+$lang['L_HELP_CRONPRINTOUT'] = 'Wenn die Textausgabe abgeschaltet ist, wird kein Text mehr ausgegeben.
+Diese Funktion ist unabhängig von der Log-Ausgabe.';
+$lang['L_HELP_CRONSAMEDB'] = 'Soll die gleiche Datenbank für Cronjob wie in den Einstellungen benutzt werden?';
+$lang['L_HELP_CRONDBINDEX'] = 'Wähle die Datenbank für den Cronjob.';
+$lang['L_HELP_FTPTRANSFER'] = 'Wenn aktiviert, wird nach dem Backup die Datei per FTP gesendet.';
+$lang['L_HELP_FTPSERVER'] = 'Adresse des FTP-Servers.';
+$lang['L_HELP_FTPPORT'] = 'Port des FTP-Servers. Standard: 21.';
+$lang['L_HELP_FTPUSER'] = 'Gibt den Benutzernamen der FTP-Verbindung an.';
+$lang['L_HELP_FTPPASS'] = 'Gibt das Passwort der FTP-Verbindung an.';
+$lang['L_HELP_FTPDIR'] = 'Wohin soll die Datei gesendet werden?';
+$lang['L_HELP_SFTPTRANSFER'] = 'Wenn aktiviert, wird nach dem Backup die Datei per SFTP gesendet.';
+$lang['L_HELP_SFTPSERVER'] = 'Adresse des SFTP-Servers.';
+$lang['L_HELP_SFTPPORT'] = 'Port des SFTP-Servers. Standard: 22.';
+$lang['L_HELP_SFTPUSER'] = 'Gibt den Benutzernamen der SFTP-Verbindung an.';
+$lang['L_HELP_SFTPPASS'] = 'Gibt das Passwort der SFTP-Verbindung an.';
+$lang['L_HELP_SFTPDIR'] = 'Wohin soll die Datei gesendet werden?';
+$lang['L_HELP_SPEED'] = 'Minimale und maximale Geschwindigkeit. Standard ist 50 bis 5000.
+(Zu hohe Geschwindigkeiten können zu Timeouts führen!)';
+$lang['L_SPEED'] = 'Geschwindigkeitskontrolle';
+$lang['L_HELP_CRONEXECPATH'] = 'Der Ort, an dem die Perlskripte liegen.
 Ausgangspunkt ist die HTTP-Adresse (also im Browser).
-Erlaubt sind absolute und relative Pfadangaben.";
-$lang['L_CRON_EXECPATH']="Pfad der Perlskripte";
-$lang['L_HELP_CRONCOMPLETELOG']="Wenn die Funktion aktiviert ist, wird die komplette Ausgabe im complete_log geschrieben. 
-Diese Funktion ist unabhängig von der Textausgabe.";
-$lang['L_HELP_FTP_MODE']="Wenn Probleme bei der FTP-Übertragung auftauchen, versuchen Sie den passiven FTP-Modus.
-
-
-";
-
-
-?>
\ No newline at end of file
+Erlaubt sind absolute und relative Pfadangaben.';
+$lang['L_CRON_EXECPATH'] = 'Pfad der Perlskripte';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Wenn die Funktion aktiviert ist, wird die komplette Ausgabe im complete_log geschrieben. 
+Diese Funktion ist unabhängig von der Textausgabe.';
+$lang['L_HELP_FTP_MODE'] = 'Wenn Probleme bei der FTP-Übertragung auftauchen, versuchen Sie den passiven FTP-Modus.';
diff --git a/msd/language/de/lang_install.php b/msd/language/de/lang_install.php
index e7fd8e9e..129eaa8b 100644
--- a/msd/language/de/lang_install.php
+++ b/msd/language/de/lang_install.php
@@ -1,92 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>die Installation ist abgeschlossen   --> <a href=\"index.php\">starte MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="zum Hauptmenü";
-$lang['L_INSTALLMENU']="Hauptmenü";
-$lang['L_STEP']="Schritt";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Deinstallation";
-$lang['L_TOOLS']="Tools";
-$lang['L_EDITCONF']="Konfiguration bearbeiten";
-$lang['L_OSWEITER']="ohne Speichern weiter";
-$lang['L_ERRORMAN']="<strong>Fehler beim Schreiben der Konfiguration!</strong><br>Bitte editieren Sie die Datei ";
-$lang['L_MANUELL']="manuell";
-$lang['L_CREATEDIRS']="erstelle Verzeichnisse";
-$lang['L_INSTALL_CONTINUE']="mit der Installation fortfahren";
-$lang['L_CONNECTTOMYSQL']=" zu MySQL verbinden ";
-$lang['L_DBPARAMETER']="Datenbank-Parameter";
-$lang['L_CONFIGNOTWRITABLE']="Die Datei \"config.php\" ist nicht beschreibbar.
-Geben Sie ihr mit einem FTP-Programm entsprechende Rechte, z. B. den CHMod-Wert 0777.";
-$lang['L_DBCONNECTION']="Datenbank-Verbindung";
-$lang['L_CONNECTIONERROR']="Fehler: Es konnte keine Verbindung herstellt werden.";
-$lang['L_CONNECTION_OK']="Datenbank-Verbindung wurde hergestellt.";
-$lang['L_SAVEANDCONTINUE']="speichern und Installation fortsetzen";
-$lang['L_CONFBASIC']="Grundeinstellungen";
-$lang['L_INSTALL_STEP2FINISHED']="Die Einstellungen wurden erfolgreich gesichert.";
-$lang['L_INSTALL_STEP2_1']="Installation mit Standardkonfiguration fortsetzen";
-$lang['L_LASTSTEP']="Abschluss der Installation";
-$lang['L_FTPMODE']="Verzeichnisse per FTP erzeugen (safe_mode)";
-$lang['L_IDOMANUAL']="Ich erstelle die Verzeichnisse manuell";
-$lang['L_DOFROM']="ausgehend von";
-$lang['L_FTPMODE2']="Erstelle die Verzeichnisse per FTP:";
-$lang['L_CONNECT']="verbinden";
-$lang['L_DIRS_CREATED']="Die Verzeichnisse wurden ordnungsgemäß erstellt.";
-$lang['L_CONNECT_TO']="verbinde zu";
-$lang['L_CHANGEDIR']="Wechsel ins Verzeichnis";
-$lang['L_CHANGEDIRERROR']="Wechsel ins Verzeichnis nicht möglich";
-$lang['L_FTP_OK']="FTP-Parameter sind ok";
-$lang['L_CREATEDIRS2']="Verzeichnisse erstellen";
-$lang['L_FTP_NOTCONNECTED']="FTP-Verbindung nicht hergestellt!";
-$lang['L_CONNWITH']="Verbindung mit";
-$lang['L_ASUSER']="als Benutzer";
-$lang['L_NOTPOSSIBLE']="nicht möglich";
-$lang['L_DIRCR1']="erstelle Arbeitsverzeichnis";
-$lang['L_DIRCR2']="erstelle Backup-Verzeichnis";
-$lang['L_DIRCR4']="erstelle Log-Verzeichnis";
-$lang['L_DIRCR5']="erstelle Konfigurationsverzeichnis";
-$lang['L_INDIR']="bin im Verzeichnis";
-$lang['L_CHECK_DIRS']="Verzeichnisse überprüfen";
-$lang['L_DISABLEDFUNCTIONS']="Abgeschaltete Funktionen";
-$lang['L_NOFTPPOSSIBLE']="Es stehen keine FTP-Funktionen zur Verfügung!";
-$lang['L_NOGZPOSSIBLE']="Es stehen keine Kompressions-Funktionen zur Verfügung!";
-$lang['L_UI1']="Es werden alle Arbeitsverzeichnisse incl. den darin enthaltenen Backups gelöscht.";
-$lang['L_UI2']="Sind Sie sicher, dass Sie das möchten?";
-$lang['L_UI3']="Nein, sofort abbrechen";
-$lang['L_UI4']="ja, bitte fortfahren";
-$lang['L_UI5']="lösche Arbeitsverzeichnis";
-$lang['L_UI6']="alles wurde erfolgreich gelöscht.";
-$lang['L_UI7']="Bitte löschen Sie das Skriptverzeichnis";
-$lang['L_UI8']="eine Ebene nach oben";
-$lang['L_UI9']="Ein Fehler trat auf, löschen war nicht möglich</p>Fehler bei Verzeichnis ";
-$lang['L_IMPORT']="Konfiguration importieren";
-$lang['L_IMPORT3']="Die Konfiguration wurde geladen...";
-$lang['L_IMPORT4']="Die Konfiguration wurde gesichert.";
-$lang['L_IMPORT5']="MySQLDumper starten";
-$lang['L_IMPORT6']="Installations-Menü";
-$lang['L_IMPORT7']="Konfiguration hochladen";
-$lang['L_IMPORT8']="zurück zum Upload";
-$lang['L_IMPORT9']="Dies ist keine Konfigurationssicherung!";
-$lang['L_IMPORT10']="Die Konfiguration wurde erfolgreich hochgeladen...";
-$lang['L_IMPORT11']="<strong>Fehler: </strong>Es gab Probleme beim Schreiben der sql_statements.";
-$lang['L_IMPORT12']="<strong>Fehler: </strong>Es gab Probleme beim Schreiben der config.php.";
-$lang['L_INSTALL_HELP_PORT']="(leer = Standardport)";
-$lang['L_INSTALL_HELP_SOCKET']="(leer = Standardsocket)";
-$lang['L_TRYAGAIN']="noch einmal versuchen";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="gefundene DB: ";
-$lang['L_FM_FILEUPLOAD']="Datei hochladen";
-$lang['L_PASS']="Passwort";
-$lang['L_NO_DB_FOUND_INFO']="Die Verbindung zur Datenbank konnte erfolgreich hergestellt werden.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>die Installation ist abgeschlossen   --> <a href="index.php">starte MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'zum Hauptmenü';
+$lang['L_INSTALLMENU'] = 'Hauptmenü';
+$lang['L_STEP'] = 'Schritt';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Deinstallation';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_EDITCONF'] = 'Konfiguration bearbeiten';
+$lang['L_OSWEITER'] = 'ohne Speichern weiter';
+$lang['L_ERRORMAN'] = '<strong>Fehler beim Schreiben der Konfiguration!</strong><br>Bitte editieren Sie die Datei ';
+$lang['L_MANUELL'] = 'manuell';
+$lang['L_CREATEDIRS'] = 'erstelle Verzeichnisse';
+$lang['L_INSTALL_CONTINUE'] = 'mit der Installation fortfahren';
+$lang['L_CONNECTTOMYSQL'] = ' zu MySQL verbinden ';
+$lang['L_DBPARAMETER'] = 'Datenbank-Parameter';
+$lang['L_CONFIGNOTWRITABLE'] = 'Die Datei "config.php" ist nicht beschreibbar.
+Geben Sie ihr mit einem FTP-Programm entsprechende Rechte, z. B. den CHMod-Wert 0777.';
+$lang['L_DBCONNECTION'] = 'Datenbank-Verbindung';
+$lang['L_CONNECTIONERROR'] = 'Fehler: Es konnte keine Verbindung herstellt werden.';
+$lang['L_CONNECTION_OK'] = 'Datenbank-Verbindung wurde hergestellt.';
+$lang['L_SAVEANDCONTINUE'] = 'speichern und Installation fortsetzen';
+$lang['L_CONFBASIC'] = 'Grundeinstellungen';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Die Einstellungen wurden erfolgreich gesichert.';
+$lang['L_INSTALL_STEP2_1'] = 'Installation mit Standardkonfiguration fortsetzen';
+$lang['L_LASTSTEP'] = 'Abschluss der Installation';
+$lang['L_IDOMANUAL'] = 'Ich erstelle die Verzeichnisse manuell';
+$lang['L_DOFROM'] = 'ausgehend von';
+$lang['L_FTPMODE2'] = 'Erstelle die Verzeichnisse per FTP:';
+$lang['L_CONNECT'] = 'verbinden';
+$lang['L_DIRS_CREATED'] = 'Die Verzeichnisse wurden ordnungsgemäß erstellt.';
+$lang['L_CONNECT_TO'] = 'verbinde zu';
+$lang['L_CHANGEDIR'] = 'Wechsel ins Verzeichnis';
+$lang['L_CHANGEDIRERROR'] = 'Wechsel ins Verzeichnis nicht möglich';
+$lang['L_FTP_OK'] = 'FTP-Parameter sind ok';
+$lang['L_SFTP_OK'] = 'FTP-Parameter sind ok';
+$lang['L_CREATEDIRS2'] = 'Verzeichnisse erstellen';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP-Verbindung nicht hergestellt!';
+$lang['L_CONNWITH'] = 'Verbindung mit';
+$lang['L_ASUSER'] = 'als Benutzer';
+$lang['L_NOTPOSSIBLE'] = 'nicht möglich';
+$lang['L_DIRCR1'] = 'erstelle Arbeitsverzeichnis';
+$lang['L_DIRCR2'] = 'erstelle Backup-Verzeichnis';
+$lang['L_DIRCR4'] = 'erstelle Log-Verzeichnis';
+$lang['L_DIRCR5'] = 'erstelle Konfigurationsverzeichnis';
+$lang['L_INDIR'] = 'bin im Verzeichnis';
+$lang['L_CHECK_DIRS'] = 'Verzeichnisse überprüfen';
+$lang['L_DISABLEDFUNCTIONS'] = 'Abgeschaltete Funktionen';
+$lang['L_NOFTPPOSSIBLE'] = 'Es stehen keine FTP-Funktionen zur Verfügung!';
+$lang['L_NOGZPOSSIBLE'] = 'Es stehen keine Kompressions-Funktionen zur Verfügung!';
+$lang['L_UI1'] = 'Es werden alle Arbeitsverzeichnisse incl. den darin enthaltenen Backups gelöscht.';
+$lang['L_UI2'] = 'Sind Sie sicher, dass Sie das möchten?';
+$lang['L_UI3'] = 'Nein, sofort abbrechen';
+$lang['L_UI4'] = 'ja, bitte fortfahren';
+$lang['L_UI5'] = 'lösche Arbeitsverzeichnis';
+$lang['L_UI6'] = 'alles wurde erfolgreich gelöscht.';
+$lang['L_UI7'] = 'Bitte löschen Sie das Skriptverzeichnis';
+$lang['L_UI8'] = 'eine Ebene nach oben';
+$lang['L_UI9'] = 'Ein Fehler trat auf, löschen war nicht möglich</p>Fehler bei Verzeichnis ';
+$lang['L_IMPORT'] = 'Konfiguration importieren';
+$lang['L_IMPORT3'] = 'Die Konfiguration wurde geladen...';
+$lang['L_IMPORT4'] = 'Die Konfiguration wurde gesichert.';
+$lang['L_IMPORT5'] = 'MyOOS [Dumper] starten';
+$lang['L_IMPORT6'] = 'Installations-Menü';
+$lang['L_IMPORT7'] = 'Konfiguration hochladen';
+$lang['L_IMPORT8'] = 'zurück zum Upload';
+$lang['L_IMPORT9'] = 'Dies ist keine Konfigurationssicherung!';
+$lang['L_IMPORT10'] = 'Die Konfiguration wurde erfolgreich hochgeladen...';
+$lang['L_IMPORT11'] = '<strong>Fehler: </strong>Es gab Probleme beim Schreiben der sql_statements.';
+$lang['L_IMPORT12'] = '<strong>Fehler: </strong>Es gab Probleme beim Schreiben der config.php.';
+$lang['L_INSTALL_HELP_PORT'] = '(leer = Standardport)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(leer = Standardsocket)';
+$lang['L_TRYAGAIN'] = 'noch einmal versuchen';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'gefundene DB: ';
+$lang['L_FM_FILEUPLOAD'] = 'Datei hochladen';
+$lang['L_PASS'] = 'Passwort';
+$lang['L_NO_DB_FOUND_INFO'] = 'Die Verbindung zur Datenbank konnte erfolgreich hergestellt werden.<br>
 Ihre Zugangsdaten sind gültig und wurden vom MySQL-Server akzeptiert.<br>
-Leider konnte MySQLDumper keine Datenbank finden.<br>
+Leider konnte MyOOS [Dumper] keine Datenbank finden.<br>
 Die automatische Erkennung per Programm ist bei manchen Hostern gesperrt.<br>
-Sie müssen Ihre Datenbank nach dem Abschluß der Installation unter dem Menüpunkt \"Konfiguration\" \"Verbindungsparameter einblenden\" angeben.<br>
-Bitte begeben Sie sich nach Abschluß der Installation umgehend dort hin und tragen den Namen Ihrer Datenbank dort ein.";
-$lang['L_SAFEMODEDESC']="Da PHP auf diesem Server mit der Option \"safe_mode=on\" ausgeführt wird, müssen folgende Verzeichnisse von Hand angelegt werden (dies können Sie mit Ihrem FTP-Programm erledigen):
-
-
-";
-$lang['L_ENTER_DB_INFO']="Klicken Sie zuerst auf den Button \"zu MySQL verbinden\". Nur wenn daraufhin keine Datenbank erkannt werden konnte, ist hier eine Angabe notwendig.";
-
-
-?>
\ No newline at end of file
+Sie müssen Ihre Datenbank nach dem Abschluß der Installation unter dem Menüpunkt "Konfiguration" "Verbindungsparameter einblenden" angeben.<br>
+Bitte begeben Sie sich nach Abschluß der Installation umgehend dort hin und tragen den Namen Ihrer Datenbank dort ein.';
+$lang['L_ENTER_DB_INFO'] = 'Klicken Sie zuerst auf den Button "zu MySQL verbinden". Nur wenn daraufhin keine Datenbank erkannt werden konnte, ist hier eine Angabe notwendig.';
diff --git a/msd/language/de/lang_log.php b/msd/language/de/lang_log.php
index edee59aa..e794f7bf 100644
--- a/msd/language/de/lang_log.php
+++ b/msd/language/de/lang_log.php
@@ -1,12 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Log löschen";
-$lang['L_LOGFILEFORMAT']="Log-Dateiformat";
-$lang['L_LOGFILENOTWRITABLE']="Log-Datei kann nicht geschrieben werden!";
-$lang['L_NOREVERSE']="Ältester Eintrag zuerst";
-$lang['L_REVERSE']="Neuster Eintrag zuerst
 
-
-";
-
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Log löschen';
+$lang['L_LOGFILEFORMAT'] = 'Log-Dateiformat';
+$lang['L_LOGFILENOTWRITABLE'] = 'Log-Datei kann nicht geschrieben werden!';
+$lang['L_NOREVERSE'] = 'Ältester Eintrag zuerst';
+$lang['L_REVERSE'] = 'Neuester Eintrag zuerst';
diff --git a/msd/language/de/lang_main.php b/msd/language/de/lang_main.php
index 73f4e5b3..404bcb5b 100644
--- a/msd/language/de/lang_main.php
+++ b/msd/language/de/lang_main.php
@@ -1,81 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Es stehen keine FTP-Funktionen zur Verfügung!";
-$lang['L_INFO_LOCATION']="Sie befinden sich auf ";
-$lang['L_INFO_DATABASES']="Folgende Datenbank(en) befinden sich auf dem MySql-Server:";
-$lang['L_INFO_NODB']="Datenbank existiert nicht";
-$lang['L_INFO_DBDETAIL']="Detail-Information von Datenbank ";
-$lang['L_INFO_DBEMPTY']="Die Datenbank ist leer!";
-$lang['L_INFO_RECORDS']="Datensätze";
-$lang['L_INFO_SIZE']="Größe";
-$lang['L_INFO_LASTUPDATE']="letztes Update";
-$lang['L_INFO_SUM']="insgesamt";
-$lang['L_INFO_OPTIMIZED']="optimiert";
-$lang['L_OPTIMIZE_DATABASES']="Tabellen optimieren";
-$lang['L_CHECK_TABLES']="Tabellen überprüfen";
-$lang['L_CLEAR_DATABASE']="Datenbank leeren";
-$lang['L_DELETE_DATABASE']="Datenbank löschen";
-$lang['L_INFO_CLEARED']="wurde geleert";
-$lang['L_INFO_DELETED']="wurde gelöscht";
-$lang['L_INFO_EMPTYDB1']="Soll die Datenbank";
-$lang['L_INFO_EMPTYDB2']=" wirklich geleert werden? (Achtung! Alle Daten gehen unwiderruflich verloren)";
-$lang['L_INFO_KILLDB']=" wirklich gelöscht werden? (Achtung! Alle Daten gehen unwiderruflich verloren)";
-$lang['L_PROCESSKILL1']="Es wird versucht, Prozess ";
-$lang['L_PROCESSKILL2']="zu beenden.";
-$lang['L_PROCESSKILL3']="Es wird seit ";
-$lang['L_PROCESSKILL4']=" Sekunde(n) versucht, Prozess ";
-$lang['L_HTACC_CREATE']="Verzeichnisschutz erstellen";
-$lang['L_ENCRYPTION_TYPE']="Verschlüsselungsart";
-$lang['L_HTACC_CRYPT']="Crypt maximal 8 Zeichen (Linux und Unix-Systeme)";
-$lang['L_HTACC_MD5']="MD5 (Linux und Unix-Systeme)";
-$lang['L_HTACC_NO_ENCRYPTION']="unverschlüsselt (Windows)";
-$lang['L_HTACCESS8']="Es besteht bereits ein Verzeichnisschutz. Wenn Sie einen neuen erstellen, wird der alte überschrieben!";
-$lang['L_HTACC_NO_USERNAME']="Sie müssen einen Namen eingeben!";
-$lang['L_PASSWORDS_UNEQUAL']="Die Passwörter sind nicht identisch oder leer!";
-$lang['L_HTACC_CONFIRM_DELETE']="Soll der Verzeichnisschutz jetzt erstellt werden?";
-$lang['L_HTACC_CREATED']="Der Verzeichnisschutz wurde erstellt.";
-$lang['L_HTACC_CONTENT']="Inhalt der Datei";
-$lang['L_HTACC_CREATE_ERROR']="Es ist ein Fehler bei der Erstellung des Verzeichnisschutzes aufgetreten!<br>Bitte erzeugen Sie die Dateien manuell mit folgendem Inhalt";
-$lang['L_HTACC_PROPOSED']="Dringend empfohlen";
-$lang['L_HTACC_EDIT']=".htaccess editieren";
-$lang['L_HTACCESS18']=".htaccess erstellen in ";
-$lang['L_HTACCESS19']="Neu laden ";
-$lang['L_HTACCESS20']="Skript ausführen";
-$lang['L_HTACCESS21']="Handler zufügen";
-$lang['L_HTACCESS22']="Ausführbar machen";
-$lang['L_HTACCESS23']="Verzeichnis-Listing";
-$lang['L_HTACCESS24']="Error-Dokument";
-$lang['L_HTACCESS25']="Rewrite aktivieren";
-$lang['L_HTACCESS26']="Deny / Allow";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Error-Log";
-$lang['L_HTACCESS29']="weitere Beispiele und Dokumentation";
-$lang['L_HTACCESS30']="Provider";
-$lang['L_HTACCESS31']="allgemein";
-$lang['L_HTACCESS32']="Achtung! Die .htaccess hat eine direkte Auswirkung auf den Browser.<br>Bei falscher Anwendung sind die Seiten nicht mehr erreichbar.";
-$lang['L_PHPBUG']="Bug in zlib! Keine Kompression möglich!";
-$lang['L_DISABLEDFUNCTIONS']="Abgeschaltete Funktionen";
-$lang['L_NOGZPOSSIBLE']="Da zlib nicht installiert ist, stehen keine GZip-Funktionen zur Verfügung!";
-$lang['L_DELETE_HTACCESS']="Verzeichnisschutz entfernen (.htaccess löschen)";
-$lang['L_WRONG_RIGHTS']="Die Datei oder das Verzeichnis '%s' ist für mich nicht beschreibbar.<br>
-Entweder hat sie den falschen Besitzer (Owner) oder die falschen Rechte (Chmod).<br> 
+
+$lang['L_NOFTPPOSSIBLE'] = 'Es stehen keine FTP-Funktionen zur Verfügung!';
+$lang['L_INFO_LOCATION'] = 'Sie befinden sich auf ';
+$lang['L_INFO_DATABASES'] = 'Folgende Datenbank(en) befinden sich auf dem MySql-Server:';
+$lang['L_INFO_NODB'] = 'Datenbank existiert nicht';
+$lang['L_INFO_DBDETAIL'] = 'Detail-Information von Datenbank ';
+$lang['L_INFO_DBEMPTY'] = 'Die Datenbank ist leer!';
+$lang['L_INFO_RECORDS'] = 'Datensätze';
+$lang['L_INFO_SIZE'] = 'Größe';
+$lang['L_INFO_LASTUPDATE'] = 'letztes Update';
+$lang['L_INFO_SUM'] = 'insgesamt';
+$lang['L_INFO_OPTIMIZED'] = 'optimiert';
+$lang['L_OPTIMIZE_DATABASES'] = 'Tabellen optimieren';
+$lang['L_CHECK_TABLES'] = 'Tabellen überprüfen';
+$lang['L_CLEAR_DATABASE'] = 'Datenbank leeren';
+$lang['L_DELETE_DATABASE'] = 'Datenbank löschen';
+$lang['L_INFO_CLEARED'] = 'wurde geleert';
+$lang['L_INFO_DELETED'] = 'wurde gelöscht';
+$lang['L_INFO_EMPTYDB1'] = 'Soll die Datenbank';
+$lang['L_INFO_EMPTYDB2'] = ' wirklich geleert werden? (Achtung! Alle Daten gehen unwiderruflich verloren)';
+$lang['L_INFO_KILLDB'] = ' wirklich gelöscht werden? (Achtung! Alle Daten gehen unwiderruflich verloren)';
+$lang['L_PROCESSKILL1'] = 'Es wird versucht, Prozess ';
+$lang['L_PROCESSKILL2'] = 'zu beenden.';
+$lang['L_PROCESSKILL3'] = 'Es wird seit ';
+$lang['L_PROCESSKILL4'] = ' Sekunde(n) versucht, Prozess ';
+$lang['L_HTACC_CREATE'] = 'Verzeichnisschutz erstellen';
+$lang['L_ENCRYPTION_TYPE'] = 'Verschlüsselungsart';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, alle Systeme)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (alle Systeme)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (alle Systeme)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - maximal 8 Zeichen (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unverschlüsselt (Windows)';
+$lang['L_HTACCESS8'] = 'Es besteht bereits ein Verzeichnisschutz. Wenn Sie einen neuen erstellen, wird der alte überschrieben!';
+$lang['L_HTACC_NO_USERNAME'] = 'Sie müssen einen Namen eingeben!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Die Passwörter sind nicht identisch oder leer!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Soll der Verzeichnisschutz jetzt erstellt werden?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Soll der Verzeichnisschutz wirklich entfernt werden?';
+$lang['L_HTACC_CREATED'] = 'Der Verzeichnisschutz wurde erstellt.';
+$lang['L_HTACC_CONTENT'] = 'Inhalt der Datei';
+$lang['L_HTACC_CREATE_ERROR'] = 'Es ist ein Fehler bei der Erstellung des Verzeichnisschutzes aufgetreten!<br>Bitte erzeugen Sie die Dateien manuell mit folgendem Inhalt';
+$lang['L_HTACC_CHECK_ERROR'] = 'Es konnte nicht überprüft werden, ob das Programm geschützt ist!<br>Der simulierte externe Zugriff konnte nicht ausgeführt werden.';
+$lang['L_HTACC_NOT_NEEDED'] = 'Das Programm ist durch übergeordnete Berechtigungen geschützt; ein lokaler Verzeichnisschutz ist nicht erforderlich.';
+$lang['L_HTACC_COMPLETE'] = 'Das Programm ist geschützt, der Verzeichnisschutz ist vollständig.';
+$lang['L_HTACC_INCOMPLETE'] = 'Das Programm ist nicht geschützt, der Verzeichnisschutz ist unvollständig!';
+$lang['L_HTACC_PROPOSED'] = 'Das Programm ist nicht geschützt, ein Verzeichnisschutz wird dringend empfohlen!';
+$lang['L_HTACC_EDIT'] = '.htaccess editieren';
+$lang['L_HTACCESS18'] = '.htaccess erstellen in ';
+$lang['L_HTACCESS19'] = 'Neu laden ';
+$lang['L_HTACCESS20'] = 'Skript ausführen';
+$lang['L_HTACCESS21'] = 'Handler zufügen';
+$lang['L_HTACCESS22'] = 'Ausführbar machen';
+$lang['L_HTACCESS23'] = 'Verzeichnis-Listing';
+$lang['L_HTACCESS24'] = 'Error-Dokument';
+$lang['L_HTACCESS25'] = 'Rewrite aktivieren';
+$lang['L_HTACCESS26'] = 'Deny / Allow';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Error-Log';
+$lang['L_HTACCESS29'] = 'weitere Beispiele und Dokumentation';
+$lang['L_HTACCESS30'] = 'Provider';
+$lang['L_HTACCESS31'] = 'Allgemein';
+$lang['L_HTACCESS32'] = 'Achtung! Die .htaccess hat eine direkte Auswirkung auf den Browser.<br>Bei falscher Anwendung sind die Seiten nicht mehr erreichbar.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Abgeschaltete Funktionen';
+$lang['L_NOGZPOSSIBLE'] = 'Da zlib nicht installiert ist, stehen keine GZip-Funktionen zur Verfügung!';
+$lang['L_DELETE_HTACCESS'] = 'Verzeichnisschutz entfernen (.htaccess löschen)';
+$lang['L_WRONG_RIGHTS'] = "Die Datei oder das Verzeichnis '%s' ist für mich nicht beschreibbar.<br>
+Entweder hat sie den falschen Besitzer (Owner) oder die falschen Rechte (Chmod).<br>
 Bitte setzen Sie die richtigen Attribute mit Ihrem FTP-Programm. <br>
 Die Datei oder das Verzeichnis benötigt die Rechte %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Ich konntes das Verzeichnis '%s' nicht erstellen.
-Bitte erstellen Sie es mit Ihrem FTP-Programm.
-
-
-";
-$lang['L_TABLE_TYPE']="Typ";
-$lang['L_CHECK']="prüfen";
-$lang['L_HTACC_SHA1']="SHA1 (alle Systeme)";
-$lang['L_OS']="Betriebssystem";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Maximale Ausführungszeit";
-$lang['L_PHP_EXTENSIONS']="PHP-Erweiterungen";
-$lang['L_MEMORY']="Speicher";
-$lang['L_FILE_MISSING']="konnte Datei nicht finden";
-
-
-?>
\ No newline at end of file
+$lang['L_CANT_CREATE_DIR'] = "Ich konnte das Verzeichnis '%s' nicht erstellen.
+Bitte erstellen Sie es mit Ihrem FTP-Programm.";
+$lang['L_TABLE_TYPE'] = 'Typ';
+$lang['L_CHECK'] = 'prüfen';
+$lang['L_OS'] = 'Betriebssystem';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'Neue Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'Es ist eine neue Version von MyOOS [Dumper] verfügbar.';
+$lang['L_UPDATED_IMPORTANT'] = 'Wichtig: Vor der Aktualisierung bitte Ihre Dateien sichern.';
+$lang['L_UPDATE'] = 'Jetzt aktualisieren';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Maximale Ausführungszeit';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Erweiterungen';
+$lang['L_MEMORY'] = 'Speicher';
+$lang['L_FILE_MISSING'] = 'konnte Datei nicht finden';
+$lang['L_INSTALLING_UPDATES'] = 'Installation von Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Aktualisierung erfolgreich';
+$lang['L_UPDATE_FAILED'] = 'Aktualisierung fehlgeschlagen';
+$lang['L_UP_TO_DATE'] = 'Aktuelle Version ist auf dem neuesten Stand';
diff --git a/msd/language/de/lang_restore.php b/msd/language/de/lang_restore.php
index 1280d89a..5dec6890 100644
--- a/msd/language/de/lang_restore.php
+++ b/msd/language/de/lang_restore.php
@@ -1,24 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Es wurden bisher <b>%d</b> Tabellen angelegt.";
-$lang['L_FILE_MISSING']="konnte Datei nicht finden";
-$lang['L_RESTORE_DB']="Datenbank '<b>%s</b>' auf Server '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> Tabellen wurden angelegt.";
-$lang['L_RESTORE_RUN1']="<br>Es wurden bisher <b>%s</b> von <b>%s</b> Datensätzen erfolgreich eingetragen.";
-$lang['L_RESTORE_RUN2']="<br>Momentan werden Daten der Tabelle '<b>%s</b>' analysiert.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> Datensätze wurden eingetragen.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Es wurden bisher <b>%d</b> von <b>%d</b> Tabellen angelegt.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Herzlichen Glückwunsch.</b><br><br>Die Datenbank wurde komplett wiederhergestellt.<br>Alle Daten aus der Backup-Datei wurden erfolgreich in die Datenbank eingetragen.<br><br>Alles fertig. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Fehler:<br>Auswahl der Datenbank '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' fehlgeschlagen!";
-$lang['L_FILE_OPEN_ERROR']="Fehler: Die Datei konnte nicht geöffnet werden.";
-$lang['L_PROGRESS_OVER_ALL']="Fortschritt gesamt";
-$lang['L_BACK_TO_OVERVIEW']="Datenbank-Übersicht";
-$lang['L_RESTORE_RUN0']="<br>Es wurden bisher <b>%s</b> Datensätze erfolgreich eingetragen.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Unbekannter SQL-Befehl:";
-$lang['L_NOTICES']="Hinweise
 
-
-";
-
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Es wurden bisher <b>%d</b> Tabellen angelegt.';
+$lang['L_FILE_MISSING'] = 'konnte Datei nicht finden';
+$lang['L_RESTORE_DB'] = "Datenbank '<b>%s</b>' auf Server '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> Tabellen wurden angelegt.';
+$lang['L_RESTORE_RUN1'] = '<br>Es wurden bisher <b>%s</b> von <b>%s</b> Datensätzen erfolgreich eingetragen.';
+$lang['L_RESTORE_RUN2'] = "<br>Momentan werden Daten der Tabelle '<b>%s</b>' analysiert.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> Datensätze wurden eingetragen.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Es wurden bisher <b>%d</b> von <b>%d</b> Tabellen angelegt.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Herzlichen Glückwunsch.</b><br><br>Die Datenbank wurde komplett wiederhergestellt.<br>Alle Daten aus der Backup-Datei wurden erfolgreich in die Datenbank eingetragen.<br><br>Alles fertig. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Fehler:<br>Auswahl der Datenbank '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' fehlgeschlagen!";
+$lang['L_FILE_OPEN_ERROR'] = 'Fehler: Die Datei konnte nicht geöffnet werden.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Fortschritt gesamt';
+$lang['L_BACK_TO_OVERVIEW'] = 'Datenbank-Übersicht';
+$lang['L_RESTORE_RUN0'] = '<br>Es wurden bisher <b>%s</b> Datensätze erfolgreich eingetragen.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Unbekannter SQL-Befehl:';
+$lang['L_NOTICES'] = 'Hinweise';
diff --git a/msd/language/de/lang_sql.php b/msd/language/de/lang_sql.php
index 9c4d8b24..1fda40d6 100644
--- a/msd/language/de/lang_sql.php
+++ b/msd/language/de/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Befehl";
-$lang['L_IMPORT_NOTABLE']="Es ist keine Tabelle für den Import ausgewählt!";
-$lang['L_PASSWORD_STRENGTH']="Kennwortstärke";
-$lang['L_SQL_WARNING']="Die Ausführung von SQL-Befehlen kann Daten manipulieren! Der Autor übernimmt keine Haftung bei Datenverlusten.";
-$lang['L_SQL_EXEC']="SQL-Befehl ausführen";
-$lang['L_SQL_DATAVIEW']="Daten-Ansicht";
-$lang['L_SQL_TABLEVIEW']="Tabellen-Ansicht";
-$lang['L_SQL_VONINS']="von insgesamt";
-$lang['L_SQL_NODATA']="keine Datensätze";
-$lang['L_SQL_RECORDUPDATED']="Datensatz wurde geändert";
-$lang['L_SQL_RECORDINSERTED']="Datensatz wurde gespeichert";
-$lang['L_SQL_BACKDBOVERVIEW']="zurück zur Datenbank-Übersicht";
-$lang['L_SQL_RECORDDELETED']="Datensatz wurde gelöscht";
-$lang['L_ASKTABLEEMPTY']="Soll die Tabelle `%s` geleert werden?";
-$lang['L_SQL_RECORDEDIT']="editiere Datensatz";
-$lang['L_SQL_RECORDNEW']="Datensatz einfügen";
-$lang['L_ASKDELETERECORD']="Soll der Datensatz gelöscht werden?";
-$lang['L_ASKDELETETABLE']="Soll die Tabelle `%s` gelöscht werden?";
-$lang['L_SQL_BEFEHLE']="SQL-Befehle";
-$lang['L_SQL_BEFEHLNEU']="neuer Befehl";
-$lang['L_SQL_BEFEHLSAVED1']="SQL-Befehl";
-$lang['L_SQL_BEFEHLSAVED2']="wurde hinzugefügt";
-$lang['L_SQL_BEFEHLSAVED3']="wurde gespeichert";
-$lang['L_SQL_BEFEHLSAVED4']="wurde nach oben gebracht";
-$lang['L_SQL_BEFEHLSAVED5']="wurde gelöscht";
-$lang['L_SQL_QUERYENTRY']="Die Abfrage enthält";
-$lang['L_SQL_COLUMNS']="Spalten";
-$lang['L_ASKDBDELETE']="Soll die Datenbank `%s` samt Inhalt wirklich gelöscht werden?";
-$lang['L_ASKDBEMPTY']="Soll die Datenbank `%s` wirklich geleert werden?";
-$lang['L_ASKDBCOPY']="Soll der Inhalt der Datenbank `%s` in die Datenbank `%s` kopiert werden?";
-$lang['L_SQL_TABLENEW']="Tabellen bearbeiten";
-$lang['L_SQL_OUTPUT']="SQL-Ausgabe";
-$lang['L_DO_NOW']="jetzt ausführen";
-$lang['L_SQL_NAMEDEST_MISSING']="Name für die Zieldatenbank fehlt!";
-$lang['L_ASKDELETEFIELD']="Soll das Feld gelöscht werden?";
-$lang['L_SQL_COMMANDS_IN']=" Zeilen in ";
-$lang['L_SQL_COMMANDS_IN2']="  Sekunde(n) abgearbeitet.";
-$lang['L_SQL_OUT1']="Es wurden ";
-$lang['L_SQL_OUT2']="Befehle ausgeführt";
-$lang['L_SQL_OUT3']="Es gab ";
-$lang['L_SQL_OUT4']="Kommentare";
-$lang['L_SQL_OUT5']="Da die Ausgabe über 5000 Zeilen enthält, wird sie nicht angezeigt.";
-$lang['L_SQL_SELECDB']="Datenbank auswählen";
-$lang['L_SQL_TABLESOFDB']="Tabellen der Datenbank";
-$lang['L_SQL_EDIT']="bearbeiten";
-$lang['L_SQL_NOFIELDDELETE']="Löschen nicht möglich, da eine Tabelle mindestens 1 Feld haben muss.";
-$lang['L_SQL_FIELDDELETE1']="Das Feld";
-$lang['L_SQL_DELETED']="wurde gelöscht.";
-$lang['L_SQL_CHANGED']="wurde geändert.";
-$lang['L_SQL_CREATED']="wurde angelegt.";
-$lang['L_SQL_NODEST_COPY']="Ohne Ziel kann nicht kopiert werden!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Zieltabelle existiert schon!";
-$lang['L_SQL_SCOPY']="Tabellenstruktur von `%s` wurde in Tabelle `%s` kopiert.";
-$lang['L_SQL_TCOPY']="Tabelle `%s` wurde mit Daten in Tabelle `%s` kopiert.";
-$lang['L_SQL_TABLENONAME']="Tabelle braucht einen Namen!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tabellenname darf nicht leer sein!";
-$lang['L_SQL_COLLATENOTMATCH']="Zeichensatz und Sortierung passen nicht zueinander!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Fehler: Kein gültiger Feldname";
-$lang['L_SQL_CREATETABLE']="Tabelle anlegen";
-$lang['L_SQL_COPYTABLE']="Tabelle kopieren";
-$lang['L_SQL_STRUCTUREONLY']="nur Struktur";
-$lang['L_SQL_STRUCTUREDATA']="Struktur und Daten";
-$lang['L_SQL_NOTABLESINDB']="Es befinden sich keine Tabellen in der Datenbank";
-$lang['L_SQL_SELECTTABLE']="Tabelle auswählen";
-$lang['L_SQL_SHOWDATATABLE']="Daten der Tabelle anzeigen";
-$lang['L_SQL_TBLPROPSOF']="Tabelleneigenschaften  von";
-$lang['L_SQL_EDITFIELD']="Editiere Feld";
-$lang['L_SQL_NEWFIELD']="Neues Feld";
-$lang['L_SQL_INDEXES']="Indizes";
-$lang['L_SQL_ATPOSITION']="an Position einfügen";
-$lang['L_SQL_FIRST']="zuerst";
-$lang['L_SQL_AFTER']="nach";
-$lang['L_SQL_CHANGEFIELD']="Feld ändern";
-$lang['L_SQL_INSERTFIELD']="Feld einfügen";
-$lang['L_SQL_INSERTNEWFIELD']="Neues Feld einfügen";
-$lang['L_SQL_TABLEINDEXES']="Indizes der Tabelle";
-$lang['L_SQL_ALLOWDUPS']="Duplikate erlaubt";
-$lang['L_SQL_CARDINALITY']="Kardinalität";
-$lang['L_SQL_TABLENOINDEXES']="Die Tabelle enthält keine Indizes";
-$lang['L_SQL_CREATEINDEX']="Neuen Index erzeugen";
-$lang['L_SQL_WASEMPTIED']="wurde geleert";
-$lang['L_SQL_RENAMEDTO']="wurde umbenannt in";
-$lang['L_SQL_DBCOPY']="Der Inhalt der Datenbank `%s` wurde in die Datenbank `%s` kopiert.";
-$lang['L_SQL_DBSCOPY']="Die Struktur der Datenbank `%s` wurde in die Datenbank `%s` kopiert.";
-$lang['L_SQL_WASCREATED']="wurde erzeugt";
-$lang['L_SQL_RENAMEDB']="Datenbank umbenennen";
-$lang['L_SQL_ACTIONS']="Aktionen";
-$lang['L_SQL_CHOOSEACTION']="Aktion wählen";
-$lang['L_SQL_DELETEDB']="Datenbank löschen";
-$lang['L_SQL_EMPTYDB']="Datenbank leeren";
-$lang['L_SQL_COPYDATADB']="Inhalt in Datenbank kopieren";
-$lang['L_SQL_COPYSDB']="Struktur in Datenbank kopieren";
-$lang['L_SQL_IMEXPORT']="Im-/Export";
-$lang['L_INFO_RECORDS']="Datensätze";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="Sollen die Tabelle `%s` geleert und die Indizes zurückgesetzt werden?";
-$lang['L_EDIT']="editieren";
-$lang['L_DELETE']="löschen";
-$lang['L_EMPTY']="leeren";
-$lang['L_EMPTYKEYS']="leeren und Indizes zurücksetzen";
-$lang['L_SQL_TABLEEMPTIED']="Tabelle `%s` wurde geleert.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Tabelle `%s` wurde geleert, und die Indizes wurden zurückgesetzt.";
-$lang['L_SQL_LIBRARY']="SQL-Bibliothek";
-$lang['L_SQL_ATTRIBUTES']="Attribute";
-$lang['L_SQL_UPLOADEDFILE']="geladene Datei: ";
-$lang['L_SQL_IMPORT']="Import in Datenbank `%s`";
-$lang['L_EXPORT']="Export";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Import-Optionen";
-$lang['L_CSVOPTIONS']="CSV-Optionen";
-$lang['L_IMPORTTABLE']="Import in Tabelle";
-$lang['L_NEWTABLE']="neue Tabelle";
-$lang['L_IMPORTSOURCE']="Import-Quelle";
-$lang['L_FROMTEXTBOX']="aus Textfeld";
-$lang['L_FROMFILE']="aus Datei";
-$lang['L_EMPTYTABLEBEFORE']="Tabelle vorher leeren";
-$lang['L_CREATEAUTOINDEX']="Auto-Index erzeugen";
-$lang['L_CSV_NAMEFIRSTLINE']="Feldnamen in die erste Zeile";
-$lang['L_CSV_FIELDSEPERATE']="Felder getrennt mit";
-$lang['L_CSV_FIELDSENCLOSED']="Felder eingeschlossen von";
-$lang['L_CSV_FIELDSESCAPE']="Felder escaped von";
-$lang['L_CSV_EOL']="Zeilen getrennt mit";
-$lang['L_CSV_NULL']="Ersetze NULL durch";
-$lang['L_CSV_FILEOPEN']="CSV-Datei öffnen";
-$lang['L_IMPORTIEREN']="importieren";
-$lang['L_SQL_EXPORT']="Export aus Datenbank `%s`";
-$lang['L_EXPORTOPTIONS']="Export-Optionen";
-$lang['L_EXCEL2003']="Excel ab 2003";
-$lang['L_SHOWRESULT']="Ergebnis anzeigen";
-$lang['L_SENDRESULTASFILE']="Ergebnis als Datei senden";
-$lang['L_EXPORTLINES']="<strong>%s</strong> Zeilen exportiert";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Die Anzahl der Tabellenfelder stimmen nicht mit den zu importierenden Daten überein (%d statt %d).";
-$lang['L_CSV_FIELDSLINES']="%d Felder ermittelt, insgesamt %d Zeilen";
-$lang['L_CSV_ERRORCREATETABLE']="Fehler beim Erstellen der Tabelle `%s`!";
-$lang['L_FM_UPLOADFILEREQUEST']="Bitte geben Sie eine Datei an.";
-$lang['L_CSV_NODATA']="Keine Daten zum Importieren gefunden!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="allgemeine Funktionen";
-$lang['L_SQLLIB_RESETAUTO']="Auto-Wert zurücksetzen";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="Board deaktivieren";
-$lang['L_SQLLIB_ACTIVATEBOARD']="Board aktivieren";
-$lang['L_SQL_NOTABLESSELECTED']="Es sind keine Tabellen ausgewählt!";
-$lang['L_TOOLS']="Tools";
-$lang['L_TOOLS_TOOLBOX']="Datenbank auswählen / Datenbankfunktionen / Im- und Export ";
-$lang['L_SQL_OPENFILE']="SQL-Datei öffnen";
-$lang['L_SQL_OPENFILE_BUTTON']="Hochaden";
-$lang['L_MAX_UPLOAD_SIZE']="Maximale Dateigröße";
-$lang['L_SQL_SEARCH']="Suche";
-$lang['L_SQL_SEARCHWORDS']="Suchbegriff(e)";
-$lang['L_START_SQL_SEARCH']="Suche starten";
-$lang['L_RESET_SEARCHWORDS']="Eingabe zurücksetzen";
-$lang['L_SEARCH_OPTIONS']="Suchoptionen";
-$lang['L_SEARCH_RESULTS']="Die Suche nach \"<b>%s</b>\" in der Tabelle \"<b>%s</b>\" lieferte folgende Treffer";
-$lang['L_SEARCH_NO_RESULTS']="Die Suche nach \"<b>%s</b>\" in der Tabelle \"<b>%s</b>\" liefert keine Ergebnisse!";
-$lang['L_NO_ENTRIES']="Die Tabelle \"<b>%s</b>\" ist leer und hat keine Einträge.";
-$lang['L_SEARCH_ACCESS_KEYS']="Blättern: vor=ALT+V, zurück=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="eine Spalte muss mindestens einen Suchbegriff enthalten (ODER-Suche)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="ein Datensatz muss alle Suchbegriffe enthalten, diese können aber in beliebigen Spalten sein (Rechenintensiv!)";
-$lang['L_SEARCH_OPTIONS_AND']="eine Spalte muss alle Suchbegriffe enthalten (UND-Suche)";
-$lang['L_SEARCH_IN_TABLE']="Suche in Tabelle";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Tabellenstruktur bearbeiten";
-$lang['L_DEFAULT_CHARSET']="Standardzeichensatz";
-$lang['L_TITLE_KEY_PRIMARY']="Primärschlüssel";
-$lang['L_TITLE_KEY_UNIQUE']="Eindeutiger Schlüssel";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Volltextschlüssel";
-$lang['L_TITLE_NOKEY']="Kein Schlüssel";
-$lang['L_TITLE_SEARCH']="Suche";
-$lang['L_TITLE_MYSQL_HELP']="MySQL Dokumentation";
-$lang['L_TITLE_UPLOAD']="SQL-Datei hochladen";
-$lang['L_PRIMARYKEY_DELETED']="Primärschlüssel gelöscht";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primärschlüssel nicht gefunden";
-$lang['L_PRIMARYKEYS_CHANGED']="Primärschlüssel geändert";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Fehler beim Ändern der Primärschlüssel";
-$lang['L_SQL_VIEW_COMPACT']="Ansicht: kompakt";
-$lang['L_SQL_VIEW_STANDARD']="Ansicht: normal";
-$lang['L_FIELDS_OF_TABLE']="Felder der Tabelle";
-$lang['L_ENGINE']="Typ";
-$lang['L_USERNAME']="Benutzername";
-$lang['L_PASSWORD']="Kennwort";
-$lang['L_PASSWORD_REPEAT']="Kennwort (Wiederholung)";
-$lang['L_INFO_SIZE']="Größe";
-$lang['L_TABLE_TYPE']="Typ";
-$lang['L_KEY_DELETED']="Index gelöscht";
-$lang['L_KEY_DELETEERROR']="Fehler beim Löschen des Index";
-$lang['L_KEY_ADDED']="Index angelegt";
-$lang['L_KEY_ADDERROR']="Fehler beim Anlegen des Index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Befehl';
+$lang['L_IMPORT_NOTABLE'] = 'Es ist keine Tabelle für den Import ausgewählt!';
+$lang['L_PASSWORD_STRENGTH'] = 'Kennwortstärke';
+$lang['L_SQL_WARNING'] = 'Die Ausführung von SQL-Befehlen kann Daten manipulieren! Der Autor übernimmt keine Haftung bei Datenverlusten.';
+$lang['L_SQL_EXEC'] = 'SQL-Befehl ausführen';
+$lang['L_SQL_DATAVIEW'] = 'Daten-Ansicht';
+$lang['L_SQL_TABLEVIEW'] = 'Tabellen-Ansicht';
+$lang['L_SQL_VONINS'] = 'von insgesamt';
+$lang['L_SQL_NODATA'] = 'keine Datensätze';
+$lang['L_SQL_RECORDUPDATED'] = 'Datensatz wurde geändert';
+$lang['L_SQL_RECORDINSERTED'] = 'Datensatz wurde gespeichert';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'zurück zur Datenbank-Übersicht';
+$lang['L_SQL_RECORDDELETED'] = 'Datensatz wurde gelöscht';
+$lang['L_ASKTABLEEMPTY'] = 'Soll die Tabelle `%s` geleert werden?';
+$lang['L_SQL_RECORDEDIT'] = 'editiere Datensatz';
+$lang['L_SQL_RECORDNEW'] = 'Datensatz einfügen';
+$lang['L_ASKDELETERECORD'] = 'Soll der Datensatz gelöscht werden?';
+$lang['L_ASKDELETETABLE'] = 'Soll die Tabelle `%s` gelöscht werden?';
+$lang['L_SQL_BEFEHLE'] = 'SQL-Befehle';
+$lang['L_SQL_BEFEHLNEU'] = 'neuer Befehl';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL-Befehl';
+$lang['L_SQL_BEFEHLSAVED2'] = 'wurde hinzugefügt';
+$lang['L_SQL_BEFEHLSAVED3'] = 'wurde gespeichert';
+$lang['L_SQL_BEFEHLSAVED4'] = 'wurde nach oben gebracht';
+$lang['L_SQL_BEFEHLSAVED5'] = 'wurde gelöscht';
+$lang['L_SQL_QUERYENTRY'] = 'Die Abfrage enthält';
+$lang['L_SQL_COLUMNS'] = 'Spalten';
+$lang['L_ASKDBDELETE'] = 'Soll die Datenbank `%s` samt Inhalt wirklich gelöscht werden?';
+$lang['L_ASKDBEMPTY'] = 'Soll die Datenbank `%s` wirklich geleert werden?';
+$lang['L_ASKDBCOPY'] = 'Soll der Inhalt der Datenbank `%s` in die Datenbank `%s` kopiert werden?';
+$lang['L_SQL_TABLENEW'] = 'Tabellen bearbeiten';
+$lang['L_SQL_OUTPUT'] = 'SQL-Ausgabe';
+$lang['L_DO_NOW'] = 'jetzt ausführen';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Name für die Zieldatenbank fehlt!';
+$lang['L_ASKDELETEFIELD'] = 'Soll das Feld gelöscht werden?';
+$lang['L_SQL_COMMANDS_IN'] = ' Zeilen in ';
+$lang['L_SQL_COMMANDS_IN2'] = '  Sekunde(n) abgearbeitet.';
+$lang['L_SQL_OUT1'] = 'Es wurden ';
+$lang['L_SQL_OUT2'] = 'Befehle ausgeführt';
+$lang['L_SQL_OUT3'] = 'Es gab ';
+$lang['L_SQL_OUT4'] = 'Kommentare';
+$lang['L_SQL_OUT5'] = 'Da die Ausgabe über 5000 Zeilen enthält, wird sie nicht angezeigt.';
+$lang['L_SQL_SELECDB'] = 'Datenbank auswählen';
+$lang['L_SQL_TABLESOFDB'] = 'Tabellen der Datenbank';
+$lang['L_SQL_EDIT'] = 'bearbeiten';
+$lang['L_SQL_NOFIELDDELETE'] = 'Löschen nicht möglich, da eine Tabelle mindestens 1 Feld haben muss.';
+$lang['L_SQL_FIELDDELETE1'] = 'Das Feld';
+$lang['L_SQL_DELETED'] = 'wurde gelöscht.';
+$lang['L_SQL_CHANGED'] = 'wurde geändert.';
+$lang['L_SQL_CREATED'] = 'wurde angelegt.';
+$lang['L_SQL_NODEST_COPY'] = 'Ohne Ziel kann nicht kopiert werden!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Zieltabelle existiert schon!';
+$lang['L_SQL_SCOPY'] = 'Tabellenstruktur von `%s` wurde in Tabelle `%s` kopiert.';
+$lang['L_SQL_TCOPY'] = 'Tabelle `%s` wurde mit Daten in Tabelle `%s` kopiert.';
+$lang['L_SQL_TABLENONAME'] = 'Tabelle braucht einen Namen!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tabellenname darf nicht leer sein!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Zeichensatz und Sortierung passen nicht zueinander!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Fehler: Kein gültiger Feldname';
+$lang['L_SQL_CREATETABLE'] = 'Tabelle anlegen';
+$lang['L_SQL_COPYTABLE'] = 'Tabelle kopieren';
+$lang['L_SQL_STRUCTUREONLY'] = 'nur Struktur';
+$lang['L_SQL_STRUCTUREDATA'] = 'Struktur und Daten';
+$lang['L_SQL_NOTABLESINDB'] = 'Es befinden sich keine Tabellen in der Datenbank';
+$lang['L_SQL_SELECTTABLE'] = 'Tabelle auswählen';
+$lang['L_SQL_SHOWDATATABLE'] = 'Daten der Tabelle anzeigen';
+$lang['L_SQL_TBLPROPSOF'] = 'Tabelleneigenschaften  von';
+$lang['L_SQL_EDITFIELD'] = 'Editiere Feld';
+$lang['L_SQL_NEWFIELD'] = 'Neues Feld';
+$lang['L_SQL_INDEXES'] = 'Indizes';
+$lang['L_SQL_ATPOSITION'] = 'an Position einfügen';
+$lang['L_SQL_FIRST'] = 'zuerst';
+$lang['L_SQL_AFTER'] = 'nach';
+$lang['L_SQL_CHANGEFIELD'] = 'Feld ändern';
+$lang['L_SQL_INSERTFIELD'] = 'Feld einfügen';
+$lang['L_SQL_INSERTNEWFIELD'] = 'Neues Feld einfügen';
+$lang['L_SQL_TABLEINDEXES'] = 'Indizes der Tabelle';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplikate erlaubt';
+$lang['L_SQL_CARDINALITY'] = 'Kardinalität';
+$lang['L_SQL_TABLENOINDEXES'] = 'Die Tabelle enthält keine Indizes';
+$lang['L_SQL_CREATEINDEX'] = 'Neuen Index erzeugen';
+$lang['L_SQL_WASEMPTIED'] = 'wurde geleert';
+$lang['L_SQL_RENAMEDTO'] = 'wurde umbenannt in';
+$lang['L_SQL_DBCOPY'] = 'Der Inhalt der Datenbank `%s` wurde in die Datenbank `%s` kopiert.';
+$lang['L_SQL_DBSCOPY'] = 'Die Struktur der Datenbank `%s` wurde in die Datenbank `%s` kopiert.';
+$lang['L_SQL_WASCREATED'] = 'wurde erzeugt';
+$lang['L_SQL_RENAMEDB'] = 'Datenbank umbenennen';
+$lang['L_SQL_ACTIONS'] = 'Aktionen';
+$lang['L_SQL_CHOOSEACTION'] = 'Aktion wählen';
+$lang['L_SQL_DELETEDB'] = 'Datenbank löschen';
+$lang['L_SQL_EMPTYDB'] = 'Datenbank leeren';
+$lang['L_SQL_COPYDATADB'] = 'Inhalt in Datenbank kopieren';
+$lang['L_SQL_COPYSDB'] = 'Struktur in Datenbank kopieren';
+$lang['L_SQL_IMEXPORT'] = 'Im-/Export';
+$lang['L_INFO_RECORDS'] = 'Datensätze';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Sollen die Tabelle `%s` geleert und die Indizes zurückgesetzt werden?';
+$lang['L_EDIT'] = 'editieren';
+$lang['L_DELETE'] = 'löschen';
+$lang['L_EMPTY'] = 'leeren';
+$lang['L_EMPTYKEYS'] = 'leeren und Indizes zurücksetzen';
+$lang['L_SQL_TABLEEMPTIED'] = 'Tabelle `%s` wurde geleert.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Tabelle `%s` wurde geleert, und die Indizes wurden zurückgesetzt.';
+$lang['L_SQL_LIBRARY'] = 'SQL-Bibliothek';
+$lang['L_SQL_ATTRIBUTES'] = 'Attribute';
+$lang['L_SQL_UPLOADEDFILE'] = 'geladene Datei: ';
+$lang['L_SQL_IMPORT'] = 'Import in Datenbank `%s`';
+$lang['L_EXPORT'] = 'Export';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = 'Import-Optionen';
+$lang['L_CSVOPTIONS'] = 'CSV-Optionen';
+$lang['L_IMPORTTABLE'] = 'Import in Tabelle';
+$lang['L_NEWTABLE'] = 'neue Tabelle';
+$lang['L_IMPORTSOURCE'] = 'Import-Quelle';
+$lang['L_FROMTEXTBOX'] = 'aus Textfeld';
+$lang['L_FROMFILE'] = 'aus Datei';
+$lang['L_EMPTYTABLEBEFORE'] = 'Tabelle vorher leeren';
+$lang['L_CREATEAUTOINDEX'] = 'Auto-Index erzeugen';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Feldnamen in die erste Zeile';
+$lang['L_CSV_FIELDSEPERATE'] = 'Felder getrennt mit';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Felder eingeschlossen von';
+$lang['L_CSV_FIELDSESCAPE'] = 'Felder escaped von';
+$lang['L_CSV_EOL'] = 'Zeilen getrennt mit';
+$lang['L_CSV_NULL'] = 'Ersetze NULL durch';
+$lang['L_CSV_FILEOPEN'] = 'CSV-Datei öffnen';
+$lang['L_IMPORTIEREN'] = 'importieren';
+$lang['L_SQL_EXPORT'] = 'Export aus Datenbank `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Export-Optionen';
+$lang['L_EXCEL2003'] = 'Excel ab 2003';
+$lang['L_SHOWRESULT'] = 'Ergebnis anzeigen';
+$lang['L_SENDRESULTASFILE'] = 'Ergebnis als Datei senden';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> Zeilen exportiert';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Die Anzahl der Tabellenfelder stimmen nicht mit den zu importierenden Daten überein (%d statt %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d Felder ermittelt, insgesamt %d Zeilen';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Fehler beim Erstellen der Tabelle `%s`!';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Bitte geben Sie eine Datei an.';
+$lang['L_CSV_NODATA'] = 'Keine Daten zum Importieren gefunden!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'allgemeine Funktionen';
+$lang['L_SQLLIB_RESETAUTO'] = 'Auto-Wert zurücksetzen';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'Board deaktivieren';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'Board aktivieren';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Es sind keine Tabellen ausgewählt!';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_TOOLS_TOOLBOX'] = 'Datenbank auswählen / Datenbankfunktionen / Im- und Export ';
+$lang['L_SQL_OPENFILE'] = 'SQL-Datei öffnen';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Hochaden';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximale Dateigröße';
+$lang['L_SQL_SEARCH'] = 'Suche';
+$lang['L_SQL_SEARCHWORDS'] = 'Suchbegriff(e)';
+$lang['L_START_SQL_SEARCH'] = 'Suche starten';
+$lang['L_RESET_SEARCHWORDS'] = 'Eingabe zurücksetzen';
+$lang['L_SEARCH_OPTIONS'] = 'Suchoptionen';
+$lang['L_SEARCH_RESULTS'] = 'Die Suche nach "<b>%s</b>" in der Tabelle "<b>%s</b>" lieferte folgende Treffer';
+$lang['L_SEARCH_NO_RESULTS'] = 'Die Suche nach "<b>%s</b>" in der Tabelle "<b>%s</b>" liefert keine Ergebnisse!';
+$lang['L_NO_ENTRIES'] = 'Die Tabelle "<b>%s</b>" ist leer und hat keine Einträge.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Blättern: vor=ALT+V, zurück=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'eine Spalte muss mindestens einen Suchbegriff enthalten (ODER-Suche)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'ein Datensatz muss alle Suchbegriffe enthalten, diese können aber in beliebigen Spalten sein (Rechenintensiv!)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'eine Spalte muss alle Suchbegriffe enthalten (UND-Suche)';
+$lang['L_SEARCH_IN_TABLE'] = 'Suche in Tabelle';
+$lang['L_ERROR_NO_FIELDS'] = 'Fehler bei Suche: es konnte nicht ermittelt werden, welche Felder die Tabelle "%s" hat!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Tabellenstruktur bearbeiten';
+$lang['L_DEFAULT_CHARSET'] = 'Standardzeichensatz';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primärschlüssel';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Eindeutiger Schlüssel';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Volltextschlüssel';
+$lang['L_TITLE_NOKEY'] = 'Kein Schlüssel';
+$lang['L_TITLE_SEARCH'] = 'Suche';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQL Dokumentation';
+$lang['L_TITLE_UPLOAD'] = 'SQL-Datei hochladen';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primärschlüssel gelöscht';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primärschlüssel nicht gefunden';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primärschlüssel geändert';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Fehler beim Ändern der Primärschlüssel';
+$lang['L_SQL_VIEW_COMPACT'] = 'Ansicht: kompakt';
+$lang['L_SQL_VIEW_STANDARD'] = 'Ansicht: normal';
+$lang['L_FIELDS_OF_TABLE'] = 'Felder der Tabelle';
+$lang['L_ENGINE'] = 'Typ';
+$lang['L_USERNAME'] = 'Benutzername';
+$lang['L_PASSWORD'] = 'Kennwort';
+$lang['L_PASSWORD_REPEAT'] = 'Kennwort (Wiederholung)';
+$lang['L_INFO_SIZE'] = 'Größe';
+$lang['L_TABLE_TYPE'] = 'Typ';
+$lang['L_KEY_DELETED'] = 'Index gelöscht';
+$lang['L_KEY_DELETEERROR'] = 'Fehler beim Löschen des Index';
+$lang['L_KEY_ADDED'] = 'Index angelegt';
+$lang['L_KEY_ADDERROR'] = 'Fehler beim Anlegen des Index';
diff --git a/msd/language/de/help.php b/msd/language/de_du/help.html
similarity index 62%
rename from msd/language/de/help.php
rename to msd/language/de_du/help.html
index c5c1094c..81b06a79 100644
--- a/msd/language/de/help.php
+++ b/msd/language/de_du/help.html
@@ -1,47 +1,74 @@
 <div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
 
 <h3>Über dieses Projekt</h3>
-Die Idee für dieses Projekt kam von Daniel Schlichtholz.<p>Er eröffnete 2004 das Forum <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a>, und schon bald fanden sich Hobby-Programmierer, die neue Skripte schrieben und die von Daniel erweiterten.<br>Innerhalb kürzester Zeit entstand aus dem kleinen Backupskript ein stattliches Projekt.<p>Wenn Du Vorschläge zur Verbesserung hast, dann wende Dich an das MySQLDumper-Forum <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>Wir wünschen Dir viel Vergnügen mit diesem Projekt.<br><p><h4>Das MySQLDumper-Team</h4>
+<p><strong>MyOOS [Dumper]</strong> ist eine verbesserte Version von MySQLDumper 1.24.4 (24. Januar 2011). Diese Weiterentwicklung berücksichtig die Entwicklung von PHP.</p>
+<p>Vor allem Stabilität, Sicherheit und Handhabung stehen bei <strong>MyOOS [Dumper]</strong> maßgeblich im Vordergrund. Aber auch ein ansprechendes Template wird mitgeliefert, welches beliebig bearbeitet und an eigene Bedürfnisse angepasst werden kann.</p>
 
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
 
-<h3>MySQLDumper Hilfe</h3>
+<p><strong>MyOOS [Dumper]</strong> ist ein Sicherungsprogramm für MySQL-Datenbanken, geschrieben in PHP und Perl. Damit können Sicherungskopien der Daten (Shop, Blog, usw.) erstellt und bei Bedarf auch wieder hergestellt werden. Besonders bei Web-Space ohne Shell-Zugang bietet sich MyOOS [Dumper] als sinnvolle Alternative an.</p> 
+
+<p>Die Idee für MySQLDumper kam von Daniel Schlichtholz. Er eröffnete 2004 das Forum MySQLDumper, woraufhin Programmierer neue Skripte schrieben und bestehende erweiterten.</p>
+<p>Offizielle Entwicklersite: www.mysqldumper.de</p>
+
+
+
+<h3>Wunschliste / Künftige Attraktionen</h3>
+<p>Hast du Verbesserungsvorschläge? Zögere nicht, das Entwicklerteam über das Forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a> zu kontaktieren.</p>
+
+
+<h3>Mitwirken</h3>
+<p>Wenn du uns dabei helfen möchtest, das MyOOS Projekt zu verbessern, freuen wir uns hier auf deine Pull Requests via GitHub.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Finanzielle Unterstützung</h3>
+<p>Man kann mit PayPal Me<br>
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>oder über den QR Code<br>  
+<img src="images/qrcode.png" alt="Finanzielle Unterstützung für MyOOS [Dumper]"></p>
+
+Geld an das MyOOS Projekt senden. <br>
+
+<p>Wir wünschen Dir viel Vergnügen mit diesem Projekt.<br><p><h4>Das MyOOS [Dumper]-Team</h4>
+
+<img src="css/mod/pics/h1_logo.gif" alt="MyOOS [Dumper]"><br>
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+
+<h3>MyOOS [Dumper] Hilfe</h3>
 
 <h4>Download</h4>
-Dieses Script erhaltet Ihr auf der Homepage von MySQLDumper.<br>
-Es empfiehlt sich, die Homepage regelmäßig zu besuchen, um Updates und
-Hilfestellungen zu erlangen.<br>
-Die Adresse lautet: <a href="http://www.mysqldumper.de" target="_blank">
-http://www.mysqldumper.de</a>
+<p>Aktuelle Versionen erhälst du immer über GitHub<br>
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
 
 <h4>Systemvoraussetzung</h4>
-Das Script arbeitet auf jedem Server (Windows, Linux, ...) <br>
-mit PHP >= Version 4.3.4 mit GZip-Unterstützung, MySQL (ab Version 3.23), JavaScript (muss aktiviert sein).
+<p>Das Script arbeitet auf jedem Server (Windows, Linux, ...) <br>
+mit PHP >= Version 7.4 mit GZip-Unterstützung, MySQL (ab Version 4.1), JavaScript (muss aktiviert sein).</p>
+<p>Aus dem MyOOS Archiv den Ordner mod in einen separaten Arbeitsordner kopieren.</p>
 
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
+<h4>Installation</h4></a>
 Die Installation geht einfach von statten.
-Entpackt das Archiv in einen beliebigen Ordner.<br>
-Ladet alle Dateien auf Euren Webserver hoch. (z. B. in die unterste Ebene in [Server Webverzeichnis/]MySQLDumper)<br>
+<p>Aus dem MyOOS Archiv den Ordner mod in einen beliebigen Ordner kopieren.<br>
+Ladet alle Dateien aus dem ordner mod auf deinen Webserver hoch. (z. B. in die unterste Ebene in [Server Webverzeichnis/]mod)<br>
 ... fertig!<br>
-Ihr könnt MySQLDumper nun im Webbrowser durch "http://mein-webserver/MySQLDumper" aufrufen,<br>
+Du kannst MyOOS [Dumper] nun im Webbrowser durch "https://example.com/mod/" aufrufen,<br>
 um die Installation abzuschließen. Folgt einfach den Instruktionen.<br>
-<br><b>Hinweis:</b><br><i>Falls auf Eurem Server der PHP-Safemode eingeschaltet ist, darf das Script keine
-Verzeichnisse erstellen.<br>
-Dies müsst Ihr dann von Hand nachholen, da MySqlDump die Daten geordnet in
+<br><b>Hinweis:</b><br><i>Falls auf Eurem Server das Script keine Verzeichnisse erstellen darf, <br>
+müsst Ihr dies dann von Hand nachholen, da MyOOS [Dumper] die Daten geordnet in
 Verzeichnissen ablegt.<br> 
 Das Script bricht mit einer entsprechenden Anweisung ab!<br>
 Nachdem Ihr die Verzeichnisse (dem Hinweis entsprechend) erstellt habt, läuft es normal und ohne Einschränkungen.</i>
 
 <a name="perl"></a><h4>Perlskript Anleitung</h4>
 Die Meisten haben ein cgi-bin Verzeichnis, in dem Perl ausgeführt werden kann. <br>
-Dies ist meist per Browser über http://www.domain.de/cgi-bin/ erreichbar. <br>
+Dies ist meist per Browser über http://www.example.com/cgi-bin/ erreichbar. <br>
 <br>
 Für diesen Fall bitte folgende Schritte durchführen:<br><br>
 
-1. Rufe im MySQLDumper die Seite Backup auf und klicke auf "Backup Perl". <br>
+1. Rufe im MyOOS [Dumper] die Seite Backup auf und klicke auf "Backup Perl". <br>
 2. Kopiere den Pfad, der hinter Eintrag in crondump.pl für $absolute_path_of_configdir: steht. <br>
 3. Öffne die Datei "crondump.pl" im Editor.<br>
 4. Trage den kopierten Pfad dort bei absolute_path_of_configdir ein (keine Leerzeichen).<br>
@@ -49,7 +76,7 @@ Für diesen Fall bitte folgende Schritte durchführen:<br><br>
 6. Kopiere crondump.pl, sowie perltest.pl und simpletest.pl ins cgi-bin-Verzeichnis (Ascii-Modus im FTP).<br>
 7. Gebe den Dateien die Rechte 755. <br>
 7b. Wenn die Endung cgi gewünscht ist, ändere bei allen 3 Dateien die Endung von pl -> cgi (umbenennen). <br>
-8. Rufe die Konfiguration im MySQLDumper auf.<br>
+8. Rufe die Konfiguration im MyOOS [Dumper] auf.<br>
 9. Wähle die Seite Cronscript. <br>
 10. Ändere Perl Ausführungspfad in /cgi-bin/ .<br>
 10b. Wenn die Scripte .pl haben, ändere die Dateiendung auf .cgi .<br>
@@ -59,7 +86,7 @@ Fertig, die Skripte lassen sich nun von der Backupseite aufrufen.<br><br>
 
 Wer Perl in allen Verzeichnissen ausführen kann, dem reichen folgende Schritte:<br><br>
 
-1. Rufe im MySQLDumper die Seite Backup auf. <br>
+1. Rufe im MyOOS [Dumper] die Seite Backup auf. <br>
 2. Kopiere den Pfad, der hinter Eintrag in crondump.pl für $absolute_path_of_configdir: steht. <br>
 3. Öffne die Datei "crondump.pl" im Editor. <br>
 4. Trage den kopierten Pfad dort bei absolute_path_of_configdir ein (keine Leerzeichen). <br>
@@ -90,8 +117,7 @@ Hier könnt Ihr eure Konfiguration bearbeiten, abspeichern oder die Ausgangskonf
 wieder herstellen.
 <ul><br>
 	<li><a name="conf1"></a><strong>Konfigurierte Datenbanken:</strong> die Auflistung der konfigurierten Datenbanken. Die aktive Datenbank wird in <b>bold</b> gelistet. </li>
-	<li><a name="conf2"></a><strong>Tabellen-Präfix:</strong> hier könnt Ihr (für jede Datenbank) einen Präfix angeben. Dies ist ein Filter, der bei Dumps nur die Tabellen berücksichtigt, die mit diesem Präfix beginnen (z.B. alle Tabellen, die mit "phpBB_" beginnen). Wenn alle Tabellen dieser Datenbank gespeichert werden sollen, 
-so lasst das Feld einfach leer.</li>
+	<li><a name="conf2"></a><strong>Tabellen-Präfix:</strong> hier könnt Ihr (für jede Datenbank) einen Präfix angeben. Dies ist ein Filter, der bei Dumps nur die Tabellen berücksichtigt, die mit diesem Präfix beginnen (z.B. alle Tabellen, die mit "phpBB_" beginnen). Wenn alle Tabellen dieser Datenbank gespeichert werden sollen, so lasst das Feld einfach leer.</li>
 	<li><a name="conf3"></a><strong>GZip-Kompression:</strong> Hier kann die Kompression aktiviert werden. Empfehlenswert ist die Aktivierung, da die Dateien doch wesentlich kleiner werden und Speicherplatz immer rar ist.</li>
 	<li><a name="conf5"></a><strong>Email mit Dumpfile:</strong> Ist diese Option aktiviert, so wird nach abgeschlossenem Backup eine Email mit dem Dump als Anhang verschickt (Vorsicht, Kompression sollte unbedingt an sein, sonst wird der Anhang zu gross und kann evtl. nicht versandt werden!).</li>
 	<li><a name="conf6"></a><strong>Email-Adresse:</strong> Empfängeradresse für die Email.</li>
diff --git a/msd/language/de_du/lang.php b/msd/language/de_du/lang.php
index 8ec515b0..035f44dc 100644
--- a/msd/language/de_du/lang.php
+++ b/msd/language/de_du/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="ja";
-$lang['L_TO']="bis";
-$lang['L_ACTIVATED']="aktiviert";
-$lang['L_NOT_ACTIVATED']="nicht aktiviert";
-$lang['L_ERROR']="Fehler";
-$lang['L_OF']=" von ";
-$lang['L_ADDED']="hinzugefügt";
-$lang['L_DB']="Datenbank";
-$lang['L_DBS']="Datenbanken";
-$lang['L_TABLES']="Tabellen";
-$lang['L_TABLE']="Tabelle";
-$lang['L_RECORDS']="Datensätze";
-$lang['L_COMPRESSED']="komprimiert (gz)";
-$lang['L_NOTCOMPRESSED']="normal (unkomprimiert)";
-$lang['L_GENERAL']="allgemein";
-$lang['L_COMMENT']="Kommentar";
-$lang['L_FILESIZE']="Dateigröße";
-$lang['L_ALL']="alle";
-$lang['L_NONE']="keine";
-$lang['L_WITH']=" mit ";
-$lang['L_DIR']="Verzeichnis";
-$lang['L_RECHTE']="Rechte";
-$lang['L_STATUS']="Status";
-$lang['L_FINISHED']="fertig";
-$lang['L_FILE']="Datei";
-$lang['L_FIELDS']="Felder";
-$lang['L_NEW']="neu";
-$lang['L_CHARSET']="Zeichensatz";
-$lang['L_COLLATION']="Sortierung";
-$lang['L_CHANGE']="Ändern";
-$lang['L_IN']="in";
-$lang['L_DO']="ausführen";
-$lang['L_VIEW']="ansehen";
-$lang['L_EXISTING']="vorhanden";
-$lang['L_BACK']="zurück";
-$lang['L_DB_HOST']="Datenbank-Hostname";
-$lang['L_DB_USER']="Datenbank-Benutzer";
-$lang['L_DB_PASS']="Datenbank-Passwort";
-$lang['L_INFO_SCRIPTDIR']="Verzeichnis von MySQLDumper";
-$lang['L_INFO_ACTDB']="Aktuelle Datenbank";
-$lang['L_WRONGCONNECTIONPARS']="Falsche oder keine Verbindungsparameter!";
-$lang['L_CONN_NOT_POSSIBLE']="Verbindung nicht möglich!";
-$lang['L_SERVERCAPTION']="Anzeige des Servers";
-$lang['L_HELP_SERVERCAPTION']="Bei Benutzung auf verschieden Systemen kann es hilfreich sein, die Server-Adresse farblich gekennzeichnet einzublenden";
-$lang['L_ACTIVATE_MULTIDUMP']="Multidump aktivieren";
-$lang['L_SAVE']="Speichern";
-$lang['L_RESET']="Zurücksetzen";
-$lang['L_PRAEFIX']="Tabellen-Präfix";
-$lang['L_AUTODELETE']="Automatisches Löschen der Backups";
-$lang['L_MAX_BACKUP_FILES_EACH2']="für jede Datenbank";
-$lang['L_SAVING_DB_FORM']="Datenbank";
-$lang['L_TESTCONNECTION']="Verbindung testen";
-$lang['L_BACK_TO_MINISQL']="Datenbank bearbeiten";
-$lang['L_CREATE']="Anlegen";
-$lang['L_VARIABELN']="Variablen";
-$lang['L_STATUSINFORMATIONEN']="Statusinformationen";
-$lang['L_VERSIONSINFORMATIONEN']="Versionsinformationen";
-$lang['L_MSD_INFO']="MyOOS [Dumper] Informationen";
-$lang['L_BACKUPFILESANZAHL']="Im Backup-Verzeichnis befinden sich";
-$lang['L_LASTBACKUP']="Letztes Backup";
-$lang['L_NOTAVAIL']="<em>nicht verfügbar</em>";
-$lang['L_VOM']="vom";
-$lang['L_MYSQLVARS']="MySQL-Variablen";
-$lang['L_MYSQLSYS']="MySQL-Befehle";
-$lang['L_STATUS']="Status";
-$lang['L_PROZESSE']="Prozesse";
-$lang['L_INFO_NOVARS']="keine Variablen verfügbar";
-$lang['L_INHALT']="Inhalt";
-$lang['L_INFO_NOSTATUS']="kein Status verfügbar";
-$lang['L_INFO_NOPROCESSES']="keine laufenden Prozesse";
-$lang['L_FM_FREESPACE']="Freier Speicher auf Server";
-$lang['L_LOAD_DATABASE']="Datenbanken neu laden";
-$lang['L_HOME']="Home";
-$lang['L_CONFIG']="Konfiguration";
-$lang['L_DUMP']="Backup";
-$lang['L_RESTORE']="Wiederherstellung";
-$lang['L_FILE_MANAGE']="Verwaltung";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Datenbank wählen";
-$lang['L_CREDITS']="Credits / Hilfe";
-$lang['L_MULTI_PART']="Multipart-Backup";
-$lang['L_LOGFILENOTWRITABLE']="Log-File kann nicht geschrieben werden!";
-$lang['L_SQL_ERROR1']="Fehler bei der Anfrage:";
-$lang['L_SQL_ERROR2']="MySQL meldet:";
-$lang['L_UNKNOWN']="unbekannt";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="unbekannt";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Komplette Ausgabe loggen";
-$lang['L_NO']="nein";
-$lang['L_CREATE_DATABASE']="Neue Datenbank anlegen";
-$lang['L_EXPORTFINISHED']="Export beendet.";
-$lang['L_SQL_BROWSER']="SQL-Browser";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Standardkodierung des MySQL-Servers";
-$lang['L_TITLE_SHOW_DATA']="Daten anzeigen";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Primärschlüssel wirklich löschen?";
-$lang['L_SETPRIMARYKEYSFOR']="Setzen neuer Primärschlüssel für die Tabelle";
-$lang['L_PRIMARYKEY_FIELD']="Schlüsselfeld";
-$lang['L_PRIMARYKEYS_SAVE']="Primärschlüssel speichern";
-$lang['L_CANCEL']="Abbruch";
-$lang['L_VISIT_HOMEPAGE']="Besuche die Homepage";
-$lang['L_SECONDS']="Sekunden";
-$lang['L_BACKUPS']="Sicherungsdateien";
-$lang['L_MINUTES']="Minuten";
-$lang['L_PAGE_REFRESHS']="Seitenaufrufe";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Setzen neuer Indizes für die Tabelle";
-$lang['L_KEY_CONFIRMDELETE']="Index wirklich löschen?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'ja';
+$lang['L_TO'] = 'bis';
+$lang['L_ACTIVATED'] = 'aktiviert';
+$lang['L_NOT_ACTIVATED'] = 'nicht aktiviert';
+$lang['L_ERROR'] = 'Fehler';
+$lang['L_OF'] = ' von ';
+$lang['L_ADDED'] = 'hinzugefügt';
+$lang['L_DB'] = 'Datenbank';
+$lang['L_DBS'] = 'Datenbanken';
+$lang['L_TABLES'] = 'Tabellen';
+$lang['L_TABLE'] = 'Tabelle';
+$lang['L_RECORDS'] = 'Datensätze';
+$lang['L_COMPRESSED'] = 'komprimiert (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (unkomprimiert)';
+$lang['L_COMMENT'] = 'Kommentar';
+$lang['L_FILESIZE'] = 'Dateigröße';
+$lang['L_ALL'] = 'alle';
+$lang['L_NONE'] = 'keine';
+$lang['L_WITH'] = ' mit ';
+$lang['L_DIR'] = 'Verzeichnis';
+$lang['L_RECHTE'] = 'Rechte';
+$lang['L_STATUS'] = 'Status';
+$lang['L_FINISHED'] = 'fertig';
+$lang['L_FILE'] = 'Datei';
+$lang['L_FIELDS'] = 'Felder';
+$lang['L_NEW'] = 'neu';
+$lang['L_CHARSET'] = 'Zeichensatz';
+$lang['L_COLLATION'] = 'Sortierung';
+$lang['L_CHANGE'] = 'Ändern';
+$lang['L_IN'] = 'in';
+$lang['L_DO'] = 'ausführen';
+$lang['L_VIEW'] = 'ansehen';
+$lang['L_EXISTING'] = 'vorhanden';
+$lang['L_BACK'] = 'zurück';
+$lang['L_DB_HOST'] = 'Datenbank-Hostname';
+$lang['L_DB_USER'] = 'Datenbank-Benutzer';
+$lang['L_DB_PASS'] = 'Datenbank-Passwort';
+$lang['L_INFO_SCRIPTDIR'] = 'Verzeichnis von MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Aktuelle Datenbank';
+$lang['L_WRONGCONNECTIONPARS'] = 'Falsche oder keine Verbindungsparameter!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Verbindung nicht möglich!';
+$lang['L_SERVERCAPTION'] = 'Anzeige des Servers';
+$lang['L_HELP_SERVERCAPTION'] = 'Bei Benutzung auf verschieden Systemen kann es hilfreich sein, die Server-Adresse farblich gekennzeichnet einzublenden';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'Multidump aktivieren';
+$lang['L_SAVE'] = 'Speichern';
+$lang['L_RESET'] = 'Zurücksetzen';
+$lang['L_PRAEFIX'] = 'Tabellen-Präfix';
+$lang['L_AUTODELETE'] = 'Automatisches Löschen der Backups';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'für jede Datenbank';
+$lang['L_SAVING_DB_FORM'] = 'Datenbank';
+$lang['L_TESTCONNECTION'] = 'Verbindung testen';
+$lang['L_BACK_TO_MINISQL'] = 'Datenbank bearbeiten';
+$lang['L_CREATE'] = 'Anlegen';
+$lang['L_VARIABELN'] = 'Variablen';
+$lang['L_STATUSINFORMATIONEN'] = 'Statusinformationen';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versionsinformationen';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] Informationen';
+$lang['L_BACKUPFILESANZAHL'] = 'Im Backup-Verzeichnis befinden sich';
+$lang['L_LASTBACKUP'] = 'Letztes Backup';
+$lang['L_NOTAVAIL'] = '<em>nicht verfügbar</em>';
+$lang['L_VOM'] = 'vom';
+$lang['L_MYSQLVARS'] = 'MySQL-Variablen';
+$lang['L_MYSQLSYS'] = 'MySQL-Befehle';
+$lang['L_STATUS'] = 'Status';
+$lang['L_PROZESSE'] = 'Prozesse';
+$lang['L_INFO_NOVARS'] = 'keine Variablen verfügbar';
+$lang['L_INHALT'] = 'Inhalt';
+$lang['L_INFO_NOSTATUS'] = 'kein Status verfügbar';
+$lang['L_INFO_NOPROCESSES'] = 'keine laufenden Prozesse';
+$lang['L_FM_FREESPACE'] = 'Freier Speicher auf Server';
+$lang['L_LOAD_DATABASE'] = 'Datenbanken neu laden';
+$lang['L_HOME'] = 'Startseite';
+$lang['L_CONFIG'] = 'Konfiguration';
+$lang['L_DUMP'] = 'Sicherung';
+$lang['L_RESTORE'] = 'Wiederherstellung';
+$lang['L_FILE_MANAGE'] = 'Verwaltung';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Datenbank wählen';
+$lang['L_CREDITS'] = 'Credits / Hilfe';
+$lang['L_MULTI_PART'] = 'Multipart-Backup';
+$lang['L_LOGFILENOTWRITABLE'] = 'Log-File kann nicht geschrieben werden!';
+$lang['L_SQL_ERROR1'] = 'Fehler bei der Anfrage:';
+$lang['L_SQL_ERROR2'] = 'MySQL meldet:';
+$lang['L_UNKNOWN'] = 'unbekannt';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'unbekannt';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Komplette Ausgabe loggen';
+$lang['L_NO'] = 'nein';
+$lang['L_CREATE_DATABASE'] = 'Neue Datenbank anlegen';
+$lang['L_EXPORTFINISHED'] = 'Export beendet.';
+$lang['L_SQL_BROWSER'] = 'SQL-Browser';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Standardkodierung des MySQL-Servers';
+$lang['L_TITLE_SHOW_DATA'] = 'Daten anzeigen';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Primärschlüssel wirklich löschen?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Setzen neuer Primärschlüssel für die Tabelle';
+$lang['L_PRIMARYKEY_FIELD'] = 'Schlüsselfeld';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Primärschlüssel speichern';
+$lang['L_CANCEL'] = 'Abbruch';
+$lang['L_VISIT_HOMEPAGE'] = 'Besuche die Homepage';
+$lang['L_SECONDS'] = 'Sekunden';
+$lang['L_BACKUPS'] = 'Sicherungsdateien';
+$lang['L_MINUTES'] = 'Minuten';
+$lang['L_PAGE_REFRESHS'] = 'Seitenaufrufe';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Setzen neuer Indizes für die Tabelle';
+$lang['L_KEY_CONFIRMDELETE'] = 'Index wirklich löschen?';
diff --git a/msd/language/de_du/lang_config_overview.php b/msd/language/de_du/lang_config_overview.php
index 6df85ef9..279aa130 100644
--- a/msd/language/de_du/lang_config_overview.php
+++ b/msd/language/de_du/lang_config_overview.php
@@ -1,111 +1,129 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Konfiguration";
-$lang['L_SAVE_SUCCESS']="Die Einstellungen wurden erfolgreich in der Konfigurationsdatei \"%s\" gespeichert.";
-$lang['L_CONFIG_LOADED']="Die Konfiguration \"%s\" wurde erfolgreich geladen.";
-$lang['L_SAVE_ERROR']="Die Einstellungen konnten nicht gespeichert werden!";
-$lang['L_CONFIG_EMAIL']="E-Mail-Benachrichtigung";
-$lang['L_CONFIG_AUTODELETE']="Auto Löschen";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="Maximale Dateigröße";
-$lang['L_HELP_MULTIPART']="Bei eingeschaltetem Multipart werden mehrere Backup-Dateien erzeugt, deren Maximalgröße sich nach der unteren Einstellung richtet";
-$lang['L_HELP_MULTIPARTGROESSE']="Die maximale Größe der einzelnen Backup-Dateien kann hier bei eingeschaltetem Multipart bestimmt werden";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Datenbank vor Wiederherstellung löschen";
-$lang['L_ALLPARS']="alle Parameter";
-$lang['L_CRON_EXTENDER']="Dateiendung des Scripts";
-$lang['L_CRON_SAVEPATH']="Konfigurationsdatei";
-$lang['L_CRON_PRINTOUT']="Textausgabe";
-$lang['L_CONFIG_CRONPERL']="Crondump-Einstellungen für das Perlscript";
-$lang['L_CRON_MAILPRG']="Mailprogramm";
-$lang['L_OPTIMIZE']="Tabellen vor dem Backup optimieren";
-$lang['L_HELP_OPTIMIZE']="Wenn die Option aktiviert ist, werden vor jedem Backup alle Tabellen optimiert";
-$lang['L_HELP_FTPTIMEOUT']="Die Zeit, die bei keiner Übertragung zum Timeout führt, Default = 90 Sekunden.";
-$lang['L_FTP_TIMEOUT']="Verbindungs-Timeout";
-$lang['L_HELP_FTPSSL']="Gibt an, ob eine sichere SSL-Verbindung für die Übertragung benutzt werden soll.";
-$lang['L_CONFIG_ASKLOAD']="Sollen die Einstellungen wirklich mit den Anfangseinstellungen überschrieben werden?";
-$lang['L_LOAD']="Grundeinstellungen";
-$lang['L_LOAD_SUCCESS']="Die Anfangseinstellungen wurden geladen.";
-$lang['L_CRON_CRONDBINDEX']="Datenbank";
-$lang['L_WITHATTACH']=" mit Anhang";
-$lang['L_WITHOUTATTACH']=" ohne Anhang";
-$lang['L_MULTIDUMPCONF']="=Multidump Einstellungen=";
-$lang['L_MULTIDUMPALL']="=alle Datenbanken=";
-$lang['L_GZIP']="GZip-Kompression";
-$lang['L_SEND_MAIL_FORM']="E-Mail senden";
-$lang['L_SEND_MAIL_DUMP']="Backup anhängen";
-$lang['L_EMAIL_ADRESS']="Empfänger";
-$lang['L_EMAIL_SENDER']="Absender der E-Mail";
-$lang['L_EMAIL_MAXSIZE']="Maximale Größe des Anhangs";
-$lang['L_NUMBER_OF_FILES_FORM']="Anzahl von Backup-Dateien pro Datenbank";
-$lang['L_LANGUAGE']="Sprache";
-$lang['L_LIST_DB']="Konfigurierte Datenbanken:";
-$lang['L_CONFIG_FTP']="FTP-Transfer der Backup-Datei";
-$lang['L_FTP_TRANSFER']="FTP-Transfer";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="User";
-$lang['L_FTP_PASS']="Passwort";
-$lang['L_FTP_DIR']="Upload-Ordner";
-$lang['L_FTP_SSL']="Sichere SSL-FTP-Verbindung";
-$lang['L_FTP_USESSL']="benutze SSL-Verbindung";
-$lang['L_SQLBOXHEIGHT']="Höhe der SQL-Box";
-$lang['L_SQLLIMIT']="Anzahl der Datensätze pro Seite";
-$lang['L_BBPARAMS']="Einstellung für BB-Code";
-$lang['L_BBTEXTCOLOR']="Textfarbe";
-$lang['L_HELP_COMMANDS']="Man kann vor und nach dem Backup einen Befehl ausführen lassen.
-Dies kann eine SQL-Anweisung sein oder ein Systembefehl (z. B. ein Script)";
-$lang['L_COMMAND']="Befehl";
-$lang['L_WRONG_CONNECTIONPARS']="Verbindungsparameter stimmen nicht!";
-$lang['L_CONNECTIONPARS']="Verbindungsparameter";
-$lang['L_EXTENDEDPARS']="erweiterte Parameter";
-$lang['L_FADE_IN_OUT']="ein-/ausblenden";
-$lang['L_DB_BACKUPPARS']="Einstellungen";
-$lang['L_GENERAL']="Allgemein";
-$lang['L_MAXSIZE']="maximale Größe";
-$lang['L_ERRORHANDLING_RESTORE']="Fehlerbehandlung bei Wiederherstellung";
-$lang['L_EHRESTORE_CONTINUE']="fortfahren und Fehler protokollieren";
-$lang['L_EHRESTORE_STOP']="anhalten";
-$lang['L_IN_MAINFRAME']="im Hauptframe";
-$lang['L_IN_LEFTFRAME']="im linken Frame";
-$lang['L_WIDTH']="Breite";
-$lang['L_SQL_BEFEHLE']="SQL-Befehle";
-$lang['L_DOWNLOAD_LANGUAGES']="andere Sprachen herunterladen";
-$lang['L_DOWNLOAD_STYLES']="andere Themen herunterladen";
-$lang['L_CONNECT_TO']="Verbinde mit";
-$lang['L_CHANGEDIR']="Wechsle in das Verzeichnis ";
-$lang['L_CHANGEDIRERROR']="Es konnte nicht in das Verzeichnis gewechselt werden!";
-$lang['L_FTP_OK']="Die Verbindung wurde erfolgreich hergestellt.";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="Es stehen keine FTP-Funktionen zur Verfügung!";
-$lang['L_FOUND_DB']="gefundene DB: ";
-$lang['L_FTP_CHOOSE_MODE']="FTP-Übertragungsmodus";
-$lang['L_FTP_PASSIVE']="passiven Übertragungsmodus benutzen";
-$lang['L_HELP_FTP_MODE']="Gibt den FTP-Übertragungsmodus an. Wenn Probleme im aktiven Modus auftreten, sollte in den passiven Modus umgeschaltet werden.";
-$lang['L_DB_IN_LIST']="Die Datenbank '%s' konnte nicht hinzugefügt werden, da sie bereits vorhanden ist.";
-$lang['L_ADD_DB_MANUALLY']="Datenbank manuell hinzufügen";
-$lang['L_DB_MANUAL_ERROR']="Die Verbindung zur Datenbank '%s' ist fehlgeschlagen!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Dateifehler: konnte die Datenbank '%s' nicht eintragen!";
-$lang['L_NO_DB_FOUND']="Es wurde keine Datenbank gefunden.
-Blende die Verbindungsparameter ein und gebe den Namen Deiner Datenbank manuell ein! ";
-$lang['L_CONFIGFILES']="Konfigurationsdateien";
-$lang['L_CONFIGFILE']="Konfigurationsdatei";
-$lang['L_MYSQL_DATA']="MySQL-Daten";
-$lang['L_CONFIGURATIONS']="Einstellungen";
-$lang['L_ACTION']="Aktion";
-$lang['L_FTP_SEND_TO']="an <strong>%s</strong><br>in <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Empfänger";
-$lang['L_NAME']="Name";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Soll die Konfigurationsdatei %s wirklich gelöscht werden?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Fehler: die Konfigurationsdatei %s konnte nicht gelöscht werden!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Die Konfigurationsdatei %s wurde erfolgreich gelöscht.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Die Konfigurationsdatei %s wurde erfolgreich angelegt.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Der Dateiname \"%s\" enthält ungültige Zeichen.";
-$lang['L_CREATE_CONFIGFILE']="Eine neue Konfigurationsdatei anlegen";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Die Konfigurationsdatei \"%s\" konnte nicht geladen werden.";
-$lang['L_BACKUP_DBS_PHP']="zu sichernde DBs (PHP)";
-$lang['L_BACKUP_DBS_PERL']="zu sichernde DBs (PERL)";
-$lang['L_CRON_COMMENT']="Kommentar eingeben";
-$lang['L_AUTODETECT']="automatisch ermitteln";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Konfiguration';
+$lang['L_SAVE_SUCCESS'] = 'Die Einstellungen wurden erfolgreich in der Konfigurationsdatei "%s" gespeichert.';
+$lang['L_CONFIG_LOADED'] = 'Die Konfiguration "%s" wurde erfolgreich geladen.';
+$lang['L_SAVE_ERROR'] = 'Die Einstellungen konnten nicht gespeichert werden!';
+$lang['L_EMAIL_NOTIFICATION'] = 'E-Mail-Benachrichtigung';
+$lang['L_CONFIG_AUTODELETE'] = 'Auto Löschen';
+$lang['L_CONFIG_INTERFACE'] = 'Benutzeroberfläche';
+$lang['L_CONFIG_EMAIL'] = 'E-Mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'Maximale Dateigröße';
+$lang['L_HELP_MULTIPART'] = 'Bei eingeschaltetem Multipart werden mehrere Backup-Dateien erzeugt, deren Maximalgröße sich nach der unteren Einstellung richtet';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Die maximale Größe der einzelnen Backup-Dateien kann hier bei eingeschaltetem Multipart bestimmt werden';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Datenbank vor Wiederherstellung löschen';
+$lang['L_ALLPARS'] = 'alle Parameter';
+$lang['L_CRON_EXTENDER'] = 'Dateiendung des Scripts';
+$lang['L_CRON_SAVEPATH'] = 'Konfigurationsdatei';
+$lang['L_CRON_PRINTOUT'] = 'Textausgabe';
+$lang['L_CONFIG_CRONPERL'] = 'Crondump-Einstellungen für das Perlscript';
+$lang['L_CRON_MAILPRG'] = 'Mailprogramm';
+$lang['L_OPTIMIZE'] = 'Tabellen vor dem Backup optimieren';
+$lang['L_HELP_OPTIMIZE'] = 'Wenn die Option aktiviert ist, werden vor jedem Backup alle Tabellen optimiert';
+$lang['L_BINARY'] = 'Exportiere binäre Daten im Hex-Format';
+$lang['L_HELP_BINARY'] = 'Bei aktivierter Option werden binäre Daten im Hex-Format exportiert um Kodierungsprobleme zu vermeiden.';
+$lang['SFTP'] = 'Die Zeit, die bei keiner Übertragung zum Timeout führt, Default = 90 Sekunden.';
+$lang['L_FTP_TIMEOUT'] = 'Verbindungs-Timeout';
+$lang['L_HELP_FTPSSL'] = 'Gibt an, ob eine sichere SSL-Verbindung für die Übertragung benutzt werden soll.';
+$lang['L_SFTP_TIMEOUT'] = 'Verbindungs-Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Gibt an, ob eine sichere SSL-Verbindung für die Übertragung benutzt werden soll.';
+$lang['L_CONFIG_ASKLOAD'] = 'Sollen die Einstellungen wirklich mit den Anfangseinstellungen überschrieben werden?';
+$lang['L_LOAD'] = 'Grundeinstellungen';
+$lang['L_LOAD_SUCCESS'] = 'Die Anfangseinstellungen wurden geladen.';
+$lang['L_CRON_CRONDBINDEX'] = 'Datenbank';
+$lang['L_WITHATTACH'] = ' mit Anhang';
+$lang['L_WITHOUTATTACH'] = ' ohne Anhang';
+$lang['L_MULTIDUMPCONF'] = '=Multidump Einstellungen=';
+$lang['L_MULTIDUMPALL'] = '=alle Datenbanken=';
+$lang['L_GZIP'] = 'GZip-Kompression';
+$lang['L_SEND_MAIL_FORM'] = 'E-Mail senden';
+$lang['L_SEND_MAIL_DUMP'] = 'Backup anhängen';
+$lang['L_EMAIL_ADRESS'] = 'Empfänger';
+$lang['L_EMAIL_SENDER'] = 'Absender der E-Mail';
+$lang['L_EMAIL_MAXSIZE'] = 'Maximale Größe des Anhangs';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Anzahl von Backup-Dateien pro Datenbank';
+$lang['L_LANGUAGE'] = 'Sprache';
+$lang['L_LIST_DB'] = 'Konfigurierte Datenbanken:';
+$lang['L_CONFIG_FTP'] = 'FTP-Transfer der Backup-Datei';
+$lang['L_FTP_TRANSFER'] = 'FTP-Transfer';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'User';
+$lang['L_FTP_PASS'] = 'Passwort';
+$lang['L_FTP_DIR'] = 'Upload-Ordner';
+$lang['L_FTP_SSL'] = 'Sichere SSL-FTP-Verbindung';
+$lang['L_FTP_USESSL'] = 'benutze SSL-Verbindung';
+$lang['L_CONFIG_SFTP'] = 'SFTP-Transfer der Backup-Datei';
+$lang['L_SFTP_TRANSFER'] = 'SFTP-Transfer';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'User';
+$lang['L_SFTP_PASS'] = 'Passwort';
+$lang['L_SFTP_DIR'] = 'Upload-Ordner';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Höhe der SQL-Box';
+$lang['L_SQLLIMIT'] = 'Anzahl der Datensätze pro Seite';
+$lang['L_BBPARAMS'] = 'Einstellung für BB-Code';
+$lang['L_BBTEXTCOLOR'] = 'Textfarbe';
+$lang['L_HELP_COMMANDS'] = 'Man kann vor und nach dem Backup einen Befehl ausführen lassen.
+Dies kann eine SQL-Anweisung sein oder ein Systembefehl (z. B. ein Script)';
+$lang['L_COMMAND'] = 'Befehl';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Verbindungsparameter stimmen nicht!';
+$lang['L_CONNECTIONPARS'] = 'Verbindungsparameter';
+$lang['L_EXTENDEDPARS'] = 'erweiterte Parameter';
+$lang['L_FADE_IN_OUT'] = 'ein-/ausblenden';
+$lang['L_DB_BACKUPPARS'] = 'Einstellungen';
+$lang['L_GENERAL'] = 'Allgemein';
+$lang['L_MAXSIZE'] = 'maximale Größe';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Fehlerbehandlung bei Wiederherstellung';
+$lang['L_EHRESTORE_CONTINUE'] = 'fortfahren und Fehler protokollieren';
+$lang['L_EHRESTORE_STOP'] = 'anhalten';
+$lang['L_IN_MAINFRAME'] = 'im Hauptframe';
+$lang['L_IN_LEFTFRAME'] = 'im linken Frame';
+$lang['L_WIDTH'] = 'Breite';
+$lang['L_SQL_BEFEHLE'] = 'SQL-Befehle';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'andere Sprachen herunterladen';
+$lang['L_DOWNLOAD_STYLES'] = 'andere Themen herunterladen';
+$lang['L_CONNECT_TO'] = 'Verbinde mit';
+$lang['L_CHANGEDIR'] = 'Wechsle in das Verzeichnis ';
+$lang['L_CHANGEDIRERROR'] = 'Es konnte nicht in das Verzeichnis gewechselt werden!';
+$lang['L_FTP_OK'] = 'Die Verbindung wurde erfolgreich hergestellt.';
+$lang['L_SFTP_OK'] = 'Die Verbindung wurde erfolgreich hergestellt.';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = 'Es stehen keine FTP-Funktionen zur Verfügung!';
+$lang['L_FOUND_DB'] = 'gefundene DB: ';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP-Übertragungsmodus';
+$lang['L_FTP_PASSIVE'] = 'passiven Übertragungsmodus benutzen';
+$lang['L_HELP_FTP_MODE'] = 'Gibt den FTP-Übertragungsmodus an. Wenn Probleme im aktiven Modus auftreten, sollte in den passiven Modus umgeschaltet werden.';
+$lang['L_SFTP_PASSIVE'] = 'passiven Übertragungsmodus benutzen';
+$lang['L_DB_IN_LIST'] = "Die Datenbank '%s' konnte nicht hinzugefügt werden, da sie bereits vorhanden ist.";
+$lang['L_ADD_DB_MANUALLY'] = 'Datenbank manuell hinzufügen';
+$lang['L_DB_MANUAL_ERROR'] = "Die Verbindung zur Datenbank '%s' ist fehlgeschlagen!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Dateifehler: konnte die Datenbank '%s' nicht eintragen!";
+$lang['L_NO_DB_FOUND'] = 'Es wurde keine Datenbank gefunden.
+Blende die Verbindungsparameter ein und gebe den Namen Deiner Datenbank manuell ein! ';
+$lang['L_CONFIGFILES'] = 'Konfigurationsdateien';
+$lang['L_CONFIGFILE'] = 'Konfigurationsdatei';
+$lang['L_MYSQL_DATA'] = 'MySQL-Daten';
+$lang['L_CONFIGURATIONS'] = 'Einstellungen';
+$lang['L_ACTION'] = 'Aktion';
+$lang['L_FTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'an <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Empfänger';
+$lang['L_NAME'] = 'Name';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Soll die Konfigurationsdatei %s wirklich gelöscht werden?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Fehler: die Konfigurationsdatei %s konnte nicht gelöscht werden!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Die Konfigurationsdatei %s wurde erfolgreich gelöscht.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Die Konfigurationsdatei %s wurde erfolgreich angelegt.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Der Dateiname "%s" enthält ungültige Zeichen.';
+$lang['L_CREATE_CONFIGFILE'] = 'Eine neue Konfigurationsdatei anlegen';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Die Konfigurationsdatei "%s" konnte nicht geladen werden.';
+$lang['L_BACKUP_DBS_PHP'] = 'zu sichernde DBs (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'zu sichernde DBs (PERL)';
+$lang['L_CRON_COMMENT'] = 'Kommentar eingeben';
+$lang['L_AUTODETECT'] = 'automatisch ermitteln';
diff --git a/msd/language/de_du/lang_dump.php b/msd/language/de_du/lang_dump.php
index 8dd103fc..da55cc35 100644
--- a/msd/language/de_du/lang_dump.php
+++ b/msd/language/de_du/lang_dump.php
@@ -1,55 +1,57 @@
 <?php
-$lang['L_DUMP_HEADLINE']="erzeuge Backup...";
-$lang['L_GZIP_COMPRESSION']="GZip-Kompression";
-$lang['L_SAVING_TABLE']="Speichere Tabelle ";
-$lang['L_OF']="von";
-$lang['L_ACTUAL_TABLE']="Aktuelle Tabelle";
-$lang['L_PROGRESS_TABLE']="Fortschritt Tabelle";
-$lang['L_PROGRESS_OVER_ALL']="Fortschritt gesamt";
-$lang['L_ENTRY']="Eintrag";
-$lang['L_DONE']="Fertig!";
-$lang['L_DUMP_SUCCESSFUL']=" wurde erfolgreich erstellt.";
-$lang['L_UPTO']="bis";
-$lang['L_EMAIL_WAS_SEND']="Die E-Mail wurde erfolgreich verschickt an ";
-$lang['L_BACK_TO_CONTROL']="weiter";
-$lang['L_BACK_TO_OVERVIEW']="Datenbank-Übersicht";
-$lang['L_DUMP_FILENAME']="Backup-Datei: ";
-$lang['L_WITHPRAEFIX']="mit Praefix";
-$lang['L_DUMP_NOTABLES']="Es konnten keine Tabellen in der Datenbank `<b>%s</b>` gefunden werden.";
-$lang['L_DUMP_ENDERGEBNIS']="Es wurden <b>%s</b> Tabellen mit insgesamt <b>%s</b> Datensätzen gesichert.<br>";
-$lang['L_MAILERROR']="Leider ist beim Verschicken der E-Mail ein Fehler aufgetreten!";
-$lang['L_EMAILBODY_ATTACH']="In der Anlage findest du die Sicherung deiner MySQL-Datenbank.<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Datei wurde erzeugt:<br><br>%s <br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden nicht als Anhang mitgeliefert!<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden in separaten E-Mails als Anhang geliefert!<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="Die Sicherung überschreitet die Maximalgröße von %s und wurde daher nicht angehängt.<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Datei wurde erzeugt:<br><br>%s
-<br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Das Backup wurde nicht angehängt.<br>Sicherung der Datenbank `%s`
-<br><br>Folgende Datei wurde erzeugt:<br><br>%s
-<br><br>Viele Grüße<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... nur der Anhang";
-$lang['L_TABLESELECTION']="Tabellenauswahl";
-$lang['L_SELECTALL']="alle auswählen";
-$lang['L_DESELECTALL']="Auswahl aufheben";
-$lang['L_STARTDUMP']="Backup starten";
-$lang['L_LASTBUFROM']="letztes Update vom";
-$lang['L_NOT_SUPPORTED']="Dieses Backup unterstützt diese Funktion nicht.";
-$lang['L_MULTIDUMP']="Multidump: Es wurden <b>%d</b> Datenbanken gesichert.";
-$lang['L_FILESENDFTP']="versende File via FTP... bitte habe etwas Geduld. ";
-$lang['L_FTPCONNERROR']="FTP-Verbindung nicht hergestellt! Verbindung mit ";
-$lang['L_FTPCONNERROR1']=" als Benutzer ";
-$lang['L_FTPCONNERROR2']=" nicht möglich";
-$lang['L_FTPCONNERROR3']="FTP-Upload war fehlerhaft! ";
-$lang['L_FTPCONNECTED1']="Verbunden mit ";
-$lang['L_FTPCONNECTED2']=" auf ";
-$lang['L_FTPCONNECTED3']=" geschrieben";
-$lang['L_NR_TABLES_SELECTED']="- mit %s gewählten Tabellen";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s Tabellen wurden optimiert.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s Fehler aufgetreten: <a href=\"log.php?r=3\">anzeigen</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Schwerwiegender Fehler: die CREATE-Anweisung der Tabelle '%s' in der Datenbank '%s' konnte nicht gelesen werden!";
 
-?>
\ No newline at end of file
+$lang['L_DUMP_HEADLINE'] = 'erzeuge Backup...';
+$lang['L_DUMP_INFO'] = 'Bitte warten! Die Datenbanktabellen werden vor dem Backup optimiert.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip-Kompression';
+$lang['L_SAVING_TABLE'] = 'Speichere Tabelle ';
+$lang['L_OF'] = 'von';
+$lang['L_ACTUAL_TABLE'] = 'Aktuelle Tabelle';
+$lang['L_PROGRESS_TABLE'] = 'Fortschritt Tabelle';
+$lang['L_PROGRESS_OVER_ALL'] = 'Fortschritt gesamt';
+$lang['L_ENTRY'] = 'Eintrag';
+$lang['L_DONE'] = 'Fertig!';
+$lang['L_DUMP_SUCCESSFUL'] = ' wurde erfolgreich erstellt.';
+$lang['L_UPTO'] = 'bis';
+$lang['L_EMAIL_WAS_SEND'] = 'Die E-Mail wurde erfolgreich verschickt an ';
+$lang['L_BACK_TO_CONTROL'] = 'weiter';
+$lang['L_BACK_TO_OVERVIEW'] = 'Datenbank-Übersicht';
+$lang['L_DUMP_FILENAME'] = 'Backup-Datei: ';
+$lang['L_WITHPRAEFIX'] = 'mit Praefix';
+$lang['L_DUMP_NOTABLES'] = 'Es konnten keine Tabellen in der Datenbank `<b>%s</b>` gefunden werden.';
+$lang['L_DUMP_ENDERGEBNIS'] = 'Es wurden <b>%s</b> Tabellen mit insgesamt <b>%s</b> Datensätzen gesichert.<br>';
+$lang['L_MAILERROR'] = 'Leider ist beim Verschicken der E-Mail ein Fehler aufgetreten!';
+$lang['L_EMAILBODY_ATTACH'] = 'In der Anlage findest du die Sicherung deiner MySQL-Datenbank.<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Datei wurde erzeugt:<br><br>%s <br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden nicht als Anhang mitgeliefert!<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Es wurde eine Multipart-Sicherung erstellt.<br>Die Sicherungen werden in separaten E-Mails als Anhang geliefert!<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Dateien wurden erzeugt:<br><br>%s<br><br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Die Sicherung überschreitet die Maximalgröße von %s und wurde daher nicht angehängt.<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Datei wurde erzeugt:<br><br>%s
+<br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Das Backup wurde nicht angehängt.<br>Sicherung der Datenbank `%s`
+<br><br>Folgende Datei wurde erzeugt:<br><br>%s
+<br><br>Viele Grüße<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... nur der Anhang';
+$lang['L_TABLESELECTION'] = 'Tabellenauswahl';
+$lang['L_SELECTALL'] = 'alle auswählen';
+$lang['L_DESELECTALL'] = 'Auswahl aufheben';
+$lang['L_STARTDUMP'] = 'Backup starten';
+$lang['L_LASTBUFROM'] = 'letztes Update vom';
+$lang['L_NOT_SUPPORTED'] = 'Dieses Backup unterstützt diese Funktion nicht.';
+$lang['L_MULTIDUMP'] = 'Multidump: Es wurden <b>%d</b> Datenbanken gesichert.';
+$lang['L_FILESENDFTP'] = 'versende File via FTP... bitte habe etwas Geduld. ';
+$lang['L_FTPCONNERROR'] = 'FTP-Verbindung nicht hergestellt! Verbindung mit ';
+$lang['L_FTPCONNERROR1'] = ' als Benutzer ';
+$lang['L_FTPCONNERROR2'] = ' nicht möglich';
+$lang['L_FTPCONNERROR3'] = 'FTP-Upload war fehlerhaft! ';
+$lang['L_FTPCONNECTED1'] = 'Verbunden mit ';
+$lang['L_FTPCONNECTED2'] = ' auf ';
+$lang['L_FTPCONNECTED3'] = ' geschrieben';
+$lang['L_FILESENDSFTP'] = 'versende File via SFTP... bitte habe etwas Geduld. ';
+$lang['L_SFTPCONNERROR'] = 'SFTP-Verbindung nicht hergestellt! Verbindung mit ';
+$lang['L_NR_TABLES_SELECTED'] = '- mit %s gewählten Tabellen';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s Tabellen wurden optimiert.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s Fehler aufgetreten: <a href="log.php?r=3">anzeigen</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Schwerwiegender Fehler: die CREATE-Anweisung der Tabelle '%s' in der Datenbank '%s' konnte nicht gelesen werden!";
diff --git a/msd/language/de_du/lang_filemanagement.php b/msd/language/de_du/lang_filemanagement.php
index 09d35df9..27e447e2 100644
--- a/msd/language/de_du/lang_filemanagement.php
+++ b/msd/language/de_du/lang_filemanagement.php
@@ -1,80 +1,80 @@
 <?php
-$lang['L_CONVERT_START']="Konvertierung starten";
-$lang['L_CONVERT_TITLE']="Konvertiere Dump ins MSD-Format";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Falsche Parameter! Konvertierung ist nicht möglich.";
-$lang['L_FM_UPLOADFILEREQUEST']="Gib bitte eine Datei an.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Dieser Dateityp ist nicht erlaubt.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Gültige Typen sind: *.gz und *.sql-Dateien";
-$lang['L_FM_UPLOADMOVEERROR']="Die hochgeladene Datei konnte nicht in den richtigen Ordner verschoben werden.";
-$lang['L_FM_UPLOADFAILED']="Der Upload ist leider fehlgeschlagen!";
-$lang['L_FM_UPLOADFILEEXISTS']="Es existiert bereits eine Datei mit diesem Namen!";
-$lang['L_FM_NOFILE']="Du hast gar keine Datei ausgewählt!";
-$lang['L_FM_DELETE1']="Die Datei ";
-$lang['L_FM_DELETE2']=" wurde erfolgreich gelöscht.";
-$lang['L_FM_DELETE3']=" konnte nicht gelöscht werden!";
-$lang['L_FM_CHOOSE_FILE']="Gewählte Datei:";
-$lang['L_FM_FILESIZE']="Dateigröße";
-$lang['L_FM_FILEDATE']="Datum";
-$lang['L_FM_NOFILESFOUND']="Keine Datei gefunden.";
-$lang['L_FM_TABLES']="Tabellen";
-$lang['L_FM_RECORDS']="Einträge";
-$lang['L_FM_ALL_BU']="alle Backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="letztes Backup";
-$lang['L_FM_TOTALSIZE']="Gesamtgröße";
-$lang['L_FM_SELECTTABLES']="Auswahl bestimmter Tabellen";
-$lang['L_FM_COMMENT']="Kommentar eingeben";
-$lang['L_FM_RESTORE']="Wiederherstellen";
-$lang['L_FM_ALERTRESTORE1']="Soll die Datenbank ";
-$lang['L_FM_ALERTRESTORE2']="mit den Inhalten der Datei";
-$lang['L_FM_ALERTRESTORE3']="wiederhergestellt werden?";
-$lang['L_FM_DELETE']="Ausgewählte Dateien löschen";
-$lang['L_FM_ASKDELETE1']="Möchtest du die Datei(en)";
-$lang['L_FM_ASKDELETE2']="wirklich löschen?";
-$lang['L_FM_ASKDELETE3']="Möchtest du Autodelete nach den eingestellten Regeln jetzt ausführen?";
-$lang['L_FM_ASKDELETE4']="Möchtest du alle Backup-Dateien jetzt löschen?";
-$lang['L_FM_ASKDELETE5']="Möchtest du alle Backup-Dateien mit ";
-$lang['L_FM_ASKDELETE5_2']="_* jetzt löschen?";
-$lang['L_FM_DELETEAUTO']="Autodelete manuell ausführen";
-$lang['L_FM_DELETEALL']="Alle Backup-Dateien löschen";
-$lang['L_FM_DELETEALLFILTER']="Alle löschen mit ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Neues Backup starten";
-$lang['L_FM_FILEUPLOAD']="Datei hochladen";
-$lang['L_FM_DBNAME']="Datenbankname";
-$lang['L_FM_FILES1']="Datenbank-Backups";
-$lang['L_FM_FILES2']="Datenbank-Strukturen";
-$lang['L_FM_AUTODEL1']="Autodelete: Folgende Dateien wurden aufgrund der maximalen Dateianzahl gelöscht:";
-$lang['L_DELETE_FILE_SUCCESS']="Die Datei \"%s\" wurde erfolgreich gelöscht.";
-$lang['L_FM_DUMPSETTINGS']="Einstellungen für das Backup";
-$lang['L_FM_OLDBACKUP']="(unbekannt)";
-$lang['L_FM_RESTORE_HEADER']="Wiederherstellung der Datenbank \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Die Datei \"%s\" konnte nicht gelöscht werden!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Perl-Cronscript ausführen";
-$lang['L_DOPERLTEST']="Perl-Module testen";
-$lang['L_DOSIMPLETEST']="Perl testen";
-$lang['L_PERLOUTPUT1']="Eintrag in crondump.pl für absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Aufruf im Browser oder für externen Cronjob";
-$lang['L_PERLOUTPUT3']="Aufruf in der Shell oder für die Crontab";
-$lang['L_RESTORE_OF_TABLES']="Wiederherstellen bestimmter Tabellen";
-$lang['L_CONVERTER']="Backup-Konverter";
-$lang['L_CONVERT_FILE']="zu konvertierende Datei";
-$lang['L_CONVERT_FILENAME']="Name der Zieldatei (ohne Endung)";
-$lang['L_CONVERTING']="Konvertierung";
-$lang['L_CONVERT_FILEREAD']="Datei '%s' wird eingelesen";
-$lang['L_CONVERT_FINISHED']="Konvertierung abgeschlossen, '%s' wurde erzeugt.";
-$lang['L_NO_MSD_BACKUPFILE']="Dateien anderer Programme";
-$lang['L_MAX_UPLOAD_SIZE']="Maximale Dateigröße";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Wenn Deine Backup-Datei größer als das angegebene Limit ist, dann musst Du diese per FTP in den \"work/backup\"-Ordner hochladen.
-Danach wird diese Datei hier in der Verwaltung angezeigt und lässt sich für eine Wiederherstellung auswählen.";
-$lang['L_ENCODING']="Kodierung";
-$lang['L_FM_CHOOSE_ENCODING']="Kodierung der Backupdatei wählen";
-$lang['L_CHOOSE_CHARSET']="Leider konnte nicht automatisch ermittelt werden mit welchem Zeichensatz diese Backupdatei seinerzeit angelegt wurde.
+
+$lang['L_CONVERT_START'] = 'Konvertierung starten';
+$lang['L_CONVERT_TITLE'] = 'Konvertiere Dump ins MOD-Format';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Falsche Parameter! Konvertierung ist nicht möglich.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Gib bitte eine Datei an.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Dieser Dateityp ist nicht erlaubt.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Gültige Typen sind: *.gz und *.sql-Dateien';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Die hochgeladene Datei konnte nicht in den richtigen Ordner verschoben werden.';
+$lang['L_FM_UPLOADFAILED'] = 'Der Upload ist leider fehlgeschlagen!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Es existiert bereits eine Datei mit diesem Namen!';
+$lang['L_FM_NOFILE'] = 'Du hast gar keine Datei ausgewählt!';
+$lang['L_FM_DELETE1'] = 'Die Datei ';
+$lang['L_FM_DELETE2'] = ' wurde erfolgreich gelöscht.';
+$lang['L_FM_DELETE3'] = ' konnte nicht gelöscht werden!';
+$lang['L_FM_CHOOSE_FILE'] = 'Gewählte Datei:';
+$lang['L_FM_FILESIZE'] = 'Dateigröße';
+$lang['L_FM_FILEDATE'] = 'Datum';
+$lang['L_FM_NOFILESFOUND'] = 'Keine Datei gefunden.';
+$lang['L_FM_TABLES'] = 'Tabellen';
+$lang['L_FM_RECORDS'] = 'Einträge';
+$lang['L_FM_ALL_BU'] = 'alle Backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'letztes Backup';
+$lang['L_FM_TOTALSIZE'] = 'Gesamtgröße';
+$lang['L_FM_SELECTTABLES'] = 'Auswahl bestimmter Tabellen';
+$lang['L_FM_COMMENT'] = 'Kommentar eingeben';
+$lang['L_FM_RESTORE'] = 'Wiederherstellen';
+$lang['L_FM_ALERTRESTORE1'] = 'Soll die Datenbank ';
+$lang['L_FM_ALERTRESTORE2'] = 'mit den Inhalten der Datei';
+$lang['L_FM_ALERTRESTORE3'] = 'wiederhergestellt werden?';
+$lang['L_FM_DELETE'] = 'Ausgewählte Dateien löschen';
+$lang['L_FM_ASKDELETE1'] = 'Möchtest du die Datei(en)';
+$lang['L_FM_ASKDELETE2'] = 'wirklich löschen?';
+$lang['L_FM_ASKDELETE3'] = 'Möchtest du Autodelete nach den eingestellten Regeln jetzt ausführen?';
+$lang['L_FM_ASKDELETE4'] = 'Möchtest du alle Backup-Dateien jetzt löschen?';
+$lang['L_FM_ASKDELETE5'] = 'Möchtest du alle Backup-Dateien mit ';
+$lang['L_FM_ASKDELETE5_2'] = '_* jetzt löschen?';
+$lang['L_FM_DELETEAUTO'] = 'Autodelete manuell ausführen';
+$lang['L_FM_DELETEALL'] = 'Alle Backup-Dateien löschen';
+$lang['L_FM_DELETEALLFILTER'] = 'Alle löschen mit ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Neues Backup starten';
+$lang['L_FM_FILEUPLOAD'] = 'Datei hochladen';
+$lang['L_FM_DBNAME'] = 'Datenbankname';
+$lang['L_FM_FILES1'] = 'Datenbank-Backups';
+$lang['L_FM_FILES2'] = 'Datenbank-Strukturen';
+$lang['L_FM_AUTODEL1'] = 'Autodelete: Folgende Dateien wurden aufgrund der maximalen Dateianzahl gelöscht:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'Die Datei "%s" wurde erfolgreich gelöscht.';
+$lang['L_FM_DUMPSETTINGS'] = 'Einstellungen für das Backup';
+$lang['L_FM_OLDBACKUP'] = '(unbekannt)';
+$lang['L_FM_RESTORE_HEADER'] = 'Wiederherstellung der Datenbank "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Die Datei "%s" konnte nicht gelöscht werden!';
+$lang['L_FM_DUMP_HEADER'] = 'Sicherung';
+$lang['L_DOCRONBUTTON'] = 'Perl-Cronscript ausführen';
+$lang['L_DOPERLTEST'] = 'Perl-Module testen';
+$lang['L_DOSIMPLETEST'] = 'Perl testen';
+$lang['L_PERLOUTPUT1'] = 'Eintrag in crondump.pl für absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Aufruf im Browser oder für externen Cronjob';
+$lang['L_PERLOUTPUT3'] = 'Aufruf in der Shell oder für die Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Wiederherstellen bestimmter Tabellen';
+$lang['L_CONVERTER'] = 'Backup-Konverter';
+$lang['L_CONVERT_FILE'] = 'zu konvertierende Datei';
+$lang['L_CONVERT_FILENAME'] = 'Name der Zieldatei (ohne Endung)';
+$lang['L_CONVERTING'] = 'Konvertierung';
+$lang['L_CONVERT_FILEREAD'] = "Datei '%s' wird eingelesen";
+$lang['L_CONVERT_FINISHED'] = "Konvertierung abgeschlossen, '%s' wurde erzeugt.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Dateien anderer Programme';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximale Dateigröße';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Wenn Deine Backup-Datei größer als das angegebene Limit ist, dann musst Du diese per FTP in den "work/backup"-Ordner hochladen.
+Danach wird diese Datei hier in der Verwaltung angezeigt und lässt sich für eine Wiederherstellung auswählen.';
+$lang['L_ENCODING'] = 'Kodierung';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Kodierung der Backupdatei wählen';
+$lang['L_CHOOSE_CHARSET'] = 'Leider konnte nicht automatisch ermittelt werden mit welchem Zeichensatz diese Backupdatei seinerzeit angelegt wurde.
 <br>Du musst die Kodierung, in der Zeichenketten in dieser Datei vorliegen, manuell angeben.
-<br>Danach stellt MySQLDumper die Verbindungskennung zum MySQL-Server auf den ausgewählten Zeichensatz und beginnt mit der Wiederherstellung der Daten.
+<br>Danach stellt MyOOS [Dumper] die Verbindungskennung zum MySQL-Server auf den ausgewählten Zeichensatz und beginnt mit der Wiederherstellung der Daten.
 <br>Solltest Du nach der Wiederherstellung Probleme mit Sonderzeichen entdecken, so kannst Du versuchen, das Backup mit einer anderen Zeichensatzauswahl wiederherzustellen.
-<br>Viel Glück. ;)";
-$lang['L_DOWNLOAD_FILE']="Datei herunterladen";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "Eine Sicherung der Systemdatenbank `%s` ist nicht möglich!";
-?>
\ No newline at end of file
+<br>Viel Glück. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Datei herunterladen';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'Eine Sicherung der Systemdatenbank `%s` ist nicht möglich!';
diff --git a/msd/language/de_du/lang_help.php b/msd/language/de_du/lang_help.php
index b8695819..4ca2d3a3 100644
--- a/msd/language/de_du/lang_help.php
+++ b/msd/language/de_du/lang_help.php
@@ -1,37 +1,41 @@
 <?php
-$lang['L_HELP_DB']="Dies ist die Liste der vorhandenen Datenbanken.";
-$lang['L_HELP_PRAEFIX']="Der Präfix ist eine Zeichenfolge für den Anfang von Tabellen, der als Filter fungiert.";
-$lang['L_HELP_ZIP']="Kompression mit GZip - emfohlen ist 'aktiviert'.";
-$lang['L_HELP_MEMORYLIMIT']="Das ist die maximale Größe in Bytes, die das Skript an Speicher bekommt.
-0 = deaktiviert";
-$lang['L_MEMORY_LIMIT']="Speichergrenze";
-$lang['L_HELP_AD1']="Wenn aktiviert, dann werden automatisch Backup-Dateien gelöscht.";
-$lang['L_HELP_AD3']="Die maximale Anzahl von Dateien, die im Backup-Verzeichnis sein dürfen (für Autodelete).
-0 = deaktiviert";
-$lang['L_HELP_LANG']="Stellt auf die gewünschte Sprache.";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Um überflüssige Daten zu eliminieren, kann man anweisen, die Datenbank vor der Wiederherstellung komplett zu leeren.";
-$lang['L_HELP_CRONEXTENDER']="Die Endung des Perlscriptes, Standard ist '.pl'.";
-$lang['L_HELP_CRONSAVEPATH']="Der Name der Konfigurationsdatei für das Perlskript.";
-$lang['L_HELP_CRONPRINTOUT']="Wenn die Textausgabe abgeschaltet ist, wird kein Text mehr ausgegeben.
-Diese Funktion ist unabhängig von der Log-Ausgabe.";
-$lang['L_HELP_CRONSAMEDB']="Soll die gleiche Datenbank für Cronjob wie in den Einstellungen benutzt werden?";
-$lang['L_HELP_CRONDBINDEX']="Wähle die Datenbank für den Cronjob.";
-$lang['L_HELP_FTPTRANSFER']="Wenn aktiviert, wird nach dem Backup die Datei per FTP gesendet.";
-$lang['L_HELP_FTPSERVER']="Adresse des FTP-Servers.";
-$lang['L_HELP_FTPPORT']="Port des FTP-Servers. Standard: 21.";
-$lang['L_HELP_FTPUSER']="Gibt den Benutzernamen der FTP-Verbindung an.";
-$lang['L_HELP_FTPPASS']="Gibt das Passwort der FTP-Verbindung an.";
-$lang['L_HELP_FTPDIR']="Wohin soll die Datei gesendet werden?";
-$lang['L_HELP_SPEED']="Minimale und maximale Geschwindigkeit. Standard ist 50 bis 5000.
-(Zu hohe Geschwindigkeiten können zu Timeouts führen!)";
-$lang['L_SPEED']="Geschwindigkeitskontrolle";
-$lang['L_HELP_CRONEXECPATH']="Der Ort, an dem die Perlskripte liegen.
+
+$lang['L_HELP_DB'] = 'Dies ist die Liste der vorhandenen Datenbanken.';
+$lang['L_HELP_PRAEFIX'] = 'Der Präfix ist eine Zeichenfolge für den Anfang von Tabellen, der als Filter fungiert.';
+$lang['L_HELP_ZIP'] = "Kompression mit GZip - emfohlen ist 'aktiviert'.";
+$lang['L_HELP_MEMORYLIMIT'] = 'Das ist die maximale Größe in Bytes, die das Skript an Speicher bekommt.
+0 = deaktiviert';
+$lang['L_MEMORY_LIMIT'] = 'Speichergrenze';
+$lang['L_HELP_AD1'] = 'Wenn aktiviert, dann werden automatisch Backup-Dateien gelöscht.';
+$lang['L_HELP_AD3'] = 'Die maximale Anzahl von Dateien, die im Backup-Verzeichnis sein dürfen (für Autodelete).
+0 = deaktiviert';
+$lang['L_HELP_LANG'] = 'Stellt auf die gewünschte Sprache.';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Um überflüssige Daten zu eliminieren, kann man anweisen, die Datenbank vor der Wiederherstellung komplett zu leeren.';
+$lang['L_HELP_CRONEXTENDER'] = "Die Endung des Perlscriptes, Standard ist '.pl'.";
+$lang['L_HELP_CRONSAVEPATH'] = 'Der Name der Konfigurationsdatei für das Perlskript.';
+$lang['L_HELP_CRONPRINTOUT'] = 'Wenn die Textausgabe abgeschaltet ist, wird kein Text mehr ausgegeben.
+Diese Funktion ist unabhängig von der Log-Ausgabe.';
+$lang['L_HELP_CRONSAMEDB'] = 'Soll die gleiche Datenbank für Cronjob wie in den Einstellungen benutzt werden?';
+$lang['L_HELP_CRONDBINDEX'] = 'Wähle die Datenbank für den Cronjob.';
+$lang['L_HELP_FTPTRANSFER'] = 'Wenn aktiviert, wird nach dem Backup die Datei per FTP gesendet.';
+$lang['L_HELP_FTPSERVER'] = 'Adresse des FTP-Servers.';
+$lang['L_HELP_FTPPORT'] = 'Port des FTP-Servers. Standard: 21.';
+$lang['L_HELP_FTPUSER'] = 'Gibt den Benutzernamen der FTP-Verbindung an.';
+$lang['L_HELP_FTPPASS'] = 'Gibt das Passwort der FTP-Verbindung an.';
+$lang['L_HELP_FTPDIR'] = 'Wohin soll die Datei gesendet werden?';
+$lang['L_HELP_SFTPTRANSFER'] = 'Wenn aktiviert, wird nach dem Backup die Datei per SFTP gesendet.';
+$lang['L_HELP_SFTPSERVER'] = 'Adresse des SFTP-Servers.';
+$lang['L_HELP_SFTPPORT'] = 'Port des SFTP-Servers. Standard: 22.';
+$lang['L_HELP_SFTPUSER'] = 'Gibt den Benutzernamen der SFTP-Verbindung an.';
+$lang['L_HELP_SFTPPASS'] = 'Gibt das Passwort der SFTP-Verbindung an.';
+$lang['L_HELP_SFTPDIR'] = 'Wohin soll die Datei gesendet werden?';
+$lang['L_HELP_SPEED'] = 'Minimale und maximale Geschwindigkeit. Standard ist 50 bis 5000.
+(Zu hohe Geschwindigkeiten können zu Timeouts führen!)';
+$lang['L_SPEED'] = 'Geschwindigkeitskontrolle';
+$lang['L_HELP_CRONEXECPATH'] = 'Der Ort, an dem die Perlskripte liegen.
 Ausgangspunkt ist die HTTP-Adresse (also im Browser).
-Erlaubt sind absolute und relative Pfadangaben.";
-$lang['L_CRON_EXECPATH']="Pfad der Perlskripte";
-$lang['L_HELP_CRONCOMPLETELOG']="Wenn die Funktion aktiviert ist, wird die komplette Ausgabe im complete_log geschrieben. 
-Diese Funktion ist unabhängig von der Textausgabe.";
-$lang['L_HELP_FTP_MODE']="Wenn Probleme bei der FTP-Übertragung auftauchen, versuche den passiven FTP-Modus.";
-
-
-?>
\ No newline at end of file
+Erlaubt sind absolute und relative Pfadangaben.';
+$lang['L_CRON_EXECPATH'] = 'Pfad der Perlskripte';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Wenn die Funktion aktiviert ist, wird die komplette Ausgabe im complete_log geschrieben. 
+Diese Funktion ist unabhängig von der Textausgabe.';
+$lang['L_HELP_FTP_MODE'] = 'Wenn Probleme bei der FTP-Übertragung auftauchen, versuche den passiven FTP-Modus.';
diff --git a/msd/language/de_du/lang_install.php b/msd/language/de_du/lang_install.php
index d18d769e..0c293662 100644
--- a/msd/language/de_du/lang_install.php
+++ b/msd/language/de_du/lang_install.php
@@ -1,89 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>die Installation ist abgeschlossen   --> <a href=\"index.php\">starte MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="zum Hauptmenü";
-$lang['L_INSTALLMENU']="Hauptmenü";
-$lang['L_STEP']="Schritt";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Deinstallation";
-$lang['L_TOOLS']="Tools";
-$lang['L_EDITCONF']="Konfiguration bearbeiten";
-$lang['L_OSWEITER']="ohne Speichern weiter";
-$lang['L_ERRORMAN']="<strong>Fehler beim Schreiben der Konfiguration!</strong><br>Bitte editiere die Datei ";
-$lang['L_MANUELL']="manuell";
-$lang['L_CREATEDIRS']="erstelle Verzeichnisse";
-$lang['L_INSTALL_CONTINUE']="mit der Installation fortfahren";
-$lang['L_CONNECTTOMYSQL']=" zu MySQL verbinden ";
-$lang['L_DBPARAMETER']="Datenbank-Parameter";
-$lang['L_CONFIGNOTWRITABLE']="Die Datei \"config.php\" ist nicht beschreibbar.
-Gib ihr mit einem FTP-Programm entsprechende Rechte, z. B. den CHMod-Wert 0777.";
-$lang['L_DBCONNECTION']="Datenbank-Verbindung";
-$lang['L_CONNECTIONERROR']="Fehler: Es konnte keine Verbindung herstellt werden.";
-$lang['L_CONNECTION_OK']="Datenbank-Verbindung wurde hergestellt.";
-$lang['L_SAVEANDCONTINUE']="speichern und Installation fortsetzen";
-$lang['L_CONFBASIC']="Grundeinstellungen";
-$lang['L_INSTALL_STEP2FINISHED']="Die Einstellungen wurden erfolgreich gesichert.";
-$lang['L_INSTALL_STEP2_1']="Installation mit Standardkonfiguration fortsetzen";
-$lang['L_LASTSTEP']="Abschluss der Installation";
-$lang['L_FTPMODE']="Verzeichnisse per FTP erzeugen (safe_mode)";
-$lang['L_IDOMANUAL']="Ich erstelle die Verzeichnisse manuell";
-$lang['L_DOFROM']="ausgehend von";
-$lang['L_FTPMODE2']="Erstelle die Verzeichnisse per FTP:";
-$lang['L_CONNECT']="verbinden";
-$lang['L_DIRS_CREATED']="Die Verzeichnisse wurden ordnungsgemäß erstellt.";
-$lang['L_CONNECT_TO']="verbinde zu";
-$lang['L_CHANGEDIR']="Wechsel ins Verzeichnis";
-$lang['L_CHANGEDIRERROR']="Wechsel ins Verzeichnis nicht möglich";
-$lang['L_FTP_OK']="FTP-Parameter sind ok";
-$lang['L_CREATEDIRS2']="Verzeichnisse erstellen";
-$lang['L_FTP_NOTCONNECTED']="FTP-Verbindung nicht hergestellt!";
-$lang['L_CONNWITH']="Verbindung mit";
-$lang['L_ASUSER']="als Benutzer";
-$lang['L_NOTPOSSIBLE']="nicht möglich";
-$lang['L_DIRCR1']="erstelle Arbeitsverzeichnis";
-$lang['L_DIRCR2']="erstelle Backup-Verzeichnis";
-$lang['L_DIRCR4']="erstelle Log-Verzeichnis";
-$lang['L_DIRCR5']="erstelle Konfigurationsverzeichnis";
-$lang['L_INDIR']="bin im Verzeichnis";
-$lang['L_CHECK_DIRS']="Verzeichnisse überprüfen";
-$lang['L_DISABLEDFUNCTIONS']="Abgeschaltete Funktionen";
-$lang['L_NOFTPPOSSIBLE']="Es stehen keine FTP-Funktionen zur Verfügung!";
-$lang['L_NOGZPOSSIBLE']="Es stehen keine Kompressions-Funktionen zur Verfügung!";
-$lang['L_UI1']="Es werden alle Arbeitsverzeichnisse incl. den darin enthaltenen Backups gelöscht.";
-$lang['L_UI2']="Bist du sicher, dass du das möchtest?";
-$lang['L_UI3']="Nein, sofort abbrechen";
-$lang['L_UI4']="ja, bitte fortfahren";
-$lang['L_UI5']="lösche Arbeitsverzeichnis";
-$lang['L_UI6']="alles wurde erfolgreich gelöscht.";
-$lang['L_UI7']="Bitte lösche das Skriptverzeichnis";
-$lang['L_UI8']="eine Ebene nach oben";
-$lang['L_UI9']="Ein Fehler trat auf, löschen war nicht möglich</p>Fehler bei Verzeichnis ";
-$lang['L_IMPORT']="Konfiguration importieren";
-$lang['L_IMPORT3']="Die Konfiguration wurde geladen...";
-$lang['L_IMPORT4']="Die Konfiguration wurde gesichert.";
-$lang['L_IMPORT5']="MySQLDumper starten";
-$lang['L_IMPORT6']="Installations-Menü";
-$lang['L_IMPORT7']="Konfiguration hochladen";
-$lang['L_IMPORT8']="zurück zum Upload";
-$lang['L_IMPORT9']="Dies ist keine Konfigurationssicherung!";
-$lang['L_IMPORT10']="Die Konfiguration wurde erfolgreich hochgeladen...";
-$lang['L_IMPORT11']="<strong>Fehler: </strong>Es gab Probleme beim Schreiben der sql_statements.";
-$lang['L_IMPORT12']="<strong>Fehler: </strong>Es gab Probleme beim Schreiben der config.php.";
-$lang['L_INSTALL_HELP_PORT']="(leer = Standardport)";
-$lang['L_INSTALL_HELP_SOCKET']="(leer = Standardsocket)";
-$lang['L_TRYAGAIN']="noch einmal versuchen";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="gefundene DB: ";
-$lang['L_FM_FILEUPLOAD']="Datei hochladen";
-$lang['L_PASS']="Passwort";
-$lang['L_NO_DB_FOUND_INFO']="Die Verbindung zur Datenbank konnte erfolgreich hergestellt werden.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>die Installation ist abgeschlossen   --> <a href="index.php">starte MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'zum Hauptmenü';
+$lang['L_INSTALLMENU'] = 'Hauptmenü';
+$lang['L_STEP'] = 'Schritt';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Deinstallation';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_EDITCONF'] = 'Konfiguration bearbeiten';
+$lang['L_OSWEITER'] = 'ohne Speichern weiter';
+$lang['L_ERRORMAN'] = '<strong>Fehler beim Schreiben der Konfiguration!</strong><br>Bitte editiere die Datei ';
+$lang['L_MANUELL'] = 'manuell';
+$lang['L_CREATEDIRS'] = 'erstelle Verzeichnisse';
+$lang['L_INSTALL_CONTINUE'] = 'mit der Installation fortfahren';
+$lang['L_CONNECTTOMYSQL'] = ' zu MySQL verbinden ';
+$lang['L_DBPARAMETER'] = 'Datenbank-Parameter';
+$lang['L_CONFIGNOTWRITABLE'] = 'Die Datei "config.php" ist nicht beschreibbar.
+Gib ihr mit einem FTP-Programm entsprechende Rechte, z. B. den CHMod-Wert 0777.';
+$lang['L_DBCONNECTION'] = 'Datenbank-Verbindung';
+$lang['L_CONNECTIONERROR'] = 'Fehler: Es konnte keine Verbindung herstellt werden.';
+$lang['L_CONNECTION_OK'] = 'Datenbank-Verbindung wurde hergestellt.';
+$lang['L_SAVEANDCONTINUE'] = 'speichern und Installation fortsetzen';
+$lang['L_CONFBASIC'] = 'Grundeinstellungen';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Die Einstellungen wurden erfolgreich gesichert.';
+$lang['L_INSTALL_STEP2_1'] = 'Installation mit Standardkonfiguration fortsetzen';
+$lang['L_LASTSTEP'] = 'Abschluss der Installation';
+$lang['L_IDOMANUAL'] = 'Ich erstelle die Verzeichnisse manuell';
+$lang['L_DOFROM'] = 'ausgehend von';
+$lang['L_FTPMODE2'] = 'Erstelle die Verzeichnisse per FTP:';
+$lang['L_CONNECT'] = 'verbinden';
+$lang['L_DIRS_CREATED'] = 'Die Verzeichnisse wurden ordnungsgemäß erstellt.';
+$lang['L_CONNECT_TO'] = 'verbinde zu';
+$lang['L_CHANGEDIR'] = 'Wechsel ins Verzeichnis';
+$lang['L_CHANGEDIRERROR'] = 'Wechsel ins Verzeichnis nicht möglich';
+$lang['L_FTP_OK'] = 'FTP-Parameter sind ok';
+$lang['L_SFTP_OK'] = 'FTP-Parameter sind ok';
+$lang['L_CREATEDIRS2'] = 'Verzeichnisse erstellen';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP-Verbindung nicht hergestellt!';
+$lang['L_CONNWITH'] = 'Verbindung mit';
+$lang['L_ASUSER'] = 'als Benutzer';
+$lang['L_NOTPOSSIBLE'] = 'nicht möglich';
+$lang['L_DIRCR1'] = 'erstelle Arbeitsverzeichnis';
+$lang['L_DIRCR2'] = 'erstelle Backup-Verzeichnis';
+$lang['L_DIRCR4'] = 'erstelle Log-Verzeichnis';
+$lang['L_DIRCR5'] = 'erstelle Konfigurationsverzeichnis';
+$lang['L_INDIR'] = 'bin im Verzeichnis';
+$lang['L_CHECK_DIRS'] = 'Verzeichnisse überprüfen';
+$lang['L_DISABLEDFUNCTIONS'] = 'Abgeschaltete Funktionen';
+$lang['L_NOFTPPOSSIBLE'] = 'Es stehen keine FTP-Funktionen zur Verfügung!';
+$lang['L_NOGZPOSSIBLE'] = 'Es stehen keine Kompressions-Funktionen zur Verfügung!';
+$lang['L_UI1'] = 'Es werden alle Arbeitsverzeichnisse incl. den darin enthaltenen Backups gelöscht.';
+$lang['L_UI2'] = 'Bist du sicher, dass du das möchtest?';
+$lang['L_UI3'] = 'Nein, sofort abbrechen';
+$lang['L_UI4'] = 'ja, bitte fortfahren';
+$lang['L_UI5'] = 'lösche Arbeitsverzeichnis';
+$lang['L_UI6'] = 'alles wurde erfolgreich gelöscht.';
+$lang['L_UI7'] = 'Bitte lösche das Skriptverzeichnis';
+$lang['L_UI8'] = 'eine Ebene nach oben';
+$lang['L_UI9'] = 'Ein Fehler trat auf, löschen war nicht möglich</p>Fehler bei Verzeichnis ';
+$lang['L_IMPORT'] = 'Konfiguration importieren';
+$lang['L_IMPORT3'] = 'Die Konfiguration wurde geladen...';
+$lang['L_IMPORT4'] = 'Die Konfiguration wurde gesichert.';
+$lang['L_IMPORT5'] = 'MyOOS [Dumper] starten';
+$lang['L_IMPORT6'] = 'Installations-Menü';
+$lang['L_IMPORT7'] = 'Konfiguration hochladen';
+$lang['L_IMPORT8'] = 'zurück zum Upload';
+$lang['L_IMPORT9'] = 'Dies ist keine Konfigurationssicherung!';
+$lang['L_IMPORT10'] = 'Die Konfiguration wurde erfolgreich hochgeladen...';
+$lang['L_IMPORT11'] = '<strong>Fehler: </strong>Es gab Probleme beim Schreiben der sql_statements.';
+$lang['L_IMPORT12'] = '<strong>Fehler: </strong>Es gab Probleme beim Schreiben der config.php.';
+$lang['L_INSTALL_HELP_PORT'] = '(leer = Standardport)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(leer = Standardsocket)';
+$lang['L_TRYAGAIN'] = 'noch einmal versuchen';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'gefundene DB: ';
+$lang['L_FM_FILEUPLOAD'] = 'Datei hochladen';
+$lang['L_PASS'] = 'Passwort';
+$lang['L_NO_DB_FOUND_INFO'] = 'Die Verbindung zur Datenbank konnte erfolgreich hergestellt werden.<br>
 Deine Zugangsdaten sind gültig und wurden vom MySQL-Server akzeptiert.<br>
-Leider konnte MySQLDumper keine Datenbank finden.<br>
+Leider konnte MyOOS [Dumper] keine Datenbank finden.<br>
 Die automatische Erkennung per Programm ist bei manchen Hostern gesperrt.<br>
-Du musst Deine Datenbank nach dem Abschluß der Installation unter dem Menüpunkt \"Konfiguration\" \"Verbindungsparameter einblenden\" angeben.<br>
-Bitte begebe Dich nach Abschluß der Installation umgehend dort hin und trage den Namen Deiner Datenbank dort ein.";
-$lang['L_SAFEMODEDESC']="Da PHP auf diesem Server mit der Option \"safe_mode=on\" ausgeführt wird, müssen folgende Verzeichnisse von Hand angelegt werden (dies kannst Du mit Deinem FTP-Programm erledigen):";
-$lang['L_ENTER_DB_INFO']="Klicke zuerst auf den Button \"zu MySQL verbinden\". Nur wenn daraufhin keine Datenbank erkannt werden konnte, ist hier eine Angabe notwendig.";
-
-
-?>
\ No newline at end of file
+Du musst Deine Datenbank nach dem Abschluß der Installation unter dem Menüpunkt "Konfiguration" "Verbindungsparameter einblenden" angeben.<br>
+Bitte begebe Dich nach Abschluß der Installation umgehend dort hin und trage den Namen Deiner Datenbank dort ein.';
+$lang['L_ENTER_DB_INFO'] = 'Klicke zuerst auf den Button "zu MySQL verbinden". Nur wenn daraufhin keine Datenbank erkannt werden konnte, ist hier eine Angabe notwendig.';
diff --git a/msd/language/de_du/lang_log.php b/msd/language/de_du/lang_log.php
index fdbdb66b..e794f7bf 100644
--- a/msd/language/de_du/lang_log.php
+++ b/msd/language/de_du/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Log löschen";
-$lang['L_LOGFILEFORMAT']="Log-Dateiformat";
-$lang['L_LOGFILENOTWRITABLE']="Log-Datei kann nicht geschrieben werden!";
-$lang['L_NOREVERSE']="Ältester Eintrag zuerst";
-$lang['L_REVERSE']="Neuster Eintrag zuerst";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Log löschen';
+$lang['L_LOGFILEFORMAT'] = 'Log-Dateiformat';
+$lang['L_LOGFILENOTWRITABLE'] = 'Log-Datei kann nicht geschrieben werden!';
+$lang['L_NOREVERSE'] = 'Ältester Eintrag zuerst';
+$lang['L_REVERSE'] = 'Neuester Eintrag zuerst';
diff --git a/msd/language/de_du/lang_main.php b/msd/language/de_du/lang_main.php
index eac4ebe8..56484b7e 100644
--- a/msd/language/de_du/lang_main.php
+++ b/msd/language/de_du/lang_main.php
@@ -1,78 +1,90 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Es stehen keine FTP-Funktionen zur Verfügung!";
-$lang['L_INFO_LOCATION']="Du befindest dich auf ";
-$lang['L_INFO_DATABASES']="Folgende Datenbank(en) befinden sich auf dem MySql-Server:";
-$lang['L_INFO_NODB']="Datenbank existiert nicht";
-$lang['L_INFO_DBDETAIL']="Detail-Information von Datenbank ";
-$lang['L_INFO_DBEMPTY']="Die Datenbank ist leer!";
-$lang['L_INFO_RECORDS']="Datensätze";
-$lang['L_INFO_SIZE']="Größe";
-$lang['L_INFO_LASTUPDATE']="letztes Update";
-$lang['L_INFO_SUM']="insgesamt";
-$lang['L_INFO_OPTIMIZED']="optimiert";
-$lang['L_OPTIMIZE_DATABASES']="Tabellen optimieren";
-$lang['L_CHECK_TABLES']="Tabellen überprüfen";
-$lang['L_CLEAR_DATABASE']="Datenbank leeren";
-$lang['L_DELETE_DATABASE']="Datenbank löschen";
-$lang['L_INFO_CLEARED']="wurde geleert";
-$lang['L_INFO_DELETED']="wurde gelöscht";
-$lang['L_INFO_EMPTYDB1']="Soll die Datenbank";
-$lang['L_INFO_EMPTYDB2']=" wirklich geleert werden? (Achtung! Alle Daten gehen unwiderruflich verloren)";
-$lang['L_INFO_KILLDB']=" wirklich gelöscht werden? (Achtung! Alle Daten gehen unwiderruflich verloren)";
-$lang['L_PROCESSKILL1']="Es wird versucht, Prozess ";
-$lang['L_PROCESSKILL2']="zu beenden.";
-$lang['L_PROCESSKILL3']="Es wird seit ";
-$lang['L_PROCESSKILL4']=" Sekunde(n) versucht, Prozess ";
-$lang['L_HTACC_CREATE']="Verzeichnisschutz erstellen";
-$lang['L_ENCRYPTION_TYPE']="Verschlüsselungsart";
-$lang['L_HTACC_CRYPT']="Crypt maximal 8 Zeichen (Linux und Unix-Systeme)";
-$lang['L_HTACC_MD5']="MD5 (Linux und Unix-Systeme)";
-$lang['L_HTACC_NO_ENCRYPTION']="unverschlüsselt (Windows)";
-$lang['L_HTACCESS8']="Es besteht bereits ein Verzeichnisschutz. Wenn Du einen neuen erstellst, wird der alte überschrieben!";
-$lang['L_HTACC_NO_USERNAME']="Du musst einen Namen eingeben!";
-$lang['L_PASSWORDS_UNEQUAL']="Die Passwörter sind nicht identisch oder leer!";
-$lang['L_HTACC_CONFIRM_DELETE']="Soll der Verzeichnisschutz jetzt erstellt werden?";
-$lang['L_HTACC_CREATED']="Der Verzeichnisschutz wurde erstellt.";
-$lang['L_HTACC_CONTENT']="Inhalt der Datei";
-$lang['L_HTACC_CREATE_ERROR']="Es ist ein Fehler bei der Erstellung des Verzeichnisschutzes aufgetreten!<br>Bitte erzeuge die Dateien manuell mit folgendem Inhalt";
-$lang['L_HTACC_PROPOSED']="Dringend empfohlen";
-$lang['L_HTACC_EDIT']=".htaccess editieren";
-$lang['L_HTACCESS18']=".htaccess erstellen in ";
-$lang['L_HTACCESS19']="Neu laden ";
-$lang['L_HTACCESS20']="Skript ausführen";
-$lang['L_HTACCESS21']="Handler zufügen";
-$lang['L_HTACCESS22']="Ausführbar machen";
-$lang['L_HTACCESS23']="Verzeichnis-Listing";
-$lang['L_HTACCESS24']="Error-Dokument";
-$lang['L_HTACCESS25']="Rewrite aktivieren";
-$lang['L_HTACCESS26']="Deny / Allow";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Error-Log";
-$lang['L_HTACCESS29']="weitere Beispiele und Dokumentation";
-$lang['L_HTACCESS30']="Provider";
-$lang['L_HTACCESS31']="allgemein";
-$lang['L_HTACCESS32']="Achtung! Die .htaccess hat eine direkte Auswirkung auf den Browser.<br>Bei falscher Anwendung sind die Seiten nicht mehr erreichbar.";
-$lang['L_PHPBUG']="Bug in zlib! Keine Kompression möglich!";
-$lang['L_DISABLEDFUNCTIONS']="Abgeschaltete Funktionen";
-$lang['L_NOGZPOSSIBLE']="Da zlib nicht installiert ist, stehen keine GZip-Funktionen zur Verfügung!";
-$lang['L_DELETE_HTACCESS']="Verzeichnisschutz entfernen (.htaccess löschen)";
-$lang['L_WRONG_RIGHTS']="Die Datei oder das Verzeichnis '%s' ist für mich nicht beschreibbar.<br>
-Entweder hat sie/es den falschen Besitzer (Owner) oder die falschen Rechte (Chmod).<br> 
+
+$lang['L_NOFTPPOSSIBLE'] = 'Es stehen keine FTP-Funktionen zur Verfügung!';
+$lang['L_INFO_LOCATION'] = 'Du befindest dich auf ';
+$lang['L_INFO_DATABASES'] = 'Folgende Datenbank(en) befinden sich auf dem MySql-Server:';
+$lang['L_INFO_NODB'] = 'Datenbank existiert nicht';
+$lang['L_INFO_DBDETAIL'] = 'Detail-Information von Datenbank ';
+$lang['L_INFO_DBEMPTY'] = 'Die Datenbank ist leer!';
+$lang['L_INFO_RECORDS'] = 'Datensätze';
+$lang['L_INFO_SIZE'] = 'Größe';
+$lang['L_INFO_LASTUPDATE'] = 'letztes Update';
+$lang['L_INFO_SUM'] = 'insgesamt';
+$lang['L_INFO_OPTIMIZED'] = 'optimiert';
+$lang['L_OPTIMIZE_DATABASES'] = 'Tabellen optimieren';
+$lang['L_CHECK_TABLES'] = 'Tabellen überprüfen';
+$lang['L_CLEAR_DATABASE'] = 'Datenbank leeren';
+$lang['L_DELETE_DATABASE'] = 'Datenbank löschen';
+$lang['L_INFO_CLEARED'] = 'wurde geleert';
+$lang['L_INFO_DELETED'] = 'wurde gelöscht';
+$lang['L_INFO_EMPTYDB1'] = 'Soll die Datenbank';
+$lang['L_INFO_EMPTYDB2'] = ' wirklich geleert werden? (Achtung! Alle Daten gehen unwiderruflich verloren)';
+$lang['L_INFO_KILLDB'] = ' wirklich gelöscht werden? (Achtung! Alle Daten gehen unwiderruflich verloren)';
+$lang['L_PROCESSKILL1'] = 'Es wird versucht, Prozess ';
+$lang['L_PROCESSKILL2'] = 'zu beenden.';
+$lang['L_PROCESSKILL3'] = 'Es wird seit ';
+$lang['L_PROCESSKILL4'] = ' Sekunde(n) versucht, Prozess ';
+$lang['L_HTACC_CREATE'] = 'Verzeichnisschutz erstellen';
+$lang['L_ENCRYPTION_TYPE'] = 'Verschlüsselungsart';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, alle Systeme)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (alle Systeme)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (alle Systeme)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - maximal 8 Zeichen (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unverschlüsselt (Windows)';
+$lang['L_HTACCESS8'] = 'Es besteht bereits ein Verzeichnisschutz. Wenn Du einen neuen erstellst, wird der alte überschrieben!';
+$lang['L_HTACC_NO_USERNAME'] = 'Du musst einen Namen eingeben!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Die Passwörter sind nicht identisch oder leer!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Soll der Verzeichnisschutz jetzt erstellt werden?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Soll der Verzeichnisschutz wirklich entfernt werden?';
+$lang['L_HTACC_CREATED'] = 'Der Verzeichnisschutz wurde erstellt.';
+$lang['L_HTACC_CONTENT'] = 'Inhalt der Datei';
+$lang['L_HTACC_CREATE_ERROR'] = 'Es ist ein Fehler bei der Erstellung des Verzeichnisschutzes aufgetreten!<br>Bitte erzeuge die Dateien manuell mit folgendem Inhalt';
+$lang['L_HTACC_CHECK_ERROR'] = 'Es konnte nicht überprüft werden, ob das Programm geschützt ist!<br>Der simulierte externe Zugriff konnte nicht ausgeführt werden.';
+$lang['L_HTACC_NOT_NEEDED'] = 'Das Programm ist durch übergeordnete Berechtigungen geschützt; ein lokaler Verzeichnisschutz ist nicht erforderlich.';
+$lang['L_HTACC_COMPLETE'] = 'Das Programm ist geschützt, der Verzeichnisschutz ist vollständig.';
+$lang['L_HTACC_INCOMPLETE'] = 'Das Programm ist nicht geschützt, der Verzeichnisschutz ist unvollständig!';
+$lang['L_HTACC_PROPOSED'] = 'Das Programm ist nicht geschützt, ein Verzeichnisschutz wird dringend empfohlen!';
+$lang['L_HTACC_EDIT'] = '.htaccess editieren';
+$lang['L_HTACCESS18'] = '.htaccess erstellen in ';
+$lang['L_HTACCESS19'] = 'Neu laden ';
+$lang['L_HTACCESS20'] = 'Skript ausführen';
+$lang['L_HTACCESS21'] = 'Handler hinzufügen';
+$lang['L_HTACCESS22'] = 'Ausführbar machen';
+$lang['L_HTACCESS23'] = 'Verzeichnisinhalt (Directory Listing)';
+$lang['L_HTACCESS24'] = 'Error-Dokument';
+$lang['L_HTACCESS25'] = 'Rewrite aktivieren';
+$lang['L_HTACCESS26'] = 'Deny / Allow';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Error-Log';
+$lang['L_HTACCESS29'] = 'weitere Beispiele und Dokumentation';
+$lang['L_HTACCESS30'] = 'Provider';
+$lang['L_HTACCESS31'] = 'Allgemein';
+$lang['L_HTACCESS32'] = 'Achtung! Die .htaccess hat eine direkte Auswirkung auf den Browser.<br>Bei falscher Anwendung sind die Seiten nicht mehr erreichbar.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Abgeschaltete Funktionen';
+$lang['L_NOGZPOSSIBLE'] = 'Da zlib nicht installiert ist, stehen keine GZip-Funktionen zur Verfügung!';
+$lang['L_DELETE_HTACCESS'] = 'Verzeichnisschutz entfernen (.htaccess löschen)';
+$lang['L_WRONG_RIGHTS'] = "Die Datei oder das Verzeichnis '%s' ist für mich nicht beschreibbar.<br>
+Entweder hat sie/es den falschen Besitzer (Owner) oder die falschen Rechte (Chmod).<br>
 Bitte setze die richtigen Attribute mit Deinem FTP-Programm. <br>
 Die Datei oder das Verzeichnis benötigt die Rechte %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Ich konntes das Verzeichnis '%s' nicht erstellen.
+$lang['L_CANT_CREATE_DIR'] = "Ich konnte das Verzeichnis '%s' nicht erstellen.
 Bitte erstelle es mit Deinem FTP-Programm.";
-$lang['L_TABLE_TYPE']="Typ";
-$lang['L_CHECK']="prüfen";
-$lang['L_HTACC_SHA1']="SHA1 (alle Systeme)";
-$lang['L_OS']="Betriebssystem";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Maximale Ausführungszeit";
-$lang['L_PHP_EXTENSIONS']="PHP-Erweiterungen";
-$lang['L_MEMORY']="Speicher";
-$lang['L_FILE_MISSING']="konnte Datei nicht finden";
-
-
-?>
\ No newline at end of file
+$lang['L_CANT_CREATE_DIR'] = "Ich konnte das '%s'-Verzeichnis nicht erstellen.
+Bitte mit Deinem FTP-Programm erstellen.";
+$lang['L_TABLE_TYPE'] = 'Typ';
+$lang['L_CHECK'] = 'prüfen';
+$lang['L_OS'] = 'Betriebssystem';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'Neue Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'Es ist eine neue Version von MyOOS [Dumper] verfügbar.';
+$lang['L_UPDATED_IMPORTANT'] = 'Wichtig: Sichere vor der Aktualisierung bitte Deine Dateien.';
+$lang['L_UPDATE'] = 'Jetzt aktualisieren';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Maximale Ausführungszeit';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Erweiterungen';
+$lang['L_MEMORY'] = 'Speicher';
+$lang['L_INSTALLING_UPDATES'] = 'Installation von Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Aktualisierung erfolgreich';
+$lang['L_UPDATE_FAILED'] = 'Aktualisierung fehlgeschlagen';
+$lang['L_UP_TO_DATE'] = 'Aktuelle Version ist auf dem neuesten Stand';
diff --git a/msd/language/de_du/lang_restore.php b/msd/language/de_du/lang_restore.php
index 230ebde5..5dec6890 100644
--- a/msd/language/de_du/lang_restore.php
+++ b/msd/language/de_du/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Es wurden bisher <b>%d</b> Tabellen angelegt.";
-$lang['L_FILE_MISSING']="konnte Datei nicht finden";
-$lang['L_RESTORE_DB']="Datenbank '<b>%s</b>' auf Server '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> Tabellen wurden angelegt.";
-$lang['L_RESTORE_RUN1']="<br>Es wurden bisher <b>%s</b> von <b>%s</b> Datensätzen erfolgreich eingetragen.";
-$lang['L_RESTORE_RUN2']="<br>Momentan werden Daten der Tabelle '<b>%s</b>' analysiert.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> Datensätze wurden eingetragen.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Es wurden bisher <b>%d</b> von <b>%d</b> Tabellen angelegt.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Herzlichen Glückwunsch.</b><br><br>Die Datenbank wurde komplett wiederhergestellt.<br>Alle Daten aus der Backup-Datei wurden erfolgreich in die Datenbank eingetragen.<br><br>Alles fertig. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Fehler:<br>Auswahl der Datenbank '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' fehlgeschlagen!";
-$lang['L_FILE_OPEN_ERROR']="Fehler: Die Datei konnte nicht geöffnet werden.";
-$lang['L_PROGRESS_OVER_ALL']="Fortschritt gesamt";
-$lang['L_BACK_TO_OVERVIEW']="Datenbank-Übersicht";
-$lang['L_RESTORE_RUN0']="<br>Es wurden bisher <b>%s</b> Datensätze erfolgreich eingetragen.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Unbekannter SQL-Befehl:";
-$lang['L_NOTICES']="Hinweise";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Es wurden bisher <b>%d</b> Tabellen angelegt.';
+$lang['L_FILE_MISSING'] = 'konnte Datei nicht finden';
+$lang['L_RESTORE_DB'] = "Datenbank '<b>%s</b>' auf Server '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> Tabellen wurden angelegt.';
+$lang['L_RESTORE_RUN1'] = '<br>Es wurden bisher <b>%s</b> von <b>%s</b> Datensätzen erfolgreich eingetragen.';
+$lang['L_RESTORE_RUN2'] = "<br>Momentan werden Daten der Tabelle '<b>%s</b>' analysiert.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> Datensätze wurden eingetragen.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Es wurden bisher <b>%d</b> von <b>%d</b> Tabellen angelegt.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Herzlichen Glückwunsch.</b><br><br>Die Datenbank wurde komplett wiederhergestellt.<br>Alle Daten aus der Backup-Datei wurden erfolgreich in die Datenbank eingetragen.<br><br>Alles fertig. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Fehler:<br>Auswahl der Datenbank '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' fehlgeschlagen!";
+$lang['L_FILE_OPEN_ERROR'] = 'Fehler: Die Datei konnte nicht geöffnet werden.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Fortschritt gesamt';
+$lang['L_BACK_TO_OVERVIEW'] = 'Datenbank-Übersicht';
+$lang['L_RESTORE_RUN0'] = '<br>Es wurden bisher <b>%s</b> Datensätze erfolgreich eingetragen.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Unbekannter SQL-Befehl:';
+$lang['L_NOTICES'] = 'Hinweise';
diff --git a/msd/language/de_du/lang_sql.php b/msd/language/de_du/lang_sql.php
index eecc2549..f1dd59dc 100644
--- a/msd/language/de_du/lang_sql.php
+++ b/msd/language/de_du/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Befehl";
-$lang['L_IMPORT_NOTABLE']="Es ist keine Tabelle für den Import ausgewählt!";
-$lang['L_PASSWORD_STRENGTH']="Kennwortstärke";
-$lang['L_SQL_WARNING']="Die Ausführung von SQL-Befehlen kann Daten manipulieren! Der Autor übernimmt keine Haftung bei Datenverlusten.";
-$lang['L_SQL_EXEC']="SQL-Befehl ausführen";
-$lang['L_SQL_DATAVIEW']="Daten-Ansicht";
-$lang['L_SQL_TABLEVIEW']="Tabellen-Ansicht";
-$lang['L_SQL_VONINS']="von insgesamt";
-$lang['L_SQL_NODATA']="keine Datensätze";
-$lang['L_SQL_RECORDUPDATED']="Datensatz wurde geändert";
-$lang['L_SQL_RECORDINSERTED']="Datensatz wurde gespeichert";
-$lang['L_SQL_BACKDBOVERVIEW']="zurück zur Datenbank-Übersicht";
-$lang['L_SQL_RECORDDELETED']="Datensatz wurde gelöscht";
-$lang['L_ASKTABLEEMPTY']="Soll die Tabelle `%s` geleert werden?";
-$lang['L_SQL_RECORDEDIT']="editiere Datensatz";
-$lang['L_SQL_RECORDNEW']="Datensatz einfügen";
-$lang['L_ASKDELETERECORD']="Soll der Datensatz gelöscht werden?";
-$lang['L_ASKDELETETABLE']="Soll die Tabelle `%s` gelöscht werden?";
-$lang['L_SQL_BEFEHLE']="SQL-Befehle";
-$lang['L_SQL_BEFEHLNEU']="neuer Befehl";
-$lang['L_SQL_BEFEHLSAVED1']="SQL-Befehl";
-$lang['L_SQL_BEFEHLSAVED2']="wurde hinzugefügt";
-$lang['L_SQL_BEFEHLSAVED3']="wurde gespeichert";
-$lang['L_SQL_BEFEHLSAVED4']="wurde nach oben gebracht";
-$lang['L_SQL_BEFEHLSAVED5']="wurde gelöscht";
-$lang['L_SQL_QUERYENTRY']="Die Abfrage enthält";
-$lang['L_SQL_COLUMNS']="Spalten";
-$lang['L_ASKDBDELETE']="Soll die Datenbank `%s` samt Inhalt wirklich gelöscht werden?";
-$lang['L_ASKDBEMPTY']="Soll die Datenbank `%s` wirklich geleert werden?";
-$lang['L_ASKDBCOPY']="Soll der Inhalt der Datenbank `%s` in die Datenbank `%s` kopiert werden?";
-$lang['L_SQL_TABLENEW']="Tabellen bearbeiten";
-$lang['L_SQL_OUTPUT']="SQL-Ausgabe";
-$lang['L_DO_NOW']="jetzt ausführen";
-$lang['L_SQL_NAMEDEST_MISSING']="Name für die Zieldatenbank fehlt!";
-$lang['L_ASKDELETEFIELD']="Soll das Feld gelöscht werden?";
-$lang['L_SQL_COMMANDS_IN']=" Zeilen in ";
-$lang['L_SQL_COMMANDS_IN2']="  Sekunde(n) abgearbeitet.";
-$lang['L_SQL_OUT1']="Es wurden ";
-$lang['L_SQL_OUT2']="Befehle ausgeführt";
-$lang['L_SQL_OUT3']="Es gab ";
-$lang['L_SQL_OUT4']="Kommentare";
-$lang['L_SQL_OUT5']="Da die Ausgabe über 5000 Zeilen enthält, wird sie nicht angezeigt.";
-$lang['L_SQL_SELECDB']="Datenbank auswählen";
-$lang['L_SQL_TABLESOFDB']="Tabellen der Datenbank";
-$lang['L_SQL_EDIT']="bearbeiten";
-$lang['L_SQL_NOFIELDDELETE']="Löschen nicht möglich, da eine Tabelle mindestens 1 Feld haben muss.";
-$lang['L_SQL_FIELDDELETE1']="Das Feld";
-$lang['L_SQL_DELETED']="wurde gelöscht.";
-$lang['L_SQL_CHANGED']="wurde geändert.";
-$lang['L_SQL_CREATED']="wurde angelegt.";
-$lang['L_SQL_NODEST_COPY']="Ohne Ziel kann nicht kopiert werden!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Zieltabelle existiert schon!";
-$lang['L_SQL_SCOPY']="Tabellenstruktur von `%s` wurde in Tabelle `%s` kopiert.";
-$lang['L_SQL_TCOPY']="Tabelle `%s` wurde mit Daten in Tabelle `%s` kopiert.";
-$lang['L_SQL_TABLENONAME']="Tabelle braucht einen Namen!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tabellenname darf nicht leer sein!";
-$lang['L_SQL_COLLATENOTMATCH']="Zeichensatz und Sortierung passen nicht zueinander!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Fehler: Kein gültiger Feldname";
-$lang['L_SQL_CREATETABLE']="Tabelle anlegen";
-$lang['L_SQL_COPYTABLE']="Tabelle kopieren";
-$lang['L_SQL_STRUCTUREONLY']="nur Struktur";
-$lang['L_SQL_STRUCTUREDATA']="Struktur und Daten";
-$lang['L_SQL_NOTABLESINDB']="Es befinden sich keine Tabellen in der Datenbank";
-$lang['L_SQL_SELECTTABLE']="Tabelle auswählen";
-$lang['L_SQL_SHOWDATATABLE']="Daten der Tabelle anzeigen";
-$lang['L_SQL_TBLPROPSOF']="Tabelleneigenschaften  von";
-$lang['L_SQL_EDITFIELD']="Editiere Feld";
-$lang['L_SQL_NEWFIELD']="Neues Feld";
-$lang['L_SQL_INDEXES']="Indizes";
-$lang['L_SQL_ATPOSITION']="an Position einfügen";
-$lang['L_SQL_FIRST']="zuerst";
-$lang['L_SQL_AFTER']="nach";
-$lang['L_SQL_CHANGEFIELD']="Feld ändern";
-$lang['L_SQL_INSERTFIELD']="Feld einfügen";
-$lang['L_SQL_INSERTNEWFIELD']="Neues Feld einfügen";
-$lang['L_SQL_TABLEINDEXES']="Indizes der Tabelle";
-$lang['L_SQL_ALLOWDUPS']="Duplikate erlaubt";
-$lang['L_SQL_CARDINALITY']="Kardinalität";
-$lang['L_SQL_TABLENOINDEXES']="Die Tabelle enthält keine Indizes";
-$lang['L_SQL_CREATEINDEX']="Neuen Index erzeugen";
-$lang['L_SQL_WASEMPTIED']="wurde geleert";
-$lang['L_SQL_RENAMEDTO']="wurde umbenannt in";
-$lang['L_SQL_DBCOPY']="Der Inhalt der Datenbank `%s` wurde in die Datenbank `%s` kopiert.";
-$lang['L_SQL_DBSCOPY']="Die Struktur der Datenbank `%s` wurde in die Datenbank `%s` kopiert.";
-$lang['L_SQL_WASCREATED']="wurde erzeugt";
-$lang['L_SQL_RENAMEDB']="Datenbank umbenennen";
-$lang['L_SQL_ACTIONS']="Aktionen";
-$lang['L_SQL_CHOOSEACTION']="Aktion wählen";
-$lang['L_SQL_DELETEDB']="Datenbank löschen";
-$lang['L_SQL_EMPTYDB']="Datenbank leeren";
-$lang['L_SQL_COPYDATADB']="Inhalt in Datenbank kopieren";
-$lang['L_SQL_COPYSDB']="Struktur in Datenbank kopieren";
-$lang['L_SQL_IMEXPORT']="Im-/Export";
-$lang['L_INFO_RECORDS']="Datensätze";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="Sollen die Tabelle `%s` geleert und die Indizes zurückgesetzt werden?";
-$lang['L_EDIT']="editieren";
-$lang['L_DELETE']="löschen";
-$lang['L_EMPTY']="leeren";
-$lang['L_EMPTYKEYS']="leeren und Indizes zurücksetzen";
-$lang['L_SQL_TABLEEMPTIED']="Tabelle `%s` wurde geleert.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Tabelle `%s` wurde geleert, und die Indizes wurden zurückgesetzt.";
-$lang['L_SQL_LIBRARY']="SQL-Bibliothek";
-$lang['L_SQL_ATTRIBUTES']="Attribute";
-$lang['L_SQL_UPLOADEDFILE']="geladene Datei: ";
-$lang['L_SQL_IMPORT']="Import in Datenbank `%s`";
-$lang['L_EXPORT']="Export";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Import-Optionen";
-$lang['L_CSVOPTIONS']="CSV-Optionen";
-$lang['L_IMPORTTABLE']="Import in Tabelle";
-$lang['L_NEWTABLE']="neue Tabelle";
-$lang['L_IMPORTSOURCE']="Import-Quelle";
-$lang['L_FROMTEXTBOX']="aus Textfeld";
-$lang['L_FROMFILE']="aus Datei";
-$lang['L_EMPTYTABLEBEFORE']="Tabelle vorher leeren";
-$lang['L_CREATEAUTOINDEX']="Auto-Index erzeugen";
-$lang['L_CSV_NAMEFIRSTLINE']="Feldnamen in die erste Zeile";
-$lang['L_CSV_FIELDSEPERATE']="Felder getrennt mit";
-$lang['L_CSV_FIELDSENCLOSED']="Felder eingeschlossen von";
-$lang['L_CSV_FIELDSESCAPE']="Felder escaped von";
-$lang['L_CSV_EOL']="Zeilen getrennt mit";
-$lang['L_CSV_NULL']="Ersetze NULL durch";
-$lang['L_CSV_FILEOPEN']="CSV-Datei öffnen";
-$lang['L_IMPORTIEREN']="importieren";
-$lang['L_SQL_EXPORT']="Export aus Datenbank `%s`";
-$lang['L_EXPORTOPTIONS']="Export-Optionen";
-$lang['L_EXCEL2003']="Excel ab 2003";
-$lang['L_SHOWRESULT']="Ergebnis anzeigen";
-$lang['L_SENDRESULTASFILE']="Ergebnis als Datei senden";
-$lang['L_EXPORTLINES']="<strong>%s</strong> Zeilen exportiert";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Die Anzahl der Tabellenfelder stimmen nicht mit den zu importierenden Daten überein (%d statt %d).";
-$lang['L_CSV_FIELDSLINES']="%d Felder ermittelt, insgesamt %d Zeilen";
-$lang['L_CSV_ERRORCREATETABLE']="Fehler beim Erstellen der Tabelle `%s`!";
-$lang['L_FM_UPLOADFILEREQUEST']="Bitte gib eine Datei an.";
-$lang['L_CSV_NODATA']="Keine Daten zum Importieren gefunden!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="allgemeine Funktionen";
-$lang['L_SQLLIB_RESETAUTO']="Auto-Wert zurücksetzen";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="Board deaktivieren";
-$lang['L_SQLLIB_ACTIVATEBOARD']="Board aktivieren";
-$lang['L_SQL_NOTABLESSELECTED']="Es sind keine Tabellen ausgewählt!";
-$lang['L_TOOLS']="Tools";
-$lang['L_TOOLS_TOOLBOX']="Datenbank auswählen / Datenbankfunktionen / Im- und Export ";
-$lang['L_SQL_OPENFILE']="SQL-Datei öffnen";
-$lang['L_SQL_OPENFILE_BUTTON']="Hochaden";
-$lang['L_MAX_UPLOAD_SIZE']="Maximale Dateigröße";
-$lang['L_SQL_SEARCH']="Suche";
-$lang['L_SQL_SEARCHWORDS']="Suchbegriff(e)";
-$lang['L_START_SQL_SEARCH']="Suche starten";
-$lang['L_RESET_SEARCHWORDS']="Eingabe zurücksetzen";
-$lang['L_SEARCH_OPTIONS']="Suchoptionen";
-$lang['L_SEARCH_RESULTS']="Die Suche nach \"<b>%s</b>\" in der Tabelle \"<b>%s</b>\" lieferte folgende Treffer";
-$lang['L_SEARCH_NO_RESULTS']="Die Suche nach \"<b>%s</b>\" in der Tabelle \"<b>%s</b>\" liefert keine Ergebnisse!";
-$lang['L_NO_ENTRIES']="Die Tabelle \"<b>%s</b>\" ist leer und hat keine Einträge.";
-$lang['L_SEARCH_ACCESS_KEYS']="Blättern: vor=ALT+V, zurück=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="eine Spalte muss mindestens einen Suchbegriff enthalten (ODER-Suche)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="ein Datensatz muss alle Suchbegriffe enthalten, diese können aber in beliebigen Spalten sein (Rechenintensiv!)";
-$lang['L_SEARCH_OPTIONS_AND']="eine Spalte muss alle Suchbegriffe enthalten (UND-Suche)";
-$lang['L_SEARCH_IN_TABLE']="Suche in Tabelle";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Tabellenstruktur bearbeiten";
-$lang['L_DEFAULT_CHARSET']="Standardzeichensatz";
-$lang['L_TITLE_KEY_PRIMARY']="Primärschlüssel";
-$lang['L_TITLE_KEY_UNIQUE']="Eindeutiger Schlüssel";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Volltextschlüssel";
-$lang['L_TITLE_NOKEY']="Kein Schlüssel";
-$lang['L_TITLE_SEARCH']="Suche";
-$lang['L_TITLE_MYSQL_HELP']="MySQL Dokumentation";
-$lang['L_TITLE_UPLOAD']="SQL-Datei hochladen";
-$lang['L_PRIMARYKEY_DELETED']="Primärschlüssel gelöscht";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primärschlüssel nicht gefunden";
-$lang['L_PRIMARYKEYS_CHANGED']="Primärschlüssel geändert";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Fehler beim Ändern der Primärschlüssel";
-$lang['L_SQL_VIEW_COMPACT']="Ansicht: kompakt";
-$lang['L_SQL_VIEW_STANDARD']="Ansicht: normal";
-$lang['L_FIELDS_OF_TABLE']="Felder der Tabelle";
-$lang['L_ENGINE']="Typ";
-$lang['L_USERNAME']="Benutzername";
-$lang['L_PASSWORD']="Kennwort";
-$lang['L_PASSWORD_REPEAT']="Kennwort (Wiederholung)";
-$lang['L_INFO_SIZE']="Größe";
-$lang['L_TABLE_TYPE']="Typ";
-$lang['L_KEY_DELETED']="Index gelöscht";
-$lang['L_KEY_DELETEERROR']="Fehler beim Löschen des Index";
-$lang['L_KEY_ADDED']="Index angelegt";
-$lang['L_KEY_ADDERROR']="Fehler beim Anlegen des Index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Befehl';
+$lang['L_IMPORT_NOTABLE'] = 'Es ist keine Tabelle für den Import ausgewählt!';
+$lang['L_PASSWORD_STRENGTH'] = 'Kennwortstärke';
+$lang['L_SQL_WARNING'] = 'Die Ausführung von SQL-Befehlen kann Daten manipulieren! Der Autor übernimmt keine Haftung bei Datenverlusten.';
+$lang['L_SQL_EXEC'] = 'SQL-Befehl ausführen';
+$lang['L_SQL_DATAVIEW'] = 'Daten-Ansicht';
+$lang['L_SQL_TABLEVIEW'] = 'Tabellen-Ansicht';
+$lang['L_SQL_VONINS'] = 'von insgesamt';
+$lang['L_SQL_NODATA'] = 'keine Datensätze';
+$lang['L_SQL_RECORDUPDATED'] = 'Datensatz wurde geändert';
+$lang['L_SQL_RECORDINSERTED'] = 'Datensatz wurde gespeichert';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'zurück zur Datenbank-Übersicht';
+$lang['L_SQL_RECORDDELETED'] = 'Datensatz wurde gelöscht';
+$lang['L_ASKTABLEEMPTY'] = 'Soll die Tabelle `%s` geleert werden?';
+$lang['L_SQL_RECORDEDIT'] = 'editiere Datensatz';
+$lang['L_SQL_RECORDNEW'] = 'Datensatz einfügen';
+$lang['L_ASKDELETERECORD'] = 'Soll der Datensatz gelöscht werden?';
+$lang['L_ASKDELETETABLE'] = 'Soll die Tabelle `%s` gelöscht werden?';
+$lang['L_SQL_BEFEHLE'] = 'SQL-Befehle';
+$lang['L_SQL_BEFEHLNEU'] = 'neuer Befehl';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL-Befehl';
+$lang['L_SQL_BEFEHLSAVED2'] = 'wurde hinzugefügt';
+$lang['L_SQL_BEFEHLSAVED3'] = 'wurde gespeichert';
+$lang['L_SQL_BEFEHLSAVED4'] = 'wurde nach oben gebracht';
+$lang['L_SQL_BEFEHLSAVED5'] = 'wurde gelöscht';
+$lang['L_SQL_QUERYENTRY'] = 'Die Abfrage enthält';
+$lang['L_SQL_COLUMNS'] = 'Spalten';
+$lang['L_ASKDBDELETE'] = 'Soll die Datenbank `%s` samt Inhalt wirklich gelöscht werden?';
+$lang['L_ASKDBEMPTY'] = 'Soll die Datenbank `%s` wirklich geleert werden?';
+$lang['L_ASKDBCOPY'] = 'Soll der Inhalt der Datenbank `%s` in die Datenbank `%s` kopiert werden?';
+$lang['L_SQL_TABLENEW'] = 'Tabellen bearbeiten';
+$lang['L_SQL_OUTPUT'] = 'SQL-Ausgabe';
+$lang['L_DO_NOW'] = 'jetzt ausführen';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Name für die Zieldatenbank fehlt!';
+$lang['L_ASKDELETEFIELD'] = 'Soll das Feld gelöscht werden?';
+$lang['L_SQL_COMMANDS_IN'] = ' Zeilen in ';
+$lang['L_SQL_COMMANDS_IN2'] = '  Sekunde(n) abgearbeitet.';
+$lang['L_SQL_OUT1'] = 'Es wurden ';
+$lang['L_SQL_OUT2'] = 'Befehle ausgeführt';
+$lang['L_SQL_OUT3'] = 'Es gab ';
+$lang['L_SQL_OUT4'] = 'Kommentare';
+$lang['L_SQL_OUT5'] = 'Da die Ausgabe über 5000 Zeilen enthält, wird sie nicht angezeigt.';
+$lang['L_SQL_SELECDB'] = 'Datenbank auswählen';
+$lang['L_SQL_TABLESOFDB'] = 'Tabellen der Datenbank';
+$lang['L_SQL_EDIT'] = 'bearbeiten';
+$lang['L_SQL_NOFIELDDELETE'] = 'Löschen nicht möglich, da eine Tabelle mindestens 1 Feld haben muss.';
+$lang['L_SQL_FIELDDELETE1'] = 'Das Feld';
+$lang['L_SQL_DELETED'] = 'wurde gelöscht.';
+$lang['L_SQL_CHANGED'] = 'wurde geändert.';
+$lang['L_SQL_CREATED'] = 'wurde angelegt.';
+$lang['L_SQL_NODEST_COPY'] = 'Ohne Ziel kann nicht kopiert werden!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Zieltabelle existiert schon!';
+$lang['L_SQL_SCOPY'] = 'Tabellenstruktur von `%s` wurde in Tabelle `%s` kopiert.';
+$lang['L_SQL_TCOPY'] = 'Tabelle `%s` wurde mit Daten in Tabelle `%s` kopiert.';
+$lang['L_SQL_TABLENONAME'] = 'Tabelle braucht einen Namen!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tabellenname darf nicht leer sein!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Zeichensatz und Sortierung passen nicht zueinander!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Fehler: Kein gültiger Feldname';
+$lang['L_SQL_CREATETABLE'] = 'Tabelle anlegen';
+$lang['L_SQL_COPYTABLE'] = 'Tabelle kopieren';
+$lang['L_SQL_STRUCTUREONLY'] = 'nur Struktur';
+$lang['L_SQL_STRUCTUREDATA'] = 'Struktur und Daten';
+$lang['L_SQL_NOTABLESINDB'] = 'Es befinden sich keine Tabellen in der Datenbank';
+$lang['L_SQL_SELECTTABLE'] = 'Tabelle auswählen';
+$lang['L_SQL_SHOWDATATABLE'] = 'Daten der Tabelle anzeigen';
+$lang['L_SQL_TBLPROPSOF'] = 'Tabelleneigenschaften  von';
+$lang['L_SQL_EDITFIELD'] = 'Editiere Feld';
+$lang['L_SQL_NEWFIELD'] = 'Neues Feld';
+$lang['L_SQL_INDEXES'] = 'Indizes';
+$lang['L_SQL_ATPOSITION'] = 'an Position einfügen';
+$lang['L_SQL_FIRST'] = 'zuerst';
+$lang['L_SQL_AFTER'] = 'nach';
+$lang['L_SQL_CHANGEFIELD'] = 'Feld ändern';
+$lang['L_SQL_INSERTFIELD'] = 'Feld einfügen';
+$lang['L_SQL_INSERTNEWFIELD'] = 'Neues Feld einfügen';
+$lang['L_SQL_TABLEINDEXES'] = 'Indizes der Tabelle';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplikate erlaubt';
+$lang['L_SQL_CARDINALITY'] = 'Kardinalität';
+$lang['L_SQL_TABLENOINDEXES'] = 'Die Tabelle enthält keine Indizes';
+$lang['L_SQL_CREATEINDEX'] = 'Neuen Index erzeugen';
+$lang['L_SQL_WASEMPTIED'] = 'wurde geleert';
+$lang['L_SQL_RENAMEDTO'] = 'wurde umbenannt in';
+$lang['L_SQL_DBCOPY'] = 'Der Inhalt der Datenbank `%s` wurde in die Datenbank `%s` kopiert.';
+$lang['L_SQL_DBSCOPY'] = 'Die Struktur der Datenbank `%s` wurde in die Datenbank `%s` kopiert.';
+$lang['L_SQL_WASCREATED'] = 'wurde erzeugt';
+$lang['L_SQL_RENAMEDB'] = 'Datenbank umbenennen';
+$lang['L_SQL_ACTIONS'] = 'Aktionen';
+$lang['L_SQL_CHOOSEACTION'] = 'Aktion wählen';
+$lang['L_SQL_DELETEDB'] = 'Datenbank löschen';
+$lang['L_SQL_EMPTYDB'] = 'Datenbank leeren';
+$lang['L_SQL_COPYDATADB'] = 'Inhalt in Datenbank kopieren';
+$lang['L_SQL_COPYSDB'] = 'Struktur in Datenbank kopieren';
+$lang['L_SQL_IMEXPORT'] = 'Im-/Export';
+$lang['L_INFO_RECORDS'] = 'Datensätze';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Sollen die Tabelle `%s` geleert und die Indizes zurückgesetzt werden?';
+$lang['L_EDIT'] = 'editieren';
+$lang['L_DELETE'] = 'löschen';
+$lang['L_EMPTY'] = 'leeren';
+$lang['L_EMPTYKEYS'] = 'leeren und Indizes zurücksetzen';
+$lang['L_SQL_TABLEEMPTIED'] = 'Tabelle `%s` wurde geleert.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Tabelle `%s` wurde geleert, und die Indizes wurden zurückgesetzt.';
+$lang['L_SQL_LIBRARY'] = 'SQL-Bibliothek';
+$lang['L_SQL_ATTRIBUTES'] = 'Attribute';
+$lang['L_SQL_UPLOADEDFILE'] = 'geladene Datei: ';
+$lang['L_SQL_IMPORT'] = 'Import in Datenbank `%s`';
+$lang['L_EXPORT'] = 'Export';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = 'Import-Optionen';
+$lang['L_CSVOPTIONS'] = 'CSV-Optionen';
+$lang['L_IMPORTTABLE'] = 'Import in Tabelle';
+$lang['L_NEWTABLE'] = 'neue Tabelle';
+$lang['L_IMPORTSOURCE'] = 'Import-Quelle';
+$lang['L_FROMTEXTBOX'] = 'aus Textfeld';
+$lang['L_FROMFILE'] = 'aus Datei';
+$lang['L_EMPTYTABLEBEFORE'] = 'Tabelle vorher leeren';
+$lang['L_CREATEAUTOINDEX'] = 'Auto-Index erzeugen';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Feldnamen in die erste Zeile';
+$lang['L_CSV_FIELDSEPERATE'] = 'Felder getrennt mit';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Felder eingeschlossen von';
+$lang['L_CSV_FIELDSESCAPE'] = 'Felder escaped von';
+$lang['L_CSV_EOL'] = 'Zeilen getrennt mit';
+$lang['L_CSV_NULL'] = 'Ersetze NULL durch';
+$lang['L_CSV_FILEOPEN'] = 'CSV-Datei öffnen';
+$lang['L_IMPORTIEREN'] = 'importieren';
+$lang['L_SQL_EXPORT'] = 'Export aus Datenbank `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Export-Optionen';
+$lang['L_EXCEL2003'] = 'Excel ab 2003';
+$lang['L_SHOWRESULT'] = 'Ergebnis anzeigen';
+$lang['L_SENDRESULTASFILE'] = 'Ergebnis als Datei senden';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> Zeilen exportiert';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Die Anzahl der Tabellenfelder stimmen nicht mit den zu importierenden Daten überein (%d statt %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d Felder ermittelt, insgesamt %d Zeilen';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Fehler beim Erstellen der Tabelle `%s`!';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Bitte gib eine Datei an.';
+$lang['L_CSV_NODATA'] = 'Keine Daten zum Importieren gefunden!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'allgemeine Funktionen';
+$lang['L_SQLLIB_RESETAUTO'] = 'Auto-Wert zurücksetzen';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'Board deaktivieren';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'Board aktivieren';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Es sind keine Tabellen ausgewählt!';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_TOOLS_TOOLBOX'] = 'Datenbank auswählen / Datenbankfunktionen / Im- und Export ';
+$lang['L_SQL_OPENFILE'] = 'SQL-Datei öffnen';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Hochaden';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximale Dateigröße';
+$lang['L_SQL_SEARCH'] = 'Suche';
+$lang['L_SQL_SEARCHWORDS'] = 'Suchbegriff(e)';
+$lang['L_START_SQL_SEARCH'] = 'Suche starten';
+$lang['L_RESET_SEARCHWORDS'] = 'Eingabe zurücksetzen';
+$lang['L_SEARCH_OPTIONS'] = 'Suchoptionen';
+$lang['L_SEARCH_RESULTS'] = 'Die Suche nach "<b>%s</b>" in der Tabelle "<b>%s</b>" lieferte folgende Treffer';
+$lang['L_SEARCH_NO_RESULTS'] = 'Die Suche nach "<b>%s</b>" in der Tabelle "<b>%s</b>" liefert keine Ergebnisse!';
+$lang['L_NO_ENTRIES'] = 'Die Tabelle "<b>%s</b>" ist leer und hat keine Einträge.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Blättern: vor=ALT+V, zurück=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'eine Spalte muss mindestens einen Suchbegriff enthalten (ODER-Suche)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'ein Datensatz muss alle Suchbegriffe enthalten, diese können aber in beliebigen Spalten sein (Rechenintensiv!)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'eine Spalte muss alle Suchbegriffe enthalten (UND-Suche)';
+$lang['L_SEARCH_IN_TABLE'] = 'Suche in Tabelle';
+$lang['L_ERROR_NO_FIELDS'] = 'Fehler bei Suche: es konnte nicht ermittelt werden, welche Felder die Tabelle "%s" hat!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Tabellenstruktur bearbeiten';
+$lang['L_DEFAULT_CHARSET'] = 'Standardzeichensatz';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primärschlüssel';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Eindeutiger Schlüssel';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Volltextschlüssel';
+$lang['L_TITLE_NOKEY'] = 'Kein Schlüssel';
+$lang['L_TITLE_SEARCH'] = 'Suche';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQL Dokumentation';
+$lang['L_TITLE_UPLOAD'] = 'SQL-Datei hochladen';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primärschlüssel gelöscht';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primärschlüssel nicht gefunden';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primärschlüssel geändert';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Fehler beim Ändern der Primärschlüssel';
+$lang['L_SQL_VIEW_COMPACT'] = 'Ansicht: kompakt';
+$lang['L_SQL_VIEW_STANDARD'] = 'Ansicht: normal';
+$lang['L_FIELDS_OF_TABLE'] = 'Felder der Tabelle';
+$lang['L_ENGINE'] = 'Typ';
+$lang['L_USERNAME'] = 'Benutzername';
+$lang['L_PASSWORD'] = 'Kennwort';
+$lang['L_PASSWORD_REPEAT'] = 'Kennwort (Wiederholung)';
+$lang['L_INFO_SIZE'] = 'Größe';
+$lang['L_TABLE_TYPE'] = 'Typ';
+$lang['L_KEY_DELETED'] = 'Index gelöscht';
+$lang['L_KEY_DELETEERROR'] = 'Fehler beim Löschen des Index';
+$lang['L_KEY_ADDED'] = 'Index angelegt';
+$lang['L_KEY_ADDERROR'] = 'Fehler beim Anlegen des Index';
diff --git a/msd/language/el/help.html b/msd/language/el/help.html
new file mode 100644
index 00000000..dc6349d9
--- /dev/null
+++ b/msd/language/el/help.html
@@ -0,0 +1,149 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> βασισμένο στο MySQLDumper 1.24.4</h3>
+
+<h3>Περί αυτού του έργου</h3>
+<p><strong>Το MyOOS [Dumper]</strong> είναι μια βελτιωμένη έκδοση του MySQLDumper 1.24.4 (24 Ιανουαρίου 2011). Αυτή η περαιτέρω ανάπτυξη λαμβάνει υπόψη την ανάπτυξη της PHP.
+<p>Το MyOOS [Dumper]</strong> ασχολείται κυρίως με τη σταθερότητα, την ασφάλεια και το χειρισμό. Περιλαμβάνεται όμως και ένα ελκυστικό πρότυπο, το οποίο μπορείτε να επεξεργαστείτε και να προσαρμόσετε στις δικές σας ανάγκες.</p>
+
+
+<p><strong>Το MyOOS [Dumper]</strong> είναι ένα πρόγραμμα δημιουργίας αντιγράφων ασφαλείας για βάσεις δεδομένων MySQL, γραμμένο σε PHP και Perl. Με αυτό, μπορούν να δημιουργηθούν αντίγραφα ασφαλείας των δεδομένων (κατάστημα, ιστολόγιο κ.λπ.) και να επαναφερθούν, εάν χρειαστεί. Ειδικά για χώρους στο διαδίκτυο που δεν έχουν πρόσβαση στο κέλυφος, το MyOOS [Dumper] προσφέρεται ως μια λογική εναλλακτική λύση.</p> 
+
+<p>Η ιδέα για το MySQLDumper προήλθε από τον Daniel Schlichtholz. Άνοιξε το φόρουμ MySQLDumper το 2004, όπου οι προγραμματιστές έγραψαν νέα σενάρια και επέκτειναν τα υπάρχοντα.</p>
+
+
+
+<h3>Λίστα επιθυμιών / Μελλοντικά αξιοθέατα</h3>.
+<p>Έχετε προτάσεις για βελτιώσεις; Μη διστάσετε να επικοινωνήσετε με την ομάδα ανάπτυξης μέσω του φόρουμ <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Συνεισφορά</h3>
+<p>Αν θέλετε να μας βοηθήσετε να βελτιώσουμε το έργο MyOOS, καλωσορίζουμε τα pull requests σας μέσω του GitHub εδώ.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Οικονομική στήριξη</h3>
+<p>Μπορείτε να χρησιμοποιήσετε το PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>ή μέσω του κωδικού QR<br>.  
+<img src="images/qrcode.png" alt="Οικονομική υποστήριξη για το MyOOS [Dumper]"></p>
+
+Στείλτε χρήματα στο έργο MyOOS. <br>
+
+<p>Ελπίζουμε να σας αρέσει αυτό το έργο.<br><p><h4>Η ομάδα MyOOS [Dumper]</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+
+<h3>Βοήθεια για το MyOOS [Dumper]</h3>
+
+<h4>Λήψη</h4>
+<p>Μπορείτε πάντα να λαμβάνετε τις τελευταίες εκδόσεις από το GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>Απαιτήσεις συστήματος</h4>
+<p>Το σενάριο λειτουργεί σε οποιονδήποτε διακομιστή (Windows, Linux, ...) <br>
+με PHP >= έκδοση 7.4 με υποστήριξη GZip, MySQL (έκδοση 4.1 ή νεότερη), JavaScript (πρέπει να είναι ενεργοποιημένη).</p>
+<p>Αντιγράψτε το φάκελο mod από το αρχείο MyOOS σε έναν ξεχωριστό φάκελο εργασίας.</p>
+
+<h4>Εγκατάσταση</h4></a>
+Η εγκατάσταση είναι απλή.
+<p>Από το αρχείο MyOOS, αντιγράψτε το φάκελο mod σε οποιονδήποτε φάκελο.<br>
+Ανεβάστε όλα τα αρχεία από το φάκελο mod στο διακομιστή ιστού σας. (π.χ. στο χαμηλότερο επίπεδο στο [server web directory/]mod)<br>
+... Έγινε!<br>
+Μπορείτε τώρα να καλέσετε το MyOOS [Dumper] στο πρόγραμμα περιήγησης στο διαδίκτυο πηγαίνοντας στο "https://example.com/mod/"<br>.
+για να ολοκληρώσετε την εγκατάσταση. Απλά ακολουθήστε τις οδηγίες.<br>
+<br><b>Σημείωση:</b><br><i>Αν στον διακομιστή σας το σενάριο δεν επιτρέπεται να δημιουργεί καταλόγους,<br>
+θα πρέπει να το κάνετε αυτό χειροκίνητα, καθώς το MyOOS [Dumper] αποθηκεύει τα δεδομένα σε καταλόγους.
+καταλόγους.<br> 
+Το σενάριο τερματίζεται με μια κατάλληλη δήλωση!<br>
+Αφού δημιουργήσετε τους καταλόγους (σύμφωνα με την υπόδειξη), εκτελείται κανονικά και χωρίς περιορισμούς.</i>
+
+<a name="perl"></a><h4>Οδηγίες για το σενάριο Perl</h4>.
+Τα περισσότερα έχουν έναν κατάλογο cgi-bin όπου μπορεί να εκτελεστεί η perl. <br>
+Αυτό είναι συνήθως προσβάσιμο από το πρόγραμμα περιήγησης μέσω του http://www.example.com/cgi-bin/. <br>
+<br>
+Σε αυτή την περίπτωση, ακολουθήστε τα παρακάτω βήματα:<br><br> 1.
+
+1. Καλέστε τη σελίδα δημιουργίας αντιγράφων ασφαλείας στο MyOOS [Dumper] και κάντε κλικ στο "Backup Perl". <br>
+2. αντιγράψτε τη διαδρομή πίσω από την καταχώρηση στο crondump.pl για το $absolute_path_of_configdir:. <br>
+3. ανοίξτε το αρχείο "crondump.pl" στον επεξεργαστή.<br>
+4. εισαγάγετε την αντιγραμμένη διαδρομή εκεί στο absolute_path_of_configdir (χωρίς κενά).<br>
+5. αποθηκεύστε το crondump.pl.<br>
+Αντιγράψτε τα crondump.pl, perltest.pl και simpletest.pl στον κατάλογο cgi-bin (λειτουργία ascii στο FTP).
+7. δώστε στα αρχεία τα δικαιώματα 755. <br>
+7b. Αν επιθυμείτε την κατάληξη cgi, αλλάξτε την κατάληξη και των 3 αρχείων από pl -> cgi (μετονομασία). <br>
+Καλέστε τη διαμόρφωση στο MyOOS [Dumper].
+9. Επιλέξτε τη σελίδα Cronscript. <br>
+10. αλλάξτε τη διαδρομή εκτέλεσης της Perl σε /cgi-bin/ .<br>
+10b. Εάν τα σενάρια έχουν επέκταση .pl, αλλάξτε την επέκταση του αρχείου σε .cgi .<br>
+11. αποθηκεύστε τη διαμόρφωση. <br><br>
+
+Έγινε, τα σενάρια μπορούν τώρα να κληθούν από τη σελίδα δημιουργίας αντιγράφων ασφαλείας.<br><br>
+
+
+Για όσους μπορούν να εκτελέσουν την Perl σε όλους τους καταλόγους, αρκούν τα ακόλουθα βήματα:<br><br> 1.
+
+1. Καλέστε τη σελίδα δημιουργίας αντιγράφων ασφαλείας στο MyOOS [Dumper]. <br>
+Αντιγράψτε τη διαδρομή πίσω από την καταχώρηση στο crondump.pl για το $absolute_path_of_configdir:. <br>
+Ανοίξτε το αρχείο "crondump.pl" στον επεξεργαστή. <br>
+4. εισαγάγετε την αντιγραμμένη διαδρομή στο absolute_path_of_configdir (χωρίς κενά). <br>
+5. αποθηκεύστε το crondump.pl .<br>
+6. Δώστε στα αρχεία τα δικαιώματα 755. <br>
+6b. Αν επιθυμείτε την κατάληξη cgi, αλλάξτε την κατάληξη και των 3 αρχείων από pl -> cgi (μετονομασία). <br>
+(ev. 10b+11 από πάνω)<br>
+<br>
+
+Οι χρήστες των Windows πρέπει να αλλάξουν την πρώτη γραμμή όλων των σεναρίων, εκεί βρίσκεται η διαδρομή της Perl. Παράδειγμα: <br>
+αντί για: #!/usr/bin/perl -w <br>
+τώρα: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Λειτουργία</h4><ul>
+
+<h6>Μενού</h6>.
+Στην παραπάνω λίστα επιλογής ορίζετε τη βάση δεδομένων.<br>
+Όλες οι ενέργειες αναφέρονται στη βάση δεδομένων που έχει οριστεί εδώ.
+
+<h6>Αρχική σελίδα</h6>
+Εδώ μπορείτε να ενημερωθείτε για το σύστημά σας, τις διάφορες εκδόσεις που είναι εγκατεστημένες και λεπτομέρειες σχετικά με τις ρυθμισμένες βάσεις δεδομένων.
+εκδόσεις που είναι εγκατεστημένες και λεπτομέρειες σχετικά με τις ρυθμισμένες βάσεις δεδομένων.<br>
+Αν κάνετε κλικ στο όνομα της βάσης δεδομένων, θα δείτε μια λίστα με τους πίνακες και τον αριθμό των καταχωρήσεων.
+με τον αριθμό των εγγραφών, το μέγεθος και την ημερομηνία της τελευταίας ενημέρωσης.
+
+<h6>Διαμόρφωση</h6>
+Εδώ μπορείτε να επεξεργαστείτε τη διαμόρφωσή σας, να την αποθηκεύσετε ή να επαναφέρετε την αρχική διαμόρφωση.
+επαναφέρετε την αρχική διαμόρφωση.
+<ul><br>
+	<li><a name="conf1"></a><strong>Διαμορφωμένες βάσεις δεδομένων:</strong> ο κατάλογος των διαμορφωμένων βάσεων δεδομένων. Η ενεργή βάση δεδομένων παρατίθεται με <b>επίγραμμα</b>. </li>
+	<li><a name="conf2"></a><strong>Πρόθεμα πίνακα:</strong> εδώ μπορείτε να καθορίσετε ένα πρόθεμα (για κάθε βάση δεδομένων). Αυτό είναι ένα φίλτρο που λαμβάνει υπόψη μόνο τους πίνακες που αρχίζουν με αυτό το πρόθεμα κατά το ντάμπινγκ (π.χ. όλους τους πίνακες που αρχίζουν με "phpBB_"). Αν θέλετε να αποθηκευτούν όλοι οι πίνακες αυτής της βάσης δεδομένων, αφήστε το πεδίο κενό.</li>.
+	<li><a name="conf3"></a><strong>Συμπίεση GZip:</strong> Εδώ μπορείτε να ενεργοποιήσετε τη συμπίεση. Συνιστάται η ενεργοποίησή του, καθώς τα αρχεία γίνονται πολύ μικρότερα και ο αποθηκευτικός χώρος είναι πάντα περιορισμένος.
+	<li><a name="conf5"></a><strong>Email με το αρχείο dump:</strong> Αν αυτή η επιλογή είναι ενεργοποιημένη, αποστέλλεται ένα email με το αρχείο dump ως συνημμένο μετά την ολοκλήρωση του backup (προσοχή, η συμπίεση πρέπει οπωσδήποτε να είναι ενεργοποιημένη, διαφορετικά το συνημμένο θα είναι πολύ μεγάλο και μπορεί να μην αποσταλεί!).
+	<li><a name="conf6"></a><strong>Διεύθυνση ηλεκτρονικού ταχυδρομείου:</strong> Διεύθυνση παραλήπτη για το μήνυμα ηλεκτρονικού ταχυδρομείου.</li>
+	<li><a name="conf7"></a><strong>Αποστολέας του email:</strong> αυτή η διεύθυνση εμφανίζεται ως αποστολέας στο email.</li>
+	<li><a name="conf13"></a><strong>Μεταφορά FTP: </strong>Εάν αυτή η επιλογή είναι ενεργοποιημένη, το αρχείο αντιγράφου ασφαλείας θα αποσταλεί μέσω FTP μετά την ολοκλήρωση του αντιγράφου ασφαλείας.</li>
+	<li><a name="conf14"></a><strong>Διακομιστής FTP: </strong>Η διεύθυνση του διακομιστή FTP (π.χ. ftp.mybackups.de).</li>
+	<li><a name="conf15"></a><strong>Θύρα διακομιστή FTP: </strong>Η θύρα του διακομιστή FTP (συνήθως 21).</li>
+	<li><a name="conf16"></a><strong>Χρήστης FTP: </strong>Το όνομα χρήστη του λογαριασμού FTP. </li>
+	<li><a name="conf17"></a><strong>Password FTP: </strong>Ο κωδικός πρόσβασης του λογαριασμού FTP. </li>
+	<li><a name="conf18"></a><strong>Φάκελος μεταφόρτωσης FTP: </strong>Ο κατάλογος στον οποίο πρέπει να πηγαίνει το αρχείο αντιγράφου ασφαλείας (τα δικαιώματα μεταφόρτωσης πρέπει να υπάρχουν!).</li>
+	<li><a name="conf8"></a><strong>Αυτόματη διαγραφή αντιγράφων ασφαλείας:</strong> Εάν αυτή η επιλογή είναι ενεργοποιημένη, τα παλαιότερα αντίγραφα ασφαλείας θα διαγράφονται αυτόματα σύμφωνα με τους ακόλουθους κανόνες.</li>
+	<li><a name="conf10"></a><strong>Αριθμός αρχείων αντιγράφων ασφαλείας:</strong> Μια τιμή > 0 διαγράφει όλα τα αρχεία αντιγράφων ασφαλείας εκτός από τον αριθμό που καθορίζεται εδώ.</li>
+	<li><a name="conf11"></a><strong>Γλώσσα:</strong> εδώ ορίζετε τη γλώσσα για τη διεπαφή.</li>
+</ul>
+
+<h6>Διοίκηση</h6>
+Εδώ εκτελούνται οι πραγματικές ενέργειες.<br>
+Εμφανίζονται όλα τα αρχεία στον κατάλογο αντιγράφων ασφαλείας.
+Για τις ενέργειες "Επαναφορά" και "Διαγραφή" πρέπει να επιλεγεί ένα αρχείο.
+<UL>
+	<li><strong>Επαναφορά:</strong> Αυτή η επιλογή ενημερώνει τη βάση δεδομένων με το επιλεγμένο αρχείο αντιγράφων ασφαλείας.</li>
+	<li><strong>Διαγραφή:</strong> Αυτό σας επιτρέπει να διαγράψετε το επιλεγμένο αρχείο αντιγράφου ασφαλείας.</li>
+	<li><strong>Έναρξη νέου αντιγράφου ασφαλείας:</strong> Εδώ ξεκινάτε ένα νέο αντίγραφο ασφαλείας (dump) σύμφωνα με τις παραμέτρους που έχουν οριστεί στη ρύθμιση παραμέτρων.
+</UL>
+
+<h6>Log</h6>
+Εδώ μπορείτε να δείτε και να διαγράψετε τις εγγραφές καταγραφής.
+<h6>Πιστωτικές μονάδες / Βοήθεια</h6>
+αυτή τη σελίδα.
+</ul>
diff --git a/msd/language/el/help.php b/msd/language/el/help.php
deleted file mode 100644
index a9c29af7..00000000
--- a/msd/language/el/help.php
+++ /dev/null
@@ -1,130 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Σχετικά με το εργαλείο</h3>
-Η ιδέα για το εργαλείο αυτό είναι του Daniel Schlichtholz.<p>Το 2004 δημιούργησε ένα φόρουμ με όνομα <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> και σύντομα, προγραμματιστές που ασχολούνται με νέα σκριπτ, ενίσχυσαν τα σκριπτ του Daniel.<br>Μέσα σε λίγο καιρό το μικρό του προγραμματάκι μετατράπηκε σε ένα σταθερότατο εργαλείο.<p>Εαν έχετε ιδέες για βελτίωση επισκευθείτε το φόρουμ  του MySQLDumper: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>Σας ευχόμαστε ατελείωτα αντίγραφα ασφαλείας με αυτό το εργαλείο.<br><br><h4>Η ομάδα του MySQLDumper</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br /> Greek translation by Anthony Vasileiou (<a href="http://thraki.info" target="_blank">diastasi</a>)
-
-<h3>Βοήθεια MySQLDumper</h3>
-
-<h4>Μεταφόρτωση</h4>
-Το Script είναι διαθέσιμο στην ιστοσελίδα του MySQLDumper.<br>
-Προτείνουμε να επισκεφτεστε συχνά την Ιστοσελίδα για τις τελευταίες πληροφορίες, αναβαθμίσεις και βοήθεια.<br>
-Η διεύθυνση είναι <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>Ελάχιστες απαιτήσεις</h4>
-Το Script λειτουργεί σχεδόν σε κάθε σύστημα διακομιστή (Windows, Linux, ...) <br>
-με PHP >= Version 4.3.4 και GZip-Library, MySQL (>= 3.23), JavaScript (πρέπει να είναι ενεργό).
-
-<a href="install.php?language=el" target="_top"><h4>Εγκατάσταση</h4></a>
-Η εγκατάσταση είναι πολύ απλή.
-Αποσυμπιέστε το αρχείο σε οποιονδήποτε φάκελο,
-που είναι διαθέσιμος από το Webserver<br>
-(π.χ. στο ριζικό κατάλογο [Server rootdir/]MySQLDumper)<br>
-αλλάξτε το config.php σε chmod 777<br>
-... έγινε!<br>
-τώρα ξεκινήστε το MySQLDumper στον πλοηγό σας πληκτρολογώντας "http://istoselida/MySQLDumper"
-για να ολοκληρωθεί η εγκατάσταση, και απλά ακολουθήστε τις οδηγίες.
-
-<br><b>Σημείωση:</b><br><i>Εαν ο webserver σας τρέχει με την επιλογή safemode=ON το MySqlDump δεν πρέπει να δημιουργεί καταλόγους.<br>
-Πρέπει να τους κάνετε μόνοι σας.<br>
-Το MySqlDump σταματάει σε αυτό το σημείο και σας λέει τι να κάνετε.<br>
-Αφού δημιουργήσετε τους καταλόγους το MySqlDump θα λειτουργήσει κανονικά.</i><br><br>
-
-<a name="perl"></a><h4>Οδηγός για το Perl script</h4>
-
-Οι περισσότεροι έχουν ένα κατάλογο cgi-bin, μέσα στον οποίο μπορεί το Perl να εκτελεστεί. <br>
-Συνήθως βρίσκεται στο http://www.domain.de/cgi-bin/ . <br><br>
-
-Κάντε τα παρακάτω βήματα για αυτή την περίπτωση.  <br><br>
-
-1.  Πατήστε στο MySQLDumper τον πλήκτρο Αντίγραφα Ασφαλείας και κατόπιν πιέστε το "Αντίγραφα Ασφαλείας Perl"   <br>
-2.  Αντιγράψτε τη διαδρομή που θα βρείτε κάτω από το "Εισαγωγή στο crondump.pl για absolute_path_of_configdir":    <br>
-3.  Ανοίξτε το αρχείο "crondump.pl" σε έναν επεξεργαστή κειμένου <br>
-4.  Επικολλήστε την αντεγραμένη διαδρομή στο σημείο με το absolute_path_of_configdir (χωρίς κενά) <br>
-5.  Αποθηκεύστε το crondump.pl <br>
-6.  Αντιγράψτε το crondump.pl, το perltest.pl και το simpletest.pl στο κατάλογο cgi-bin (ASCII mode στο ftp-client!) <br>
-7.  Δώστε chmod 755 στα scripts.  <br>
-7b. Εάν επιθυμείτε κατάληξη cgi, αλλάξτε τις καταλήξεις και από τα 3 αρχεία pl - > cgi (μετονομασία)  <br>
-8.  Πηγαίνετε στο MySQLDumper στη σελίδα "Ρυθμίσεις"<br>
-9.  Κάντε κλικ στο "Cronscript" <br>
-10. Αλλάξτε τη διαδρομή εκτέλεσης του Perl σε /cgi-bin/<br>
-10b. Εάν τα Scripts έχεουν μετονομαστεί σε *.cgi , αλλάξτε την κατάληξη αρχείου σε cgi <br>
-11  Αποθηκεύστε τις Ρυθμίσεις <br><br>
-
-Ετοιμοι ! Τα scripts είναι διαθέσιμα από τη σελίδα "Αντίγραφα Ασφαλείας" <br><br>
-
-Οταν μπορείτε να εκτελέσετε Perl, χρειάζονται μόνο τα παρακάτω βήματα:  <br><br>
-
-1.  Πηγαίνετε στο MySQLDumper στη σελίδα "Αντίγραφα Ασφαλείας".  <br>
-2.  Αντιγράψτε τη διαδρομή που θα βρείτε κάτω από το "Εισαγωγή στο crondump.pl για absolute_path_of_configdir":  <br>
-3.  Ανοίξτε το αρχείο "crondump.pl" σε έναν επεξεργαστή κειμένου <br>
-4.  Επικολλήστε την αντεγραμένη διαδρομή στο σημείο με το absolute_path_of_configdir (χωρίς κενά) <br>
-5.  Αποθηκεύστε το crondump.pl <br>
-
-6.  Δώστε chmod 755 στα scripts.  <br> 
-6b. Εάν επιθυμείτε κατάληξη cgi, αλλάξτε τις καταλήξεις και από τα 3 αρχεία pl - > cgi (μετονομασία)  <br>
-    (προχωρήστε στα βήματα 10b+11 παραπάνω) <br><br>
-
-
-Οι χρήστες Windows πρέπει να αλλάξουν την πρώτη γραμμή σε όλα τα Perlscripts, στη διαδρομή του Perl.  <br><br>
-
-Παράδειγμα:  <br>
-
-αντί για :  #!/usr/bin/perl w <br>
-τώρα #!C:\perl\bin\perl.exe w<br><br>
-
-<h4>Λειτουργία</h4><ul>
-
-<h6>Μενού</h6>
-Εδω επιλέγετε τη Β.Δεδομένων σας από το μενού πολλαπλών επιλογών "Επιλογή Β.Δεδομένων".<br>
-Ολες οι παραπάνω επιλογές αναφέρονται στην επιλεγμένη Β.Δεδομένων.
-
-<h6>Αρχική</h6>
-Εδώ βλέπετε πληροφορίες για το σύστημα σας, τις εκδόσεις και λεπτομέρειες σχετικά με τις Β.Δεδομένων σας.<br>
-Εαν κάνετε κλικ σε μία Β.Δεδομένων στον πίνακα, θα πάρετε μία λίστα με εγγραφές με αριθμήσεις εγγραφών, μέγεθος και τελευταία επεξεργασία.
-
-<h6>Ρυθμίσεις</h6>
-Εδώ επεξεργάζεστε τις ρυθμίσεις σας, τις αποθηκεύετε ή φορτώνετε τις προεπιλεγμένες.
-<ul>
-	<li><a name="conf1"><strong>Λίστα Β.Δεδομένων:</strong> Η λίστα των Β.Δεδομένων σας. Η ενεργή Β.Δεδομένων είναι έντονη.</li>
-	<li><a name="conf2"><strong>Πρόθεμα πίνακα:</strong> Εδώ επιλέγετε ένα πρόθεμα πίνακα για κάθε Β.Δεδομένων χωριστά. Το πρόθεμα είναι ένα φίλτρο, που διαχειρίζεται τους πίνακες σε ένα αντίγραφο ασφαλείας, που ξεκινάει με αυτό το  πρόθεμα (π.χ. όλοι οι πίνακες ξεκινούν με "phpBB_"). Εαν δε θέλετε να το χρησιμοποιήσετε, αφήστε το πεδίο κενό.</li>
-	<li><a name="conf3"><strong>Συμπίεση GZip:</strong> Εδώ ενεργοποιείτε τη συμπίεση. Προτείνεται να εργάζεστε με την συμπίεση ενεργοποιημένη, για μικρότερο μέγεθος αρχείων, ώστε να μην πιάνουν πολύ χώρο στο δίσκο.</li>
-	<li><a name="conf19"></a><strong>Αριθμός εγγραφών για αντίγραφα ασφαλείας:</strong> Ο αριθμός των εγγραφών που διαβάζονται ταυτόχρονα κατά τη λειτουργία αντιγράφων ασφαλείας, πριν το script κάνει callback. Για αργούς διακομιστές μειώστε την παράμετρο για να αποφύγετε timeouts.</li>
-	<li><a name="conf20"></a><strong>Αριθμός εγγραφών για επαναφορά:</strong> Ο αριθμός των εγγραφών που διαβάζονται ταυτόχρονα κατά την επαναφορά, πριν το script κάνει callback. Για αργούς διακομιστές μειώστε την παράμετρο για να αποφύγετε timeouts.</li>
-	<li><a name="conf4"></a><strong>Κατάλογος για τα αρχεία αντιγράφων ασφαλείας:</strong> επιλέξτε τον κατάλογο για τα αντίγραφα ασφαλείας. Εάν επιλέξετε έναν νέο, Το script θα τον δημιουργήσει για σας. Μπορείτε να χρησιμοποιήσετε σχετικές ή απόλυτες διαδρομές.</li>
-	<li><a name="conf5"></a><strong>Αποστολή Αντιγράφου ασφαλείας ως email:</strong> Οταν έχετε αυτή την επιλογή, το script θα στείλει αυτόματα το ολοκληρωμένο αντίγραφο ασφαλείας μέσω email με συννημένο (Προσέξτε!, πρέπει να χρησιμοποιείτε συμπίεση με αυτή την επιλογή επειδή το αντίγραφο ασφαλείας μπορεί να είναι τεράστιο για email!)</li>
-	<li><a name="conf6"></a><strong>Διεύθυνση Email:</strong> Διεύθυνση email παραλήπτη</li>
-	<li><a name="conf7"></a><strong>Θέμα Email:</strong> Το θέμα του email</li>
-	<li><a name="conf13"></a><strong>Μεταφορά FTP: </strong>Οταν έχετε αυτή την επιλογή, το script θα στείλει αυτόματα το ολοκληρωμένο αντίγραφο ασφαλείας μέσω FTP.</li>
-	<li><a name="conf14"><strong>Διακομιστής FTP: </strong>Η διεύθυνση του διακομιστή FTP (π.χ. ftp.mybackups.de)</li>
-	<li><a name="conf15"></a><strong>Θύρα διακομιστή FTP: </strong>Η θύρα για τον διακομιστή FTP (συνήθως 21)</li>
-	<li><a name="conf16"></a><strong>Χρήστης FTP: </strong>Το όνομα χρήστη του λογαριασμού FTP</li>
-	<li><a name="conf17"></a><strong>Κωδικός FTP: </strong>Ο κωδικός του λογαριασμού FTP</li>
-	<li><a name="conf18"></a><strong>Κατάλογος φόρτωσης FTP: </strong>Ο κατάλογος που αποθηκεύονται τα αντίγραφα ασφαλείας (πρέπει να έχει δικαιώματα για φόρτωση!)</li>
-	
-	<li><a name="conf8"></a><strong>automatic deletion of backups:</strong> When you activate this options, backup files will be deleted automatically by the following rules.</li>
-	<li><a name="conf10"></a><strong>Delete by number of files:</strong> A Value > 0 deletes all files except the given value</li>
-	<li><a name="conf11"></a><strong>Langauge:</strong> choose your language for the interface.</li>
-</ul>
-
-<h6>Διαχείριση Αρχείων</h6>
-Ολες οι ενέργειες βρίσκονται εδώ.<br>
-Εδώ θα δείτε όλα τα αρχεία αντιγράφων ασφαλείας που βρίσκονται στον κατάλογο backup.
-Για την "Επαναφορά" και "Διαγραφή" πρέπει να επιλέξετε πρώτα ένα αρχείο.
-<UL>
-	<li><strong>Επαναφορά:</strong> επαναφέρετε τη Β.Δεδομένων σας με εγγραφές απο το επιλεγμένο αντίγραφο ασφαλείας.</li>
-	<li><strong>Διαγραφή:</strong> διαγράφετε το επιλεγμένο αντίγραφο ασφαλείας.</li>
-	<li><strong>Νέο αντίγραφο ασφαλείας:</strong> εδώ μπορείτε να ξεκινήσετε ένα νέο αντίγραφο ασφαλείας (dump) με τις περαμέτρους που έχετε ορίσει.</li>
-</UL>
-
-<h6>Καταγραφές</h6>
-Εδώ βλέπετε όλες τις εγγραφές στο αρχείο καταγραφών και μπορείτε να τις διαγράψετε.
-
-<h6>Επαινοι / Βοήθεια</h6>
-Αυτή η σελίδα.
-</ul>
\ No newline at end of file
diff --git a/msd/language/el/lang.php b/msd/language/el/lang.php
index 249b9986..ed6cfc0c 100644
--- a/msd/language/el/lang.php
+++ b/msd/language/el/lang.php
@@ -1,115 +1,112 @@
 <?php
-$lang['L_YES']="ναι";
-$lang['L_TO']="σε";
-$lang['L_ACTIVATED']="ενεργό";
-$lang['L_NOT_ACTIVATED']="ανενεργό";
-$lang['L_ERROR']="Σφάλμα";
-$lang['L_OF']=" από ";
-$lang['L_ADDED']="προστέθηκε";
-$lang['L_DB']="Β.Δεδομένων";
-$lang['L_DBS']="Β.Δεδομένων";
-$lang['L_TABLES']="Πίνακες";
-$lang['L_TABLE']="Πίνακας";
-$lang['L_RECORDS']="Εγγραφή";
-$lang['L_COMPRESSED']="συμπιεσμένο (gz)";
-$lang['L_NOTCOMPRESSED']="απλό (ασυμπίεστο)";
-$lang['L_GENERAL']="γενικά";
-$lang['L_COMMENT']="Σχόλιο";
-$lang['L_FILESIZE']="Μέγεθος αρχείου";
-$lang['L_ALL']="όλα";
-$lang['L_NONE']="κανένα";
-$lang['L_WITH']=" με ";
-$lang['L_DIR']="Κατάλογος";
-$lang['L_RECHTE']="Προσβάσεις";
-$lang['L_STATUS']="Κατάσταση";
-$lang['L_FINISHED']="τελείωσε";
-$lang['L_FILE']="Αρχείο";
-$lang['L_FIELDS']="Πεδία";
-$lang['L_NEW']="νεο";
-$lang['L_CHARSET']="Κωδικοποίηση";
-$lang['L_COLLATION']="Collation";
-$lang['L_CHANGE']="αλλαγή";
-$lang['L_IN']="σε";
-$lang['L_DO']="Εκτέλεσε";
-$lang['L_VIEW']="προβολή";
-$lang['L_EXISTING']="υπάρχων";
-$lang['L_BACK']="πίσω";
-$lang['L_DB_HOST']="Ονομα Host";
-$lang['L_DB_USER']="χρήστης";
-$lang['L_DB_PASS']="κωδικός";
-$lang['L_INFO_SCRIPTDIR']="Κατάλογος του MySQLDumper";
-$lang['L_INFO_ACTDB']="Παρούσα Β.Δεδομένων";
-$lang['L_WRONGCONNECTIONPARS']="Λάθος ή καμία παράμετρος σύνδεσης!";
-$lang['L_CONN_NOT_POSSIBLE']="Μη δυνατή σύνδεση !";
-$lang['L_SERVERCAPTION']="Προβολή Διακομιστή";
-$lang['L_HELP_SERVERCAPTION']="Οταν χρησιμοποιείται το MySQLDumper σε διαφορετικά domain ή διακομιστές, μπορεί να είναι χρήσιμο να προβάλλεται το όνομα του διακομιστή στην κορυφή της οθόνης.";
-$lang['L_ACTIVATE_MULTIDUMP']="ενεργοποίηση MultiDump";
-$lang['L_SAVE']="Αποθήκευση";
-$lang['L_RESET']="Επαναφορά";
-$lang['L_PRAEFIX']="Πρόθεμα πίνακα";
-$lang['L_AUTODELETE']="Αυτόματη διαγραφή αντιγράφου ασφαλείας";
-$lang['L_MAX_BACKUP_FILES_EACH2']="Για κάθε Β.Δεδομένων";
-$lang['L_SAVING_DB_FORM']="Β.Δεδομένων";
-$lang['L_TESTCONNECTION']="Δοκιμή σύνδεσης";
-$lang['L_BACK_TO_MINISQL']="Επεξεργασία Β.Δεδομένων";
-$lang['L_CREATE']="Δημιουργία";
-$lang['L_VARIABELN']="Μεταβλητές";
-$lang['L_STATUSINFORMATIONEN']="Πληροφορίες κατάστασης";
-$lang['L_VERSIONSINFORMATIONEN']="Πληροφορίες Εκδοσης";
-$lang['L_MSD_INFO']="Πληροφορίες MyOOS [Dumper]";
-$lang['L_BACKUPFILESANZAHL']="στο φάκελο Backup είναι ";
-$lang['L_LASTBACKUP']="Τελευταίο Αντίγραφο Ασφαλείας";
-$lang['L_NOTAVAIL']="<em>δεν υπάρχει</em>";
-$lang['L_VOM']="από";
-$lang['L_MYSQLVARS']="Μεταβλητές MySQL";
-$lang['L_MYSQLSYS']="Εντολές MySQL";
-$lang['L_STATUS']="Κατάσταση";
-$lang['L_PROZESSE']="Διαδικασίες";
-$lang['L_INFO_NOVARS']="Καμία μεταβλητή διαθέσιμη";
-$lang['L_INHALT']="Τιμή";
-$lang['L_INFO_NOSTATUS']="Καμία κατάσταση διαθέσιμη";
-$lang['L_INFO_NOPROCESSES']="Δεν εκτελείται διαδικασία";
-$lang['L_FM_FREESPACE']="Ελεύθερος χώρος στο διακομιστή";
-$lang['L_LOAD_DATABASE']="Επαναφόρτωση Β.Δεδομένων";
-$lang['L_HOME']="Αρχική";
-$lang['L_CONFIG']="Ρυθμίσεις";
-$lang['L_DUMP']="Αντίγραφα ασφαλείας";
-$lang['L_RESTORE']="Επαναφορά";
-$lang['L_FILE_MANAGE']="Διαχείριση αρχείων";
-$lang['L_LOG']="Καταγραφές";
-$lang['L_CHOOSE_DB']="Επιλογή Β.Δεδομένων";
-$lang['L_CREDITS']="Επαινοι / Βοήθεια";
-$lang['L_MULTI_PART']="Multipart Αντίγραφα ασφαλείας";
-$lang['L_LOGFILENOTWRITABLE']="Αδυναμία εγγραφής Καταγραφών !";
-$lang['L_SQL_ERROR1']="Σφάλμα στο ερώτημα:";
-$lang['L_SQL_ERROR2']="Η MySQL λέει:";
-$lang['L_UNKNOWN']="αγνωστο";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="άγνωστο";
-$lang['L_OK']="ΟΚ";
-$lang['L_CRON_COMPLETELOG']="Εξοδος Καταγραφών πλήρης";
-$lang['L_NO']="όχι";
-$lang['L_CREATE_DATABASE']="Δημιουργία νέας Β.Δεδομένων";
-$lang['L_EXPORTFINISHED']="Εξαγωγή τελειωμένη.";
-$lang['L_SQL_BROWSER']="Πλοηγός SQL";
-$lang['L_SERVER']="Διακομιστής";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Στανταρ κωδικοποίηση του διακομιστή MySQL
+
+$lang['L_YES'] = 'ναι';
+$lang['L_TO'] = 'σε';
+$lang['L_ACTIVATED'] = 'ενεργό';
+$lang['L_NOT_ACTIVATED'] = 'ανενεργό';
+$lang['L_ERROR'] = 'Σφάλμα';
+$lang['L_OF'] = ' από ';
+$lang['L_ADDED'] = 'προστέθηκε';
+$lang['L_DB'] = 'Β.Δεδομένων';
+$lang['L_DBS'] = 'Β.Δεδομένων';
+$lang['L_TABLES'] = 'Πίνακες';
+$lang['L_TABLE'] = 'Πίνακας';
+$lang['L_RECORDS'] = 'Εγγραφή';
+$lang['L_COMPRESSED'] = 'συμπιεσμένο (gz)';
+$lang['L_NOTCOMPRESSED'] = 'απλό (ασυμπίεστο)';
+$lang['L_COMMENT'] = 'Σχόλιο';
+$lang['L_FILESIZE'] = 'Μέγεθος αρχείου';
+$lang['L_ALL'] = 'όλα';
+$lang['L_NONE'] = 'κανένα';
+$lang['L_WITH'] = ' με ';
+$lang['L_DIR'] = 'Κατάλογος';
+$lang['L_RECHTE'] = 'Προσβάσεις';
+$lang['L_STATUS'] = 'Κατάσταση';
+$lang['L_FINISHED'] = 'τελείωσε';
+$lang['L_FILE'] = 'Αρχείο';
+$lang['L_FIELDS'] = 'Πεδία';
+$lang['L_NEW'] = 'νεο';
+$lang['L_CHARSET'] = 'Κωδικοποίηση';
+$lang['L_COLLATION'] = 'Collation';
+$lang['L_CHANGE'] = 'αλλαγή';
+$lang['L_IN'] = 'σε';
+$lang['L_DO'] = 'Εκτέλεσε';
+$lang['L_VIEW'] = 'προβολή';
+$lang['L_EXISTING'] = 'υπάρχων';
+$lang['L_BACK'] = 'πίσω';
+$lang['L_DB_HOST'] = 'Ονομα Host';
+$lang['L_DB_USER'] = 'χρήστης';
+$lang['L_DB_PASS'] = 'κωδικός';
+$lang['L_INFO_SCRIPTDIR'] = 'Κατάλογος του MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Παρούσα Β.Δεδομένων';
+$lang['L_WRONGCONNECTIONPARS'] = 'Λάθος ή καμία παράμετρος σύνδεσης!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Μη δυνατή σύνδεση !';
+$lang['L_SERVERCAPTION'] = 'Προβολή Διακομιστή';
+$lang['L_HELP_SERVERCAPTION'] = 'Οταν χρησιμοποιείται το MyOOS [Dumper] σε διαφορετικά domain ή διακομιστές, μπορεί να είναι χρήσιμο να προβάλλεται το όνομα του διακομιστή στην κορυφή της οθόνης.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'ενεργοποίηση MultiDump';
+$lang['L_SAVE'] = 'Αποθήκευση';
+$lang['L_RESET'] = 'Επαναφορά';
+$lang['L_PRAEFIX'] = 'Πρόθεμα πίνακα';
+$lang['L_AUTODELETE'] = 'Αυτόματη διαγραφή αντιγράφου ασφαλείας';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'Για κάθε Β.Δεδομένων';
+$lang['L_SAVING_DB_FORM'] = 'Β.Δεδομένων';
+$lang['L_TESTCONNECTION'] = 'Δοκιμή σύνδεσης';
+$lang['L_BACK_TO_MINISQL'] = 'Επεξεργασία Β.Δεδομένων';
+$lang['L_CREATE'] = 'Δημιουργία';
+$lang['L_VARIABELN'] = 'Μεταβλητές';
+$lang['L_STATUSINFORMATIONEN'] = 'Πληροφορίες κατάστασης';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Πληροφορίες Εκδοσης';
+$lang['L_MOD_INFO'] = 'Πληροφορίες MyOOS [Dumper]';
+$lang['L_BACKUPFILESANZAHL'] = 'στο φάκελο Backup είναι ';
+$lang['L_LASTBACKUP'] = 'Τελευταίο Αντίγραφο Ασφαλείας';
+$lang['L_NOTAVAIL'] = '<em>δεν υπάρχει</em>';
+$lang['L_VOM'] = 'από';
+$lang['L_MYSQLVARS'] = 'Μεταβλητές MySQL';
+$lang['L_MYSQLSYS'] = 'Εντολές MySQL';
+$lang['L_STATUS'] = 'Κατάσταση';
+$lang['L_PROZESSE'] = 'Διαδικασίες';
+$lang['L_INFO_NOVARS'] = 'Καμία μεταβλητή διαθέσιμη';
+$lang['L_INHALT'] = 'Τιμή';
+$lang['L_INFO_NOSTATUS'] = 'Καμία κατάσταση διαθέσιμη';
+$lang['L_INFO_NOPROCESSES'] = 'Δεν εκτελείται διαδικασία';
+$lang['L_FM_FREESPACE'] = 'Ελεύθερος χώρος στο διακομιστή';
+$lang['L_LOAD_DATABASE'] = 'Επαναφόρτωση Β.Δεδομένων';
+$lang['L_HOME'] = 'Αρχική';
+$lang['L_CONFIG'] = 'Ρυθμίσεις';
+$lang['L_DUMP'] = 'Αντίγραφα ασφαλείας';
+$lang['L_RESTORE'] = 'Επαναφορά';
+$lang['L_FILE_MANAGE'] = 'Διαχείριση αρχείων';
+$lang['L_LOG'] = 'Καταγραφές';
+$lang['L_CHOOSE_DB'] = 'Επιλογή Β.Δεδομένων';
+$lang['L_CREDITS'] = 'Επαινοι / Βοήθεια';
+$lang['L_MULTI_PART'] = 'Multipart Αντίγραφα ασφαλείας';
+$lang['L_LOGFILENOTWRITABLE'] = 'Αδυναμία εγγραφής Καταγραφών !';
+$lang['L_SQL_ERROR1'] = 'Σφάλμα στο ερώτημα:';
+$lang['L_SQL_ERROR2'] = 'Η MySQL λέει:';
+$lang['L_UNKNOWN'] = 'αγνωστο';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'άγνωστο';
+$lang['L_OK'] = 'ΟΚ';
+$lang['L_CRON_COMPLETELOG'] = 'Εξοδος Καταγραφών πλήρης';
+$lang['L_NO'] = 'όχι';
+$lang['L_CREATE_DATABASE'] = 'Δημιουργία νέας Β.Δεδομένων';
+$lang['L_EXPORTFINISHED'] = 'Εξαγωγή τελειωμένη.';
+$lang['L_SQL_BROWSER'] = 'Πλοηγός SQL';
+$lang['L_SERVER'] = 'Διακομιστής';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Στανταρ κωδικοποίηση του διακομιστή MySQL
 
 
-";
-$lang['L_TITLE_SHOW_DATA']="Προβολή δεδομένων";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Διαγραφή πρωτεύον κλειδιού?";
-$lang['L_SETPRIMARYKEYSFOR']="Ορισμός πρωτεύοντων κλειδιών για πίνακες";
-$lang['L_PRIMARYKEY_FIELD']="Πεδίο πρωτεύον κλειδιού";
-$lang['L_PRIMARYKEYS_SAVE']="Αποθήκευση πρωτεύοντων κλειδιών";
-$lang['L_CANCEL']="άκυρο";
-$lang['L_VISIT_HOMEPAGE']="Επισκεφθείτε την Ιστοσελίδα";
-$lang['L_SECONDS']="Δευτερόλεπτα";
-$lang['L_BACKUPS']="Αντίγραφα Ασφαλείας";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
-
-
-?>
\ No newline at end of file
+';
+$lang['L_TITLE_SHOW_DATA'] = 'Προβολή δεδομένων';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Διαγραφή πρωτεύον κλειδιού?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Ορισμός πρωτεύοντων κλειδιών για πίνακες';
+$lang['L_PRIMARYKEY_FIELD'] = 'Πεδίο πρωτεύον κλειδιού';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Αποθήκευση πρωτεύοντων κλειδιών';
+$lang['L_CANCEL'] = 'άκυρο';
+$lang['L_VISIT_HOMEPAGE'] = 'Επισκεφθείτε την Ιστοσελίδα';
+$lang['L_SECONDS'] = 'Δευτερόλεπτα';
+$lang['L_BACKUPS'] = 'Αντίγραφα Ασφαλείας';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/el/lang_config_overview.php b/msd/language/el/lang_config_overview.php
index d857e5a7..a97ddb0f 100644
--- a/msd/language/el/lang_config_overview.php
+++ b/msd/language/el/lang_config_overview.php
@@ -1,111 +1,128 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Ρυθμίσεις";
-$lang['L_SAVE_SUCCESS']="Οι Ρυθμίσεις αποθηκεύθηκαν.";
-$lang['L_CONFIG_LOADED']="Οι Ρυθμίσεις \"%s\" έχουν εισαχθεί επιτυχώς.";
-$lang['L_SAVE_ERROR']="Σφάλμα - οι ρυθμίσεις δεν αποθηκεύθηκαν!";
-$lang['L_CONFIG_EMAIL']="Ειδοποίηση Email";
-$lang['L_CONFIG_AUTODELETE']="Αυτόματη Διαγραφή";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="μέγιστο μέγεθος αρχείου";
-$lang['L_HELP_MULTIPART']="Εαν το Multipart είναι ενεργοποιημένο, δημιουργούνται πολλαπλά Αντίγραφα ασφαλείας με μέγιστο μέγεθος που ορίζεται απο τη ρύθμιση παρακάτω";
-$lang['L_HELP_MULTIPARTGROESSE']="Το μέγιστο μέγεθος των Αντιγράφων ασφαλείας ορίζεται εδώ, εάν είναι ενεργό το Multipart";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Διαγραφή πινάκων πριν την επαναφορά";
-$lang['L_ALLPARS']="Ολοι οι παράμετροι";
-$lang['L_CRON_EXTENDER']="Κατάληξη αρχείου";
-$lang['L_CRON_SAVEPATH']="Αρχείο ρύθμισης";
-$lang['L_CRON_PRINTOUT']="Προβολή στην οθόνη.";
-$lang['L_CONFIG_CRONPERL']="Ρυθμίσεις Crondump για Perl script";
-$lang['L_CRON_MAILPRG']="Πρόγραμμα Mail";
-$lang['L_OPTIMIZE']="βελτιστοποίηση πινάκων πριν το Αντίγραφο ασφαλείας";
-$lang['L_HELP_OPTIMIZE']="Εαν αυτό είναι ενεργό, όλοι οι πίνακες θα βελτιστοποιηθούν πριν γίνει αντίγραφο ασφαλείας";
-$lang['L_HELP_FTPTIMEOUT']="προεπιλεγμένη ρύθμιση για υπέρβαση χρόνου είναι τα 90 δευτ.";
-$lang['L_FTP_TIMEOUT']="Υπέρβαση χρόνου σύνδεσης";
-$lang['L_HELP_FTPSSL']="Επιλέξτε εάν η σύνδεση θα γίνει μέσω SSL.";
-$lang['L_CONFIG_ASKLOAD']="θέλετε να αλλάξετε τις ρυθμίσεις με τις προεπιλεγμένες?";
-$lang['L_LOAD']="Ρυθμ. Προεπιλογής";
-$lang['L_LOAD_SUCCESS']="Οι προεπιλεγμένες ρυθμίσεις φορτώθηκαν.";
-$lang['L_CRON_CRONDBINDEX']="Β. Δεδομένων";
-$lang['L_WITHATTACH']=" με επισύναψη";
-$lang['L_WITHOUTATTACH']=" χωρίς επισύναψη";
-$lang['L_MULTIDUMPCONF']="=Ρύθμιση Multidump=";
-$lang['L_MULTIDUMPALL']="=όλες οι Β.Δεδομένων=";
-$lang['L_GZIP']="Συμίεση GZip";
-$lang['L_SEND_MAIL_FORM']="Αποστολή email αναφοράς";
-$lang['L_SEND_MAIL_DUMP']="Επισύναψη αντιγράφου ασφαλείας";
-$lang['L_EMAIL_ADRESS']="Διεύθυνση Email";
-$lang['L_EMAIL_SENDER']="Διεύθυνση αποστολέα του email";
-$lang['L_EMAIL_MAXSIZE']="Μέγιστο μέγεθος συννημένου";
-$lang['L_NUMBER_OF_FILES_FORM']="Διαγραφή ανά αριθμό αρχείων";
-$lang['L_LANGUAGE']="Γλώσσα";
-$lang['L_LIST_DB']="Λίστα Β.Δεδομένων:";
-$lang['L_CONFIG_FTP']="Μεταφορά FTP των Αντιγράφων ασφαλείας";
-$lang['L_FTP_TRANSFER']="Μεταφορά FTP";
-$lang['L_FTP_SERVER']="Διακομιστής";
-$lang['L_FTP_PORT']="Θύρα";
-$lang['L_FTP_USER']="Χρήστης";
-$lang['L_FTP_PASS']="Κωδικός";
-$lang['L_FTP_DIR']="Κατάλογος Φόρτωσης";
-$lang['L_FTP_SSL']="Ασφαλής Σύνδεση SSL FTP";
-$lang['L_FTP_USESSL']="Χρήση σύνδεσης SSL";
-$lang['L_SQLBOXHEIGHT']="Υψος πλαισίου SQL";
-$lang['L_SQLLIMIT']="Αριθμός εγγραφών ανά σελίδα";
-$lang['L_BBPARAMS']="Ρύθμιση για BB-Code";
-$lang['L_BBTEXTCOLOR']="Χρώμα κειμένου";
-$lang['L_HELP_COMMANDS']="Μπορείτε να εκτελέσετε μία εντολή πριν ή μετά το αντίγραφο Ασφαλείας.
-Η εντολή αυτή μπορεί να είναι SQL-Construct ή εντολή Συστήματος (π.χ. ένα script)";
-$lang['L_COMMAND']="Εντολή";
-$lang['L_WRONG_CONNECTIONPARS']="Οι παράμετροι σύνδεσης είναι λάθος !";
-$lang['L_CONNECTIONPARS']="Παράμετροι σύνδεσης";
-$lang['L_EXTENDEDPARS']="Επιπλέον παράμετροι";
-$lang['L_FADE_IN_OUT']="Προβολή ανοικτό/κλειστό";
-$lang['L_DB_BACKUPPARS']="Παράμετροι Αντιγράφων ασφαλείας Β.Δεδομένων";
-$lang['L_GENERAL']="Γενικά";
-$lang['L_MAXSIZE']="Μέγιστο μέγεθος";
-$lang['L_ERRORHANDLING_RESTORE']="Διαχείριση σφαλμάτων κατά την επαναφορά";
-$lang['L_EHRESTORE_CONTINUE']="συνέχιση και καταγραφή σφαλμάτων";
-$lang['L_EHRESTORE_STOP']="σταμάτημα";
-$lang['L_IN_MAINFRAME']="στο κύριο πλαίσιο";
-$lang['L_IN_LEFTFRAME']="στο αριστερό πλαίσιο";
-$lang['L_WIDTH']="Πλάτος";
-$lang['L_SQL_BEFEHLE']="Εντολές SQL";
-$lang['L_DOWNLOAD_LANGUAGES']="μεταφόρτωση άλλων γλωσσών";
-$lang['L_DOWNLOAD_STYLES']="μεταφόρτωση άλλων θεμάτων";
-$lang['L_CONNECT_TO']="Σύνδεση σε";
-$lang['L_CHANGEDIR']="Αλλαγή σε κατάλογο";
-$lang['L_CHANGEDIRERROR']="Αδυναμία αλλαγής καταλόγου!";
-$lang['L_FTP_OK']="Επιτυχής Σύνδεση.";
-$lang['L_INSTALL']="Εγκατάσταση";
-$lang['L_NOFTPPOSSIBLE']="Δεν έχετε λειτουργίες FTP !";
-$lang['L_FOUND_DB']="βρέθηκαν Β.Δ.";
-$lang['L_FTP_CHOOSE_MODE']="Λειτουργία μεταφοράς FTP";
-$lang['L_FTP_PASSIVE']="χρήση passive mode";
-$lang['L_HELP_FTP_MODE']="Επιλέξτε το passive mode αν παρουσιαστούν προβλήματα καθώς χρησιμοποιείτε το active mode.";
-$lang['L_DB_IN_LIST']="Η Β.Δεδομένων '%s' δε μπόρεσε να προστεθεί γιατί υπάρχει ήδη. ";
-$lang['L_ADD_DB_MANUALLY']="Προσθήκη Β.Δεδομένων χειροκίνητα";
-$lang['L_DB_MANUAL_ERROR']="Δυστυχώς, δεν συνδέθηκα με τη Β.Δεδομένων '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Σφάλμα αρχείου: Δεν εισάχθηκε η Β.Δεδομένων '%s'!";
-$lang['L_NO_DB_FOUND']="Δε βρήκα καμία Β.Δεδομένων αυτόματα!
-Παρακαλώ εμφανίστε τις παραμέτρους σύνδεσης, και δώστε χειροκίνητα το όνομα της Β.Δεδομένων.";
-$lang['L_CONFIGFILES']="Αρχεία ρύθμισης";
-$lang['L_CONFIGFILE']="Αρχείο ρύθμισης";
-$lang['L_MYSQL_DATA']="Δεδομένα MySQL";
-$lang['L_CONFIGURATIONS']="Ρυθμίσεις";
-$lang['L_ACTION']="Ενέργεια";
-$lang['L_FTP_SEND_TO']="Προς <strong>%s</strong><br> στο <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="Κοινοπ.";
-$lang['L_NAME']="Ονομα";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Διαγραφή του αρχείου ρύθμισης %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Σφάλμα: Δεν μπορεί να διαγραφεί το αρχείο ρύθμισης %s!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Το αρχείο ρύθμισης %s διαγράφηκε επιτυχώς.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Το αρχείο ρύθμισης %s δημιουργήθηκε επιτυχώς.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Το όνομα αρχείου \"%s\" περιέχει μη αποδεκτούς χαρακτήρες.";
-$lang['L_CREATE_CONFIGFILE']="Δημιουργία νέου αρχείου ρύθμισης";
-$lang['L_ERROR_LOADING_CONFIGFILE']="δεν ανοίγει το αρχείο ρύθμισης \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="ΒΔ για αντιγ. ασφαλείας (PHP)";
-$lang['L_BACKUP_DBS_PERL']="ΒΔ για αντιγ. ασφαλείας (PERL)";
-$lang['L_CRON_COMMENT']="Δώστε σχόλιο";
-$lang['L_AUTODETECT']="αυτόματος εντοπισμός";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Ρυθμίσεις';
+$lang['L_SAVE_SUCCESS'] = 'Οι Ρυθμίσεις αποθηκεύθηκαν.';
+$lang['L_CONFIG_LOADED'] = 'Οι Ρυθμίσεις "%s" έχουν εισαχθεί επιτυχώς.';
+$lang['L_SAVE_ERROR'] = 'Σφάλμα - οι ρυθμίσεις δεν αποθηκεύθηκαν!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Ειδοποίηση Email';
+$lang['L_CONFIG_AUTODELETE'] = 'Αυτόματη Διαγραφή';
+$lang['L_CONFIG_INTERFACE'] = 'Interface';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'μέγιστο μέγεθος αρχείου';
+$lang['L_HELP_MULTIPART'] = 'Εαν το Multipart είναι ενεργοποιημένο, δημιουργούνται πολλαπλά Αντίγραφα ασφαλείας με μέγιστο μέγεθος που ορίζεται απο τη ρύθμιση παρακάτω';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Το μέγιστο μέγεθος των Αντιγράφων ασφαλείας ορίζεται εδώ, εάν είναι ενεργό το Multipart';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Διαγραφή πινάκων πριν την επαναφορά';
+$lang['L_ALLPARS'] = 'Ολοι οι παράμετροι';
+$lang['L_CRON_EXTENDER'] = 'Κατάληξη αρχείου';
+$lang['L_CRON_SAVEPATH'] = 'Αρχείο ρύθμισης';
+$lang['L_CRON_PRINTOUT'] = 'Προβολή στην οθόνη.';
+$lang['L_CONFIG_CRONPERL'] = 'Ρυθμίσεις Crondump για Perl script';
+$lang['L_CRON_MAILPRG'] = 'Πρόγραμμα Mail';
+$lang['L_OPTIMIZE'] = 'βελτιστοποίηση πινάκων πριν το Αντίγραφο ασφαλείας';
+$lang['L_HELP_OPTIMIZE'] = 'Εαν αυτό είναι ενεργό, όλοι οι πίνακες θα βελτιστοποιηθούν πριν γίνει αντίγραφο ασφαλείας';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'προεπιλεγμένη ρύθμιση για υπέρβαση χρόνου είναι τα 90 δευτ.';
+$lang['L_FTP_TIMEOUT'] = 'Υπέρβαση χρόνου σύνδεσης';
+$lang['L_HELP_FTPSSL'] = 'Επιλέξτε εάν η σύνδεση θα γίνει μέσω SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Υπέρβαση χρόνου σύνδεσης';
+$lang['L_HELP_SFTPSSL'] = 'Επιλέξτε εάν η σύνδεση θα γίνει μέσω SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'θέλετε να αλλάξετε τις ρυθμίσεις με τις προεπιλεγμένες?';
+$lang['L_LOAD'] = 'Ρυθμ. Προεπιλογής';
+$lang['L_LOAD_SUCCESS'] = 'Οι προεπιλεγμένες ρυθμίσεις φορτώθηκαν.';
+$lang['L_CRON_CRONDBINDEX'] = 'Β. Δεδομένων';
+$lang['L_WITHATTACH'] = ' με επισύναψη';
+$lang['L_WITHOUTATTACH'] = ' χωρίς επισύναψη';
+$lang['L_MULTIDUMPCONF'] = '=Ρύθμιση Multidump=';
+$lang['L_MULTIDUMPALL'] = '=όλες οι Β.Δεδομένων=';
+$lang['L_GZIP'] = 'Συμίεση GZip';
+$lang['L_SEND_MAIL_FORM'] = 'Αποστολή email αναφοράς';
+$lang['L_SEND_MAIL_DUMP'] = 'Επισύναψη αντιγράφου ασφαλείας';
+$lang['L_EMAIL_ADRESS'] = 'Διεύθυνση Email';
+$lang['L_EMAIL_SENDER'] = 'Διεύθυνση αποστολέα του email';
+$lang['L_EMAIL_MAXSIZE'] = 'Μέγιστο μέγεθος συννημένου';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Διαγραφή ανά αριθμό αρχείων';
+$lang['L_LANGUAGE'] = 'Γλώσσα';
+$lang['L_LIST_DB'] = 'Λίστα Β.Δεδομένων:';
+$lang['L_CONFIG_FTP'] = 'Μεταφορά FTP των Αντιγράφων ασφαλείας';
+$lang['L_FTP_TRANSFER'] = 'Μεταφορά FTP';
+$lang['L_FTP_SERVER'] = 'Διακομιστής';
+$lang['L_FTP_PORT'] = 'Θύρα';
+$lang['L_FTP_USER'] = 'Χρήστης';
+$lang['L_FTP_PASS'] = 'Κωδικός';
+$lang['L_FTP_DIR'] = 'Κατάλογος Φόρτωσης';
+$lang['L_FTP_SSL'] = 'Ασφαλής Σύνδεση SSL FTP';
+$lang['L_FTP_USESSL'] = 'Χρήση σύνδεσης SSL';
+$lang['L_CONFIG_SFTP'] = 'Μεταφορά SFTP των Αντιγράφων ασφαλείας';
+$lang['L_SFTP_TRANSFER'] = 'Μεταφορά SFTP';
+$lang['L_SFTP_SERVER'] = 'Διακομιστής';
+$lang['L_SFTP_PORT'] = 'Θύρα';
+$lang['L_SFTP_USER'] = 'Χρήστης';
+$lang['L_SFTP_PASS'] = 'Κωδικός';
+$lang['L_SFTP_DIR'] = 'Κατάλογος Φόρτωσης';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Υψος πλαισίου SQL';
+$lang['L_SQLLIMIT'] = 'Αριθμός εγγραφών ανά σελίδα';
+$lang['L_BBPARAMS'] = 'Ρύθμιση για BB-Code';
+$lang['L_BBTEXTCOLOR'] = 'Χρώμα κειμένου';
+$lang['L_HELP_COMMANDS'] = 'Μπορείτε να εκτελέσετε μία εντολή πριν ή μετά το αντίγραφο Ασφαλείας.
+Η εντολή αυτή μπορεί να είναι SQL-Construct ή εντολή Συστήματος (π.χ. ένα script)';
+$lang['L_COMMAND'] = 'Εντολή';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Οι παράμετροι σύνδεσης είναι λάθος !';
+$lang['L_CONNECTIONPARS'] = 'Παράμετροι σύνδεσης';
+$lang['L_EXTENDEDPARS'] = 'Επιπλέον παράμετροι';
+$lang['L_FADE_IN_OUT'] = 'Προβολή ανοικτό/κλειστό';
+$lang['L_DB_BACKUPPARS'] = 'Παράμετροι Αντιγράφων ασφαλείας Β.Δεδομένων';
+$lang['L_GENERAL'] = 'Γενικά';
+$lang['L_MAXSIZE'] = 'Μέγιστο μέγεθος';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Διαχείριση σφαλμάτων κατά την επαναφορά';
+$lang['L_EHRESTORE_CONTINUE'] = 'συνέχιση και καταγραφή σφαλμάτων';
+$lang['L_EHRESTORE_STOP'] = 'σταμάτημα';
+$lang['L_IN_MAINFRAME'] = 'στο κύριο πλαίσιο';
+$lang['L_IN_LEFTFRAME'] = 'στο αριστερό πλαίσιο';
+$lang['L_WIDTH'] = 'Πλάτος';
+$lang['L_SQL_BEFEHLE'] = 'Εντολές SQL';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'μεταφόρτωση άλλων γλωσσών';
+$lang['L_DOWNLOAD_STYLES'] = 'μεταφόρτωση άλλων θεμάτων';
+$lang['L_CONNECT_TO'] = 'Σύνδεση σε';
+$lang['L_CHANGEDIR'] = 'Αλλαγή σε κατάλογο';
+$lang['L_CHANGEDIRERROR'] = 'Αδυναμία αλλαγής καταλόγου!';
+$lang['L_FTP_OK'] = 'Επιτυχής Σύνδεση.';
+$lang['L_INSTALL'] = 'Εγκατάσταση';
+$lang['L_NOFTPPOSSIBLE'] = 'Δεν έχετε λειτουργίες FTP !';
+$lang['L_FOUND_DB'] = 'βρέθηκαν Β.Δ.';
+$lang['L_FTP_CHOOSE_MODE'] = 'Λειτουργία μεταφοράς FTP';
+$lang['L_FTP_PASSIVE'] = 'χρήση passive mode';
+$lang['L_HELP_FTP_MODE'] = 'Επιλέξτε το passive mode αν παρουσιαστούν προβλήματα καθώς χρησιμοποιείτε το active mode.';
+$lang['L_SFTP_PASSIVE'] = 'χρήση passive mode';
+$lang['L_DB_IN_LIST'] = "Η Β.Δεδομένων '%s' δε μπόρεσε να προστεθεί γιατί υπάρχει ήδη. ";
+$lang['L_ADD_DB_MANUALLY'] = 'Προσθήκη Β.Δεδομένων χειροκίνητα';
+$lang['L_DB_MANUAL_ERROR'] = "Δυστυχώς, δεν συνδέθηκα με τη Β.Δεδομένων '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Σφάλμα αρχείου: Δεν εισάχθηκε η Β.Δεδομένων '%s'!";
+$lang['L_NO_DB_FOUND'] = 'Δε βρήκα καμία Β.Δεδομένων αυτόματα!
+Παρακαλώ εμφανίστε τις παραμέτρους σύνδεσης, και δώστε χειροκίνητα το όνομα της Β.Δεδομένων.';
+$lang['L_CONFIGFILES'] = 'Αρχεία ρύθμισης';
+$lang['L_CONFIGFILE'] = 'Αρχείο ρύθμισης';
+$lang['L_MYSQL_DATA'] = 'Δεδομένα MySQL';
+$lang['L_CONFIGURATIONS'] = 'Ρυθμίσεις';
+$lang['L_ACTION'] = 'Ενέργεια';
+$lang['L_FTP_SEND_TO'] = 'Προς <strong>%s</strong><br> στο <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'Προς <strong>%s</strong><br> στο <strong>%s</strong>';
+$lang['L_SFTP'] = 'FTP';
+$lang['L_EMAIL_CC'] = 'Κοινοπ.';
+$lang['L_NAME'] = 'Ονομα';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Διαγραφή του αρχείου ρύθμισης %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Σφάλμα: Δεν μπορεί να διαγραφεί το αρχείο ρύθμισης %s!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Το αρχείο ρύθμισης %s διαγράφηκε επιτυχώς.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Το αρχείο ρύθμισης %s δημιουργήθηκε επιτυχώς.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Το όνομα αρχείου "%s" περιέχει μη αποδεκτούς χαρακτήρες.';
+$lang['L_CREATE_CONFIGFILE'] = 'Δημιουργία νέου αρχείου ρύθμισης';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'δεν ανοίγει το αρχείο ρύθμισης "%s".';
+$lang['L_BACKUP_DBS_PHP'] = 'ΒΔ για αντιγ. ασφαλείας (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'ΒΔ για αντιγ. ασφαλείας (PERL)';
+$lang['L_CRON_COMMENT'] = 'Δώστε σχόλιο';
+$lang['L_AUTODETECT'] = 'αυτόματος εντοπισμός';
diff --git a/msd/language/el/lang_dump.php b/msd/language/el/lang_dump.php
index e3e2ec1c..5788a82a 100644
--- a/msd/language/el/lang_dump.php
+++ b/msd/language/el/lang_dump.php
@@ -1,57 +1,58 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Δημιουργία Αντιγράφου Ασφαλείας...";
-$lang['L_GZIP_COMPRESSION']="Συμπίεση GZip";
-$lang['L_SAVING_TABLE']="Αποθήκευση πίνακα ";
-$lang['L_OF']="από";
-$lang['L_ACTUAL_TABLE']="Παρών πίνακας";
-$lang['L_PROGRESS_TABLE']="Πρόοδος του πίνακα";
-$lang['L_PROGRESS_OVER_ALL']="Συνολική Πρόοδος";
-$lang['L_ENTRY']="Εισαγωγή";
-$lang['L_DONE']="Εγινε!";
-$lang['L_DUMP_SUCCESSFUL']=" δημιουργήθηκε επιτυχώς.";
-$lang['L_UPTO']="έως";
-$lang['L_EMAIL_WAS_SEND']="Email στάλθηκε επιτυχώς σε ";
-$lang['L_BACK_TO_CONTROL']="Συνέχεια";
-$lang['L_BACK_TO_OVERVIEW']="Επισκόπηση Β.Δεδομένων";
-$lang['L_DUMP_FILENAME']="Αρχείο Αντιγράφου Ασφαλείας: ";
-$lang['L_WITHPRAEFIX']="με πρόθεμα";
-$lang['L_DUMP_NOTABLES']="Δε βρέθηκαν πίνακες στη Β.Δεδομένων `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="Το αρχείο περιέχει <b>%s</b> πίνακες με <b>%s</b> εγγραφές.<br>";
-$lang['L_MAILERROR']="Η αποστολή email απέτυχε!";
-$lang['L_EMAILBODY_ATTACH']="Το συννημένο περιέχει αντίγραφο ασφαλείας της Βάσης MySQL.<br>Αντίγραφο της Β.Δεδομένων `%s`
-<br><br>Το παρακάτω αρχείο δημιουργήθηκε:<br><br>%s <br><br>Ευχαριστίες<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Ενα αντίγραφο ασφαλείας Multipart δημιουργήθηκε.<br>Τα Αντίγραφα ασφαλείας δεν επισυνάφθηκαν σε αυτό το email!<br>Αντίγραφο της Β.Δεδομένων `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'Δημιουργία Αντιγράφου Ασφαλείας...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'Συμπίεση GZip';
+$lang['L_SAVING_TABLE'] = 'Αποθήκευση πίνακα ';
+$lang['L_OF'] = 'από';
+$lang['L_ACTUAL_TABLE'] = 'Παρών πίνακας';
+$lang['L_PROGRESS_TABLE'] = 'Πρόοδος του πίνακα';
+$lang['L_PROGRESS_OVER_ALL'] = 'Συνολική Πρόοδος';
+$lang['L_ENTRY'] = 'Εισαγωγή';
+$lang['L_DONE'] = 'Εγινε!';
+$lang['L_DUMP_SUCCESSFUL'] = ' δημιουργήθηκε επιτυχώς.';
+$lang['L_UPTO'] = 'έως';
+$lang['L_EMAIL_WAS_SEND'] = 'Email στάλθηκε επιτυχώς σε ';
+$lang['L_BACK_TO_CONTROL'] = 'Συνέχεια';
+$lang['L_BACK_TO_OVERVIEW'] = 'Επισκόπηση Β.Δεδομένων';
+$lang['L_DUMP_FILENAME'] = 'Αρχείο Αντιγράφου Ασφαλείας: ';
+$lang['L_WITHPRAEFIX'] = 'με πρόθεμα';
+$lang['L_DUMP_NOTABLES'] = 'Δε βρέθηκαν πίνακες στη Β.Δεδομένων `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = 'Το αρχείο περιέχει <b>%s</b> πίνακες με <b>%s</b> εγγραφές.<br>';
+$lang['L_MAILERROR'] = 'Η αποστολή email απέτυχε!';
+$lang['L_EMAILBODY_ATTACH'] = 'Το συννημένο περιέχει αντίγραφο ασφαλείας της Βάσης MySQL.<br>Αντίγραφο της Β.Δεδομένων `%s`
+<br><br>Το παρακάτω αρχείο δημιουργήθηκε:<br><br>%s <br><br>Ευχαριστίες<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Ενα αντίγραφο ασφαλείας Multipart δημιουργήθηκε.<br>Τα Αντίγραφα ασφαλείας δεν επισυνάφθηκαν σε αυτό το email!<br>Αντίγραφο της Β.Δεδομένων `%s`
 <br><br>Δημιουργήθηκαν τα παρακάτω αρχεία:<br><br>%s
-<br><br>Ευχαριστίες<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Δημιουργήθηκε ένα Multipart Αντίγραφο ασφαλείας.<br>Τα Αντίγραφα ασφαλείας επισυνάφθηκαν σε χωριστά emails.<br>Αντίγραφο της Β.Δεδομένων `%s`
-<br><br>Δημιουργήθηκαν τα παρακάτω αρχεία:<br><br>%s <br><br>Ευχαριστίες<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="`<br><br>Ευχαριστώ<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="Το αντίγραφο ασφαλείας έχει υπερβεί το μέγιστο μέγεθος %s και δεν επισυνάφθηκε σε αυτό το email.<br>Αντίγραφο της Β.Δεδομένων `%s`
+<br><br>Ευχαριστίες<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Δημιουργήθηκε ένα Multipart Αντίγραφο ασφαλείας.<br>Τα Αντίγραφα ασφαλείας επισυνάφθηκαν σε χωριστά emails.<br>Αντίγραφο της Β.Δεδομένων `%s`
+<br><br>Δημιουργήθηκαν τα παρακάτω αρχεία:<br><br>%s <br><br>Ευχαριστίες<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '`<br><br>Ευχαριστώ<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Το αντίγραφο ασφαλείας έχει υπερβεί το μέγιστο μέγεθος %s και δεν επισυνάφθηκε σε αυτό το email.<br>Αντίγραφο της Β.Δεδομένων `%s`
 <br><br>Δημιουργήθηκε το παρακάτω αρχείο:<br><br>%s
-<br><br>Ευχαριστίες<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Τα αρχεία δεν επισυνάφθηκαν σε αυτό το email!<br>Αντίγραφο της Β.Δεδομένων `%s`
+<br><br>Ευχαριστίες<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Τα αρχεία δεν επισυνάφθηκαν σε αυτό το email!<br>Αντίγραφο της Β.Δεδομένων `%s`
 <br><br>Δημιουργήθηκε το παρακάτω αρχείο:<br><br>%s
-<br><br>Ευχαριστίες<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... συννημένο μόνο.";
-$lang['L_TABLESELECTION']="Επιλογή πίνακα";
-$lang['L_SELECTALL']="Επιλογή όλων";
-$lang['L_DESELECTALL']="Αποεπιλογή όλων";
-$lang['L_STARTDUMP']="Εκκίνηση Αντιγράφων Ασφαλείας";
-$lang['L_LASTBUFROM']="Τελευταία αναβάθμιση από";
-$lang['L_NOT_SUPPORTED']="Το αντίγραφο ασφαλείας δεν υποστηρίζει αυτή τη λειτουργία.";
-$lang['L_MULTIDUMP']="Multidump: Το αντίγραφο ασφαλείας της Β.Δεδομένων <b>%d</b> ολοκληρώθηκε.";
-$lang['L_FILESENDFTP']="αποστολή αρχείου μέσω FTP... παρακαλώ περιμένετε. ";
-$lang['L_FTPCONNERROR']="Δεν έγινε σύνδεση FTP ! ΄Σύνδεση με ";
-$lang['L_FTPCONNERROR1']=" σαν χρήστης ";
-$lang['L_FTPCONNERROR2']=" δεν είναι δυνατόν";
-$lang['L_FTPCONNERROR3']="Η Φόρτωση FTP απέτυχε! ";
-$lang['L_FTPCONNECTED1']="Συνδεμένο με ";
-$lang['L_FTPCONNECTED2']=" σε ";
-$lang['L_FTPCONNECTED3']=" Επιτυχής μεταφορά";
-$lang['L_NR_TABLES_SELECTED']="- με %s επιλεγμένους πίνακες";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s πίνακες έχουν βελτιστοποιηθεί.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s σφάλματα παρουσιάστηκαν: <a href=\"log.php?r=3\">view</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Γενικό Σφάλμα: Η δήλωση CREATE-Statement του πίνακα '%s' στη Β.Δεδομένων '%s' δε μπορεί να διαβαστεί!";
-
-
-?>
\ No newline at end of file
+<br><br>Ευχαριστίες<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... συννημένο μόνο.';
+$lang['L_TABLESELECTION'] = 'Επιλογή πίνακα';
+$lang['L_SELECTALL'] = 'Επιλογή όλων';
+$lang['L_DESELECTALL'] = 'Αποεπιλογή όλων';
+$lang['L_STARTDUMP'] = 'Εκκίνηση Αντιγράφων Ασφαλείας';
+$lang['L_LASTBUFROM'] = 'Τελευταία αναβάθμιση από';
+$lang['L_NOT_SUPPORTED'] = 'Το αντίγραφο ασφαλείας δεν υποστηρίζει αυτή τη λειτουργία.';
+$lang['L_MULTIDUMP'] = 'Multidump: Το αντίγραφο ασφαλείας της Β.Δεδομένων <b>%d</b> ολοκληρώθηκε.';
+$lang['L_FILESENDFTP'] = 'αποστολή αρχείου μέσω FTP... παρακαλώ περιμένετε. ';
+$lang['L_FTPCONNERROR'] = 'Δεν έγινε σύνδεση FTP ! ΄Σύνδεση με ';
+$lang['L_FTPCONNERROR1'] = ' σαν χρήστης ';
+$lang['L_FTPCONNERROR2'] = ' δεν είναι δυνατόν';
+$lang['L_FTPCONNERROR3'] = 'Η Φόρτωση FTP απέτυχε! ';
+$lang['L_FTPCONNECTED1'] = 'Συνδεμένο με ';
+$lang['L_FTPCONNECTED2'] = ' σε ';
+$lang['L_FTPCONNECTED3'] = ' Επιτυχής μεταφορά';
+$lang['L_NR_TABLES_SELECTED'] = '- με %s επιλεγμένους πίνακες';
+$lang['L_FILESENDSFTP'] = 'αποστολή αρχείου μέσω SFTP... παρακαλώ περιμένετε. ';
+$lang['L_SFTPCONNERROR'] = 'Δεν έγινε σύνδεση SFTP ! ΄Σύνδεση με ';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s πίνακες έχουν βελτιστοποιηθεί.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s σφάλματα παρουσιάστηκαν: <a href="log.php?r=3">view</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Γενικό Σφάλμα: Η δήλωση CREATE-Statement του πίνακα '%s' στη Β.Δεδομένων '%s' δε μπορεί να διαβαστεί!";
diff --git a/msd/language/el/lang_filemanagement.php b/msd/language/el/lang_filemanagement.php
index 106afd7f..9b62525f 100644
--- a/msd/language/el/lang_filemanagement.php
+++ b/msd/language/el/lang_filemanagement.php
@@ -1,79 +1,79 @@
 <?php
-$lang['L_CONVERT_START']="Εκκίνηση μετατροπής";
-$lang['L_CONVERT_TITLE']="Μετατροπή από Dump σε μορφή MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Λάθος παράμετροι!  Δε μπορεί να γίνει μετατροπή.";
-$lang['L_FM_UPLOADFILEREQUEST']="παρακαλώ επιλέξτε ένα αρχείο.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Ο τύπος αρχείου δεν υποστηρίζεται.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Υποστηριζόμενοι τύποι είναι: αρχεία *.gz και *.sql";
-$lang['L_FM_UPLOADMOVEERROR']="Δεν μπόρεσα να μετακινήσω το επιλεγμένο αρχείο στο φάκελο φόρτωσης.";
-$lang['L_FM_UPLOADFAILED']="Η φόρτωση απέτυχε!";
-$lang['L_FM_UPLOADFILEEXISTS']="Υπάρχει ήδη αρχείο με ίδιο όνομα !";
-$lang['L_FM_NOFILE']="Δεν επιλέξατε αρχείο!";
-$lang['L_FM_DELETE1']="Το αρχείο ";
-$lang['L_FM_DELETE2']=" διαγράφηκε επιτυχώς.";
-$lang['L_FM_DELETE3']=" δεν μπορεί να διαγραφεί!";
-$lang['L_FM_CHOOSE_FILE']="Επιλεγμένο αρχείο:";
-$lang['L_FM_FILESIZE']="Μέγεθος αρχείου";
-$lang['L_FM_FILEDATE']="Ημερομηνία αρχείου";
-$lang['L_FM_NOFILESFOUND']="Δε βρέθηκε αρχείο.";
-$lang['L_FM_TABLES']="Πίνακες";
-$lang['L_FM_RECORDS']="Εγγραφές";
-$lang['L_FM_ALL_BU']="Ολα τα Αντίγραφα Ασφαλείας";
-$lang['L_FM_ANZ_BU']="Αντίγραφα Ασφαλείας";
-$lang['L_FM_LAST_BU']="Τελευταίο Αντίγραφο Ασφαλείας";
-$lang['L_FM_TOTALSIZE']="Συνολικό μέγεθος";
-$lang['L_FM_SELECTTABLES']="Επιλέξτε πίνακες";
-$lang['L_FM_COMMENT']="Εισαγωγή σχολίων";
-$lang['L_FM_RESTORE']="Επαναφορά";
-$lang['L_FM_ALERTRESTORE1']="Η Β.Δεδομένων";
-$lang['L_FM_ALERTRESTORE2']="να επαναφερθεί με εγγραφές απο το αρχείο";
-$lang['L_FM_ALERTRESTORE3']="Να γίνει επαναφορά ?";
-$lang['L_FM_DELETE']="Διαγραφή";
-$lang['L_FM_ASKDELETE1']="Το αρχείο ";
-$lang['L_FM_ASKDELETE2']="να διαγραφεί?";
-$lang['L_FM_ASKDELETE3']="Θέλετε η αυτόματη διαγραφή να εκτελεστεί τώρα με τους υπάρχοντες κανόνες?";
-$lang['L_FM_ASKDELETE4']="Να διαγραφούν όλα τα αντίγραφα ασφαλείας?";
-$lang['L_FM_ASKDELETE5']="Να διαγραφούν όλα τα αντίγραφα ασφαλείας με ";
-$lang['L_FM_ASKDELETE5_2']="_* Διαγραφή τώρα?";
-$lang['L_FM_DELETEAUTO']="Εκτέλεση αυτόματης διαγραφής χειροκίνητα";
-$lang['L_FM_DELETEALL']="Διαγραφή όλων των αντιγράφων ασφαλείας";
-$lang['L_FM_DELETEALLFILTER']="Διαγραφή όλων με ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Εκκίνηση νέου Αντιγράφου ασφαλείας";
-$lang['L_FM_FILEUPLOAD']="Φόρτωση αρχείου";
-$lang['L_FM_DBNAME']="Ονομα Β.Δεδομένων";
-$lang['L_FM_FILES1']="Αντίγραφα ασφαλείας Β.Δεδομένων";
-$lang['L_FM_FILES2']="Δομή Β.Δεδομένων";
-$lang['L_FM_AUTODEL1']="Αυτόματη διαγραφή: τα παρακάτω αρχεία διαγράφηκαν λόγω ρύθμισης μέγιστου αριθμού αρχείων:";
-$lang['L_DELETE_FILE_SUCCESS']="Το αρχείο \"%s\" διαγράφηκε επιτυχώς.";
-$lang['L_FM_DUMPSETTINGS']="Ρύθμιση";
-$lang['L_FM_OLDBACKUP']="(άγνωστο)";
-$lang['L_FM_RESTORE_HEADER']="επαναφορά της Β.Δεδομένων \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Σφάλμα στη διαγραφή του αρχείου \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Αντίγραφα Ασφαλείας";
-$lang['L_DOCRONBUTTON']="Εκτέλεση του Perl Cron script";
-$lang['L_DOPERLTEST']="Δοκιμή μονάδων Perl";
-$lang['L_DOSIMPLETEST']="Δοκιμή Perl";
-$lang['L_PERLOUTPUT1']="Εισαγωγή στο crondump.pl για absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Δεσμός URL για τον πλοηγό ή για εξωτερική Cron job";
-$lang['L_PERLOUTPUT3']="Γραμμή εντολών για το Κέλυφος ή για το Crontab";
-$lang['L_RESTORE_OF_TABLES']="Επιλέξτε τους πίνακες που θα επαναφερθούν";
-$lang['L_CONVERTER']="Μετατροπέας Αντιγράφων ασφαλείας";
-$lang['L_CONVERT_FILE']="Αρχεία για μετατροπή";
-$lang['L_CONVERT_FILENAME']="Ονομα αρχείου προορισμού (χωρίς κατάληξη)";
-$lang['L_CONVERTING']="Μετατροπή";
-$lang['L_CONVERT_FILEREAD']="Ανάγνωση αρχείου '%s'";
-$lang['L_CONVERT_FINISHED']="Η μετατροπή τελείωσε, '%s' εγγράφηκε επιτυχώς.";
-$lang['L_NO_MSD_BACKUPFILE']="Αντίγραφα Ασφαλείας άλλων scripts";
-$lang['L_MAX_UPLOAD_SIZE']="Μέγιστο μέγεθος αρχείου";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Αν το Dumpfile είναι μεγαλύτερο από το παραπάνω επιτρεπτό όριο, φορτώστε το με FTP στον κατάλογο \"work/backup\".
-Μετά μπορείτε να το επιλέξετε για επαναφορά. ";
-$lang['L_ENCODING']="κωδικοποίηση";
-$lang['L_FM_CHOOSE_ENCODING']="Επιλογή κωδικοποίησης για το Αντίγραφο ασφαλείας";
-$lang['L_CHOOSE_CHARSET']="Το MySQLDumper δε μπόρεσε να αναγνωρίσει αυτόματα την κωδικοποίηση του αντιγράφου ασφαλείας.
+
+$lang['L_CONVERT_START'] = 'Εκκίνηση μετατροπής';
+$lang['L_CONVERT_TITLE'] = 'Μετατροπή από Dump σε μορφή MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Λάθος παράμετροι!  Δε μπορεί να γίνει μετατροπή.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'παρακαλώ επιλέξτε ένα αρχείο.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Ο τύπος αρχείου δεν υποστηρίζεται.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Υποστηριζόμενοι τύποι είναι: αρχεία *.gz και *.sql';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Δεν μπόρεσα να μετακινήσω το επιλεγμένο αρχείο στο φάκελο φόρτωσης.';
+$lang['L_FM_UPLOADFAILED'] = 'Η φόρτωση απέτυχε!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Υπάρχει ήδη αρχείο με ίδιο όνομα !';
+$lang['L_FM_NOFILE'] = 'Δεν επιλέξατε αρχείο!';
+$lang['L_FM_DELETE1'] = 'Το αρχείο ';
+$lang['L_FM_DELETE2'] = ' διαγράφηκε επιτυχώς.';
+$lang['L_FM_DELETE3'] = ' δεν μπορεί να διαγραφεί!';
+$lang['L_FM_CHOOSE_FILE'] = 'Επιλεγμένο αρχείο:';
+$lang['L_FM_FILESIZE'] = 'Μέγεθος αρχείου';
+$lang['L_FM_FILEDATE'] = 'Ημερομηνία αρχείου';
+$lang['L_FM_NOFILESFOUND'] = 'Δε βρέθηκε αρχείο.';
+$lang['L_FM_TABLES'] = 'Πίνακες';
+$lang['L_FM_RECORDS'] = 'Εγγραφές';
+$lang['L_FM_ALL_BU'] = 'Ολα τα Αντίγραφα Ασφαλείας';
+$lang['L_FM_ANZ_BU'] = 'Αντίγραφα Ασφαλείας';
+$lang['L_FM_LAST_BU'] = 'Τελευταίο Αντίγραφο Ασφαλείας';
+$lang['L_FM_TOTALSIZE'] = 'Συνολικό μέγεθος';
+$lang['L_FM_SELECTTABLES'] = 'Επιλέξτε πίνακες';
+$lang['L_FM_COMMENT'] = 'Εισαγωγή σχολίων';
+$lang['L_FM_RESTORE'] = 'Επαναφορά';
+$lang['L_FM_ALERTRESTORE1'] = 'Η Β.Δεδομένων';
+$lang['L_FM_ALERTRESTORE2'] = 'να επαναφερθεί με εγγραφές απο το αρχείο';
+$lang['L_FM_ALERTRESTORE3'] = 'Να γίνει επαναφορά ?';
+$lang['L_FM_DELETE'] = 'Διαγραφή';
+$lang['L_FM_ASKDELETE1'] = 'Το αρχείο ';
+$lang['L_FM_ASKDELETE2'] = 'να διαγραφεί?';
+$lang['L_FM_ASKDELETE3'] = 'Θέλετε η αυτόματη διαγραφή να εκτελεστεί τώρα με τους υπάρχοντες κανόνες?';
+$lang['L_FM_ASKDELETE4'] = 'Να διαγραφούν όλα τα αντίγραφα ασφαλείας?';
+$lang['L_FM_ASKDELETE5'] = 'Να διαγραφούν όλα τα αντίγραφα ασφαλείας με ';
+$lang['L_FM_ASKDELETE5_2'] = '_* Διαγραφή τώρα?';
+$lang['L_FM_DELETEAUTO'] = 'Εκτέλεση αυτόματης διαγραφής χειροκίνητα';
+$lang['L_FM_DELETEALL'] = 'Διαγραφή όλων των αντιγράφων ασφαλείας';
+$lang['L_FM_DELETEALLFILTER'] = 'Διαγραφή όλων με ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Εκκίνηση νέου Αντιγράφου ασφαλείας';
+$lang['L_FM_FILEUPLOAD'] = 'Φόρτωση αρχείου';
+$lang['L_FM_DBNAME'] = 'Ονομα Β.Δεδομένων';
+$lang['L_FM_FILES1'] = 'Αντίγραφα ασφαλείας Β.Δεδομένων';
+$lang['L_FM_FILES2'] = 'Δομή Β.Δεδομένων';
+$lang['L_FM_AUTODEL1'] = 'Αυτόματη διαγραφή: τα παρακάτω αρχεία διαγράφηκαν λόγω ρύθμισης μέγιστου αριθμού αρχείων:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'Το αρχείο "%s" διαγράφηκε επιτυχώς.';
+$lang['L_FM_DUMPSETTINGS'] = 'Ρύθμιση';
+$lang['L_FM_OLDBACKUP'] = '(άγνωστο)';
+$lang['L_FM_RESTORE_HEADER'] = 'επαναφορά της Β.Δεδομένων "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Σφάλμα στη διαγραφή του αρχείου "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Αντίγραφα Ασφαλείας';
+$lang['L_DOCRONBUTTON'] = 'Εκτέλεση του Perl Cron script';
+$lang['L_DOPERLTEST'] = 'Δοκιμή μονάδων Perl';
+$lang['L_DOSIMPLETEST'] = 'Δοκιμή Perl';
+$lang['L_PERLOUTPUT1'] = 'Εισαγωγή στο crondump.pl για absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Δεσμός URL για τον πλοηγό ή για εξωτερική Cron job';
+$lang['L_PERLOUTPUT3'] = 'Γραμμή εντολών για το Κέλυφος ή για το Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Επιλέξτε τους πίνακες που θα επαναφερθούν';
+$lang['L_CONVERTER'] = 'Μετατροπέας Αντιγράφων ασφαλείας';
+$lang['L_CONVERT_FILE'] = 'Αρχεία για μετατροπή';
+$lang['L_CONVERT_FILENAME'] = 'Ονομα αρχείου προορισμού (χωρίς κατάληξη)';
+$lang['L_CONVERTING'] = 'Μετατροπή';
+$lang['L_CONVERT_FILEREAD'] = "Ανάγνωση αρχείου '%s'";
+$lang['L_CONVERT_FINISHED'] = "Η μετατροπή τελείωσε, '%s' εγγράφηκε επιτυχώς.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Αντίγραφα Ασφαλείας άλλων scripts';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Μέγιστο μέγεθος αρχείου';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Αν το Dumpfile είναι μεγαλύτερο από το παραπάνω επιτρεπτό όριο, φορτώστε το με FTP στον κατάλογο "work/backup".
+Μετά μπορείτε να το επιλέξετε για επαναφορά. ';
+$lang['L_ENCODING'] = 'κωδικοποίηση';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Επιλογή κωδικοποίησης για το Αντίγραφο ασφαλείας';
+$lang['L_CHOOSE_CHARSET'] = 'Το MyOOS [Dumper] δε μπόρεσε να αναγνωρίσει αυτόματα την κωδικοποίηση του αντιγράφου ασφαλείας.
 <br>Επιλέξτε το σετ χαρακτήρων με το οποίο αποθηκέυθηκε το αντίγραφο ασφαλείας.
 <br>Αν παρουσιαστούν προβλήματα με κάποιους χαρακτήρες μετά την επαναφορά, επαναλάβετε την επαναφορά κι επιλέξτε άλλο σετ χαρακτήρων.
-<br>Καλή επιτυχία. ;)";
-$lang['L_DOWNLOAD_FILE']="Μεταφόρτωση αρχείου";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+<br>Καλή επιτυχία. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Μεταφόρτωση αρχείου';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/el/lang_help.php b/msd/language/el/lang_help.php
index fd01a328..99c902e8 100644
--- a/msd/language/el/lang_help.php
+++ b/msd/language/el/lang_help.php
@@ -1,39 +1,40 @@
 <?php
-$lang['L_HELP_DB']="Αυτή είναι μια λίστα με Β.Δεδομένων";
-$lang['L_HELP_PRAEFIX']="Το πρόθεμα είναι ένα αλφαριθμητικό στην αρχή του ονόματος πίνακα, που λειτουργεί σαν φίλτρο.";
-$lang['L_HELP_ZIP']="Συμπίεση με GZip - προτεινόμενη κατάσταση 'ενεργό'";
-$lang['L_HELP_MEMORYLIMIT']="Το μέγιστο μέγεθος μνήμης σε Bytes για το script
-0 = ανενεργό";
-$lang['L_MEMORY_LIMIT']="Οριο μνήμης";
-$lang['L_HELP_AD1']="Αν ενεργοποιηθεί, τα αντίγραφα ασφαλείας θα διαγράφονται αυτόματα.";
-$lang['L_HELP_AD3']="Ο μέγιστος αριθμός των αρχείων αντιγράφων ασφαλείας (για αυτόματη διαγραφή)
-0 = ανενεργό";
-$lang['L_HELP_LANG']="επιλέξτε τη γλώσσα σας";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Για να εξαφανίσετε άχρηστα δεδομένα επιλέξτε το άδειασμα της Β.Δεδομένων πριν την επαναφορά";
-$lang['L_HELP_CRONEXTENDER']="Η κατάληξη του Perl scripts, προεπιλογή είναι '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="Το όνομα του αρχείου ρύθμισης για το Perl script";
-$lang['L_HELP_CRONPRINTOUT']="Αν απενεργοποιηθεί δε θα προβάλλεται έξοδος στην οθόνη.
-Είναι ανεξάρτητο από την έξοδο στο αρχείο καταγραφών.";
-$lang['L_HELP_CRONSAMEDB']="Χρήση ίδιας Β.Δεδομένων στο Cron job όπως ρυθμίστηκε στη Β.Δεδομένων?";
-$lang['L_HELP_CRONDBINDEX']="επιλέξτε τη Β.Δεδομένων για το Cron job";
-$lang['L_HELP_FTPTRANSFER']="αν είναι ενεργό, το αρχείο θα αποστέλεται με FTP.";
-$lang['L_HELP_FTPSERVER']="Διεύθυνση του διακομιστή FTP";
-$lang['L_HELP_FTPPORT']="Θύρα του διακομιστή FTP, προεπιλογή: 21";
-$lang['L_HELP_FTPUSER']="Δώστε όνομα χρήστη για το FTP";
-$lang['L_HELP_FTPPASS']="Δώστε κωδικό για το FTP";
-$lang['L_HELP_FTPDIR']="Που βρίσκεται ο κατάλογος φόρτωσης? δώστε διαδρομή!";
-$lang['L_HELP_SPEED']="Ελάχιστη και μέγιστη ταχύτητα, προεπιλογή είναι 50 εως 5000";
-$lang['L_SPEED']="Ελεγχος ταχύτητας";
-$lang['L_HELP_CRONEXECPATH']="Η τοποθεσία των Perl scripts.
+
+$lang['L_HELP_DB'] = 'Αυτή είναι μια λίστα με Β.Δεδομένων';
+$lang['L_HELP_PRAEFIX'] = 'Το πρόθεμα είναι ένα αλφαριθμητικό στην αρχή του ονόματος πίνακα, που λειτουργεί σαν φίλτρο.';
+$lang['L_HELP_ZIP'] = "Συμπίεση με GZip - προτεινόμενη κατάσταση 'ενεργό'";
+$lang['L_HELP_MEMORYLIMIT'] = 'Το μέγιστο μέγεθος μνήμης σε Bytes για το script
+0 = ανενεργό';
+$lang['L_MEMORY_LIMIT'] = 'Οριο μνήμης';
+$lang['L_HELP_AD1'] = 'Αν ενεργοποιηθεί, τα αντίγραφα ασφαλείας θα διαγράφονται αυτόματα.';
+$lang['L_HELP_AD3'] = 'Ο μέγιστος αριθμός των αρχείων αντιγράφων ασφαλείας (για αυτόματη διαγραφή)
+0 = ανενεργό';
+$lang['L_HELP_LANG'] = 'επιλέξτε τη γλώσσα σας';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Για να εξαφανίσετε άχρηστα δεδομένα επιλέξτε το άδειασμα της Β.Δεδομένων πριν την επαναφορά';
+$lang['L_HELP_CRONEXTENDER'] = "Η κατάληξη του Perl scripts, προεπιλογή είναι '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'Το όνομα του αρχείου ρύθμισης για το Perl script';
+$lang['L_HELP_CRONPRINTOUT'] = 'Αν απενεργοποιηθεί δε θα προβάλλεται έξοδος στην οθόνη.
+Είναι ανεξάρτητο από την έξοδο στο αρχείο καταγραφών.';
+$lang['L_HELP_CRONSAMEDB'] = 'Χρήση ίδιας Β.Δεδομένων στο Cron job όπως ρυθμίστηκε στη Β.Δεδομένων?';
+$lang['L_HELP_CRONDBINDEX'] = 'επιλέξτε τη Β.Δεδομένων για το Cron job';
+$lang['L_HELP_FTPTRANSFER'] = 'αν είναι ενεργό, το αρχείο θα αποστέλεται με FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Διεύθυνση του διακομιστή FTP';
+$lang['L_HELP_FTPPORT'] = 'Θύρα του διακομιστή FTP, προεπιλογή: 21';
+$lang['L_HELP_FTPUSER'] = 'Δώστε όνομα χρήστη για το FTP';
+$lang['L_HELP_FTPPASS'] = 'Δώστε κωδικό για το FTP';
+$lang['L_HELP_FTPDIR'] = 'Που βρίσκεται ο κατάλογος φόρτωσης? δώστε διαδρομή!';
+$lang['L_HELP_SFTPTRANSFER'] = 'αν είναι ενεργό, το αρχείο θα αποστέλεται με SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Διεύθυνση του διακομιστή SFTP';
+$lang['L_HELP_SFTPPORT'] = 'Θύρα του διακομιστή SFTP, προεπιλογή: 22';
+$lang['L_HELP_SFTPUSER'] = 'Δώστε όνομα χρήστη για το SFTP';
+$lang['L_HELP_SFTPPASS'] = 'Δώστε κωδικό για το SFTP';
+$lang['L_HELP_SFTPDIR'] = 'Που βρίσκεται ο κατάλογος φόρτωσης? δώστε διαδρομή!';
+$lang['L_HELP_SPEED'] = 'Ελάχιστη και μέγιστη ταχύτητα, προεπιλογή είναι 50 εως 5000';
+$lang['L_SPEED'] = 'Ελεγχος ταχύτητας';
+$lang['L_HELP_CRONEXECPATH'] = 'Η τοποθεσία των Perl scripts.
  Σημείο εκκίνησης είναι η διεύθυνση HTTP (όπως η διευθύνσεις στον πλοηγό)
-Επιτρεπόμενα είναι εισαγωγές απόλυτες ή σχετικές.";
-$lang['L_CRON_EXECPATH']="Διαδρομή των Perl scripts";
-$lang['L_HELP_CRONCOMPLETELOG']="Οταν ενεργοποιηθεί, η πλήρης έξοδος γράφεται στο complete_log-file.
-Είναι ανεξάρτητο από την προβολή κειμένου";
-$lang['L_HELP_FTP_MODE']="Οταν συμβούν προβλήματα κατά την μεταφορά μέσω FTP, δοκιμάστε τη χρήση passive mode.
-
-
-";
-
-
-?>
\ No newline at end of file
+Επιτρεπόμενα είναι εισαγωγές απόλυτες ή σχετικές.';
+$lang['L_CRON_EXECPATH'] = 'Διαδρομή των Perl scripts';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Οταν ενεργοποιηθεί, η πλήρης έξοδος γράφεται στο complete_log-file.
+Είναι ανεξάρτητο από την προβολή κειμένου';
+$lang['L_HELP_FTP_MODE'] = 'Οταν συμβούν προβλήματα κατά την μεταφορά μέσω FTP, δοκιμάστε τη χρήση passive mode.';
diff --git a/msd/language/el/lang_install.php b/msd/language/el/lang_install.php
index cd79727b..2d24665e 100644
--- a/msd/language/el/lang_install.php
+++ b/msd/language/el/lang_install.php
@@ -1,92 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Η εγκατάσταση ολοκληρώθηκε  --> <a href=\"index.php\">εκκίνηση MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Πίσω στο κυρίως μενού";
-$lang['L_INSTALLMENU']="Κυρίως μενού";
-$lang['L_STEP']="Βήμα";
-$lang['L_INSTALL']="Εγκατάσταση";
-$lang['L_UNINSTALL']="Απεγκατάσταση";
-$lang['L_TOOLS']="Εργαλεία";
-$lang['L_EDITCONF']="Επεξεργασία ρύθμισης";
-$lang['L_OSWEITER']="Συνέχεια χωρίς αποθήκευση";
-$lang['L_ERRORMAN']="<strong>Σφάλμα κατά την αποθήκευση της ρύθμισης!</strong><br>Παρακαλώ επεξεργαστείτε το αρχείο ";
-$lang['L_MANUELL']="χειροκίνητα";
-$lang['L_CREATEDIRS']="Δημιουργία Καταλόγων";
-$lang['L_INSTALL_CONTINUE']="Συνεχίστε την εγκατάσταση";
-$lang['L_CONNECTTOMYSQL']="Σύνδεση με MySQL ";
-$lang['L_DBPARAMETER']="Παράμετροι Β.Δεδομένων";
-$lang['L_CONFIGNOTWRITABLE']="Δεν μπορώ να γράψω στο αρχείο \"config.php\".
-Παρακαλώ χρησιμοποιήστε το πρόγραμμα FTP και αλλάξτε το chmod του αρχείου σε 0777.";
-$lang['L_DBCONNECTION']="Σύνδεση Β.Δεδομένων";
-$lang['L_CONNECTIONERROR']="Σφάλμα: αδυναμία σύνδεσης.";
-$lang['L_CONNECTION_OK']="Η σύνδεση με τη Β.Δεδομένων είναι επιτυχής.";
-$lang['L_SAVEANDCONTINUE']="Αποθήκευση και συνέχεια με την εγκατάσταση";
-$lang['L_CONFBASIC']="Βασικές παράμετροι";
-$lang['L_INSTALL_STEP2FINISHED']="Οι παράμετροι Β.Δεδομένων αποθηκεύτηκαν επιτυχώς.";
-$lang['L_INSTALL_STEP2_1']="Συνέχεια εγκατάστασης με τις προεπιλεγμένες ρυθμίσεις";
-$lang['L_LASTSTEP']="Τέλος εγκατάστασης";
-$lang['L_FTPMODE']="Δημιουργία απαραίτητων καταλόγων σε ασφαλή λειτουργία";
-$lang['L_IDOMANUAL']="Δημιουργώ τους καταλόγους μόνος μου";
-$lang['L_DOFROM']="εκκίνηση από";
-$lang['L_FTPMODE2']="Δημιουργία καταλόγων με FTP:";
-$lang['L_CONNECT']="σύνδεση";
-$lang['L_DIRS_CREATED']="Οι κατάλογοι δημιουργήθηκαν και δώθηκαν οι απαραίτητες προσβάσεις.";
-$lang['L_CONNECT_TO']="σύνδεση με";
-$lang['L_CHANGEDIR']="αλλαγή σε κατάλογο";
-$lang['L_CHANGEDIRERROR']="η αλλαγή σε κατάλογο δεν έγινε";
-$lang['L_FTP_OK']="Οι παράμετροι FTP είναι εντάξει";
-$lang['L_CREATEDIRS2']="Δημιουργία καταλόγων";
-$lang['L_FTP_NOTCONNECTED']="Η σύνδεση FTP δεν έγινε!";
-$lang['L_CONNWITH']="Σύνδεση με";
-$lang['L_ASUSER']="όπως χρήστη";
-$lang['L_NOTPOSSIBLE']="δε γίνεται";
-$lang['L_DIRCR1']="δημιουργία καταλόγου work";
-$lang['L_DIRCR2']="δημιουργία καταλόγου backup";
-$lang['L_DIRCR4']="δημιουργία καταλόγου log";
-$lang['L_DIRCR5']="δημιουργία καταλόγου configuration";
-$lang['L_INDIR']="τώρα στον κατάλογο";
-$lang['L_CHECK_DIRS']="Ελεγχος καταλόγων";
-$lang['L_DISABLEDFUNCTIONS']="Ανενεργές λειτουργίες";
-$lang['L_NOFTPPOSSIBLE']="Δεν έχετε λειτουργίες FTP !";
-$lang['L_NOGZPOSSIBLE']="Δεν έχετε λειτουργίες συμπίεσης !";
-$lang['L_UI1']="Ολοι οι κατάλογοι που μπορεί να περιέχουν αντίγραφα ασφαλείας θα διαγραφούν.";
-$lang['L_UI2']="Το θέλετε σίγουρα?";
-$lang['L_UI3']="Οχι, ακύρωσε το αμέσως";
-$lang['L_UI4']="Ναι, παρακαλώ συνέχισε";
-$lang['L_UI5']="διαγραφή καταλόγων λειτουργίας";
-$lang['L_UI6']="όλα διαγράφηκαν επιτυχώς.";
-$lang['L_UI7']="Παρακαλώ διαγράψτε τον κατάλογο script";
-$lang['L_UI8']="ένα επίπεδο πάνω";
-$lang['L_UI9']="Ενα Σφάλμα δεν επιτρέπει τη διαγραφή</p>Σφάλμα με τον κατάλογο ";
-$lang['L_IMPORT']="Εισαγωγή ρυθμίσεων";
-$lang['L_IMPORT3']="Οι ρυθμίσεις φορτώθηκαν ...";
-$lang['L_IMPORT4']="Οι ρυθμίσεις αποθηκεύτηκαν.";
-$lang['L_IMPORT5']="Εκκίνηση MySQLDumper";
-$lang['L_IMPORT6']="Μενού εγκατάστασης";
-$lang['L_IMPORT7']="Φόρτωση ρυθμίσεων";
-$lang['L_IMPORT8']="πίσω σε φόρτωση";
-$lang['L_IMPORT9']="Αυτό δεν είναι αντίγραφο ασφαλείας ρυθμίσεων !";
-$lang['L_IMPORT10']="Οι ρυθμίσεις φορτώθηκαν κανονικά ...";
-$lang['L_IMPORT11']="<strong>Σφάλμα: </strong>Εμφανίστηκε πρόβλημα στην εγγραφή του sql_statements";
-$lang['L_IMPORT12']="<strong>Σφάλμα: </strong>Εμφανίστηκε πρόβλημα στην εγγραφή του config.php";
-$lang['L_INSTALL_HELP_PORT']="(άδειο = προεπιλεγμένη θύρα)";
-$lang['L_INSTALL_HELP_SOCKET']="(άδειο = προεπιλεγμένο Socket)";
-$lang['L_TRYAGAIN']="Δοκιμάστε πάλι";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Θύρα";
-$lang['L_FOUND_DB']="βρέθηκε Β.Δ.";
-$lang['L_FM_FILEUPLOAD']="Φόρτωση αρχείου";
-$lang['L_PASS']="Κωδικός";
-$lang['L_NO_DB_FOUND_INFO']="Η σύνδεση με τη Β.Δεδομένων έγινε επιτυχώς.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>Η εγκατάσταση ολοκληρώθηκε  --> <a href="index.php">εκκίνηση MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Πίσω στο κυρίως μενού';
+$lang['L_INSTALLMENU'] = 'Κυρίως μενού';
+$lang['L_STEP'] = 'Βήμα';
+$lang['L_INSTALL'] = 'Εγκατάσταση';
+$lang['L_UNINSTALL'] = 'Απεγκατάσταση';
+$lang['L_TOOLS'] = 'Εργαλεία';
+$lang['L_EDITCONF'] = 'Επεξεργασία ρύθμισης';
+$lang['L_OSWEITER'] = 'Συνέχεια χωρίς αποθήκευση';
+$lang['L_ERRORMAN'] = '<strong>Σφάλμα κατά την αποθήκευση της ρύθμισης!</strong><br>Παρακαλώ επεξεργαστείτε το αρχείο ';
+$lang['L_MANUELL'] = 'χειροκίνητα';
+$lang['L_CREATEDIRS'] = 'Δημιουργία Καταλόγων';
+$lang['L_INSTALL_CONTINUE'] = 'Συνεχίστε την εγκατάσταση';
+$lang['L_CONNECTTOMYSQL'] = 'Σύνδεση με MySQL ';
+$lang['L_DBPARAMETER'] = 'Παράμετροι Β.Δεδομένων';
+$lang['L_CONFIGNOTWRITABLE'] = 'Δεν μπορώ να γράψω στο αρχείο "config.php".
+Παρακαλώ χρησιμοποιήστε το πρόγραμμα FTP και αλλάξτε το chmod του αρχείου σε 0777.';
+$lang['L_DBCONNECTION'] = 'Σύνδεση Β.Δεδομένων';
+$lang['L_CONNECTIONERROR'] = 'Σφάλμα: αδυναμία σύνδεσης.';
+$lang['L_CONNECTION_OK'] = 'Η σύνδεση με τη Β.Δεδομένων είναι επιτυχής.';
+$lang['L_SAVEANDCONTINUE'] = 'Αποθήκευση και συνέχεια με την εγκατάσταση';
+$lang['L_CONFBASIC'] = 'Βασικές παράμετροι';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Οι παράμετροι Β.Δεδομένων αποθηκεύτηκαν επιτυχώς.';
+$lang['L_INSTALL_STEP2_1'] = 'Συνέχεια εγκατάστασης με τις προεπιλεγμένες ρυθμίσεις';
+$lang['L_LASTSTEP'] = 'Τέλος εγκατάστασης';
+$lang['L_FTPMODE'] = 'Δημιουργία απαραίτητων καταλόγων σε ασφαλή λειτουργία';
+$lang['L_IDOMANUAL'] = 'Δημιουργώ τους καταλόγους μόνος μου';
+$lang['L_DOFROM'] = 'εκκίνηση από';
+$lang['L_FTPMODE2'] = 'Δημιουργία καταλόγων με FTP:';
+$lang['L_CONNECT'] = 'σύνδεση';
+$lang['L_DIRS_CREATED'] = 'Οι κατάλογοι δημιουργήθηκαν και δώθηκαν οι απαραίτητες προσβάσεις.';
+$lang['L_CONNECT_TO'] = 'σύνδεση με';
+$lang['L_CHANGEDIR'] = 'αλλαγή σε κατάλογο';
+$lang['L_CHANGEDIRERROR'] = 'η αλλαγή σε κατάλογο δεν έγινε';
+$lang['L_FTP_OK'] = 'Οι παράμετροι FTP είναι εντάξει';
+$lang['L_CREATEDIRS2'] = 'Δημιουργία καταλόγων';
+$lang['L_FTP_NOTCONNECTED'] = 'Η σύνδεση FTP δεν έγινε!';
+$lang['L_CONNWITH'] = 'Σύνδεση με';
+$lang['L_ASUSER'] = 'όπως χρήστη';
+$lang['L_NOTPOSSIBLE'] = 'δε γίνεται';
+$lang['L_DIRCR1'] = 'δημιουργία καταλόγου work';
+$lang['L_DIRCR2'] = 'δημιουργία καταλόγου backup';
+$lang['L_DIRCR4'] = 'δημιουργία καταλόγου log';
+$lang['L_DIRCR5'] = 'δημιουργία καταλόγου configuration';
+$lang['L_INDIR'] = 'τώρα στον κατάλογο';
+$lang['L_CHECK_DIRS'] = 'Ελεγχος καταλόγων';
+$lang['L_DISABLEDFUNCTIONS'] = 'Ανενεργές λειτουργίες';
+$lang['L_NOFTPPOSSIBLE'] = 'Δεν έχετε λειτουργίες FTP !';
+$lang['L_NOGZPOSSIBLE'] = 'Δεν έχετε λειτουργίες συμπίεσης !';
+$lang['L_UI1'] = 'Ολοι οι κατάλογοι που μπορεί να περιέχουν αντίγραφα ασφαλείας θα διαγραφούν.';
+$lang['L_UI2'] = 'Το θέλετε σίγουρα?';
+$lang['L_UI3'] = 'Οχι, ακύρωσε το αμέσως';
+$lang['L_UI4'] = 'Ναι, παρακαλώ συνέχισε';
+$lang['L_UI5'] = 'διαγραφή καταλόγων λειτουργίας';
+$lang['L_UI6'] = 'όλα διαγράφηκαν επιτυχώς.';
+$lang['L_UI7'] = 'Παρακαλώ διαγράψτε τον κατάλογο script';
+$lang['L_UI8'] = 'ένα επίπεδο πάνω';
+$lang['L_UI9'] = 'Ενα Σφάλμα δεν επιτρέπει τη διαγραφή</p>Σφάλμα με τον κατάλογο ';
+$lang['L_IMPORT'] = 'Εισαγωγή ρυθμίσεων';
+$lang['L_IMPORT3'] = 'Οι ρυθμίσεις φορτώθηκαν ...';
+$lang['L_IMPORT4'] = 'Οι ρυθμίσεις αποθηκεύτηκαν.';
+$lang['L_IMPORT5'] = 'Εκκίνηση MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Μενού εγκατάστασης';
+$lang['L_IMPORT7'] = 'Φόρτωση ρυθμίσεων';
+$lang['L_IMPORT8'] = 'πίσω σε φόρτωση';
+$lang['L_IMPORT9'] = 'Αυτό δεν είναι αντίγραφο ασφαλείας ρυθμίσεων !';
+$lang['L_IMPORT10'] = 'Οι ρυθμίσεις φορτώθηκαν κανονικά ...';
+$lang['L_IMPORT11'] = '<strong>Σφάλμα: </strong>Εμφανίστηκε πρόβλημα στην εγγραφή του sql_statements';
+$lang['L_IMPORT12'] = '<strong>Σφάλμα: </strong>Εμφανίστηκε πρόβλημα στην εγγραφή του config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(άδειο = προεπιλεγμένη θύρα)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(άδειο = προεπιλεγμένο Socket)';
+$lang['L_TRYAGAIN'] = 'Δοκιμάστε πάλι';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Θύρα';
+$lang['L_FOUND_DB'] = 'βρέθηκε Β.Δ.';
+$lang['L_FM_FILEUPLOAD'] = 'Φόρτωση αρχείου';
+$lang['L_PASS'] = 'Κωδικός';
+$lang['L_NO_DB_FOUND_INFO'] = 'Η σύνδεση με τη Β.Δεδομένων έγινε επιτυχώς.<br>
 Τα δεδομένα χρήστη είναι σωστά και έγιναν αποδεκτά από τον διακομιστή MySQL.<br>
-Αλλά το MySQLDumper δε βρήκε καμία Β.Δεδομένων.<br>
+Αλλά το MyOOS [Dumper] δε βρήκε καμία Β.Δεδομένων.<br>
 Η αυτόματη αναγνώριση μέσω script μπλοκάρεται σε κάποιον διακομιστή.<br>
 Δώστε το όνομα της βάσης σας χειροκίνητα μόλις τελειώσει η εγκατάσταση.
-Καντε κλικ στο \"Ρυθμίσεις\" \"Παράμετροι Σύνδεσης - προβολή\" και δώστε εκεί το όνομα της βάσης σας.";
-$lang['L_SAFEMODEDESC']="Επειδή η PHP τρέχει σε ασφαλή λειτουργία safe_mode πρέπει να δημιουργήσετε τους παρακάτω καταλόγους χειροκίνητα χρησιμοποιώντας το πρόγραμμα FTP:
-
-
-";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+Καντε κλικ στο "Ρυθμίσεις" "Παράμετροι Σύνδεσης - προβολή" και δώστε εκεί το όνομα της βάσης σας.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/el/lang_log.php b/msd/language/el/lang_log.php
index 60a0d7fd..ffb7d244 100644
--- a/msd/language/el/lang_log.php
+++ b/msd/language/el/lang_log.php
@@ -1,11 +1,9 @@
 <?php
-$lang['L_LOG_DELETE']="διαγραφή καταγραφής";
-$lang['L_LOGFILEFORMAT']="μορφή αρχείου καταγραφής";
-$lang['L_LOGFILENOTWRITABLE']="Δε μπορώ να γράψω σε αρχείο καταγραφής !";
-$lang['L_NOREVERSE']="Πρώτα παλιές εγγραφές";
-$lang['L_REVERSE']="Πρώτα τελευταίες εγγραφές
 
-";
+$lang['L_LOG_DELETE'] = 'διαγραφή καταγραφής';
+$lang['L_LOGFILEFORMAT'] = 'μορφή αρχείου καταγραφής';
+$lang['L_LOGFILENOTWRITABLE'] = 'Δε μπορώ να γράψω σε αρχείο καταγραφής !';
+$lang['L_NOREVERSE'] = 'Πρώτα παλιές εγγραφές';
+$lang['L_REVERSE'] = 'Πρώτα τελευταίες εγγραφές
 
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/el/lang_main.php b/msd/language/el/lang_main.php
index 0db80b10..e4230d36 100644
--- a/msd/language/el/lang_main.php
+++ b/msd/language/el/lang_main.php
@@ -1,80 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Δεν έχετε λειτουργίες FTP !";
-$lang['L_INFO_LOCATION']="Η τοποθεσία σας είναι ";
-$lang['L_INFO_DATABASES']="Οι παρακάτω Β.Δεδομένων βρίσκονται στο διακομιστή σας:";
-$lang['L_INFO_NODB']="Η Β.Δεδομένων δεν υπάρχει.";
-$lang['L_INFO_DBDETAIL']="Λεπτομέρειες της Β.Δεδομένων ";
-$lang['L_INFO_DBEMPTY']="Η Β.Δεδομένων είναι άδεια !";
-$lang['L_INFO_RECORDS']="Εγγραφές";
-$lang['L_INFO_SIZE']="Μέγεθος";
-$lang['L_INFO_LASTUPDATE']="Τελευταία ενημέρωση";
-$lang['L_INFO_SUM']="σύνολο";
-$lang['L_INFO_OPTIMIZED']="Βελτιστοποιημένο";
-$lang['L_OPTIMIZE_DATABASES']="Βελτιστοποίηση Πινάκων";
-$lang['L_CHECK_TABLES']="Ελεγχος πινάκων";
-$lang['L_CLEAR_DATABASE']="Εκκαθάριση Β.Δεδομένων";
-$lang['L_DELETE_DATABASE']="Διαγραφή Β.Δεδομένων";
-$lang['L_INFO_CLEARED']="εκκαθαρίστηκε";
-$lang['L_INFO_DELETED']="διαγράφηκε";
-$lang['L_INFO_EMPTYDB1']="Η Β.Δεδομένων";
-$lang['L_INFO_EMPTYDB2']=" να εκκαθαριστεί? (Προσοχή: Ολα τα δεδομένα θα χαθούν για πάντα!)";
-$lang['L_INFO_KILLDB']="να διαγραφεί? (Προσοχή: Ολα τα δεδομένα θα χαθούν για πάντα!)";
-$lang['L_PROCESSKILL1']="Το script προσπαθεί να σταματήσει τη διαδικασία ";
-$lang['L_PROCESSKILL2']="για σταμάτημα.";
-$lang['L_PROCESSKILL3']="Το script προσπαθεί από  ";
-$lang['L_PROCESSKILL4']=" δευτ. για σταμάτημα διαδικασίας ";
-$lang['L_HTACC_CREATE']="Δημιουργία προστασίας καταλόγου";
-$lang['L_ENCRYPTION_TYPE']="Είδος κρυπτογράφησης";
-$lang['L_HTACC_CRYPT']="Crypt (Linux και Unix-Systems)";
-$lang['L_HTACC_MD5']="MD5 (Linux και Unix-Systems)";
-$lang['L_HTACC_NO_ENCRYPTION']="απλό κείμενο, χωρίς κρυπτογράφηση (Windows)";
-$lang['L_HTACCESS8']="Υπάρχει προστασία καταλόγου. Εαν κάνετε νέα, η παλιά θα διαγραφεί !";
-$lang['L_HTACC_NO_USERNAME']="Πρέπει να δώσετε ένα όνομα!";
-$lang['L_PASSWORDS_UNEQUAL']="Οι κωδικοί δεν είναι ίδιοι ή είναι άδειοι !";
-$lang['L_HTACC_CONFIRM_DELETE']="Θέλετε η προστασία καταλόγων να εγγραφεί τώρα ?";
-$lang['L_HTACC_CREATED']="Δημιουργήθηκε προστασία καταλόγων.";
-$lang['L_HTACC_CONTENT']="Περιεχόμενα αρχείου";
-$lang['L_HTACC_CREATE_ERROR']="Παρουσιάστηκε σφάλμα κατά την δημιουργία προστασίας καταλόγου !<br>Παρακαλώ δημιουργήστε τα 2 αρχεία χειροκίνητα με τα παρακάτω περιεχόμενα";
-$lang['L_HTACC_PROPOSED']="Προτείνεται επειγόντως";
-$lang['L_HTACC_EDIT']="Επεξεργασία .htaccess";
-$lang['L_HTACCESS18']="Δημιουργία .htaccess σε ";
-$lang['L_HTACCESS19']="Επαναφόρτωση ";
-$lang['L_HTACCESS20']="Εκτέλεση script";
-$lang['L_HTACCESS21']="Προσθήκη handler";
-$lang['L_HTACCESS22']="Κάνε εκτελέσιμο";
-$lang['L_HTACCESS23']="Λίστα καταλόγου";
-$lang['L_HTACCESS24']="Αρχείο σφαλμάτων";
-$lang['L_HTACCESS25']="Ενεργοποίηση rewrite";
-$lang['L_HTACCESS26']="Επέτρεψε / Απαγόρευσε";
-$lang['L_HTACCESS27']="Ανακατεύθυνση";
-$lang['L_HTACCESS28']="Καταγραφές σφαλμάτων";
-$lang['L_HTACCESS29']="Περισσότερα παραδείγματα και λεπτομέρειες";
-$lang['L_HTACCESS30']="Πάροχος";
-$lang['L_HTACCESS31']="Γενικά";
-$lang['L_HTACCESS32']="Προσοχή! Το .htaccess επηρεάζει άμεσα τη συμπεριφορά του πλοηγού.<br>Με λάθος περιεχόμενο, αυτές οι σελίδες δεν θα είναι προσβάσιμες πλέον.";
-$lang['L_PHPBUG']="Σφάλμα στο zlib ! Δε γίνεται συμπίεση!";
-$lang['L_DISABLEDFUNCTIONS']="Ανενεργές λειτουργίες";
-$lang['L_NOGZPOSSIBLE']="Επειδή το Zlib δεν είναι εγκατεστημένο, δε μπορείτε να κάνετε χρήση του GZip!";
-$lang['L_DELETE_HTACCESS']="Κατάργηση προστασίας καταλόγου (διαγραφή .htaccess)";
-$lang['L_WRONG_RIGHTS']="Το αρχείο ή ο κατάλογος '%s' δεν είναι εγγράψιμος.<br>
+
+$lang['L_NOFTPPOSSIBLE'] = 'Δεν έχετε λειτουργίες FTP !';
+$lang['L_INFO_LOCATION'] = 'Η τοποθεσία σας είναι ';
+$lang['L_INFO_DATABASES'] = 'Οι παρακάτω Β.Δεδομένων βρίσκονται στο διακομιστή σας:';
+$lang['L_INFO_NODB'] = 'Η Β.Δεδομένων δεν υπάρχει.';
+$lang['L_INFO_DBDETAIL'] = 'Λεπτομέρειες της Β.Δεδομένων ';
+$lang['L_INFO_DBEMPTY'] = 'Η Β.Δεδομένων είναι άδεια !';
+$lang['L_INFO_RECORDS'] = 'Εγγραφές';
+$lang['L_INFO_SIZE'] = 'Μέγεθος';
+$lang['L_INFO_LASTUPDATE'] = 'Τελευταία ενημέρωση';
+$lang['L_INFO_SUM'] = 'σύνολο';
+$lang['L_INFO_OPTIMIZED'] = 'Βελτιστοποιημένο';
+$lang['L_OPTIMIZE_DATABASES'] = 'Βελτιστοποίηση Πινάκων';
+$lang['L_CHECK_TABLES'] = 'Ελεγχος πινάκων';
+$lang['L_CLEAR_DATABASE'] = 'Εκκαθάριση Β.Δεδομένων';
+$lang['L_DELETE_DATABASE'] = 'Διαγραφή Β.Δεδομένων';
+$lang['L_INFO_CLEARED'] = 'εκκαθαρίστηκε';
+$lang['L_INFO_DELETED'] = 'διαγράφηκε';
+$lang['L_INFO_EMPTYDB1'] = 'Η Β.Δεδομένων';
+$lang['L_INFO_EMPTYDB2'] = ' να εκκαθαριστεί? (Προσοχή: Ολα τα δεδομένα θα χαθούν για πάντα!)';
+$lang['L_INFO_KILLDB'] = 'να διαγραφεί? (Προσοχή: Ολα τα δεδομένα θα χαθούν για πάντα!)';
+$lang['L_PROCESSKILL1'] = 'Το script προσπαθεί να σταματήσει τη διαδικασία ';
+$lang['L_PROCESSKILL2'] = 'για σταμάτημα.';
+$lang['L_PROCESSKILL3'] = 'Το script προσπαθεί από  ';
+$lang['L_PROCESSKILL4'] = ' δευτ. για σταμάτημα διαδικασίας ';
+$lang['L_HTACC_CREATE'] = 'Δημιουργία προστασίας καταλόγου';
+$lang['L_ENCRYPTION_TYPE'] = 'Είδος κρυπτογράφησης';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Υπάρχει προστασία καταλόγου. Εαν κάνετε νέα, η παλιά θα διαγραφεί !';
+$lang['L_HTACC_NO_USERNAME'] = 'Πρέπει να δώσετε ένα όνομα!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Οι κωδικοί δεν είναι ίδιοι ή είναι άδειοι !';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Θέλετε η προστασία καταλόγων να εγγραφεί τώρα ?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'Δημιουργήθηκε προστασία καταλόγων.';
+$lang['L_HTACC_CONTENT'] = 'Περιεχόμενα αρχείου';
+$lang['L_HTACC_CREATE_ERROR'] = 'Παρουσιάστηκε σφάλμα κατά την δημιουργία προστασίας καταλόγου !<br>Παρακαλώ δημιουργήστε τα 2 αρχεία χειροκίνητα με τα παρακάτω περιεχόμενα';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'Προτείνεται επειγόντως';
+$lang['L_HTACC_EDIT'] = 'Επεξεργασία .htaccess';
+$lang['L_HTACCESS18'] = 'Δημιουργία .htaccess σε ';
+$lang['L_HTACCESS19'] = 'Επαναφόρτωση ';
+$lang['L_HTACCESS20'] = 'Εκτέλεση script';
+$lang['L_HTACCESS21'] = 'Προσθήκη handler';
+$lang['L_HTACCESS22'] = 'Κάνε εκτελέσιμο';
+$lang['L_HTACCESS23'] = 'Λίστα καταλόγου';
+$lang['L_HTACCESS24'] = 'Αρχείο σφαλμάτων';
+$lang['L_HTACCESS25'] = 'Ενεργοποίηση rewrite';
+$lang['L_HTACCESS26'] = 'Επέτρεψε / Απαγόρευσε';
+$lang['L_HTACCESS27'] = 'Ανακατεύθυνση';
+$lang['L_HTACCESS28'] = 'Καταγραφές σφαλμάτων';
+$lang['L_HTACCESS29'] = 'Περισσότερα παραδείγματα και λεπτομέρειες';
+$lang['L_HTACCESS30'] = 'Πάροχος';
+$lang['L_HTACCESS31'] = 'Γενικά';
+$lang['L_HTACCESS32'] = 'Προσοχή! Το .htaccess επηρεάζει άμεσα τη συμπεριφορά του πλοηγού.<br>Με λάθος περιεχόμενο, αυτές οι σελίδες δεν θα είναι προσβάσιμες πλέον.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Ανενεργές λειτουργίες';
+$lang['L_NOGZPOSSIBLE'] = 'Επειδή το Zlib δεν είναι εγκατεστημένο, δε μπορείτε να κάνετε χρήση του GZip!';
+$lang['L_DELETE_HTACCESS'] = 'Κατάργηση προστασίας καταλόγου (διαγραφή .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "Το αρχείο ή ο κατάλογος '%s' δεν είναι εγγράψιμος.<br>
 Τα δικαιώματα (chmod) δε ρυθμίστηκαν σωστά ή έχουν λάθος ιδιοκτήτη.<br>
 Δώστε τις σωστές ιδιότητες χρησιμοποιώντας το πρόγραμμα FTP.<br>
 Το αρχείο ή ο κατάλογος πρέπει να ρυθμιστεί σε %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Δε δημιουργήθηκε κατάλογος '%s'. 
-Δημιουργήστε τον χρησιμοποιώντας το πρόγραμμα FTP.
-
-";
-$lang['L_TABLE_TYPE']="Τύπος";
-$lang['L_CHECK']="έλεγχος";
-$lang['L_HTACC_SHA1']="SHA1(όλα τα συστήματα)";
-$lang['L_OS']="Λειτουργικό Σύστημα";
-$lang['L_MSD_VERSION']="Εκδοση MySQLDumper";
-$lang['L_MYSQL_VERSION']="Εκδοση MySQL";
-$lang['L_PHP_VERSION']="Εκδοση PHP";
-$lang['L_MAX_EXECUTION_TIME']="Μεγ. χρόνος εκτέλεσης";
-$lang['L_PHP_EXTENSIONS']="Επεκτάσεις PHP";
-$lang['L_MEMORY']="Μνήμη";
-$lang['L_FILE_MISSING']="δε βρέθηκε το αρχείο";
-
-
-?>
\ No newline at end of file
+$lang['L_CANT_CREATE_DIR'] = "Δε δημιουργήθηκε κατάλογος '%s'. 
+Δημιουργήστε τον χρησιμοποιώντας το πρόγραμμα FTP.";
+$lang['L_TABLE_TYPE'] = 'Τύπος';
+$lang['L_CHECK'] = 'έλεγχος';
+$lang['L_OS'] = 'Λειτουργικό Σύστημα';
+$lang['L_MOD_VERSION'] = 'Εκδοση MyOOS [Dumper]';
+$lang['L_NEW_MOD_VERSION'] = 'Νέα έκδοση';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'Μια νέα έκδοση του MyOOS [Dumper] είναι διαθέσιμη.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'Εκδοση MySQL';
+$lang['L_PHP_VERSION'] = 'Εκδοση PHP';
+$lang['L_MAX_EXECUTION_TIME'] = 'Μεγ. χρόνος εκτέλεσης';
+$lang['L_PHP_EXTENSIONS'] = 'Επεκτάσεις PHP';
+$lang['L_MEMORY'] = 'Μνήμη';
+$lang['L_FILE_MISSING'] = 'δε βρέθηκε το αρχείο';
+$lang['L_INSTALLING_UPDATES'] = 'Εγκατάσταση ενημερώσεων';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Επιτυχής ενημέρωση';
+$lang['L_UPDATE_FAILED'] = 'Αποτυχημένη ενημέρωση';
+$lang['L_UP_TO_DATE'] = 'Η τρέχουσα έκδοση είναι ενημερωμένη';
diff --git a/msd/language/el/lang_restore.php b/msd/language/el/lang_restore.php
index 23cf58e2..8c632b0b 100644
--- a/msd/language/el/lang_restore.php
+++ b/msd/language/el/lang_restore.php
@@ -1,24 +1,22 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="μέχρι τώρα δημιουργήθηκαν <b>%d</b> πίνακες.";
-$lang['L_FILE_MISSING']="δε βρέθηκε το αρχείο";
-$lang['L_RESTORE_DB']="Β.Δεδομένων '<b>%s</b>' σε '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> πίνακες δημιουργήθηκαν.";
-$lang['L_RESTORE_RUN1']="<br>Μέχρι τώρα  <b>%s</b> από <b>%s</b> εγγραφές έχουν προστεθεί.";
-$lang['L_RESTORE_RUN2']="<br>Τώρα ο πίνακας '<b>%s</b>' επαναφέρεται.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> εγγραφές έχουν εισαχθεί.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Μέχρι τώρα <b>%d</b> από <b>%d</b> πίνακες δημιουργήθηκαν.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Συγχαρητήρια.</b><br><br>Εγινε η επαναφορά της Β.Δεδομένων.<br>Ολα τα δεδομένα απο το Αντίγραφο Ασφαλείας έχουν επαναφερθεί.<br><br>Ολα ολοκληρώθηκαν. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Σφάλμα:<br>Επιλογή Β.Δεδομένων <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> απέτυχε!";
-$lang['L_FILE_OPEN_ERROR']="Σφάλμα: δεν μπόρεσα να ανοίξω το αρχείο.";
-$lang['L_PROGRESS_OVER_ALL']="Γενική πρόοδος";
-$lang['L_BACK_TO_OVERVIEW']="Προεπισκόπιση Β.Δεδομένων";
-$lang['L_RESTORE_RUN0']="<br>Μέχρι τώρα <b>%s</b> εγγραφές έχουν προστεθεί.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Αγνωστη εντολή SQL";
-$lang['L_NOTICES']="Σημειώσεις
+
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'μέχρι τώρα δημιουργήθηκαν <b>%d</b> πίνακες.';
+$lang['L_FILE_MISSING'] = 'δε βρέθηκε το αρχείο';
+$lang['L_RESTORE_DB'] = "Β.Δεδομένων '<b>%s</b>' σε '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> πίνακες δημιουργήθηκαν.';
+$lang['L_RESTORE_RUN1'] = '<br>Μέχρι τώρα  <b>%s</b> από <b>%s</b> εγγραφές έχουν προστεθεί.';
+$lang['L_RESTORE_RUN2'] = "<br>Τώρα ο πίνακας '<b>%s</b>' επαναφέρεται.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> εγγραφές έχουν εισαχθεί.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Μέχρι τώρα <b>%d</b> από <b>%d</b> πίνακες δημιουργήθηκαν.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Συγχαρητήρια.</b><br><br>Εγινε η επαναφορά της Β.Δεδομένων.<br>Ολα τα δεδομένα απο το Αντίγραφο Ασφαλείας έχουν επαναφερθεί.<br><br>Ολα ολοκληρώθηκαν. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>Σφάλμα:<br>Επιλογή Β.Δεδομένων <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> απέτυχε!';
+$lang['L_FILE_OPEN_ERROR'] = 'Σφάλμα: δεν μπόρεσα να ανοίξω το αρχείο.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Γενική πρόοδος';
+$lang['L_BACK_TO_OVERVIEW'] = 'Προεπισκόπιση Β.Δεδομένων';
+$lang['L_RESTORE_RUN0'] = '<br>Μέχρι τώρα <b>%s</b> εγγραφές έχουν προστεθεί.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Αγνωστη εντολή SQL';
+$lang['L_NOTICES'] = 'Σημειώσεις
 
 
-";
-
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/el/lang_sql.php b/msd/language/el/lang_sql.php
index 299594b4..27b43a47 100644
--- a/msd/language/el/lang_sql.php
+++ b/msd/language/el/lang_sql.php
@@ -1,194 +1,190 @@
 <?php
-$lang['L_COMMAND']="Εντολή";
-$lang['L_IMPORT_NOTABLE']="Δεν επιλέχθηκε πίνακας για εισαγωγή!";
-$lang['L_PASSWORD_STRENGTH']="Ισχύς κωδικού";
-$lang['L_SQL_WARNING']="Η εκτέλεση των εντολών SQL μπορεί να τροποποιήσει δεδομένα. ΠΡΟΣΟΧΗ! Ο δημιουργός δε φέρει καμία απολύτως ευθύνη για καταστροφή ή απώλεια δεδομένων.";
-$lang['L_SQL_EXEC']="Εκτέλεση εντολής SQL";
-$lang['L_SQL_DATAVIEW']="Προβολή δεδομένων";
-$lang['L_SQL_TABLEVIEW']="Προβολή πίνακα";
-$lang['L_SQL_VONINS']="από τελείως";
-$lang['L_SQL_NODATA']="καμία εγγραφή";
-$lang['L_SQL_RECORDUPDATED']="Εγγραφή αναβαθμίστηκε";
-$lang['L_SQL_RECORDINSERTED']="Εγγραφή προστέθηκε";
-$lang['L_SQL_BACKDBOVERVIEW']="Πίσω στην επισκόπηση";
-$lang['L_SQL_RECORDDELETED']="Εγγραφή διαγράφηκε";
-$lang['L_ASKTABLEEMPTY']="Να αδειάσει ο πίνακας `%s`?";
-$lang['L_SQL_RECORDEDIT']="επεξεργασία εγγραφής";
-$lang['L_SQL_RECORDNEW']="νέα εγγραφή";
-$lang['L_ASKDELETERECORD']="Θέλετε να διαγραφεί η εγγραφή?";
-$lang['L_ASKDELETETABLE']="Να διαγραφεί ο πίνακας `%s` ?";
-$lang['L_SQL_BEFEHLE']="Εντολές SQL";
-$lang['L_SQL_BEFEHLNEU']="Νέα εντολή";
-$lang['L_SQL_BEFEHLSAVED1']="Εντολή SQL";
-$lang['L_SQL_BEFEHLSAVED2']="προστέθηκε";
-$lang['L_SQL_BEFEHLSAVED3']="αποθηκεύθηκε";
-$lang['L_SQL_BEFEHLSAVED4']="μετακινήθηκε";
-$lang['L_SQL_BEFEHLSAVED5']="διαγράφηκε";
-$lang['L_SQL_QUERYENTRY']="Η αναζήτηση περιλαμβάνει";
-$lang['L_SQL_COLUMNS']="Στήλες";
-$lang['L_ASKDBDELETE']="Θέλετε να διαγραφεί η Β.Δεδομένων `%s` με το περιεχόμενο?";
-$lang['L_ASKDBEMPTY']="Θέλετε να αδειάσει η Β.Δεδομένων `%s` ?";
-$lang['L_ASKDBCOPY']="Θέλετε να αντιγραφεί η Β.Δεδομένων `%s` στη Β.Δεδομένων `%s`?";
-$lang['L_SQL_TABLENEW']="Επεξεργασία πινάκων";
-$lang['L_SQL_OUTPUT']="Εξοδος SQL";
-$lang['L_DO_NOW']="λειτούργησε τώρα";
-$lang['L_SQL_NAMEDEST_MISSING']="Λείπει το όνομα προορισμού !";
-$lang['L_ASKDELETEFIELD']="Να διαγραφεί το πεδίο?";
-$lang['L_SQL_COMMANDS_IN']=" γραμμές σε ";
-$lang['L_SQL_COMMANDS_IN2']="   δευτ. χρειάστηκαν.";
-$lang['L_SQL_OUT1']="Εκτελέστηκε ";
-$lang['L_SQL_OUT2']="Εντολές";
-$lang['L_SQL_OUT3']="Είχε ";
-$lang['L_SQL_OUT4']="Σχόλια";
-$lang['L_SQL_OUT5']="Επειδή η έξοδος έχει πάνω από 5000 γραμμές δε θα προβληθεί.";
-$lang['L_SQL_SELECDB']="Επιλογή Β.Δεδομένων";
-$lang['L_SQL_TABLESOFDB']="Πίνακες της Β.Δεδομένων";
-$lang['L_SQL_EDIT']="επεξεργασία";
-$lang['L_SQL_NOFIELDDELETE']="Η διαγραφή δεν είναι δυνατή επειδή ο πίνακας πρέπει να έχει τουλάχιστον ένα πεδίο.";
-$lang['L_SQL_FIELDDELETE1']="Το πεδίο";
-$lang['L_SQL_DELETED']="διαγράφηκε";
-$lang['L_SQL_CHANGED']="άλλαξε.";
-$lang['L_SQL_CREATED']="δημιουργήθηκε.";
-$lang['L_SQL_NODEST_COPY']="Καμία αντιγραφή χωρίς προορισμό !";
-$lang['L_SQL_DESTTABLE_EXISTS']="Ο πίνακας προορισμού υπάρχει !";
-$lang['L_SQL_SCOPY']="Η δομή του πίνακα `%s` αντιγράφηκε στον πίνακα `%s`.";
-$lang['L_SQL_TCOPY']="Ο πίνακας `%s` αντιγράφηκε με δεδομένα στον πίνακα `%s`.";
-$lang['L_SQL_TABLENONAME']="Ο πίνακας χρειάζεται ένα όνομα!";
-$lang['L_SQL_TBLNAMEEMPTY']="Το όνομα του πίνακα δεν μπορεί να είναι κενό!";
-$lang['L_SQL_COLLATENOTMATCH']="Σετ χαρακτήρων και Collation δεν ταιριάζουν!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Σφάλμα: Ακυρο όνομα πεδίου";
-$lang['L_SQL_CREATETABLE']="δημιουργία πίνακα";
-$lang['L_SQL_COPYTABLE']="αντιγραφή πίνακα";
-$lang['L_SQL_STRUCTUREONLY']="Μόνο δομή";
-$lang['L_SQL_STRUCTUREDATA']="Δομή και Δεδομένα";
-$lang['L_SQL_NOTABLESINDB']="Δε βρέθηκαν πίνακες στη Β.Δεδομένων";
-$lang['L_SQL_SELECTTABLE']="επιλογή πίνακα";
-$lang['L_SQL_SHOWDATATABLE']="Προβολή δεδομένων του πίνακα";
-$lang['L_SQL_TBLPROPSOF']="Ιδιότητες πίνακα από";
-$lang['L_SQL_EDITFIELD']="επεξεργασία πεδίου";
-$lang['L_SQL_NEWFIELD']="Νέο πεδίο";
-$lang['L_SQL_INDEXES']="Ευρετήρια";
-$lang['L_SQL_ATPOSITION']="εισαγωγή στη θέση";
-$lang['L_SQL_FIRST']="πρώτο";
-$lang['L_SQL_AFTER']="μετά";
-$lang['L_SQL_CHANGEFIELD']="αλλαγή πεδίου";
-$lang['L_SQL_INSERTFIELD']="εισαγωγή πεδίου";
-$lang['L_SQL_INSERTNEWFIELD']="εισαγωγή νέου πεδίου";
-$lang['L_SQL_TABLEINDEXES']="Περιεχόμενα πίνακα";
-$lang['L_SQL_ALLOWDUPS']="επιτρέπονται διπλοεγγραφές";
-$lang['L_SQL_CARDINALITY']="Πρωτεύων";
-$lang['L_SQL_TABLENOINDEXES']="Κανένα ευρετήριο στον πίνακα";
-$lang['L_SQL_CREATEINDEX']="δημιουργία νέου ευρετηρίου";
-$lang['L_SQL_WASEMPTIED']="άδειασε";
-$lang['L_SQL_RENAMEDTO']="μετονομάστηκε σε";
-$lang['L_SQL_DBCOPY']="Τα περιεχόμενα της Β.Δεδομένων `%s` αντιγράφηκαν στη Β.Δεδομένων `%s`.";
-$lang['L_SQL_DBSCOPY']="Η δομή της Β.Δεδομένων `%s` αντιγράφηκε στη Β.Δεδομένων `%s`.";
-$lang['L_SQL_WASCREATED']="δημιουργήθηκε";
-$lang['L_SQL_RENAMEDB']="Μετονομασία Β.Δεδομένων";
-$lang['L_SQL_ACTIONS']="Ενέργειες";
-$lang['L_SQL_CHOOSEACTION']="Επιλογή ενέργειας";
-$lang['L_SQL_DELETEDB']="Διαγραφή Β.Δεδομένων";
-$lang['L_SQL_EMPTYDB']="Αδειασμα Β.Δεδομένων";
-$lang['L_SQL_COPYDATADB']="Αντιγραφή όλης της Β.Δεδομένων σε";
-$lang['L_SQL_COPYSDB']="Αντιγραφή δομής Β.Δεδομένων";
-$lang['L_SQL_IMEXPORT']="Εισαγωγή-Εξαγωγή";
-$lang['L_INFO_RECORDS']="εγγραφές";
-$lang['L_NAME']="Ονομα";
-$lang['L_ASKTABLEEMPTYKEYS']="Να αδειάσει ο πίνακας `%s` και να επαναφερθούν τα ευρετήρια?";
-$lang['L_EDIT']="επεξεργασία";
-$lang['L_DELETE']="διαγραφή";
-$lang['L_EMPTY']="άδειασμα";
-$lang['L_EMPTYKEYS']="άδειασμα κι επαναφορά των ευρετηρίων";
-$lang['L_SQL_TABLEEMPTIED']="Διαγράφηκε ο πίνακας `%s` .";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Διαγράφηκε ο πίνακας `%s` κι επαναφέρθηκαν τα ευρετήρια.";
-$lang['L_SQL_LIBRARY']="Βιβλιοθήκη SQL";
-$lang['L_SQL_ATTRIBUTES']="Ιδιότητες";
-$lang['L_SQL_UPLOADEDFILE']="φορτωμένο αρχείο: ";
-$lang['L_SQL_IMPORT']="Εισαγωγή στη Β.Δεδομένων `%s`";
-$lang['L_EXPORT']="Εξαγωγή";
-$lang['L_IMPORT']="Εισαγωγή";
-$lang['L_IMPORTOPTIONS']="Εισαγωγή επιλογών";
-$lang['L_CSVOPTIONS']="Επιλογές CSV";
-$lang['L_IMPORTTABLE']="Εισαγωγή στον πίνακα";
-$lang['L_NEWTABLE']="Νέος πίνακας";
-$lang['L_IMPORTSOURCE']="Εισαγωγή πηγής";
-$lang['L_FROMTEXTBOX']="από το πλαίσιο κειμένου";
-$lang['L_FROMFILE']="από αρχείο";
-$lang['L_EMPTYTABLEBEFORE']="Αδειασμα πίνακα πριν";
-$lang['L_CREATEAUTOINDEX']="Δημιουργία αυτόματου ευρετηρίου";
-$lang['L_CSV_NAMEFIRSTLINE']="Ονόματα πεδίων στην πρώτη γραμμή";
-$lang['L_CSV_FIELDSEPERATE']="Τα πεδία χωρίζονται με";
-$lang['L_CSV_FIELDSENCLOSED']="Τα πεδία περικλείονται με";
-$lang['L_CSV_FIELDSESCAPE']="Τα πεδία θα χρησιμοποιούν χαρακτήρες διαφυγής";
-$lang['L_CSV_EOL']="Διαχωρισμός γραμμών με";
-$lang['L_CSV_NULL']="Αντικατάσταση NULL με";
-$lang['L_CSV_FILEOPEN']="Ανοιγμα αρχείου CSV";
-$lang['L_IMPORTIEREN']="Εισαγωγή";
-$lang['L_SQL_EXPORT']="Εξαγωγή από Β.Δεδομένων `%s`";
-$lang['L_EXPORTOPTIONS']="Εξαγωγή επιλογών";
-$lang['L_EXCEL2003']="Excel του 2003";
-$lang['L_SHOWRESULT']="προβολή αποτελεσμάτων";
-$lang['L_SENDRESULTASFILE']="αποστολή αποτελεσμάτων ως αρχείο";
-$lang['L_EXPORTLINES']="<strong>%s</strong> γραμμές έχουν εξαχθεί";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Η αρίθμηση των πεδίων δε ταιριάζει με αυτή των δεδομένων που θα εισαχθούν (%d αντί για %d).";
-$lang['L_CSV_FIELDSLINES']="%d πεδία αναγνωρίστηκαν, συνολικά %d γραμμές";
-$lang['L_CSV_ERRORCREATETABLE']="Σφάλμα κατά την δημιουργία του πίνακα `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="παρακαλώ επιλέξτε ένα αρχείο.";
-$lang['L_CSV_NODATA']="Δε βρέθηκαν δεδομένα για εισαγωγή!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="γενικές λειτουργίες";
-$lang['L_SQLLIB_RESETAUTO']="επαναφορά αυτόματης αύξησης";
-$lang['L_SQLLIB_BOARDS']="Κοινότητες";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="απενεργοποίηση Board";
-$lang['L_SQLLIB_ACTIVATEBOARD']="ενεργοποίηση Board";
-$lang['L_SQL_NOTABLESSELECTED']="Δεν επιλέχθηκαν πίνακες !";
-$lang['L_TOOLS']="Εργαλεία";
-$lang['L_TOOLS_TOOLBOX']="Επιλογή Β.Δεδομένων / Λειτουργίες Β.Δεδομένων / Εισαγωγή - Εξαγωγή ";
-$lang['L_SQL_OPENFILE']="Ανοιγμα αρχείου SQL";
-$lang['L_SQL_OPENFILE_BUTTON']="Φόρτωση";
-$lang['L_MAX_UPLOAD_SIZE']="Μέγιστο μέγεθος αρχείου";
-$lang['L_SQL_SEARCH']="Αναζήτηση";
-$lang['L_SQL_SEARCHWORDS']="Αναζήτηση λέξεων";
-$lang['L_START_SQL_SEARCH']="Εκκίνηση αναζήτησης";
-$lang['L_RESET_SEARCHWORDS']="Επαναφορά λέξεων αναζήτησης";
-$lang['L_SEARCH_OPTIONS']="Επιλογές αναζήτησης";
-$lang['L_SEARCH_RESULTS']="Η αναζήτηση για \"<b>%s</b>\" στον πίνακα \"<b>%s</b>\" φέρνει τα ακόλουθα αποτελέσματα";
-$lang['L_SEARCH_NO_RESULTS']="Η αναζήτηση για \"<b>%s</b>\" στον πίνακα \"<b>%s</b>\" δεν έχει αποτελέσματα!";
-$lang['L_NO_ENTRIES']="Ο πίνακας \"<b>%s</b>\" είναι άδειος και δεν έχει καταχωρήσεις.";
-$lang['L_SEARCH_ACCESS_KEYS']="Πλοήγηση: εμπρός=ALT+V, πίσω=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="Η στήλη πρέπει να έχει τουλάχιστον μία από τις λέξεις αναζήτησης (OR-search)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="Η γραμμή πρέπει περιλαμβάνει όλες τις λέξεις αναζήτησης αλλά μπορεί να είναι σε κάποια στήλη (χρειάζεται λίγο χρόνο)";
-$lang['L_SEARCH_OPTIONS_AND']="Η γραμμή πρέπει περιλαμβάνει όλες τις λέξεις αναζήτησης (AND-search)";
-$lang['L_SEARCH_IN_TABLE']="Αναζήτηση στον πίνακα";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Επεξεργασία δομής πίνακα";
-$lang['L_DEFAULT_CHARSET']="Προεπιλεγμένο σετ χαρακτήρων";
-$lang['L_TITLE_KEY_PRIMARY']="Πρωτεύων κλειδί";
-$lang['L_TITLE_KEY_UNIQUE']="Μοναδικό κλειδί";
-$lang['L_TITLE_INDEX']="Ευρετήριο";
-$lang['L_TITLE_KEY_FULLTEXT']="Κλειδί πλήρη κειμένου";
-$lang['L_TITLE_NOKEY']="Κανένα κλειδί";
-$lang['L_TITLE_SEARCH']="Αναζήτηση";
-$lang['L_TITLE_MYSQL_HELP']="Τεκμηρίωση MySQl";
-$lang['L_TITLE_UPLOAD']="Φόρτωση αρχείου SQL
 
-
-";
-$lang['L_PRIMARYKEY_DELETED']="Το πρωτεύων κλειδί διαγράφηκε";
-$lang['L_PRIMARYKEY_NOTFOUND']="Δε βρέθηκε πρωτεύων κλειδί";
-$lang['L_PRIMARYKEYS_CHANGED']="Τα πρωτεύοντα κλειδιά άλλαξαν";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Σφάλμα στην αλλαγή πρωτεύοντων κλειδιών";
-$lang['L_SQL_VIEW_COMPACT']="Προβολή: Συμπαγής";
-$lang['L_SQL_VIEW_STANDARD']="Προβολή: Κανονική";
-$lang['L_FIELDS_OF_TABLE']="Πεδία πινάκων";
-$lang['L_ENGINE']="Μηχανή";
-$lang['L_USERNAME']="Ονομα χρήστη";
-$lang['L_PASSWORD']="Κωδικός";
-$lang['L_PASSWORD_REPEAT']="Κωδικός (Επανάληψη)";
-$lang['L_INFO_SIZE']="Μέγεθος";
-$lang['L_TABLE_TYPE']="Τύπος";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
-
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Εντολή';
+$lang['L_IMPORT_NOTABLE'] = 'Δεν επιλέχθηκε πίνακας για εισαγωγή!';
+$lang['L_PASSWORD_STRENGTH'] = 'Ισχύς κωδικού';
+$lang['L_SQL_WARNING'] = 'Η εκτέλεση των εντολών SQL μπορεί να τροποποιήσει δεδομένα. ΠΡΟΣΟΧΗ! Ο δημιουργός δε φέρει καμία απολύτως ευθύνη για καταστροφή ή απώλεια δεδομένων.';
+$lang['L_SQL_EXEC'] = 'Εκτέλεση εντολής SQL';
+$lang['L_SQL_DATAVIEW'] = 'Προβολή δεδομένων';
+$lang['L_SQL_TABLEVIEW'] = 'Προβολή πίνακα';
+$lang['L_SQL_VONINS'] = 'από τελείως';
+$lang['L_SQL_NODATA'] = 'καμία εγγραφή';
+$lang['L_SQL_RECORDUPDATED'] = 'Εγγραφή αναβαθμίστηκε';
+$lang['L_SQL_RECORDINSERTED'] = 'Εγγραφή προστέθηκε';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'Πίσω στην επισκόπηση';
+$lang['L_SQL_RECORDDELETED'] = 'Εγγραφή διαγράφηκε';
+$lang['L_ASKTABLEEMPTY'] = 'Να αδειάσει ο πίνακας `%s`?';
+$lang['L_SQL_RECORDEDIT'] = 'επεξεργασία εγγραφής';
+$lang['L_SQL_RECORDNEW'] = 'νέα εγγραφή';
+$lang['L_ASKDELETERECORD'] = 'Θέλετε να διαγραφεί η εγγραφή?';
+$lang['L_ASKDELETETABLE'] = 'Να διαγραφεί ο πίνακας `%s` ?';
+$lang['L_SQL_BEFEHLE'] = 'Εντολές SQL';
+$lang['L_SQL_BEFEHLNEU'] = 'Νέα εντολή';
+$lang['L_SQL_BEFEHLSAVED1'] = 'Εντολή SQL';
+$lang['L_SQL_BEFEHLSAVED2'] = 'προστέθηκε';
+$lang['L_SQL_BEFEHLSAVED3'] = 'αποθηκεύθηκε';
+$lang['L_SQL_BEFEHLSAVED4'] = 'μετακινήθηκε';
+$lang['L_SQL_BEFEHLSAVED5'] = 'διαγράφηκε';
+$lang['L_SQL_QUERYENTRY'] = 'Η αναζήτηση περιλαμβάνει';
+$lang['L_SQL_COLUMNS'] = 'Στήλες';
+$lang['L_ASKDBDELETE'] = 'Θέλετε να διαγραφεί η Β.Δεδομένων `%s` με το περιεχόμενο?';
+$lang['L_ASKDBEMPTY'] = 'Θέλετε να αδειάσει η Β.Δεδομένων `%s` ?';
+$lang['L_ASKDBCOPY'] = 'Θέλετε να αντιγραφεί η Β.Δεδομένων `%s` στη Β.Δεδομένων `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Επεξεργασία πινάκων';
+$lang['L_SQL_OUTPUT'] = 'Εξοδος SQL';
+$lang['L_DO_NOW'] = 'λειτούργησε τώρα';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Λείπει το όνομα προορισμού !';
+$lang['L_ASKDELETEFIELD'] = 'Να διαγραφεί το πεδίο?';
+$lang['L_SQL_COMMANDS_IN'] = ' γραμμές σε ';
+$lang['L_SQL_COMMANDS_IN2'] = '   δευτ. χρειάστηκαν.';
+$lang['L_SQL_OUT1'] = 'Εκτελέστηκε ';
+$lang['L_SQL_OUT2'] = 'Εντολές';
+$lang['L_SQL_OUT3'] = 'Είχε ';
+$lang['L_SQL_OUT4'] = 'Σχόλια';
+$lang['L_SQL_OUT5'] = 'Επειδή η έξοδος έχει πάνω από 5000 γραμμές δε θα προβληθεί.';
+$lang['L_SQL_SELECDB'] = 'Επιλογή Β.Δεδομένων';
+$lang['L_SQL_TABLESOFDB'] = 'Πίνακες της Β.Δεδομένων';
+$lang['L_SQL_EDIT'] = 'επεξεργασία';
+$lang['L_SQL_NOFIELDDELETE'] = 'Η διαγραφή δεν είναι δυνατή επειδή ο πίνακας πρέπει να έχει τουλάχιστον ένα πεδίο.';
+$lang['L_SQL_FIELDDELETE1'] = 'Το πεδίο';
+$lang['L_SQL_DELETED'] = 'διαγράφηκε';
+$lang['L_SQL_CHANGED'] = 'άλλαξε.';
+$lang['L_SQL_CREATED'] = 'δημιουργήθηκε.';
+$lang['L_SQL_NODEST_COPY'] = 'Καμία αντιγραφή χωρίς προορισμό !';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Ο πίνακας προορισμού υπάρχει !';
+$lang['L_SQL_SCOPY'] = 'Η δομή του πίνακα `%s` αντιγράφηκε στον πίνακα `%s`.';
+$lang['L_SQL_TCOPY'] = 'Ο πίνακας `%s` αντιγράφηκε με δεδομένα στον πίνακα `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'Ο πίνακας χρειάζεται ένα όνομα!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Το όνομα του πίνακα δεν μπορεί να είναι κενό!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Σετ χαρακτήρων και Collation δεν ταιριάζουν!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Σφάλμα: Ακυρο όνομα πεδίου';
+$lang['L_SQL_CREATETABLE'] = 'δημιουργία πίνακα';
+$lang['L_SQL_COPYTABLE'] = 'αντιγραφή πίνακα';
+$lang['L_SQL_STRUCTUREONLY'] = 'Μόνο δομή';
+$lang['L_SQL_STRUCTUREDATA'] = 'Δομή και Δεδομένα';
+$lang['L_SQL_NOTABLESINDB'] = 'Δε βρέθηκαν πίνακες στη Β.Δεδομένων';
+$lang['L_SQL_SELECTTABLE'] = 'επιλογή πίνακα';
+$lang['L_SQL_SHOWDATATABLE'] = 'Προβολή δεδομένων του πίνακα';
+$lang['L_SQL_TBLPROPSOF'] = 'Ιδιότητες πίνακα από';
+$lang['L_SQL_EDITFIELD'] = 'επεξεργασία πεδίου';
+$lang['L_SQL_NEWFIELD'] = 'Νέο πεδίο';
+$lang['L_SQL_INDEXES'] = 'Ευρετήρια';
+$lang['L_SQL_ATPOSITION'] = 'εισαγωγή στη θέση';
+$lang['L_SQL_FIRST'] = 'πρώτο';
+$lang['L_SQL_AFTER'] = 'μετά';
+$lang['L_SQL_CHANGEFIELD'] = 'αλλαγή πεδίου';
+$lang['L_SQL_INSERTFIELD'] = 'εισαγωγή πεδίου';
+$lang['L_SQL_INSERTNEWFIELD'] = 'εισαγωγή νέου πεδίου';
+$lang['L_SQL_TABLEINDEXES'] = 'Περιεχόμενα πίνακα';
+$lang['L_SQL_ALLOWDUPS'] = 'επιτρέπονται διπλοεγγραφές';
+$lang['L_SQL_CARDINALITY'] = 'Πρωτεύων';
+$lang['L_SQL_TABLENOINDEXES'] = 'Κανένα ευρετήριο στον πίνακα';
+$lang['L_SQL_CREATEINDEX'] = 'δημιουργία νέου ευρετηρίου';
+$lang['L_SQL_WASEMPTIED'] = 'άδειασε';
+$lang['L_SQL_RENAMEDTO'] = 'μετονομάστηκε σε';
+$lang['L_SQL_DBCOPY'] = 'Τα περιεχόμενα της Β.Δεδομένων `%s` αντιγράφηκαν στη Β.Δεδομένων `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'Η δομή της Β.Δεδομένων `%s` αντιγράφηκε στη Β.Δεδομένων `%s`.';
+$lang['L_SQL_WASCREATED'] = 'δημιουργήθηκε';
+$lang['L_SQL_RENAMEDB'] = 'Μετονομασία Β.Δεδομένων';
+$lang['L_SQL_ACTIONS'] = 'Ενέργειες';
+$lang['L_SQL_CHOOSEACTION'] = 'Επιλογή ενέργειας';
+$lang['L_SQL_DELETEDB'] = 'Διαγραφή Β.Δεδομένων';
+$lang['L_SQL_EMPTYDB'] = 'Αδειασμα Β.Δεδομένων';
+$lang['L_SQL_COPYDATADB'] = 'Αντιγραφή όλης της Β.Δεδομένων σε';
+$lang['L_SQL_COPYSDB'] = 'Αντιγραφή δομής Β.Δεδομένων';
+$lang['L_SQL_IMEXPORT'] = 'Εισαγωγή-Εξαγωγή';
+$lang['L_INFO_RECORDS'] = 'εγγραφές';
+$lang['L_NAME'] = 'Ονομα';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Να αδειάσει ο πίνακας `%s` και να επαναφερθούν τα ευρετήρια?';
+$lang['L_EDIT'] = 'επεξεργασία';
+$lang['L_DELETE'] = 'διαγραφή';
+$lang['L_EMPTY'] = 'άδειασμα';
+$lang['L_EMPTYKEYS'] = 'άδειασμα κι επαναφορά των ευρετηρίων';
+$lang['L_SQL_TABLEEMPTIED'] = 'Διαγράφηκε ο πίνακας `%s` .';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Διαγράφηκε ο πίνακας `%s` κι επαναφέρθηκαν τα ευρετήρια.';
+$lang['L_SQL_LIBRARY'] = 'Βιβλιοθήκη SQL';
+$lang['L_SQL_ATTRIBUTES'] = 'Ιδιότητες';
+$lang['L_SQL_UPLOADEDFILE'] = 'φορτωμένο αρχείο: ';
+$lang['L_SQL_IMPORT'] = 'Εισαγωγή στη Β.Δεδομένων `%s`';
+$lang['L_EXPORT'] = 'Εξαγωγή';
+$lang['L_IMPORT'] = 'Εισαγωγή';
+$lang['L_IMPORTOPTIONS'] = 'Εισαγωγή επιλογών';
+$lang['L_CSVOPTIONS'] = 'Επιλογές CSV';
+$lang['L_IMPORTTABLE'] = 'Εισαγωγή στον πίνακα';
+$lang['L_NEWTABLE'] = 'Νέος πίνακας';
+$lang['L_IMPORTSOURCE'] = 'Εισαγωγή πηγής';
+$lang['L_FROMTEXTBOX'] = 'από το πλαίσιο κειμένου';
+$lang['L_FROMFILE'] = 'από αρχείο';
+$lang['L_EMPTYTABLEBEFORE'] = 'Αδειασμα πίνακα πριν';
+$lang['L_CREATEAUTOINDEX'] = 'Δημιουργία αυτόματου ευρετηρίου';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Ονόματα πεδίων στην πρώτη γραμμή';
+$lang['L_CSV_FIELDSEPERATE'] = 'Τα πεδία χωρίζονται με';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Τα πεδία περικλείονται με';
+$lang['L_CSV_FIELDSESCAPE'] = 'Τα πεδία θα χρησιμοποιούν χαρακτήρες διαφυγής';
+$lang['L_CSV_EOL'] = 'Διαχωρισμός γραμμών με';
+$lang['L_CSV_NULL'] = 'Αντικατάσταση NULL με';
+$lang['L_CSV_FILEOPEN'] = 'Ανοιγμα αρχείου CSV';
+$lang['L_IMPORTIEREN'] = 'Εισαγωγή';
+$lang['L_SQL_EXPORT'] = 'Εξαγωγή από Β.Δεδομένων `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Εξαγωγή επιλογών';
+$lang['L_EXCEL2003'] = 'Excel του 2003';
+$lang['L_SHOWRESULT'] = 'προβολή αποτελεσμάτων';
+$lang['L_SENDRESULTASFILE'] = 'αποστολή αποτελεσμάτων ως αρχείο';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> γραμμές έχουν εξαχθεί';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Η αρίθμηση των πεδίων δε ταιριάζει με αυτή των δεδομένων που θα εισαχθούν (%d αντί για %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d πεδία αναγνωρίστηκαν, συνολικά %d γραμμές';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Σφάλμα κατά την δημιουργία του πίνακα `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'παρακαλώ επιλέξτε ένα αρχείο.';
+$lang['L_CSV_NODATA'] = 'Δε βρέθηκαν δεδομένα για εισαγωγή!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'γενικές λειτουργίες';
+$lang['L_SQLLIB_RESETAUTO'] = 'επαναφορά αυτόματης αύξησης';
+$lang['L_SQLLIB_BOARDS'] = 'Κοινότητες';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'απενεργοποίηση Board';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'ενεργοποίηση Board';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Δεν επιλέχθηκαν πίνακες !';
+$lang['L_TOOLS'] = 'Εργαλεία';
+$lang['L_TOOLS_TOOLBOX'] = 'Επιλογή Β.Δεδομένων / Λειτουργίες Β.Δεδομένων / Εισαγωγή - Εξαγωγή ';
+$lang['L_SQL_OPENFILE'] = 'Ανοιγμα αρχείου SQL';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Φόρτωση';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Μέγιστο μέγεθος αρχείου';
+$lang['L_SQL_SEARCH'] = 'Αναζήτηση';
+$lang['L_SQL_SEARCHWORDS'] = 'Αναζήτηση λέξεων';
+$lang['L_START_SQL_SEARCH'] = 'Εκκίνηση αναζήτησης';
+$lang['L_RESET_SEARCHWORDS'] = 'Επαναφορά λέξεων αναζήτησης';
+$lang['L_SEARCH_OPTIONS'] = 'Επιλογές αναζήτησης';
+$lang['L_SEARCH_RESULTS'] = 'Η αναζήτηση για "<b>%s</b>" στον πίνακα "<b>%s</b>" φέρνει τα ακόλουθα αποτελέσματα';
+$lang['L_SEARCH_NO_RESULTS'] = 'Η αναζήτηση για "<b>%s</b>" στον πίνακα "<b>%s</b>" δεν έχει αποτελέσματα!';
+$lang['L_NO_ENTRIES'] = 'Ο πίνακας "<b>%s</b>" είναι άδειος και δεν έχει καταχωρήσεις.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Πλοήγηση: εμπρός=ALT+V, πίσω=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'Η στήλη πρέπει να έχει τουλάχιστον μία από τις λέξεις αναζήτησης (OR-search)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'Η γραμμή πρέπει περιλαμβάνει όλες τις λέξεις αναζήτησης αλλά μπορεί να είναι σε κάποια στήλη (χρειάζεται λίγο χρόνο)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'Η γραμμή πρέπει περιλαμβάνει όλες τις λέξεις αναζήτησης (AND-search)';
+$lang['L_SEARCH_IN_TABLE'] = 'Αναζήτηση στον πίνακα';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Επεξεργασία δομής πίνακα';
+$lang['L_DEFAULT_CHARSET'] = 'Προεπιλεγμένο σετ χαρακτήρων';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Πρωτεύων κλειδί';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Μοναδικό κλειδί';
+$lang['L_TITLE_INDEX'] = 'Ευρετήριο';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Κλειδί πλήρη κειμένου';
+$lang['L_TITLE_NOKEY'] = 'Κανένα κλειδί';
+$lang['L_TITLE_SEARCH'] = 'Αναζήτηση';
+$lang['L_TITLE_MYSQL_HELP'] = 'Τεκμηρίωση MySQl';
+$lang['L_TITLE_UPLOAD'] = 'Φόρτωση αρχείου SQL';
+$lang['L_PRIMARYKEY_DELETED'] = 'Το πρωτεύων κλειδί διαγράφηκε';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Δε βρέθηκε πρωτεύων κλειδί';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Τα πρωτεύοντα κλειδιά άλλαξαν';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Σφάλμα στην αλλαγή πρωτεύοντων κλειδιών';
+$lang['L_SQL_VIEW_COMPACT'] = 'Προβολή: Συμπαγής';
+$lang['L_SQL_VIEW_STANDARD'] = 'Προβολή: Κανονική';
+$lang['L_FIELDS_OF_TABLE'] = 'Πεδία πινάκων';
+$lang['L_ENGINE'] = 'Μηχανή';
+$lang['L_USERNAME'] = 'Ονομα χρήστη';
+$lang['L_PASSWORD'] = 'Κωδικός';
+$lang['L_PASSWORD_REPEAT'] = 'Κωδικός (Επανάληψη)';
+$lang['L_INFO_SIZE'] = 'Μέγεθος';
+$lang['L_TABLE_TYPE'] = 'Τύπος';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/en/help.html b/msd/language/en/help.html
new file mode 100644
index 00000000..64a1411b
--- /dev/null
+++ b/msd/language/en/help.html
@@ -0,0 +1,147 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/en/help.php b/msd/language/en/help.php
deleted file mode 100644
index e1f6a4da..00000000
--- a/msd/language/en/help.php
+++ /dev/null
@@ -1,130 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>About this project</h3>
-The idea for this project comes from Daniel Schlichtholz.<p>In 2004 he created a forum called <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> and soon, programmers who wrote new scripts, supplemented Daniel's scripts.<br>After a short time the small backup-script developed into a stately project.<p>If you have any improvement suggestions you can visit the MySQLDumper-Forum: <a href="http://forum.mysqldumper.de" target="_blank">http://www.mysqldumper.de</a>.<p>We wish you a lot of fun with this project.<br><br><h4>The MySQLDumper-Team</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz<br>
-</td></tr></table>
-
-<h3>MySQLDumper Help</h3>
-
-<h4>Download</h4>
-This Script is available on the Homepage of MySQLDumper.<br>
-It is recommanded to visit the Homepage frequently to get the latest information, updates and help.<br>
-The address is <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>System Mandatories</h4>
-The Script works with nearly any server (Windows, Linux, ...) <br>
-and PHP >= Version 4.3.4 with GZip-Library, MySQL (>= 3.23), JavaScript (must be enabled).
-
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
-The installation is very easy.
-Unpack the archive in any folder,
-which is accessible from the Webserver<br>
-(e.g. in the root directory [Server rootdir/]MySQLDumper)<br>
-change config.php to chmod 777<br>
-... all done!<br>
-you can start MySQLDumper in your Browser by typing "http://webserver/MySQLDumper"
-to complete the setup, just follow the instructions.
-
-<br><b>Note:</b><br><i>If your webserver runs with the option safemode=ON MySqlDump mustn't create directories.<br>
-You will have to do that yourself.<br>
-MySqlDump breaks in that case and tells you what to do.<br>
-After you created the directories MySqlDump will function normally.</i><br>
-
-<a name="perl"></a><h4>Guidance for the Perl script</h4>
-
-Most have a cgi-bin directory, in which Perl can be executed. <br>
-This is usually by Browser over http://www.domain.de/cgi-bin/ available. <br><br>
-
-Make the following steps for this case please.  <br><br>
-
-1.  Call in MySQLDumper the page Backup and click "Backup Perl"   <br>
-2.  Copy the path, that stands behind entry in crondump.pl for $absolute_path_of_configdir:    <br>
-3. open the file "crondump.pl" in the editor <br>
-4. paste the copied path there with absolute_path_of_configdir (no blanks) <br>
-5.  Save crondump.pl <br>
-6. copy crondump.pl, as well as perltest.pl and simpletest.pl to the cgi-bin directory (ASCII mode in the ftp-client!) <br>
-7. chmod 755 to the scripts.  <br>
-7b. If the ending cgi is desired, change the ending of all 3 files  pl - > cgi (rename)  <br>
-8.  Call in the MySQLDumper the page Configuration<br>
-9. click on Cronscript <br>
-10. changes Perl execution path to /cgi-bin/<br>
-10b. if the Scripts are renamed to *.cgi , change Fileextension to cgi <br>
-11 save the Configuration <br><br>
-
-Ready ! The scripts are available from the Page "Backup" <br><br>
-
-When you can execute Perl anywhere, only following step are needed:  <br><br>
-
-1.  Call in MySQLDumper the page Backup.  <br>
-2.  Copy the path, that stands behind entry in crondump.pl for $absolute_path_of_configdir:  <br>
-3. open the file "crondump.pl" in the editor <br>
-4. paste the copied path there with absolute_path_of_configdir (no blanks) <br>
-5.  Save crondump.pl <br>
-
-6. chmod 755 to the scripts.  <br> 
-6b. If the ending cgi is desired, change the ending of all 3 files  pl - > cgi (rename)  <br>
-(ev. 10b+11 from above) <br><br>
-
-
-Windowsuser must change the first line of all Perlscripts, to the path of Perl.  <br><br>
-
-Example:  <br>
-
-instead of:  #!/usr/bin/perl w <br>
-now #!C:\perl\bin\perl.exe w<br>
-
-<h4>Operating</h4><ul>
-
-<h6>Menu</h6>
-In the select box above you choose your database.<br>
-All actions refer to this database.
-
-<h6>Home</h6>
-Here you get information about your system, the version numbers and details about the configured databases.<br>
-If you click on a database in the table, you get a list of tables with record counts, size and last update stamp.
-
-<h6>Configuration</h6>
-Here you can edit your configuration, save it or load the default settings.
-<ul>
-	<li><a name="conf1"><strong>Configured Databases:</strong> list of configured databases. The active database is in bold.</li>
-	<li><a name="conf2"><strong>Table-Prefix:</strong> you can choose a prefix for each database seperated. The prefix is a filter, which only handle the tables in a dump, that start with this prefix (e.g. all tables starting with "phpBB_"). If you don't want to use it, leave this field empty.</li>
-	<li><a name="conf3"><strong>GZip-Compression:</strong> Here you can activate the compression. It is recommended to work with compression because of the smaller size of files, netherless disk space is ever rarely.</li>
-	<li><a name="conf19"></a><strong>Records count for backup:</strong> These are the number of records which are being read simultaneously while the backup, before the script makes the callback. For slow server you can reduce this parameter to prevent timeouts.</li>
-	<li><a name="conf20"></a><strong>Records count for restore:</strong> These are the number of records which are being read simultaneously while the backup, before the script makes the callback. For slow server you can reduce this parameter to prevent timeouts.</li>
-	<li><a name="conf4"></a><strong>Directory for Backup files:</strong> choose your directory for the backup files. If you choose a new one, the script will create it for you. You can use relative or absolute paths.</li>
-	<li><a name="conf5"></a><strong>Send dumpfile as email:</strong> When this option is enabled, the script will automatically send the finished backup file as an email with an attachment (be careful!, you should use compression with this option because the dumpfile may be too large for email!)</li>
-	<li><a name="conf6"></a><strong>Email address:</strong> Recipient's email address</li>
-	<li><a name="conf7"></a><strong>Email subject:</strong> The subject of the email</li>
-	<li><a name="conf13"></a><strong>FTP-Transfer: </strong>When this option is enabled, the script will automatically send the finished backup file via FTP.</li>
-	<li><a name="conf14"><strong>FTP Server: </strong>the Address of the FTP-Servers (e.g. ftp.mybackups.de)</li>
-	<li><a name="conf15"></a><strong>FTP Server Port: </strong>the Port for the FTP-Server (normally 21)</li>
-	<li><a name="conf16"></a><strong>FTP User: </strong>the username for the FTP-Account</li>
-	<li><a name="conf17"></a><strong>FTP Passwort: </strong>the password for the FTP-Account</li>
-	<li><a name="conf18"></a><strong>FTP Upload-Ordner: </strong>the folder for saving the backup file (there must be Upload-Rights!)</li>
-	
-	<li><a name="conf8"></a><strong>automatic deletion of backups:</strong> When you activate this options, backup files will be deleted automatically by the following rules.</li>
-	<li><a name="conf10"></a><strong>Delete by number of files:</strong> A Value > 0 deletes all files except the given value</li>
-	<li><a name="conf11"></a><strong>Langauge:</strong> choose your language for the interface.</li>
-</ul>
-
-<h6>Management</h6>
-All the actions are listed here.<br>
-You see all files in the backup directory.
-For the actions "Restore" and "Delete" you have to select a file first.
-<UL>
-	<li><strong>Restore:</strong> you restore the database with the records of the selected backupfile.</li>
-	<li><strong>Delete:</strong> you can delete the selected backup file.</li>
-	<li><strong>Start new Dump:</strong> here you  start a new backup (dump) with your configured parameters.</li>
-</UL>
-
-<h6>Log</h6>
-You can read the Log entries and delete them.
-
-<h6>Credits / Help</h6>
-This page.
-</ul>
\ No newline at end of file
diff --git a/msd/language/en/lang.php b/msd/language/en/lang.php
index 59b31f23..90b809e6 100644
--- a/msd/language/en/lang.php
+++ b/msd/language/en/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="yes";
-$lang['L_TO']="to";
-$lang['L_ACTIVATED']="activated";
-$lang['L_NOT_ACTIVATED']="not activated";
-$lang['L_ERROR']="Error";
-$lang['L_OF']=" of ";
-$lang['L_ADDED']="added";
-$lang['L_DB']="Database";
-$lang['L_DBS']="Databases";
-$lang['L_TABLES']="Tables";
-$lang['L_TABLE']="Table";
-$lang['L_RECORDS']="Records";
-$lang['L_COMPRESSED']="compressed (gz)";
-$lang['L_NOTCOMPRESSED']="normal (uncompressed)";
-$lang['L_GENERAL']="general";
-$lang['L_COMMENT']="Comment";
-$lang['L_FILESIZE']="File size";
-$lang['L_ALL']="all";
-$lang['L_NONE']="none";
-$lang['L_WITH']=" with ";
-$lang['L_DIR']="Directory";
-$lang['L_RECHTE']="Permissions";
-$lang['L_STATUS']="State";
-$lang['L_FINISHED']="finished";
-$lang['L_FILE']="File";
-$lang['L_FIELDS']="Fields";
-$lang['L_NEW']="new";
-$lang['L_CHARSET']="Charset";
-$lang['L_COLLATION']="Collation";
-$lang['L_CHANGE']="change";
-$lang['L_IN']="in";
-$lang['L_DO']="Execute";
-$lang['L_VIEW']="view";
-$lang['L_EXISTING']="existing";
-$lang['L_BACK']="back";
-$lang['L_DB_HOST']="Hostname";
-$lang['L_DB_USER']="User";
-$lang['L_DB_PASS']="Password";
-$lang['L_INFO_SCRIPTDIR']="MySQLDumper directory";
-$lang['L_INFO_ACTDB']="Selected Database";
-$lang['L_WRONGCONNECTIONPARS']="Connection parameters wrong or missing!";
-$lang['L_CONN_NOT_POSSIBLE']="Connection not possible !";
-$lang['L_SERVERCAPTION']="Display Server";
-$lang['L_HELP_SERVERCAPTION']="When using MySQLDumper on different domains or servers, it can be helpful to display the domain/server name at the top of the screen.";
-$lang['L_ACTIVATE_MULTIDUMP']="Activate MultiDump";
-$lang['L_SAVE']="Save";
-$lang['L_RESET']="Reset";
-$lang['L_PRAEFIX']="Table Prefix";
-$lang['L_AUTODELETE']="Delete backups automatically";
-$lang['L_MAX_BACKUP_FILES_EACH2']="For each database";
-$lang['L_SAVING_DB_FORM']="Database";
-$lang['L_TESTCONNECTION']="Test Connection";
-$lang['L_BACK_TO_MINISQL']="Edit Database";
-$lang['L_CREATE']="Create";
-$lang['L_VARIABELN']="Variables";
-$lang['L_STATUSINFORMATIONEN']="Status Information";
-$lang['L_VERSIONSINFORMATIONEN']="Version Information";
-$lang['L_MSD_INFO']="MyOOS [Dumper]Information";
-$lang['L_BACKUPFILESANZAHL']="In the Backup directory there are";
-$lang['L_LASTBACKUP']="Last Backup";
-$lang['L_NOTAVAIL']="<em>not available</em>";
-$lang['L_VOM']="from";
-$lang['L_MYSQLVARS']="MySQL Variables";
-$lang['L_MYSQLSYS']="MySQL Commands";
-$lang['L_STATUS']="State";
-$lang['L_PROZESSE']="Processes";
-$lang['L_INFO_NOVARS']="no variables available";
-$lang['L_INHALT']="Value";
-$lang['L_INFO_NOSTATUS']="no status available";
-$lang['L_INFO_NOPROCESSES']="no running processes";
-$lang['L_FM_FREESPACE']="Free Space on Server";
-$lang['L_LOAD_DATABASE']="Reload databases";
-$lang['L_HOME']="Home";
-$lang['L_CONFIG']="Configuration";
-$lang['L_DUMP']="Backup";
-$lang['L_RESTORE']="Restore";
-$lang['L_FILE_MANAGE']="File Administration";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Select Database";
-$lang['L_CREDITS']="Credits / Help";
-$lang['L_MULTI_PART']="Multipart Backup";
-$lang['L_LOGFILENOTWRITABLE']="Can't write logfile !";
-$lang['L_SQL_ERROR1']="Error in Query:";
-$lang['L_SQL_ERROR2']="MySQL says:";
-$lang['L_UNKNOWN']="unknown";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="unknown";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Log complete output";
-$lang['L_NO']="no";
-$lang['L_CREATE_DATABASE']="Create new database";
-$lang['L_EXPORTFINISHED']="Export finished.";
-$lang['L_SQL_BROWSER']="SQL-Browser";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Standard encoding of MySQL-Server";
-$lang['L_TITLE_SHOW_DATA']="Show data";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="Cancel";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Backups";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'yes';
+$lang['L_TO'] = 'to';
+$lang['L_ACTIVATED'] = 'activated';
+$lang['L_NOT_ACTIVATED'] = 'not activated';
+$lang['L_ERROR'] = 'Error';
+$lang['L_OF'] = ' of ';
+$lang['L_ADDED'] = 'added';
+$lang['L_DB'] = 'Database';
+$lang['L_DBS'] = 'Databases';
+$lang['L_TABLES'] = 'Tables';
+$lang['L_TABLE'] = 'Table';
+$lang['L_RECORDS'] = 'Records';
+$lang['L_COMPRESSED'] = 'compressed (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (uncompressed)';
+$lang['L_COMMENT'] = 'Comment';
+$lang['L_FILESIZE'] = 'File size';
+$lang['L_ALL'] = 'all';
+$lang['L_NONE'] = 'none';
+$lang['L_WITH'] = ' with ';
+$lang['L_DIR'] = 'Directory';
+$lang['L_RECHTE'] = 'Permissions';
+$lang['L_STATUS'] = 'State';
+$lang['L_FINISHED'] = 'finished';
+$lang['L_FILE'] = 'File';
+$lang['L_FIELDS'] = 'Fields';
+$lang['L_NEW'] = 'new';
+$lang['L_CHARSET'] = 'Charset';
+$lang['L_COLLATION'] = 'Collation';
+$lang['L_CHANGE'] = 'change';
+$lang['L_IN'] = 'in';
+$lang['L_DO'] = 'Execute';
+$lang['L_VIEW'] = 'view';
+$lang['L_EXISTING'] = 'existing';
+$lang['L_BACK'] = 'back';
+$lang['L_DB_HOST'] = 'Hostname';
+$lang['L_DB_USER'] = 'User';
+$lang['L_DB_PASS'] = 'Password';
+$lang['L_INFO_SCRIPTDIR'] = 'MyOOS [Dumper] directory';
+$lang['L_INFO_ACTDB'] = 'Selected Database';
+$lang['L_WRONGCONNECTIONPARS'] = 'Connection parameters wrong or missing!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Connection not possible !';
+$lang['L_SERVERCAPTION'] = 'Display Server';
+$lang['L_HELP_SERVERCAPTION'] = 'When using MyOOS [Dumper] on different domains or servers, it can be helpful to display the domain/server name at the top of the screen.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'Activate MultiDump';
+$lang['L_SAVE'] = 'Save';
+$lang['L_RESET'] = 'Reset';
+$lang['L_PRAEFIX'] = 'Table Prefix';
+$lang['L_AUTODELETE'] = 'Delete backups automatically';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'For each database';
+$lang['L_SAVING_DB_FORM'] = 'Database';
+$lang['L_TESTCONNECTION'] = 'Test Connection';
+$lang['L_BACK_TO_MINISQL'] = 'Edit Database';
+$lang['L_CREATE'] = 'Create';
+$lang['L_VARIABELN'] = 'Variables';
+$lang['L_STATUSINFORMATIONEN'] = 'Status Information';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Version Information';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper]Information';
+$lang['L_BACKUPFILESANZAHL'] = 'In the Backup directory there are';
+$lang['L_LASTBACKUP'] = 'Last Backup';
+$lang['L_NOTAVAIL'] = '<em>not available</em>';
+$lang['L_VOM'] = 'from';
+$lang['L_MYSQLVARS'] = 'MySQL Variables';
+$lang['L_MYSQLSYS'] = 'MySQL Commands';
+$lang['L_STATUS'] = 'State';
+$lang['L_PROZESSE'] = 'Processes';
+$lang['L_INFO_NOVARS'] = 'no variables available';
+$lang['L_INHALT'] = 'Value';
+$lang['L_INFO_NOSTATUS'] = 'no status available';
+$lang['L_INFO_NOPROCESSES'] = 'no running processes';
+$lang['L_FM_FREESPACE'] = 'Free Space on Server';
+$lang['L_LOAD_DATABASE'] = 'Reload databases';
+$lang['L_HOME'] = 'Home';
+$lang['L_CONFIG'] = 'Configuration';
+$lang['L_DUMP'] = 'Backup';
+$lang['L_RESTORE'] = 'Restore';
+$lang['L_FILE_MANAGE'] = 'File Administration';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Select Database';
+$lang['L_CREDITS'] = 'Credits / Help';
+$lang['L_MULTI_PART'] = 'Multipart Backup';
+$lang['L_LOGFILENOTWRITABLE'] = "Can't write logfile !";
+$lang['L_SQL_ERROR1'] = 'Error in Query:';
+$lang['L_SQL_ERROR2'] = 'MySQL says:';
+$lang['L_UNKNOWN'] = 'unknown';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'unknown';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Log complete output';
+$lang['L_NO'] = 'no';
+$lang['L_CREATE_DATABASE'] = 'Create new database';
+$lang['L_EXPORTFINISHED'] = 'Export finished.';
+$lang['L_SQL_BROWSER'] = 'SQL-Browser';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Standard encoding of MySQL-Server';
+$lang['L_TITLE_SHOW_DATA'] = 'Show data';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'Cancel';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Backups';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/en/lang_config_overview.php b/msd/language/en/lang_config_overview.php
index 008a7310..bd9cf594 100644
--- a/msd/language/en/lang_config_overview.php
+++ b/msd/language/en/lang_config_overview.php
@@ -1,110 +1,127 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Configuration";
-$lang['L_SAVE_SUCCESS']="Configuration was saved succesfully into configuration file \"%s\".";
-$lang['L_CONFIG_LOADED']="Configuration \"%s\" has been imported successfully.";
-$lang['L_SAVE_ERROR']="Error - unable to save configuration!";
-$lang['L_CONFIG_EMAIL']="Email Notification";
-$lang['L_CONFIG_AUTODELETE']="Autodelete";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="maximum File size";
-$lang['L_HELP_MULTIPART']="If Multipart is switched on, Backup creates multiple Backup files, with the maximum size determined by the configuration below";
-$lang['L_HELP_MULTIPARTGROESSE']="The maximum size of Backup files is set here, if Multipart is switched on";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Delete tables before restoring";
-$lang['L_ALLPARS']="All Parameters";
-$lang['L_CRON_EXTENDER']="File extension";
-$lang['L_CRON_SAVEPATH']="Configuration file";
-$lang['L_CRON_PRINTOUT']="Print output on screen.";
-$lang['L_CONFIG_CRONPERL']="Crondump Settings for Perl script";
-$lang['L_CRON_MAILPRG']="Mail program";
-$lang['L_OPTIMIZE']="Optimize Tables before Backup";
-$lang['L_HELP_OPTIMIZE']="If this option is activated, all tables will be optimized before the backup";
-$lang['L_HELP_FTPTIMEOUT']="Default setting for Timeout is 90 seconds.";
-$lang['L_FTP_TIMEOUT']="Connection Timeout";
-$lang['L_HELP_FTPSSL']="Choose if the connection will be established via SSL.";
-$lang['L_CONFIG_ASKLOAD']="Do you want to override the actual settings with the default settings?";
-$lang['L_LOAD']="Load default settings";
-$lang['L_LOAD_SUCCESS']="The default settings were loaded.";
-$lang['L_CRON_CRONDBINDEX']="Database";
-$lang['L_WITHATTACH']=" with attach";
-$lang['L_WITHOUTATTACH']=" without attach";
-$lang['L_MULTIDUMPCONF']="=Multidump Configuration=";
-$lang['L_MULTIDUMPALL']="=all Databases=";
-$lang['L_GZIP']="GZip compression";
-$lang['L_SEND_MAIL_FORM']="Send email report";
-$lang['L_SEND_MAIL_DUMP']="Attach backup";
-$lang['L_EMAIL_ADRESS']="Receiver";
-$lang['L_EMAIL_SENDER']="Sender address of the email";
-$lang['L_EMAIL_MAXSIZE']="Maximum size of attachment";
-$lang['L_NUMBER_OF_FILES_FORM']="Delete by number of files per database";
-$lang['L_LANGUAGE']="Language";
-$lang['L_LIST_DB']="Configured Databases:";
-$lang['L_CONFIG_FTP']="FTP Transfer of Backup file";
-$lang['L_FTP_TRANSFER']="FTP Transfer";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="User";
-$lang['L_FTP_PASS']="Password";
-$lang['L_FTP_DIR']="Upload directory";
-$lang['L_FTP_SSL']="Secure SSL FTP connection";
-$lang['L_FTP_USESSL']="use SSL Connection";
-$lang['L_SQLBOXHEIGHT']="Height of SQL-Box";
-$lang['L_SQLLIMIT']="Count of records each page";
-$lang['L_BBPARAMS']="Configuration for BB-Code";
-$lang['L_BBTEXTCOLOR']="Text color";
-$lang['L_HELP_COMMANDS']="You can execute a command before and after the backup.\nThis command can be a SQL-Construct or a System Command (e.g. a script)";
-$lang['L_COMMAND']="Command";
-$lang['L_WRONG_CONNECTIONPARS']="Connection parameters are wrong !";
-$lang['L_CONNECTIONPARS']="Connection Parameter";
-$lang['L_EXTENDEDPARS']="Extended Parameter";
-$lang['L_FADE_IN_OUT']="Display on/off";
-$lang['L_DB_BACKUPPARS']="Database Backup Parameter";
-$lang['L_GENERAL']="General";
-$lang['L_MAXSIZE']="max. Size";
-$lang['L_ERRORHANDLING_RESTORE']="Error Handling while restoring";
-$lang['L_EHRESTORE_CONTINUE']="continue and log errors";
-$lang['L_EHRESTORE_STOP']="stop";
-$lang['L_IN_MAINFRAME']="in main frame";
-$lang['L_IN_LEFTFRAME']="in left frame";
-$lang['L_WIDTH']="Width";
-$lang['L_SQL_BEFEHLE']="SQL Commands";
-$lang['L_DOWNLOAD_LANGUAGES']="download other languages";
-$lang['L_DOWNLOAD_STYLES']="download other themes";
-$lang['L_CONNECT_TO']="Connect to";
-$lang['L_CHANGEDIR']="Changing to Directory";
-$lang['L_CHANGEDIRERROR']="Couldn`t change directory!";
-$lang['L_FTP_OK']="Connection successful.";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="You don't have FTP functions !";
-$lang['L_FOUND_DB']="found db";
-$lang['L_FTP_CHOOSE_MODE']="FTP Transfer Mode";
-$lang['L_FTP_PASSIVE']="use passive mode";
-$lang['L_HELP_FTP_MODE']="Choose the passive mode when you discover problems while using the active mode.";
-$lang['L_DB_IN_LIST']="The database '%s' couldn't be added because it is allready existing. ";
-$lang['L_ADD_DB_MANUALLY']="Add database manually";
-$lang['L_DB_MANUAL_ERROR']="Sorry, couldn't connect to database '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Fileerror: couldn't insert database '%s'!";
-$lang['L_NO_DB_FOUND']="I couldn't find any databases automatically!
+
+$lang['L_CONFIG_HEADLINE'] = 'Configuration';
+$lang['L_SAVE_SUCCESS'] = 'Configuration was saved succesfully into configuration file "%s".';
+$lang['L_CONFIG_LOADED'] = 'Configuration "%s" has been imported successfully.';
+$lang['L_SAVE_ERROR'] = 'Error - unable to save configuration!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Email Notification';
+$lang['L_CONFIG_AUTODELETE'] = 'Autodelete';
+$lang['L_CONFIG_INTERFACE'] = 'Interface';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'Maximum File size';
+$lang['L_HELP_MULTIPART'] = 'If Multipart is switched on, Backup creates multiple Backup files, with the maximum size determined by the configuration below';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'The maximum size of Backup files is set here, if Multipart is switched on';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Delete tables before restoring';
+$lang['L_ALLPARS'] = 'All Parameters';
+$lang['L_CRON_EXTENDER'] = 'File extension';
+$lang['L_CRON_SAVEPATH'] = 'Configuration file';
+$lang['L_CRON_PRINTOUT'] = 'Print output on screen.';
+$lang['L_CONFIG_CRONPERL'] = 'Crondump Settings for Perl script';
+$lang['L_CRON_MAILPRG'] = 'Mail program';
+$lang['L_OPTIMIZE'] = 'Optimize Tables before Backup';
+$lang['L_HELP_OPTIMIZE'] = 'If this option is activated, all tables will be optimized before the backup';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'Default setting for Timeout is 90 seconds.';
+$lang['L_FTP_TIMEOUT'] = 'Connection Timeout';
+$lang['L_HELP_FTPSSL'] = 'Choose if the connection will be established via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Connection Timeout';
+$lang['L_HELP_SFTPSSL'] = 'Choose if the connection will be established via SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'Do you want to override the actual settings with the default settings?';
+$lang['L_LOAD'] = 'Load default settings';
+$lang['L_LOAD_SUCCESS'] = 'The default settings were loaded.';
+$lang['L_CRON_CRONDBINDEX'] = 'Database';
+$lang['L_WITHATTACH'] = ' with attach';
+$lang['L_WITHOUTATTACH'] = ' without attach';
+$lang['L_MULTIDUMPCONF'] = '=Multidump Configuration=';
+$lang['L_MULTIDUMPALL'] = '=all Databases=';
+$lang['L_GZIP'] = 'GZip compression';
+$lang['L_SEND_MAIL_FORM'] = 'Send email report';
+$lang['L_SEND_MAIL_DUMP'] = 'Attach backup';
+$lang['L_EMAIL_ADRESS'] = 'Receiver';
+$lang['L_EMAIL_SENDER'] = 'Sender address of the email';
+$lang['L_EMAIL_MAXSIZE'] = 'Maximum size of attachment';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Delete by number of files per database';
+$lang['L_LANGUAGE'] = 'Language';
+$lang['L_LIST_DB'] = 'Configured Databases:';
+$lang['L_CONFIG_FTP'] = 'FTP Transfer of Backup file';
+$lang['L_FTP_TRANSFER'] = 'FTP Transfer';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'User';
+$lang['L_FTP_PASS'] = 'Password';
+$lang['L_FTP_DIR'] = 'Upload directory';
+$lang['L_FTP_SSL'] = 'Secure SSL FTP connection';
+$lang['L_FTP_USESSL'] = 'use SSL Connection';
+$lang['L_CONFIG_SFTP'] = 'SFTP Transfer of Backup file';
+$lang['L_SFTP_TRANSFER'] = 'SFTP Transfer';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'User';
+$lang['L_SFTP_PASS'] = 'Password';
+$lang['L_SFTP_DIR'] = 'Upload directory';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Height of SQL-Box';
+$lang['L_SQLLIMIT'] = 'Count of records each page';
+$lang['L_BBPARAMS'] = 'Configuration for BB-Code';
+$lang['L_BBTEXTCOLOR'] = 'Text color';
+$lang['L_HELP_COMMANDS'] = "You can execute a command before and after the backup.\nThis command can be a SQL-Construct or a System Command (e.g. a script)";
+$lang['L_COMMAND'] = 'Command';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Connection parameters are wrong !';
+$lang['L_CONNECTIONPARS'] = 'Connection Parameter';
+$lang['L_EXTENDEDPARS'] = 'Extended Parameter';
+$lang['L_FADE_IN_OUT'] = 'Display on/off';
+$lang['L_DB_BACKUPPARS'] = 'Database Backup Parameter';
+$lang['L_GENERAL'] = 'General';
+$lang['L_MAXSIZE'] = 'max. Size';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Error Handling while restoring';
+$lang['L_EHRESTORE_CONTINUE'] = 'continue and log errors';
+$lang['L_EHRESTORE_STOP'] = 'stop';
+$lang['L_IN_MAINFRAME'] = 'in main frame';
+$lang['L_IN_LEFTFRAME'] = 'in left frame';
+$lang['L_WIDTH'] = 'Width';
+$lang['L_SQL_BEFEHLE'] = 'SQL Commands';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'download other languages';
+$lang['L_DOWNLOAD_STYLES'] = 'download other themes';
+$lang['L_CONNECT_TO'] = 'Connect to';
+$lang['L_CHANGEDIR'] = 'Changing to Directory';
+$lang['L_CHANGEDIRERROR'] = 'Couldn`t change directory!';
+$lang['L_FTP_OK'] = 'Connection successful.';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = "You don't have FTP functions !";
+$lang['L_FOUND_DB'] = 'found db';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP Transfer Mode';
+$lang['L_FTP_PASSIVE'] = 'use passive mode';
+$lang['L_HELP_FTP_MODE'] = 'Choose the passive mode when you discover problems while using the active mode.';
+$lang['L_SFTP_PASSIVE'] = 'use passive mode';
+$lang['L_DB_IN_LIST'] = "The database '%s' couldn't be added because it is allready existing. ";
+$lang['L_ADD_DB_MANUALLY'] = 'Add database manually';
+$lang['L_DB_MANUAL_ERROR'] = "Sorry, couldn't connect to database '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Fileerror: couldn't insert database '%s'!";
+$lang['L_NO_DB_FOUND'] = "I couldn't find any databases automatically!
 Please unhide the connection parameters, and enter the name of your database manually.";
-$lang['L_CONFIGFILES']="Configuration Files";
-$lang['L_CONFIGFILE']="Config File";
-$lang['L_MYSQL_DATA']="MySQL-Data";
-$lang['L_CONFIGURATIONS']="Configurations";
-$lang['L_ACTION']="Action";
-$lang['L_FTP_SEND_TO']="to <strong>%s</strong><br> into <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Receiver";
-$lang['L_NAME']="Name";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Really delete the configuration file %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Error: couldn't delete configuration file %s!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="The configuration file %s has successfully been deleted.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Configuration file %s has successfully been created.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Filename \"%s\" contains invalid characters.";
-$lang['L_CREATE_CONFIGFILE']="Create a new configuration file";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Couldn't load configfile \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="DBs to backup (PHP)";
-$lang['L_BACKUP_DBS_PERL']="DBs to backup (PERL)";
-$lang['L_CRON_COMMENT']="Enter Comment";
-$lang['L_AUTODETECT']="auto detect";
-
-
-?>
\ No newline at end of file
+$lang['L_CONFIGFILES'] = 'Configuration Files';
+$lang['L_CONFIGFILE'] = 'Config File';
+$lang['L_MYSQL_DATA'] = 'MySQL-Data';
+$lang['L_CONFIGURATIONS'] = 'Configurations';
+$lang['L_ACTION'] = 'Action';
+$lang['L_FTP_SEND_TO'] = 'to <strong>%s</strong><br> into <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'to <strong>%s</strong><br> into <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Receiver';
+$lang['L_NAME'] = 'Name';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Really delete the configuration file %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = "Error: couldn't delete configuration file %s!";
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'The configuration file %s has successfully been deleted.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Configuration file %s has successfully been created.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Filename "%s" contains invalid characters.';
+$lang['L_CREATE_CONFIGFILE'] = 'Create a new configuration file';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = "Couldn't load configfile \"%s\".";
+$lang['L_BACKUP_DBS_PHP'] = 'DBs to backup (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'DBs to backup (PERL)';
+$lang['L_CRON_COMMENT'] = 'Enter Comment';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/en/lang_dump.php b/msd/language/en/lang_dump.php
index beca324d..54b92b8e 100644
--- a/msd/language/en/lang_dump.php
+++ b/msd/language/en/lang_dump.php
@@ -1,57 +1,58 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Create backup...";
-$lang['L_GZIP_COMPRESSION']="GZip Compression";
-$lang['L_SAVING_TABLE']="Saving table ";
-$lang['L_OF']="of";
-$lang['L_ACTUAL_TABLE']="Actual table";
-$lang['L_PROGRESS_TABLE']="Progress of table";
-$lang['L_PROGRESS_OVER_ALL']="Overall Progress";
-$lang['L_ENTRY']="Entry";
-$lang['L_DONE']="Done!";
-$lang['L_DUMP_SUCCESSFUL']=" was successfully created.";
-$lang['L_UPTO']="up to";
-$lang['L_EMAIL_WAS_SEND']="Email was successfully sent to ";
-$lang['L_BACK_TO_CONTROL']="Continue";
-$lang['L_BACK_TO_OVERVIEW']="Database Overview";
-$lang['L_DUMP_FILENAME']="Backup File: ";
-$lang['L_WITHPRAEFIX']="with prefix";
-$lang['L_DUMP_NOTABLES']="No tables found in database `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="The file contains <b>%s</b> tables with <b>%s</b> records.<br>";
-$lang['L_MAILERROR']="Sending of email failed!";
-$lang['L_EMAILBODY_ATTACH']="The Attachment contains the backup of your MySQL-Database.<br>Backup of Database `%s`
-<br><br>Following File was created:<br><br>%s <br><br>Kind regards<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="A Multipart Backup was created.<br>The Backup files are not attached to this email!<br>Backup of Database `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'Create backup...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip Compression';
+$lang['L_SAVING_TABLE'] = 'Saving table ';
+$lang['L_OF'] = 'of';
+$lang['L_ACTUAL_TABLE'] = 'Actual table';
+$lang['L_PROGRESS_TABLE'] = 'Progress of table';
+$lang['L_PROGRESS_OVER_ALL'] = 'Overall Progress';
+$lang['L_ENTRY'] = 'Entry';
+$lang['L_DONE'] = 'Done!';
+$lang['L_DUMP_SUCCESSFUL'] = ' was successfully created.';
+$lang['L_UPTO'] = 'up to';
+$lang['L_EMAIL_WAS_SEND'] = 'Email was successfully sent to ';
+$lang['L_BACK_TO_CONTROL'] = 'Continue';
+$lang['L_BACK_TO_OVERVIEW'] = 'Database Overview';
+$lang['L_DUMP_FILENAME'] = 'Backup File: ';
+$lang['L_WITHPRAEFIX'] = 'with prefix';
+$lang['L_DUMP_NOTABLES'] = 'No tables found in database `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = 'The file contains <b>%s</b> tables with <b>%s</b> records.<br>';
+$lang['L_MAILERROR'] = 'Sending of email failed!';
+$lang['L_EMAILBODY_ATTACH'] = 'The Attachment contains the backup of your MySQL-Database.<br>Backup of Database `%s`
+<br><br>Following File was created:<br><br>%s <br><br>Kind regards<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'A Multipart Backup was created.<br>The Backup files are not attached to this email!<br>Backup of Database `%s`
 <br><br>Following Files were created:<br><br>%s
-<br><br>Kind regards<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="A Multipart Backup was created.<br>The Backup files are attached to separate emails.<br>Backup of Database `%s`
-<br><br>Following Files were created:<br><br>%s <br><br>Kind regards<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="`<br><br>Kind regards<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="The Backup file exceeded the maximum size of %s and was not attached to this email.<br>Backup of Database `%s`
+<br><br>Kind regards<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'A Multipart Backup was created.<br>The Backup files are attached to separate emails.<br>Backup of Database `%s`
+<br><br>Following Files were created:<br><br>%s <br><br>Kind regards<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '`<br><br>Kind regards<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'The Backup file exceeded the maximum size of %s and was not attached to this email.<br>Backup of Database `%s`
 <br><br>Following File was created:<br><br>%s
-<br><br>Kind regards<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Files are not attached to this email!<br>Backup of Database `%s`
+<br><br>Kind regards<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Files are not attached to this email!<br>Backup of Database `%s`
 <br><br>Following File was created:<br><br>%s
-<br><br>Kind regards<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... attachment only.";
-$lang['L_TABLESELECTION']="Table selection";
-$lang['L_SELECTALL']="Select All";
-$lang['L_DESELECTALL']="Deselect all";
-$lang['L_STARTDUMP']="Start Backup";
-$lang['L_LASTBUFROM']="last update from";
-$lang['L_NOT_SUPPORTED']="This backup doesn't support this function.";
-$lang['L_MULTIDUMP']="Multidump: Backup of <b>%d</b> Databases done.";
-$lang['L_FILESENDFTP']="send file via FTP... please be patient. ";
-$lang['L_FTPCONNERROR']="FTP connection not established! Connection with ";
-$lang['L_FTPCONNERROR1']=" as user ";
-$lang['L_FTPCONNERROR2']=" not possible";
-$lang['L_FTPCONNERROR3']="FTP Upload failed! ";
-$lang['L_FTPCONNECTED1']="Connected with ";
-$lang['L_FTPCONNECTED2']=" on ";
-$lang['L_FTPCONNECTED3']=" transfer successful";
-$lang['L_NR_TABLES_SELECTED']="- with %s selected tables";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tables have been optimized.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s errors occured: <a href=\"log.php?r=3\">view</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Fatal error: the CREATE-Statement of table '%s' in database '%s' couldn't be read!";
-
-
-?>
\ No newline at end of file
+<br><br>Kind regards<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... attachment only.';
+$lang['L_TABLESELECTION'] = 'Table selection';
+$lang['L_SELECTALL'] = 'Select All';
+$lang['L_DESELECTALL'] = 'Deselect all';
+$lang['L_STARTDUMP'] = 'Start Backup';
+$lang['L_LASTBUFROM'] = 'last update from';
+$lang['L_NOT_SUPPORTED'] = "This backup doesn't support this function.";
+$lang['L_MULTIDUMP'] = 'Multidump: Backup of <b>%d</b> Databases done.';
+$lang['L_FILESENDFTP'] = 'send file via FTP... please be patient. ';
+$lang['L_FTPCONNERROR'] = 'FTP connection not established! Connection with ';
+$lang['L_FTPCONNERROR1'] = ' as user ';
+$lang['L_FTPCONNERROR2'] = ' not possible';
+$lang['L_FTPCONNERROR3'] = 'FTP Upload failed! ';
+$lang['L_FTPCONNECTED1'] = 'Connected with ';
+$lang['L_FTPCONNECTED2'] = ' on ';
+$lang['L_FTPCONNECTED3'] = ' transfer successful';
+$lang['L_FILESENDSFTP'] = 'send file via SFTP... please be patient. ';
+$lang['L_SFTPCONNERROR'] = 'SFTP connection not established! Connection with ';
+$lang['L_NR_TABLES_SELECTED'] = '- with %s selected tables';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tables have been optimized.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s errors occured: <a href="log.php?r=3">view</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Fatal error: the CREATE-Statement of table '%s' in database '%s' couldn't be read!";
diff --git a/msd/language/en/lang_filemanagement.php b/msd/language/en/lang_filemanagement.php
index d9d71aeb..969798ea 100644
--- a/msd/language/en/lang_filemanagement.php
+++ b/msd/language/en/lang_filemanagement.php
@@ -1,79 +1,79 @@
 <?php
-$lang['L_CONVERT_START']="Start Conversion";
-$lang['L_CONVERT_TITLE']="Convert Dump to MSD Format";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Wrong parameters!  Conversion is not possible.";
-$lang['L_FM_UPLOADFILEREQUEST']="please choose a file.";
-$lang['L_FM_UPLOADNOTALLOWED1']="This file type is not supported.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Valid types are: *.gz and *.sql-files";
-$lang['L_FM_UPLOADMOVEERROR']="Couldn't move selected file to the upload directory.";
-$lang['L_FM_UPLOADFAILED']="The upload has failed!";
-$lang['L_FM_UPLOADFILEEXISTS']="A file with the same name already exists !";
-$lang['L_FM_NOFILE']="You didn't choose a file!";
-$lang['L_FM_DELETE1']="The file ";
-$lang['L_FM_DELETE2']=" was deleted successfully.";
-$lang['L_FM_DELETE3']=" couldn't be deleted!";
-$lang['L_FM_CHOOSE_FILE']="Chosen file:";
-$lang['L_FM_FILESIZE']="File size";
-$lang['L_FM_FILEDATE']="File date";
-$lang['L_FM_NOFILESFOUND']="No file found.";
-$lang['L_FM_TABLES']="Tables";
-$lang['L_FM_RECORDS']="Records";
-$lang['L_FM_ALL_BU']="All Backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="Last Backup";
-$lang['L_FM_TOTALSIZE']="Total Size";
-$lang['L_FM_SELECTTABLES']="Select tables";
-$lang['L_FM_COMMENT']="Enter Comment";
-$lang['L_FM_RESTORE']="Restore";
-$lang['L_FM_ALERTRESTORE1']="Should the database";
-$lang['L_FM_ALERTRESTORE2']="be restored with the records from the file";
-$lang['L_FM_ALERTRESTORE3']=" ?";
-$lang['L_FM_DELETE']="Delete";
-$lang['L_FM_ASKDELETE1']="Should the file(s)";
-$lang['L_FM_ASKDELETE2']="really be deleted?";
-$lang['L_FM_ASKDELETE3']="Do you want autodelete to be executed with configured rules now?";
-$lang['L_FM_ASKDELETE4']="Do you want to delete all backup files?";
-$lang['L_FM_ASKDELETE5']="Do you want to delete all backup files with ";
-$lang['L_FM_ASKDELETE5_2']="_* ?";
-$lang['L_FM_DELETEAUTO']="Run autodelete manually";
-$lang['L_FM_DELETEALL']="Delete all backup files";
-$lang['L_FM_DELETEALLFILTER']="Delete all with ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Start New Backup";
-$lang['L_FM_FILEUPLOAD']="Upload file";
-$lang['L_FM_DBNAME']="Database name";
-$lang['L_FM_FILES1']="Database Backups";
-$lang['L_FM_FILES2']="Database Structures";
-$lang['L_FM_AUTODEL1']="Autodelete: the following files were deleted because of maximum files setting:";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="Backup Configuration";
-$lang['L_FM_OLDBACKUP']="(unknown)";
-$lang['L_FM_RESTORE_HEADER']="Restore of Database \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Run the Perl Cron script";
-$lang['L_DOPERLTEST']="Test Perl Modules";
-$lang['L_DOSIMPLETEST']="Test Perl";
-$lang['L_PERLOUTPUT1']="Entry in crondump.pl for absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="URL for the browser or for external Cron job";
-$lang['L_PERLOUTPUT3']="Commandline in the Shell or for the Crontab";
-$lang['L_RESTORE_OF_TABLES']="Choose tables to be restored";
-$lang['L_CONVERTER']="Backup Converter";
-$lang['L_CONVERT_FILE']="File to be converted";
-$lang['L_CONVERT_FILENAME']="Name of destination file (without extension)";
-$lang['L_CONVERTING']="Converting";
-$lang['L_CONVERT_FILEREAD']="Read file '%s'";
-$lang['L_CONVERT_FINISHED']="Conversion finished, '%s' was written successfully.";
-$lang['L_NO_MSD_BACKUPFILE']="Backups of other scripts";
-$lang['L_MAX_UPLOAD_SIZE']="Maximum filesize";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="If your Dumpfile is bigger than the above mentioned limit, you must upload it via FTP into the directory \"work/backup\".
-After that you can choose it to begin a restore progress. ";
-$lang['L_ENCODING']="encoding";
-$lang['L_FM_CHOOSE_ENCODING']="Choose encoding of backup file";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper couldn't detect the encoding of the backup file automatically.
+
+$lang['L_CONVERT_START'] = 'Start Conversion';
+$lang['L_CONVERT_TITLE'] = 'Convert Dump to MOD Format';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Wrong parameters!  Conversion is not possible.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'please choose a file.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'This file type is not supported.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Valid types are: *.gz and *.sql-files';
+$lang['L_FM_UPLOADMOVEERROR'] = "Couldn't move selected file to the upload directory.";
+$lang['L_FM_UPLOADFAILED'] = 'The upload has failed!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'A file with the same name already exists !';
+$lang['L_FM_NOFILE'] = "You didn't choose a file!";
+$lang['L_FM_DELETE1'] = 'The file ';
+$lang['L_FM_DELETE2'] = ' was deleted successfully.';
+$lang['L_FM_DELETE3'] = " couldn't be deleted!";
+$lang['L_FM_CHOOSE_FILE'] = 'Chosen file:';
+$lang['L_FM_FILESIZE'] = 'File size';
+$lang['L_FM_FILEDATE'] = 'File date';
+$lang['L_FM_NOFILESFOUND'] = 'No file found.';
+$lang['L_FM_TABLES'] = 'Tables';
+$lang['L_FM_RECORDS'] = 'Records';
+$lang['L_FM_ALL_BU'] = 'All Backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'Last Backup';
+$lang['L_FM_TOTALSIZE'] = 'Total Size';
+$lang['L_FM_SELECTTABLES'] = 'Select tables';
+$lang['L_FM_COMMENT'] = 'Enter Comment';
+$lang['L_FM_RESTORE'] = 'Restore';
+$lang['L_FM_ALERTRESTORE1'] = 'Should the database';
+$lang['L_FM_ALERTRESTORE2'] = 'be restored with the records from the file';
+$lang['L_FM_ALERTRESTORE3'] = ' ?';
+$lang['L_FM_DELETE'] = 'Delete';
+$lang['L_FM_ASKDELETE1'] = 'Should the file(s)';
+$lang['L_FM_ASKDELETE2'] = 'really be deleted?';
+$lang['L_FM_ASKDELETE3'] = 'Do you want autodelete to be executed with configured rules now?';
+$lang['L_FM_ASKDELETE4'] = 'Do you want to delete all backup files?';
+$lang['L_FM_ASKDELETE5'] = 'Do you want to delete all backup files with ';
+$lang['L_FM_ASKDELETE5_2'] = '_* ?';
+$lang['L_FM_DELETEAUTO'] = 'Run autodelete manually';
+$lang['L_FM_DELETEALL'] = 'Delete all backup files';
+$lang['L_FM_DELETEALLFILTER'] = 'Delete all with ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Start New Backup';
+$lang['L_FM_FILEUPLOAD'] = 'Upload file';
+$lang['L_FM_DBNAME'] = 'Database name';
+$lang['L_FM_FILES1'] = 'Database Backups';
+$lang['L_FM_FILES2'] = 'Database Structures';
+$lang['L_FM_AUTODEL1'] = 'Autodelete: the following files were deleted because of maximum files setting:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'Backup Configuration';
+$lang['L_FM_OLDBACKUP'] = '(unknown)';
+$lang['L_FM_RESTORE_HEADER'] = 'Restore of Database "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Run the Perl Cron script';
+$lang['L_DOPERLTEST'] = 'Test Perl Modules';
+$lang['L_DOSIMPLETEST'] = 'Test Perl';
+$lang['L_PERLOUTPUT1'] = 'Entry in crondump.pl for absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'URL for the browser or for external Cron job';
+$lang['L_PERLOUTPUT3'] = 'Commandline in the Shell or for the Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Choose tables to be restored';
+$lang['L_CONVERTER'] = 'Backup Converter';
+$lang['L_CONVERT_FILE'] = 'File to be converted';
+$lang['L_CONVERT_FILENAME'] = 'Name of destination file (without extension)';
+$lang['L_CONVERTING'] = 'Converting';
+$lang['L_CONVERT_FILEREAD'] = "Read file '%s'";
+$lang['L_CONVERT_FINISHED'] = "Conversion finished, '%s' was written successfully.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Backups of other scripts';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximum filesize';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'If your Dumpfile is bigger than the above mentioned limit, you must upload it via FTP into the directory "work/backup".
+After that you can choose it to begin a restore progress. ';
+$lang['L_ENCODING'] = 'encoding';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Choose encoding of backup file';
+$lang['L_CHOOSE_CHARSET'] = "MyOOS [Dumper] couldn't detect the encoding of the backup file automatically.
 <br>You must choose the charset with which this backup was saved.
 <br>If you discover any problems with some characters after restoring, you can repeat the backup-progress and then choose another character set.
 <br>Good luck. ;)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/en/lang_help.php b/msd/language/en/lang_help.php
index 0e38e593..be9083b2 100644
--- a/msd/language/en/lang_help.php
+++ b/msd/language/en/lang_help.php
@@ -1,33 +1,37 @@
 <?php
-$lang['L_HELP_DB']="This is the list of all Databases";
-$lang['L_HELP_PRAEFIX']="the prefix is a string at the beginning of a table name, which works as a filter.";
-$lang['L_HELP_ZIP']="Compression with GZip - recommended state is 'activated'";
-$lang['L_HELP_MEMORYLIMIT']="The max. amount of memory in Bytes for the script\n0 = deactivated";
-$lang['L_MEMORY_LIMIT']="Memory limit";
-$lang['L_HELP_AD1']="If activated, then backup files will be deleted automatically.";
-$lang['L_HELP_AD3']="the maximum number of backup files (for autodelete)
-0 = deactivated";
-$lang['L_HELP_LANG']="select your language";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="To eliminate useless data you can instruct to empty the database before restore";
-$lang['L_HELP_CRONEXTENDER']="The extension of the Perl scripts, default is '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="The name of the configuration file for the Perl script";
-$lang['L_HELP_CRONPRINTOUT']="If deactivated the output will not be printed on screen.
-It is independant from the printing in the logfile.";
-$lang['L_HELP_CRONSAMEDB']="Use same database in Cron job like configured under Database?";
-$lang['L_HELP_CRONDBINDEX']="choose the database for Cron job";
-$lang['L_HELP_FTPTRANSFER']="if activated, file will be sent via FTP.";
-$lang['L_HELP_FTPSERVER']="Address of the FTP-Server";
-$lang['L_HELP_FTPPORT']="Port of the FTP-Server, standard: 21";
-$lang['L_HELP_FTPUSER']="enter username for FTP";
-$lang['L_HELP_FTPPASS']="enter password for FTP";
-$lang['L_HELP_FTPDIR']="where is the upload-dir? enter path!";
-$lang['L_HELP_SPEED']="Minimum and maximum speed, default is 50 to 5000";
-$lang['L_SPEED']="Speed control";
-$lang['L_HELP_CRONEXECPATH']="The place of the Perl scripts.\nStarting Point is the HTTP-Address (like Addresses in the Browser)\nAllowed are absolute or relative entries.";
-$lang['L_CRON_EXECPATH']="Path of Perl scripts";
-$lang['L_HELP_CRONCOMPLETELOG']="When activated the complete output is written in the complete_log-file.
-This is independent from text printing";
-$lang['L_HELP_FTP_MODE']="When problems occur while transfering via FTP, try to use the passive mode. ";
 
-
-?>
\ No newline at end of file
+$lang['L_HELP_DB'] = 'This is the list of all Databases';
+$lang['L_HELP_PRAEFIX'] = 'the prefix is a string at the beginning of a table name, which works as a filter.';
+$lang['L_HELP_ZIP'] = "Compression with GZip - recommended state is 'activated'";
+$lang['L_HELP_MEMORYLIMIT'] = "The max. amount of memory in Bytes for the script\n0 = deactivated";
+$lang['L_MEMORY_LIMIT'] = 'Memory limit';
+$lang['L_HELP_AD1'] = 'If activated, then backup files will be deleted automatically.';
+$lang['L_HELP_AD3'] = 'the maximum number of backup files (for autodelete)
+0 = deactivated';
+$lang['L_HELP_LANG'] = 'select your language';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'To eliminate useless data you can instruct to empty the database before restore';
+$lang['L_HELP_CRONEXTENDER'] = "The extension of the Perl scripts, default is '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'The name of the configuration file for the Perl script';
+$lang['L_HELP_CRONPRINTOUT'] = 'If deactivated the output will not be printed on screen.
+It is independant from the printing in the logfile.';
+$lang['L_HELP_CRONSAMEDB'] = 'Use same database in Cron job like configured under Database?';
+$lang['L_HELP_CRONDBINDEX'] = 'choose the database for Cron job';
+$lang['L_HELP_FTPTRANSFER'] = 'if activated, file will be sent via FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Address of the FTP-Server';
+$lang['L_HELP_FTPPORT'] = 'Port of the FTP-Server, standard: 21';
+$lang['L_HELP_FTPUSER'] = 'enter username for FTP';
+$lang['L_HELP_FTPPASS'] = 'enter password for FTP';
+$lang['L_HELP_FTPDIR'] = 'where is the upload-dir? enter path!';
+$lang['L_HELP_SFTPTRANSFER'] = 'if activated, file will be sent via SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Address of the SFTP-Server';
+$lang['L_HELP_SFTPPORT'] = 'Port of the SFTP-Server, standard: 22';
+$lang['L_HELP_SFTPUSER'] = 'enter username for SFTP';
+$lang['L_HELP_SFTPPASS'] = 'enter password for SFTP';
+$lang['L_HELP_SFTPDIR'] = 'where is the upload-dir? enter path!';
+$lang['L_HELP_SPEED'] = 'Minimum and maximum speed, default is 50 to 5000';
+$lang['L_SPEED'] = 'Speed control';
+$lang['L_HELP_CRONEXECPATH'] = "The place of the Perl scripts.\nStarting Point is the HTTP-Address (like Addresses in the Browser)\nAllowed are absolute or relative entries.";
+$lang['L_CRON_EXECPATH'] = 'Path of Perl scripts';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'When activated the complete output is written in the complete_log-file.
+This is independent from text printing';
+$lang['L_HELP_FTP_MODE'] = 'When problems occur while transfering via FTP, try to use the passive mode. ';
diff --git a/msd/language/en/lang_install.php b/msd/language/en/lang_install.php
index 42d7b56a..063aea8c 100644
--- a/msd/language/en/lang_install.php
+++ b/msd/language/en/lang_install.php
@@ -1,89 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Installation completed  --> <a href=\"index.php\">start MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Back to main menu";
-$lang['L_INSTALLMENU']="Main menu";
-$lang['L_STEP']="Step";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Uninstall";
-$lang['L_TOOLS']="Tools";
-$lang['L_EDITCONF']="Edit configuration";
-$lang['L_OSWEITER']="Continue without saving";
-$lang['L_ERRORMAN']="<strong>Error while saving the Configuration!</strong><br>Please edit the File ";
-$lang['L_MANUELL']="manually";
-$lang['L_CREATEDIRS']="Create Directories";
-$lang['L_INSTALL_CONTINUE']="Continue with installation";
-$lang['L_CONNECTTOMYSQL']="Connect to MySQL ";
-$lang['L_DBPARAMETER']="Database Parameters";
-$lang['L_CONFIGNOTWRITABLE']="I cannot write to file \"config.php\".
-Please use your FTP program and chmod this file to 0777.";
-$lang['L_DBCONNECTION']="Database Connection";
-$lang['L_CONNECTIONERROR']="Error: unable to connect.";
-$lang['L_CONNECTION_OK']="Database connection was established.";
-$lang['L_SAVEANDCONTINUE']="Save and continue installation";
-$lang['L_CONFBASIC']="Basic Parameter";
-$lang['L_INSTALL_STEP2FINISHED']="Database parameters were saved successfully.";
-$lang['L_INSTALL_STEP2_1']="Continue installation with the default settings";
-$lang['L_LASTSTEP']="Installation Finish";
-$lang['L_FTPMODE']="Create necessary directories in safe-mode";
-$lang['L_IDOMANUAL']="I create the directories myself";
-$lang['L_DOFROM']="starting from";
-$lang['L_FTPMODE2']="Create the dirs with FTP:";
-$lang['L_CONNECT']="connect";
-$lang['L_DIRS_CREATED']="The directories are created and correctly permissioned.";
-$lang['L_CONNECT_TO']="connect to";
-$lang['L_CHANGEDIR']="change to dir";
-$lang['L_CHANGEDIRERROR']="change to dir was not possible";
-$lang['L_FTP_OK']="FTP parameter are ok";
-$lang['L_CREATEDIRS2']="Create directories";
-$lang['L_FTP_NOTCONNECTED']="FTP connection not established!";
-$lang['L_CONNWITH']="Connection with";
-$lang['L_ASUSER']="as user";
-$lang['L_NOTPOSSIBLE']="not possible";
-$lang['L_DIRCR1']="create workdir";
-$lang['L_DIRCR2']="create backupdir";
-$lang['L_DIRCR4']="create logdir";
-$lang['L_DIRCR5']="create configurationdir";
-$lang['L_INDIR']="now in dir";
-$lang['L_CHECK_DIRS']="Check my directories";
-$lang['L_DISABLEDFUNCTIONS']="Disabled Functions";
-$lang['L_NOFTPPOSSIBLE']="You don't have FTP functions !";
-$lang['L_NOGZPOSSIBLE']="You don't have compression functions !";
-$lang['L_UI1']="All working directories which can contain backups will be deleted.";
-$lang['L_UI2']="Are you sure you want that?";
-$lang['L_UI3']="no, cancel immediately";
-$lang['L_UI4']="yes, please continue";
-$lang['L_UI5']="delete working directories";
-$lang['L_UI6']="all was deleted successfully.";
-$lang['L_UI7']="Please delete the script directory";
-$lang['L_UI8']="one level up";
-$lang['L_UI9']="An error occured, deleting was not possible</p>Error with directory ";
-$lang['L_IMPORT']="Import Configuration";
-$lang['L_IMPORT3']="Configuration was loaded ...";
-$lang['L_IMPORT4']="Configuration was saved.";
-$lang['L_IMPORT5']="Start MySQLDumper";
-$lang['L_IMPORT6']="Installation Menu";
-$lang['L_IMPORT7']="Upload configuration";
-$lang['L_IMPORT8']="back to upload";
-$lang['L_IMPORT9']="This is not a configuration backup !";
-$lang['L_IMPORT10']="Configuration was uploaded successfully ...";
-$lang['L_IMPORT11']="<strong>Error: </strong>There were problems writing sql_statements";
-$lang['L_IMPORT12']="<strong>Error: </strong>There were problems writing config.php";
-$lang['L_INSTALL_HELP_PORT']="(empty = Default Port)";
-$lang['L_INSTALL_HELP_SOCKET']="(empty = Default Socket)";
-$lang['L_TRYAGAIN']="Try again";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="found db";
-$lang['L_FM_FILEUPLOAD']="Upload file";
-$lang['L_PASS']="Password";
-$lang['L_NO_DB_FOUND_INFO']="The connection to the database was successfully established.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>Installation completed  --> <a href="index.php">start MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Back to main menu';
+$lang['L_INSTALLMENU'] = 'Main menu';
+$lang['L_STEP'] = 'Step';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Uninstall';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_EDITCONF'] = 'Edit configuration';
+$lang['L_OSWEITER'] = 'Continue without saving';
+$lang['L_ERRORMAN'] = '<strong>Error while saving the Configuration!</strong><br>Please edit the File ';
+$lang['L_MANUELL'] = 'manually';
+$lang['L_CREATEDIRS'] = 'Create Directories';
+$lang['L_INSTALL_CONTINUE'] = 'Continue with installation';
+$lang['L_CONNECTTOMYSQL'] = 'Connect to MySQL ';
+$lang['L_DBPARAMETER'] = 'Database Parameters';
+$lang['L_CONFIGNOTWRITABLE'] = 'I cannot write to file "config.php".
+Please use your FTP program and chmod this file to 0777.';
+$lang['L_DBCONNECTION'] = 'Database Connection';
+$lang['L_CONNECTIONERROR'] = 'Error: unable to connect.';
+$lang['L_CONNECTION_OK'] = 'Database connection was established.';
+$lang['L_SAVEANDCONTINUE'] = 'Save and continue installation';
+$lang['L_CONFBASIC'] = 'Basic Parameter';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Database parameters were saved successfully.';
+$lang['L_INSTALL_STEP2_1'] = 'Continue installation with the default settings';
+$lang['L_LASTSTEP'] = 'Installation Finish';
+$lang['L_FTPMODE'] = 'Create necessary directories in safe-mode';
+$lang['L_IDOMANUAL'] = 'I create the directories myself';
+$lang['L_DOFROM'] = 'starting from';
+$lang['L_FTPMODE2'] = 'Create the dirs with FTP:';
+$lang['L_CONNECT'] = 'connect';
+$lang['L_DIRS_CREATED'] = 'The directories are created and correctly permissioned.';
+$lang['L_CONNECT_TO'] = 'connect to';
+$lang['L_CHANGEDIR'] = 'change to dir';
+$lang['L_CHANGEDIRERROR'] = 'change to dir was not possible';
+$lang['L_FTP_OK'] = 'FTP parameter are ok';
+$lang['L_CREATEDIRS2'] = 'Create directories';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP connection not established!';
+$lang['L_CONNWITH'] = 'Connection with';
+$lang['L_ASUSER'] = 'as user';
+$lang['L_NOTPOSSIBLE'] = 'not possible';
+$lang['L_DIRCR1'] = 'create workdir';
+$lang['L_DIRCR2'] = 'create backupdir';
+$lang['L_DIRCR4'] = 'create logdir';
+$lang['L_DIRCR5'] = 'create configurationdir';
+$lang['L_INDIR'] = 'now in dir';
+$lang['L_CHECK_DIRS'] = 'Check my directories';
+$lang['L_DISABLEDFUNCTIONS'] = 'Disabled Functions';
+$lang['L_NOFTPPOSSIBLE'] = "You don't have FTP functions !";
+$lang['L_NOGZPOSSIBLE'] = "You don't have compression functions !";
+$lang['L_UI1'] = 'All working directories which can contain backups will be deleted.';
+$lang['L_UI2'] = 'Are you sure you want that?';
+$lang['L_UI3'] = 'no, cancel immediately';
+$lang['L_UI4'] = 'yes, please continue';
+$lang['L_UI5'] = 'delete working directories';
+$lang['L_UI6'] = 'all was deleted successfully.';
+$lang['L_UI7'] = 'Please delete the script directory';
+$lang['L_UI8'] = 'one level up';
+$lang['L_UI9'] = 'An error occured, deleting was not possible</p>Error with directory ';
+$lang['L_IMPORT'] = 'Import Configuration';
+$lang['L_IMPORT3'] = 'Configuration was loaded ...';
+$lang['L_IMPORT4'] = 'Configuration was saved.';
+$lang['L_IMPORT5'] = 'Start MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Installation Menu';
+$lang['L_IMPORT7'] = 'Upload configuration';
+$lang['L_IMPORT8'] = 'back to upload';
+$lang['L_IMPORT9'] = 'This is not a configuration backup !';
+$lang['L_IMPORT10'] = 'Configuration was uploaded successfully ...';
+$lang['L_IMPORT11'] = '<strong>Error: </strong>There were problems writing sql_statements';
+$lang['L_IMPORT12'] = '<strong>Error: </strong>There were problems writing config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(empty = Default Port)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(empty = Default Socket)';
+$lang['L_TRYAGAIN'] = 'Try again';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'found db';
+$lang['L_FM_FILEUPLOAD'] = 'Upload file';
+$lang['L_PASS'] = 'Password';
+$lang['L_NO_DB_FOUND_INFO'] = 'The connection to the database was successfully established.<br>
 Your userdata is valid and was accepted by the MySQL-Server.<br>
-But MySQLDumper was not able to find any database.<br>
+But MyOOS [Dumper] was not able to find any database.<br>
 The automatic detection via script is blocked on some servers.<br>
 You must enter your database name manually after the installation is finished.
-Click on \"configuration\" \"Connection Parameter - display\" and enter the database name there.";
-$lang['L_SAFEMODEDESC']="Because PHP is running in safe_mode you need to create the following directories manually using your FTP-Programm:";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+Click on "configuration" "Connection Parameter - display" and enter the database name there.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/en/lang_log.php b/msd/language/en/lang_log.php
index 7764bec4..1ae40c99 100644
--- a/msd/language/en/lang_log.php
+++ b/msd/language/en/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="delete Log";
-$lang['L_LOGFILEFORMAT']="Log file format";
-$lang['L_LOGFILENOTWRITABLE']="Can't write Log file !";
-$lang['L_NOREVERSE']="Oldest entry first";
-$lang['L_REVERSE']="Last entry first";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'delete Log';
+$lang['L_LOGFILEFORMAT'] = 'Log file format';
+$lang['L_LOGFILENOTWRITABLE'] = "Can't write Log file !";
+$lang['L_NOREVERSE'] = 'Oldest entry first';
+$lang['L_REVERSE'] = 'Last entry first';
diff --git a/msd/language/en/lang_main.php b/msd/language/en/lang_main.php
index 20af74f6..98a1d928 100644
--- a/msd/language/en/lang_main.php
+++ b/msd/language/en/lang_main.php
@@ -1,78 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="You don't have FTP functions !";
-$lang['L_INFO_LOCATION']="Your location is ";
-$lang['L_INFO_DATABASES']="The following database(s) are on your server:";
-$lang['L_INFO_NODB']="database does not exist.";
-$lang['L_INFO_DBDETAIL']="Detailed info of database ";
-$lang['L_INFO_DBEMPTY']="The database is empty !";
-$lang['L_INFO_RECORDS']="Records";
-$lang['L_INFO_SIZE']="Size";
-$lang['L_INFO_LASTUPDATE']="Last update";
-$lang['L_INFO_SUM']="total";
-$lang['L_INFO_OPTIMIZED']="optimized";
-$lang['L_OPTIMIZE_DATABASES']="Optimize Tables";
-$lang['L_CHECK_TABLES']="Check Tables";
-$lang['L_CLEAR_DATABASE']="Clear database";
-$lang['L_DELETE_DATABASE']="Delete database";
-$lang['L_INFO_CLEARED']="was cleared";
-$lang['L_INFO_DELETED']="was deleted";
-$lang['L_INFO_EMPTYDB1']="Should the Database";
-$lang['L_INFO_EMPTYDB2']=" be truncated? (Attention: All Data will be lost forever!)";
-$lang['L_INFO_KILLDB']=" be deleted? (Attention: All Data will be lost forever!)";
-$lang['L_PROCESSKILL1']="The script tries to kill process ";
-$lang['L_PROCESSKILL2']=".";
-$lang['L_PROCESSKILL3']="The script tries since  ";
-$lang['L_PROCESSKILL4']=" sec. to kill the process ";
-$lang['L_HTACC_CREATE']="Create directory protection";
-$lang['L_ENCRYPTION_TYPE']="Kind of encrypting";
-$lang['L_HTACC_CRYPT']="Crypt 8 Chars max (Linux and Unix-Systems)";
-$lang['L_HTACC_MD5']="MD5 (Linux and Unix-Systems)";
-$lang['L_HTACC_NO_ENCRYPTION']="plain text, no cryption (Windows)";
-$lang['L_HTACCESS8']="It already exists an directory protection. If you create a new one, the older one will be overwritten !";
-$lang['L_HTACC_NO_USERNAME']="You have to enter a name!";
-$lang['L_PASSWORDS_UNEQUAL']="The Passwords are not identical or empty !";
-$lang['L_HTACC_CONFIRM_DELETE']="Should the directory protection be written now ?";
-$lang['L_HTACC_CREATED']="The directory protection was created.";
-$lang['L_HTACC_CONTENT']="Contents of file";
-$lang['L_HTACC_CREATE_ERROR']="There was an error while creating the directory protection !<br>Please create the 2 files manually with the following content";
-$lang['L_HTACC_PROPOSED']="Urgently recommended";
-$lang['L_HTACC_EDIT']="Edit .htaccess";
-$lang['L_HTACCESS18']="Create .htaccess in ";
-$lang['L_HTACCESS19']="Reload ";
-$lang['L_HTACCESS20']="Execute script";
-$lang['L_HTACCESS21']="Add handler";
-$lang['L_HTACCESS22']="Make executable";
-$lang['L_HTACCESS23']="Directory Listing";
-$lang['L_HTACCESS24']="Error Document";
-$lang['L_HTACCESS25']="Activate rewrite";
-$lang['L_HTACCESS26']="Deny / Allow";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Error Log";
-$lang['L_HTACCESS29']="More examples and documentation";
-$lang['L_HTACCESS30']="Provider";
-$lang['L_HTACCESS31']="General";
-$lang['L_HTACCESS32']="Attention! The .htaccess directly affects the browser's behavior.<br>With incorrect content, these pages may no longer be accessible.";
-$lang['L_PHPBUG']="Bug in zlib ! No Compression possible!";
-$lang['L_DISABLEDFUNCTIONS']="Disabled Functions";
-$lang['L_NOGZPOSSIBLE']="Because Zlib is not installed, you cannot use GZip-Functions!";
-$lang['L_DELETE_HTACCESS']="Remove directory protection (delete .htaccess)";
-$lang['L_WRONG_RIGHTS']="The file or the directory '%s' is not writable for me.<br>
+
+$lang['L_NOFTPPOSSIBLE'] = "You don't have FTP functions !";
+$lang['L_INFO_LOCATION'] = 'Your location is ';
+$lang['L_INFO_DATABASES'] = 'The following database(s) are on your server:';
+$lang['L_INFO_NODB'] = 'database does not exist.';
+$lang['L_INFO_DBDETAIL'] = 'Detailed info of database ';
+$lang['L_INFO_DBEMPTY'] = 'The database is empty !';
+$lang['L_INFO_RECORDS'] = 'Records';
+$lang['L_INFO_SIZE'] = 'Size';
+$lang['L_INFO_LASTUPDATE'] = 'Last update';
+$lang['L_INFO_SUM'] = 'total';
+$lang['L_INFO_OPTIMIZED'] = 'optimized';
+$lang['L_OPTIMIZE_DATABASES'] = 'Optimize Tables';
+$lang['L_CHECK_TABLES'] = 'Check Tables';
+$lang['L_CLEAR_DATABASE'] = 'Clear database';
+$lang['L_DELETE_DATABASE'] = 'Delete database';
+$lang['L_INFO_CLEARED'] = 'was cleared';
+$lang['L_INFO_DELETED'] = 'was deleted';
+$lang['L_INFO_EMPTYDB1'] = 'Should the Database';
+$lang['L_INFO_EMPTYDB2'] = ' be truncated? (Attention: All Data will be lost forever!)';
+$lang['L_INFO_KILLDB'] = ' be deleted? (Attention: All Data will be lost forever!)';
+$lang['L_PROCESSKILL1'] = 'The script tries to kill process ';
+$lang['L_PROCESSKILL2'] = '.';
+$lang['L_PROCESSKILL3'] = 'The script tries since  ';
+$lang['L_PROCESSKILL4'] = ' sec. to kill the process ';
+$lang['L_HTACC_CREATE'] = 'Create directory protection';
+$lang['L_ENCRYPTION_TYPE'] = 'Kind of encrypting';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'It already exists an directory protection. If you create a new one, the older one will be overwritten !';
+$lang['L_HTACC_NO_USERNAME'] = 'You have to enter a name!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'The Passwords are not identical or empty !';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Should the directory protection be written now?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'The directory protection was created.';
+$lang['L_HTACC_CONTENT'] = 'Contents of file';
+$lang['L_HTACC_CREATE_ERROR'] = 'There was an error while creating the directory protection !<br>Please create the 2 files manually with the following content';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'Edit .htaccess';
+$lang['L_HTACCESS18'] = 'Create .htaccess in ';
+$lang['L_HTACCESS19'] = 'Reload ';
+$lang['L_HTACCESS20'] = 'Execute script';
+$lang['L_HTACCESS21'] = 'Add handler';
+$lang['L_HTACCESS22'] = 'Make executable';
+$lang['L_HTACCESS23'] = 'Directory Listing';
+$lang['L_HTACCESS24'] = 'Error Document';
+$lang['L_HTACCESS25'] = 'Activate rewrite';
+$lang['L_HTACCESS26'] = 'Deny / Allow';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Error Log';
+$lang['L_HTACCESS29'] = 'More examples and documentation';
+$lang['L_HTACCESS30'] = 'Provider';
+$lang['L_HTACCESS31'] = 'General';
+$lang['L_HTACCESS32'] = "Attention! The .htaccess directly affects the browser's behavior.<br>With incorrect content, these pages may no longer be accessible.";
+$lang['L_DISABLEDFUNCTIONS'] = 'Disabled Functions';
+$lang['L_NOGZPOSSIBLE'] = 'Because Zlib is not installed, you cannot use GZip-Functions!';
+$lang['L_DELETE_HTACCESS'] = 'Remove directory protection (delete .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "The file or the directory '%s' is not writable for me.<br>
 The rights (chmod) are not set properly or it has the wrong owner.<br>
 Pleae set the correct attributes using your FTP program.<br>
 The file or the directory needs to be set to %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Couldn' t create dir '%s'. 
+$lang['L_CANT_CREATE_DIR'] = "Couldn' t create dir '%s'.
 Please create it using your FTP program.";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="couldn't find file";
-
-
-?>
\ No newline at end of file
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = "couldn't find file";
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/en/lang_restore.php b/msd/language/en/lang_restore.php
index 9a0075c0..250947d0 100644
--- a/msd/language/en/lang_restore.php
+++ b/msd/language/en/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Up to now <b>%d</b> tables were created.";
-$lang['L_FILE_MISSING']="couldn't find file";
-$lang['L_RESTORE_DB']="Database '<b>%s</b>' on '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> tables created.";
-$lang['L_RESTORE_RUN1']="<br>Up to now  <b>%s</b> of <b>%s</b> records were successfully added.";
-$lang['L_RESTORE_RUN2']="<br>Now the table '<b>%s</b>' is restoring.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> records inserted.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Up to now <b>%d</b> of <b>%d</b> tables were created.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Congratulations.</b><br><br>The restoration of the database is done.<br>All data from the Backup file was restored.<br><br>Everything is done. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Error:<br>Selection of database <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> failed!";
-$lang['L_FILE_OPEN_ERROR']="Error: could not open file.";
-$lang['L_PROGRESS_OVER_ALL']="Overall Progress";
-$lang['L_BACK_TO_OVERVIEW']="Database Overview";
-$lang['L_RESTORE_RUN0']="<br>up to now <b>%s</b> records were successfully added.";
-$lang['L_UNKNOWN_SQLCOMMAND']="unknown SQL-Command";
-$lang['L_NOTICES']="Notices";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Up to now <b>%d</b> tables were created.';
+$lang['L_FILE_MISSING'] = "couldn't find file";
+$lang['L_RESTORE_DB'] = "Database '<b>%s</b>' on '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> tables created.';
+$lang['L_RESTORE_RUN1'] = '<br>Up to now  <b>%s</b> of <b>%s</b> records were successfully added.';
+$lang['L_RESTORE_RUN2'] = "<br>Now the table '<b>%s</b>' is restoring.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> records inserted.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Up to now <b>%d</b> of <b>%d</b> tables were created.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Congratulations.</b><br><br>The restoration of the database is done.<br>All data from the Backup file was restored.<br><br>Everything is done. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>Error:<br>Selection of database <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> failed!';
+$lang['L_FILE_OPEN_ERROR'] = 'Error: could not open file.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Overall Progress';
+$lang['L_BACK_TO_OVERVIEW'] = 'Database Overview';
+$lang['L_RESTORE_RUN0'] = '<br>up to now <b>%s</b> records were successfully added.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'unknown SQL-Command';
+$lang['L_NOTICES'] = 'Notices';
diff --git a/msd/language/en/lang_sql.php b/msd/language/en/lang_sql.php
index d5a530fb..96384c03 100644
--- a/msd/language/en/lang_sql.php
+++ b/msd/language/en/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Command";
-$lang['L_IMPORT_NOTABLE']="No table was selected for import!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="The execution of SQL Statements can manipulate data. TAKE CARE! The Authors don't accept any liability for damaged or lost data.";
-$lang['L_SQL_EXEC']="Execute SQL Statement";
-$lang['L_SQL_DATAVIEW']="Data View";
-$lang['L_SQL_TABLEVIEW']="Table View";
-$lang['L_SQL_VONINS']="from totally";
-$lang['L_SQL_NODATA']="no records";
-$lang['L_SQL_RECORDUPDATED']="Record was updated";
-$lang['L_SQL_RECORDINSERTED']="Record was added";
-$lang['L_SQL_BACKDBOVERVIEW']="Back to Overview";
-$lang['L_SQL_RECORDDELETED']="Record was deleted";
-$lang['L_ASKTABLEEMPTY']="Should the table `%s` be emptied?";
-$lang['L_SQL_RECORDEDIT']="edit record";
-$lang['L_SQL_RECORDNEW']="new record";
-$lang['L_ASKDELETERECORD']="Are you sure to delete this record?";
-$lang['L_ASKDELETETABLE']="Should the table `%s` be deleted?";
-$lang['L_SQL_BEFEHLE']="SQL Commands";
-$lang['L_SQL_BEFEHLNEU']="New command";
-$lang['L_SQL_BEFEHLSAVED1']="SQL Command";
-$lang['L_SQL_BEFEHLSAVED2']="was added";
-$lang['L_SQL_BEFEHLSAVED3']="was saved";
-$lang['L_SQL_BEFEHLSAVED4']="was moved up";
-$lang['L_SQL_BEFEHLSAVED5']="was deleted";
-$lang['L_SQL_QUERYENTRY']="The Query contains";
-$lang['L_SQL_COLUMNS']="Columns";
-$lang['L_ASKDBDELETE']="Do you want to delete the Database `%s` with the content?";
-$lang['L_ASKDBEMPTY']="Do you want to empty the Database `%s` ?";
-$lang['L_ASKDBCOPY']="Do you  want to copy database `%s` to database `%s`?";
-$lang['L_SQL_TABLENEW']="Edit Tables";
-$lang['L_SQL_OUTPUT']="SQL Output";
-$lang['L_DO_NOW']="operate now";
-$lang['L_SQL_NAMEDEST_MISSING']="Name of Destination is missing !";
-$lang['L_ASKDELETEFIELD']="Do you want to delete the Field?";
-$lang['L_SQL_COMMANDS_IN']=" lines in ";
-$lang['L_SQL_COMMANDS_IN2']="  sec. parsed.";
-$lang['L_SQL_OUT1']="Executed ";
-$lang['L_SQL_OUT2']="Commands";
-$lang['L_SQL_OUT3']="It had ";
-$lang['L_SQL_OUT4']="Comments";
-$lang['L_SQL_OUT5']="Because the output contains more than 5000 lines it isn't displayed.";
-$lang['L_SQL_SELECDB']="Select Database";
-$lang['L_SQL_TABLESOFDB']="Tables of Database";
-$lang['L_SQL_EDIT']="edit";
-$lang['L_SQL_NOFIELDDELETE']="Delete is not possible because Tables must contain at least one field.";
-$lang['L_SQL_FIELDDELETE1']="The Field";
-$lang['L_SQL_DELETED']="was deleted";
-$lang['L_SQL_CHANGED']="was changed.";
-$lang['L_SQL_CREATED']="was created.";
-$lang['L_SQL_NODEST_COPY']="No Copy without Destination !";
-$lang['L_SQL_DESTTABLE_EXISTS']="Destination Table exists !";
-$lang['L_SQL_SCOPY']="Table structure of `%s` was copied in Table `%s`.";
-$lang['L_SQL_TCOPY']="Table `%s` was copied with data in Table `%s`.";
-$lang['L_SQL_TABLENONAME']="Table needs a name!";
-$lang['L_SQL_TBLNAMEEMPTY']="Table name can't be empty!";
-$lang['L_SQL_COLLATENOTMATCH']="Charset and Collation don't fit together!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Error: No valid fieldname";
-$lang['L_SQL_CREATETABLE']="create table";
-$lang['L_SQL_COPYTABLE']="copy table";
-$lang['L_SQL_STRUCTUREONLY']="Only Structure";
-$lang['L_SQL_STRUCTUREDATA']="Structure and Data";
-$lang['L_SQL_NOTABLESINDB']="No tables found in Database";
-$lang['L_SQL_SELECTTABLE']="select table";
-$lang['L_SQL_SHOWDATATABLE']="Show Data of Table";
-$lang['L_SQL_TBLPROPSOF']="Table properties of";
-$lang['L_SQL_EDITFIELD']="Edit field";
-$lang['L_SQL_NEWFIELD']="New field";
-$lang['L_SQL_INDEXES']="Indices";
-$lang['L_SQL_ATPOSITION']="insert at position";
-$lang['L_SQL_FIRST']="first";
-$lang['L_SQL_AFTER']="after";
-$lang['L_SQL_CHANGEFIELD']="change field";
-$lang['L_SQL_INSERTFIELD']="insert field";
-$lang['L_SQL_INSERTNEWFIELD']="insert new field";
-$lang['L_SQL_TABLEINDEXES']="Indexes of table";
-$lang['L_SQL_ALLOWDUPS']="Duplicates allowed";
-$lang['L_SQL_CARDINALITY']="Cardinality";
-$lang['L_SQL_TABLENOINDEXES']="No Indexes in Table";
-$lang['L_SQL_CREATEINDEX']="create new index";
-$lang['L_SQL_WASEMPTIED']="was emptied";
-$lang['L_SQL_RENAMEDTO']="was renamed to";
-$lang['L_SQL_DBCOPY']="The Content of Database `%s` was copied in Database `%s`.";
-$lang['L_SQL_DBSCOPY']="The Structure of Database `%s` was copied in Database `%s`.";
-$lang['L_SQL_WASCREATED']="was created";
-$lang['L_SQL_RENAMEDB']="Rename Database";
-$lang['L_SQL_ACTIONS']="Actions";
-$lang['L_SQL_CHOOSEACTION']="Choose action";
-$lang['L_SQL_DELETEDB']="Delete Database";
-$lang['L_SQL_EMPTYDB']="Empty Database";
-$lang['L_SQL_COPYDATADB']="Copy complete Database to";
-$lang['L_SQL_COPYSDB']="Copy Structure of Database";
-$lang['L_SQL_IMEXPORT']="Import-Export";
-$lang['L_INFO_RECORDS']="records";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="Should the table `%s` be emptied and the Indices reset?";
-$lang['L_EDIT']="edit";
-$lang['L_DELETE']="delete";
-$lang['L_EMPTY']="empty";
-$lang['L_EMPTYKEYS']="empty and reset indexes";
-$lang['L_SQL_TABLEEMPTIED']="Table `%s` was deleted.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Table `%s` was deleted and the indices were reset.";
-$lang['L_SQL_LIBRARY']="SQL Library";
-$lang['L_SQL_ATTRIBUTES']="Attributes";
-$lang['L_SQL_UPLOADEDFILE']="loaded file: ";
-$lang['L_SQL_IMPORT']="Import in Database `%s`";
-$lang['L_EXPORT']="Export";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Import Options";
-$lang['L_CSVOPTIONS']="CSV Options";
-$lang['L_IMPORTTABLE']="Import in Table";
-$lang['L_NEWTABLE']="New table";
-$lang['L_IMPORTSOURCE']="Import Source";
-$lang['L_FROMTEXTBOX']="from text box";
-$lang['L_FROMFILE']="from file";
-$lang['L_EMPTYTABLEBEFORE']="Empty table before";
-$lang['L_CREATEAUTOINDEX']="Create Auto-Index";
-$lang['L_CSV_NAMEFIRSTLINE']="Field names in first line";
-$lang['L_CSV_FIELDSEPERATE']="Fields separated with";
-$lang['L_CSV_FIELDSENCLOSED']="Fields enclosed by";
-$lang['L_CSV_FIELDSESCAPE']="Fields escaped with";
-$lang['L_CSV_EOL']="Seperate lines with";
-$lang['L_CSV_NULL']="Replace NULL with";
-$lang['L_CSV_FILEOPEN']="Open CSV file";
-$lang['L_IMPORTIEREN']="Import";
-$lang['L_SQL_EXPORT']="Export from Database `%s`";
-$lang['L_EXPORTOPTIONS']="Export Options";
-$lang['L_EXCEL2003']="Excel from 2003";
-$lang['L_SHOWRESULT']="show result";
-$lang['L_SENDRESULTASFILE']="send result as file";
-$lang['L_EXPORTLINES']="<strong>%s</strong> lines exported";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="The count of fields doesn't match with that of the data to import (%d instead of %d).";
-$lang['L_CSV_FIELDSLINES']="%d fields recognized, totally %d lines";
-$lang['L_CSV_ERRORCREATETABLE']="Error while creating table `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="please choose a file.";
-$lang['L_CSV_NODATA']="No data found for import!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="general functions";
-$lang['L_SQLLIB_RESETAUTO']="reset auto-increment";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="deactivate Board";
-$lang['L_SQLLIB_ACTIVATEBOARD']="activate Board";
-$lang['L_SQL_NOTABLESSELECTED']="No tables selected !";
-$lang['L_TOOLS']="Tools";
-$lang['L_TOOLS_TOOLBOX']="Select Database / Datebase functions / Import - Export ";
-$lang['L_SQL_OPENFILE']="Open SQL-File";
-$lang['L_SQL_OPENFILE_BUTTON']="Upload";
-$lang['L_MAX_UPLOAD_SIZE']="Maximum file size";
-$lang['L_SQL_SEARCH']="Search";
-$lang['L_SQL_SEARCHWORDS']="Searchword(s)";
-$lang['L_START_SQL_SEARCH']="start search";
-$lang['L_RESET_SEARCHWORDS']="reset search words";
-$lang['L_SEARCH_OPTIONS']="Search options";
-$lang['L_SEARCH_RESULTS']="The search for \"<b>%s</b>\" in table \"<b>%s</b>\" brings the following results";
-$lang['L_SEARCH_NO_RESULTS']="The search for \"<b>%s</b>\" in table \"<b>%s</b>\" doesn't bring any hits!";
-$lang['L_NO_ENTRIES']="Table \"<b>%s</b>\" is empty and doesn't have any entry.";
-$lang['L_SEARCH_ACCESS_KEYS']="Browse: forward=ALT+V, backwards=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="a column must have one of the search words (OR-search)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="a row must contain all of the search words but they can be in any column (could take some time)";
-$lang['L_SEARCH_OPTIONS_AND']="a column must contain all search words (AND-search)";
-$lang['L_SEARCH_IN_TABLE']="Search in table";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Edit table structure";
-$lang['L_DEFAULT_CHARSET']="Default character set";
-$lang['L_TITLE_KEY_PRIMARY']="Primary key";
-$lang['L_TITLE_KEY_UNIQUE']="Unique key";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Fulltext key";
-$lang['L_TITLE_NOKEY']="No key";
-$lang['L_TITLE_SEARCH']="Search";
-$lang['L_TITLE_MYSQL_HELP']="MySQl Documentation";
-$lang['L_TITLE_UPLOAD']="Upload SQL file";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="Size";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Command';
+$lang['L_IMPORT_NOTABLE'] = 'No table was selected for import!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = "The execution of SQL Statements can manipulate data. TAKE CARE! The Authors don't accept any liability for damaged or lost data.";
+$lang['L_SQL_EXEC'] = 'Execute SQL Statement';
+$lang['L_SQL_DATAVIEW'] = 'Data View';
+$lang['L_SQL_TABLEVIEW'] = 'Table View';
+$lang['L_SQL_VONINS'] = 'from totally';
+$lang['L_SQL_NODATA'] = 'no records';
+$lang['L_SQL_RECORDUPDATED'] = 'Record was updated';
+$lang['L_SQL_RECORDINSERTED'] = 'Record was added';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'Back to Overview';
+$lang['L_SQL_RECORDDELETED'] = 'Record was deleted';
+$lang['L_ASKTABLEEMPTY'] = 'Should the table `%s` be emptied?';
+$lang['L_SQL_RECORDEDIT'] = 'edit record';
+$lang['L_SQL_RECORDNEW'] = 'new record';
+$lang['L_ASKDELETERECORD'] = 'Are you sure to delete this record?';
+$lang['L_ASKDELETETABLE'] = 'Should the table `%s` be deleted?';
+$lang['L_SQL_BEFEHLE'] = 'SQL Commands';
+$lang['L_SQL_BEFEHLNEU'] = 'New command';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL Command';
+$lang['L_SQL_BEFEHLSAVED2'] = 'was added';
+$lang['L_SQL_BEFEHLSAVED3'] = 'was saved';
+$lang['L_SQL_BEFEHLSAVED4'] = 'was moved up';
+$lang['L_SQL_BEFEHLSAVED5'] = 'was deleted';
+$lang['L_SQL_QUERYENTRY'] = 'The Query contains';
+$lang['L_SQL_COLUMNS'] = 'Columns';
+$lang['L_ASKDBDELETE'] = 'Do you want to delete the Database `%s` with the content?';
+$lang['L_ASKDBEMPTY'] = 'Do you want to empty the Database `%s` ?';
+$lang['L_ASKDBCOPY'] = 'Do you  want to copy database `%s` to database `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Edit Tables';
+$lang['L_SQL_OUTPUT'] = 'SQL Output';
+$lang['L_DO_NOW'] = 'operate now';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Name of Destination is missing !';
+$lang['L_ASKDELETEFIELD'] = 'Do you want to delete the Field?';
+$lang['L_SQL_COMMANDS_IN'] = ' lines in ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sec. parsed.';
+$lang['L_SQL_OUT1'] = 'Executed ';
+$lang['L_SQL_OUT2'] = 'Commands';
+$lang['L_SQL_OUT3'] = 'It had ';
+$lang['L_SQL_OUT4'] = 'Comments';
+$lang['L_SQL_OUT5'] = "Because the output contains more than 5000 lines it isn't displayed.";
+$lang['L_SQL_SELECDB'] = 'Select Database';
+$lang['L_SQL_TABLESOFDB'] = 'Tables of Database';
+$lang['L_SQL_EDIT'] = 'edit';
+$lang['L_SQL_NOFIELDDELETE'] = 'Delete is not possible because Tables must contain at least one field.';
+$lang['L_SQL_FIELDDELETE1'] = 'The Field';
+$lang['L_SQL_DELETED'] = 'was deleted';
+$lang['L_SQL_CHANGED'] = 'was changed.';
+$lang['L_SQL_CREATED'] = 'was created.';
+$lang['L_SQL_NODEST_COPY'] = 'No Copy without Destination !';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Destination Table exists !';
+$lang['L_SQL_SCOPY'] = 'Table structure of `%s` was copied in Table `%s`.';
+$lang['L_SQL_TCOPY'] = 'Table `%s` was copied with data in Table `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'Table needs a name!';
+$lang['L_SQL_TBLNAMEEMPTY'] = "Table name can't be empty!";
+$lang['L_SQL_COLLATENOTMATCH'] = "Charset and Collation don't fit together!";
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Error: No valid fieldname';
+$lang['L_SQL_CREATETABLE'] = 'create table';
+$lang['L_SQL_COPYTABLE'] = 'copy table';
+$lang['L_SQL_STRUCTUREONLY'] = 'Only Structure';
+$lang['L_SQL_STRUCTUREDATA'] = 'Structure and Data';
+$lang['L_SQL_NOTABLESINDB'] = 'No tables found in Database';
+$lang['L_SQL_SELECTTABLE'] = 'select table';
+$lang['L_SQL_SHOWDATATABLE'] = 'Show Data of Table';
+$lang['L_SQL_TBLPROPSOF'] = 'Table properties of';
+$lang['L_SQL_EDITFIELD'] = 'Edit field';
+$lang['L_SQL_NEWFIELD'] = 'New field';
+$lang['L_SQL_INDEXES'] = 'Indices';
+$lang['L_SQL_ATPOSITION'] = 'insert at position';
+$lang['L_SQL_FIRST'] = 'first';
+$lang['L_SQL_AFTER'] = 'after';
+$lang['L_SQL_CHANGEFIELD'] = 'change field';
+$lang['L_SQL_INSERTFIELD'] = 'insert field';
+$lang['L_SQL_INSERTNEWFIELD'] = 'insert new field';
+$lang['L_SQL_TABLEINDEXES'] = 'Indexes of table';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplicates allowed';
+$lang['L_SQL_CARDINALITY'] = 'Cardinality';
+$lang['L_SQL_TABLENOINDEXES'] = 'No Indexes in Table';
+$lang['L_SQL_CREATEINDEX'] = 'create new index';
+$lang['L_SQL_WASEMPTIED'] = 'was emptied';
+$lang['L_SQL_RENAMEDTO'] = 'was renamed to';
+$lang['L_SQL_DBCOPY'] = 'The Content of Database `%s` was copied in Database `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'The Structure of Database `%s` was copied in Database `%s`.';
+$lang['L_SQL_WASCREATED'] = 'was created';
+$lang['L_SQL_RENAMEDB'] = 'Rename Database';
+$lang['L_SQL_ACTIONS'] = 'Actions';
+$lang['L_SQL_CHOOSEACTION'] = 'Choose action';
+$lang['L_SQL_DELETEDB'] = 'Delete Database';
+$lang['L_SQL_EMPTYDB'] = 'Empty Database';
+$lang['L_SQL_COPYDATADB'] = 'Copy complete Database to';
+$lang['L_SQL_COPYSDB'] = 'Copy Structure of Database';
+$lang['L_SQL_IMEXPORT'] = 'Import-Export';
+$lang['L_INFO_RECORDS'] = 'records';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Should the table `%s` be emptied and the Indices reset?';
+$lang['L_EDIT'] = 'edit';
+$lang['L_DELETE'] = 'delete';
+$lang['L_EMPTY'] = 'empty';
+$lang['L_EMPTYKEYS'] = 'empty and reset indexes';
+$lang['L_SQL_TABLEEMPTIED'] = 'Table `%s` was deleted.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Table `%s` was deleted and the indices were reset.';
+$lang['L_SQL_LIBRARY'] = 'SQL Library';
+$lang['L_SQL_ATTRIBUTES'] = 'Attributes';
+$lang['L_SQL_UPLOADEDFILE'] = 'loaded file: ';
+$lang['L_SQL_IMPORT'] = 'Import in Database `%s`';
+$lang['L_EXPORT'] = 'Export';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = 'Import Options';
+$lang['L_CSVOPTIONS'] = 'CSV Options';
+$lang['L_IMPORTTABLE'] = 'Import in Table';
+$lang['L_NEWTABLE'] = 'New table';
+$lang['L_IMPORTSOURCE'] = 'Import Source';
+$lang['L_FROMTEXTBOX'] = 'from text box';
+$lang['L_FROMFILE'] = 'from file';
+$lang['L_EMPTYTABLEBEFORE'] = 'Empty table before';
+$lang['L_CREATEAUTOINDEX'] = 'Create Auto-Index';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Field names in first line';
+$lang['L_CSV_FIELDSEPERATE'] = 'Fields separated with';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Fields enclosed by';
+$lang['L_CSV_FIELDSESCAPE'] = 'Fields escaped with';
+$lang['L_CSV_EOL'] = 'Seperate lines with';
+$lang['L_CSV_NULL'] = 'Replace NULL with';
+$lang['L_CSV_FILEOPEN'] = 'Open CSV file';
+$lang['L_IMPORTIEREN'] = 'Import';
+$lang['L_SQL_EXPORT'] = 'Export from Database `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Export Options';
+$lang['L_EXCEL2003'] = 'Excel from 2003';
+$lang['L_SHOWRESULT'] = 'show result';
+$lang['L_SENDRESULTASFILE'] = 'send result as file';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> lines exported';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = "The count of fields doesn't match with that of the data to import (%d instead of %d).";
+$lang['L_CSV_FIELDSLINES'] = '%d fields recognized, totally %d lines';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Error while creating table `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'please choose a file.';
+$lang['L_CSV_NODATA'] = 'No data found for import!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'general functions';
+$lang['L_SQLLIB_RESETAUTO'] = 'reset auto-increment';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'deactivate Board';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'activate Board';
+$lang['L_SQL_NOTABLESSELECTED'] = 'No tables selected !';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_TOOLS_TOOLBOX'] = 'Select Database / Datebase functions / Import - Export ';
+$lang['L_SQL_OPENFILE'] = 'Open SQL-File';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Upload';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximum file size';
+$lang['L_SQL_SEARCH'] = 'Search';
+$lang['L_SQL_SEARCHWORDS'] = 'Searchword(s)';
+$lang['L_START_SQL_SEARCH'] = 'start search';
+$lang['L_RESET_SEARCHWORDS'] = 'reset search words';
+$lang['L_SEARCH_OPTIONS'] = 'Search options';
+$lang['L_SEARCH_RESULTS'] = 'The search for "<b>%s</b>" in table "<b>%s</b>" brings the following results';
+$lang['L_SEARCH_NO_RESULTS'] = "The search for \"<b>%s</b>\" in table \"<b>%s</b>\" doesn't bring any hits!";
+$lang['L_NO_ENTRIES'] = "Table \"<b>%s</b>\" is empty and doesn't have any entry.";
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Browse: forward=ALT+V, backwards=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'a column must have one of the search words (OR-search)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'a row must contain all of the search words but they can be in any column (could take some time)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'a column must contain all search words (AND-search)';
+$lang['L_SEARCH_IN_TABLE'] = 'Search in table';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Edit table structure';
+$lang['L_DEFAULT_CHARSET'] = 'Default character set';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primary key';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Unique key';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Fulltext key';
+$lang['L_TITLE_NOKEY'] = 'No key';
+$lang['L_TITLE_SEARCH'] = 'Search';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQl Documentation';
+$lang['L_TITLE_UPLOAD'] = 'Upload SQL file';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'Size';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/es/help.html b/msd/language/es/help.html
new file mode 100644
index 00000000..d8ddaa7a
--- /dev/null
+++ b/msd/language/es/help.html
@@ -0,0 +1,149 @@
+<div id="contenido">
+<h3><strong>MyOOS [Dumper]</strong> basado en MySQLDumper 1.24.4</h3>
+
+<h3>Acerca de este proyecto</h3>
+<p><strong>MyOOS [Dumper]</strong> es una versión mejorada de MySQLDumper 1.24.4 (24 de enero de 2011). Esta evolución tiene en cuenta el desarrollo de PHP.
+<p>MyOOS [Dumper]</strong> se preocupa principalmente por la estabilidad, la seguridad y el manejo. Pero también se incluye una atractiva plantilla que se puede editar y adaptar a tus propias necesidades.</p> <p>
+
+
+<p><strong>MyOOS [Dumper]</strong> es un programa de copias de seguridad para bases de datos MySQL, escrito en PHP y Perl. Con él, se pueden crear copias de seguridad de los datos (tienda, blog, etc.) y también restaurarlas si es necesario. Especialmente para los espacios web sin acceso al shell, MyOOS [Dumper] se ofrece como una alternativa sensata.</p> <p> 
+
+<p>La idea de MySQLDumper fue de Daniel Schlichtholz. En 2004 abrió el foro MySQLDumper, donde los programadores escribieron nuevos scripts y ampliaron los existentes.</p> <p>
+
+
+<h3>Lista de deseos / futuras atracciones</h3>.
+<p>¿Tienes alguna sugerencia de mejora? No dude en ponerse en contacto con el equipo de desarrollo a través del foro <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.
+
+
+<h3>Contribuir</h3>
+<p>Si quieres ayudarnos a mejorar el proyecto MyOOS, agradecemos tus pull requests a través de GitHub aquí.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Ayuda financiera</h3>
+<p>Puede utilizar PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>o a través del código QR<br>.  
+<img src="images/qrcode.png" alt="Apoyo financiero a MyOOS [Dumper]"></p>
+
+Envía dinero al proyecto MyOOS. <br>
+
+<p>Esperamos que disfrutes de este proyecto.<br><p>El equipo de MyOOS [Dumper]</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+
+<img src="css/mod/pics/h1_logo.gif" alt="MyOOS [Dumper]">
+
+<h3>MyOOS [Dumper] Ayuda</h3>
+
+<h4>Descarga</h4>
+<p>Siempre puedes obtener las últimas versiones en GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>Requisitos del sistema</h4>
+<p>El script funciona en cualquier servidor (Windows, Linux, ...) <br>
+con PHP >= versión 7.4 con soporte GZip, MySQL (versión 4.1 o superior), JavaScript (debe estar habilitado).</p> <p>
+<p>Copie la carpeta del mod del archivo MyOOS en una carpeta de trabajo separada.</p> <p>
+
+<h4>Instalación</h4></a>
+La instalación es sencilla.
+<p>Desde el archivo MyOOS, copia la carpeta del mod en cualquier carpeta.<br>
+Sube todos los archivos de la carpeta del mod a tu servidor web. (por ejemplo, al nivel más bajo en [directorio web del servidor/]mod)<br>
+... Hecho! <br>
+Ahora puede llamar a MyOOS [Dumper] en su navegador web yendo a "https://example.com/mod/"<br>.
+para completar la instalación. Sólo tienes que seguir las instrucciones.<br>
+<br><b>Nota:</b><br><i>Si en su servidor el script no tiene permiso para crear directorios,<br>
+tendrá que hacerlo manualmente, ya que MyOOS [Dumper] almacena los datos en directorios.
+directorios.<br> 
+El script termina con una declaración apropiada! <br>
+Después de haber creado los directorios (según la pista), se ejecuta normalmente y sin restricciones.</i>
+
+<a name="perl"></a><h4>Instrucciones del script de Perl</h4>.
+La mayoría tiene un directorio cgi-bin donde se puede ejecutar perl. <br>
+Suele ser accesible por el navegador a través de http://www.example.com/cgi-bin/. <br>
+<br>
+En este caso, por favor, lleve a cabo los siguientes pasos:<br><br> 1.
+
+1. llama a la página de Backup en MyOOS [Dumper] y haz clic en "Backup Perl". <br>
+2. copie la ruta detrás de la entrada en crondump.pl para $absolute_path_of_configdir:. <br>
+3. abrir el archivo "crondump.pl" en el editor.<br>
+4. introduzca la ruta copiada allí en absolute_path_of_configdir (sin espacios).<br>
+5. guardar crondump.pl.<br>
+Copie crondump.pl, perltest.pl y simpletest.pl en el directorio cgi-bin (modo ascii en FTP).
+7. dar a los archivos los permisos 755. <br>
+7b. Si se desea la terminación cgi, cambiar la terminación de los 3 archivos de pl -> cgi (renombrar). <br>
+Llama a la configuración en MyOOS [Dumper].
+9. seleccione la página Cronscript. <br>
+10. cambiar la ruta de ejecución de Perl a /cgi-bin/ .<br>
+10b. Si los scripts tienen .pl, cambie la extensión del archivo a .cgi.<br>
+11. Guarde la configuración. <br><br>
+
+Hecho, los scripts ahora pueden ser llamados desde la página de respaldo.<br><br>
+
+
+Para aquellos que pueden ejecutar Perl en todos los directorios, los siguientes pasos son suficientes:<br><br> 1.
+
+1. llama a la página de copia de seguridad en MyOOS [Dumper]. <br>
+Copie la ruta detrás de la entrada en crondump.pl para $absolute_path_of_configdir:. <br>
+Abra el archivo "crondump.pl" en el editor. <br>
+4. introduzca allí la ruta copiada en absolute_path_of_configdir (sin espacios). <br>
+5. guardar crondump.pl.<br>
+6. Dé a los archivos los permisos 755. <br>
+6b. Si se desea la terminación cgi, cambiar la terminación de los 3 archivos de pl -> cgi (renombrar). <br>
+(ev. 10b+11 de arriba)<br>
+<br>
+
+Los usuarios de Windows tienen que cambiar la primera línea de todos los scripts, ahí está la ruta de Perl. Ejemplo: <br>
+en lugar de: #! /usr/bin/perl -w <br>
+ahora: #C:_usr/bin/perl.exe -w
+
+<h4>Operación</h4><ul>
+
+<h6>Menú</h6>.
+En la lista de selección anterior se establece la base de datos.<br>
+Todas las acciones se refieren a la base de datos establecida aquí.
+
+<h6>Inicio</h6>
+Aquí podrá conocer su sistema, las distintas versiones instaladas y los detalles de las bases de datos configuradas.
+versiones instaladas y detalles sobre las bases de datos configuradas.<br>
+Si hace clic en el nombre de la base de datos, verá una lista de las tablas con el número de entradas
+con el número de entradas, el tamaño y la última fecha de actualización.
+
+<h6>Configuración</h6>
+Aquí puede editar su configuración, guardarla o restaurar la configuración inicial.
+restaurar la configuración inicial.
+<ul><br>
+	<li><a name="conf1"></a><strong>Bases de datos configuradas:</strong> la lista de bases de datos configuradas. La base de datos activa aparece en <b>negrita</b>. </li> <li>Por lo tanto, no es necesario que el usuario se sienta cómodo.
+	<li><a name="conf2"></a><strong>Prefijo de la tabla:</strong> aquí se puede especificar un prefijo (para cada base de datos). Se trata de un filtro que sólo tiene en cuenta las tablas que empiezan por este prefijo al realizar el volcado (por ejemplo, todas las tablas que empiezan por "phpBB_"). Si quiere que se guarden todas las tablas de esta base de datos, simplemente deje el campo vacío.</li>.
+	<li><a name="conf3"></a><strong>Compresión GZip:</strong> Aquí puedes activar la compresión. Se recomienda activarlo, ya que los archivos se hacen mucho más pequeños y el espacio de almacenamiento es siempre escaso.
+	<li><a name="conf5"></a><strong>Correo electrónico con el archivo de volcado:</strong> Si esta opción está activada, se enviará un correo electrónico con el volcado como archivo adjunto una vez finalizada la copia de seguridad (atención, la compresión debe estar definitivamente activada, de lo contrario, el archivo adjunto será demasiado grande y podría no enviarse).
+	<li><a name="conf6"></a><strong>Dirección de correo electrónico:</strong> Dirección del destinatario del correo electrónico.</li>.
+	<li><a name="conf7"></a><strong>Remitente del correo electrónico:</strong> esta dirección aparece como remitente en el correo electrónico.</li>.
+	<li><a name="conf13"></a><strong>Transferencia FTP: </strong>Si esta opción está activada, el archivo de copia de seguridad se enviará por FTP una vez finalizada la copia de seguridad.</li>.
+	<li><a name="conf14"></a><strong>Servidor FTP: </strong>La dirección del servidor FTP (por ejemplo, ftp.mybackups.de).</li>.
+	<li><a name="conf15"></a><strong>Puerto del servidor FTP: </strong>El puerto del servidor FTP (normalmente el 21).</li>.
+	<li><a name="conf16"></a><strong>Usuario FTP: </strong>El nombre de usuario de la cuenta FTP. </li> <li>Por lo tanto, no es necesario que el usuario se sienta cómodo.
+	<li><a name="conf17"></a><strong>Contraseña FTP: </strong>La contraseña de la cuenta FTP. </li> <li>Por lo tanto, no es necesario que el usuario se sienta cómodo.
+	<li><a name="conf18"></a><strong>Carpeta de carga FTP: </strong>El directorio donde debe ir el archivo de copia de seguridad (¡los permisos de carga deben existir!).</li>.
+	<li><a name="conf8"></a><strong>Borrado automático de copias de seguridad:</strong> Si esta opción está activada, las copias de seguridad más antiguas se borrarán automáticamente según las siguientes reglas.</li>.
+	<li><a name="conf10"></a><strong>Número de archivos de copia de seguridad:</strong> Un valor > 0 elimina todos los archivos de copia de seguridad excepto el número especificado aquí.</li>
+	<li><a name="conf11"></a><strong>Idioma:</strong> aquí se establece el idioma de la interfaz.</li>.
+
+
+<h6>Administración</h6>
+Aquí es donde se realizan las acciones reales.<br>
+Se muestran todos los archivos del directorio de la copia de seguridad.
+Para las acciones "Restaurar" y "Borrar" debe seleccionarse un archivo.
+<UL>
+	<li><strong>Restaurar:</strong> Esto actualiza la base de datos con el archivo de copia de seguridad seleccionado.</li>.
+	<li><strong>Borrar:</strong> Permite eliminar el archivo de copia de seguridad seleccionado.</li>.
+	<li><strong>Iniciar nueva copia de seguridad:</strong> Aquí puede iniciar una nueva copia de seguridad (volcado) según los parámetros establecidos en la configuración.
+</UL>
+
+<h6>Log</h6>
+Aquí puede ver y eliminar las entradas del registro.
+<h6>Créditos / Ayuda</h6>
+esta página.
\ No newline at end of file
diff --git a/msd/language/es/help.php b/msd/language/es/help.php
deleted file mode 100644
index d4cda68d..00000000
--- a/msd/language/es/help.php
+++ /dev/null
@@ -1,162 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Sobre este proyecto </h3>
-La idea para este proyecto proviene de Daniel Schlichholz.
-<p>En 2004 abrió el foro <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> e inmediatamente algunos aficionados a la programación se encontraron allí, para escribir y ampliar la versión inicial de los scripts de Daniel.<br>
-En poco tiempo quedó establecido el proyecto de realizar un script de copia de seguridad.
-<p>Si tiene Vd. alguna propuesta de mejora, notifíquela en el foro de MySQLDumper-Forum: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.
-<p>Le deseamos que disfrute del trabajo realizado en este proyecto.<br>
-<p>
-<h4>El equipo de MySQLDumper</h4>
-
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz <br>
-Traducción al Español: <a href="http://www.boutiquedeliberico.es" target="_blank">Javier Herrera Sanjuán</a> 
-</td></tr></table>
-<br>
-
-<h3>Ayuda de MySQLDumper</h3>
-
-
-<h4>Descarga</h4>
-Este script puede descargarlo desde la página principal de MySQLDumper.<br>
-Se recomienda que visite dicha página regularmente, para mantener el producto actualizado y poder descargar las ampliaciones que se vayan realizando.<br>
-La dirección es: <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>Requisitos del sistema </h4>
-<p>El script funciona en cualquier servidor (Windows, Linux, ...) que soporte una versión de PHP superior a la 4.3.4 
-(con GZip instalado) <br>
-y con MySQL a partir de la versión 3.23</p>
-<p>Además, debe tener activado el ejecutar secuencias de comandos  JavaScript en su navegador.</p>
-<a href="install.php?language=de" target="_top">
-<h4>Instalación</h4>
-</a>
-La instalación es muy sencilla. Simplemente extraiga los ficheros (conservando la estructura de directorios) en una carpeta cualquiera.<br>
-Suba (por FTP u otros medios) dichos ficheros a su servidor web. (por ejemplo, [directorio web de su servidor]/MySQLDumper)<br>
-... listo!<br>
-Ahora puede ejecutar MySQLDumper desde su navegador llamándolo desde la dirección "http://www.su_servidor.com/MySQLDumper", para iniciar el proceso de configuración, para el que simplemente debe seguir las instrucciones en pantalla.<br>
-<br><b>Aviso:</b><br>
-<i>En caso de que su servidor tenga activado el modo seguro de PHP, el script no podrá crear los directorios que necesita.<br>
-Si es así, deberá hacerlo Vd. de forma manual, según las instrucciones del proceso de configuración.<br>
-Tras haber creado dichos directorios, todo funcionará normalmente y sin restricciones.</i>
-
-<a name="perl"></a>
-<h4>Instrucciones para la instalación del script Perl</h4>
-<p>En la mayoría de los casos, el servidor dispondrá de un directorio llamado cgi-bin (o perl) desde el que pueden ejecutarse scripts perl. <br>
-  Dichos scripts se podrán acceder desde su navegador mediante la dirección http://www.su_servidor.com/cgi-bin/ . <br>
-  <br>
-Si este es su caso, siga las instrucciones siguientes:<br>
-<br>
-1. Ejecute MySQLDumper desde su navegador, y vaya a la página de and click "Backup Perl"<br>
-2. Copie el camino que aparece en la sección de propiedades del Cronscript Perl, al lado de $absolute_path_of_configdir: . <br>
-3. Abra el fichero "crondump.pl" en un editor cualquiera de texto.<br>
-4. Pegue el camino copiado en la entrada absolute_path_of_configdir (sin espacios vacíos). Hay una muestra dos líneas por encima. <br>
-5. Guarde "crondump.pl".<br>
-6. Copie los ficheros "crondump.pl", así como "perltest.pl" y "simpletest.pl" en el directorio cgi-bin (hágalo en modo ASCII si usa FTP).<br>
-7. Dé a dichos ficheros los derechos 0x755 (use chmod desde shell o desde su programa de FTP).<br>
-7b. En caso de ser neesaria la extensión "cgi" para los scripts, cámbiela en los tres ficheros de "pl" a "cgi" (cambiar nombre).<br>
-8. Vaya a la página de
-<?php echo $lang['config']?> 
-en MySQLDumper.<br>
-9. Elija el apartado Cronscript.<br>
-10. Cambie el Camino al Cronscript a "/cgi-bin/" (sin comillas). <br>
-10b. Si ha renombrado los scripts a ".cgi", cambie la extensión de los scripts a ".cgi".<br>
-11. Guarde la configuración.<br>
-<br>
-Ya ha terminado. Ahora puede llamar los scripts desde la página de
-<?php echo $lang['config']?>
-. Le recomendamos que pruebe primero tanto Perl como los Módulos Perl, usando los botones apropiados para ello. Si no funciona alguno de los dos, es probable que no pueda utilizar su script.<br>
-<br>
-Aquellos usuarios que pueden ejecutar Perl en cualquier directorio, pueden alternativamente, seguir los pasos siguientes (más sencillos):<br>
-<br>
-1. Ejecute MySQLDumper desde su navegador, y vaya a la página de
-<?php echo $lang['config']?>
-<br>
-2. Copie el camino que aparece en la sección de propiedades del Cronscript Perl, al lado de $absolute_path_of_configdir: . <br>
-3. Abra el fichero "crondump.pl" en un editor cualquiera de texto.<br>
-4. Pegue el camino copiado en la entrada absolute_path_of_configdir (sin espacios vacíos). Hay una muestra dos líneas por encima. <br>
-5. Guarde "crondump.pl" (si lo ha editado en local, súbalo nuevamente al servidor).<br>
-6. Dé a los ficheros "crondump.pl", así como "perltest.pl" y "simpletest.pl", los derechos 0x755 (use chmod desde shell o desde su programa de FTP).<br>
-7. En caso de ser neesaria la extensión "cgi" para los scripts, cámbiela en los tres ficheros de "pl" a "cgi" (cambiar nombre).<br>
-8. Si ha renombrado los scripts a ".cgi", vaya a la página de
-<?php echo $lang['config']?>
-en MySQLDumper, elija el apartado Cronscript y cambie la extensión de los scripts a ".cgi". Guarde la configuración.<br>
-  <br>
-
-  <b>Nota:</b> Tanto los usuarios de Windows como los usuarios de servidores con configuraciones no estándar, deberán cambiar en los tres scripts la primera línea para reflejar el camino correcto de Perl. Por ejemplo: <br>
-en vez de: #!/usr/bin/perl -w <br>
-ponga: #!C:\perl\bin\perl.exe -w <br>
-</p>
-<h4>Instrucciones de uso</h4>
-
-<h6>Menú</h6>
-<p>En el desplegable superior se encuentra la lista de bases de datos disponibles para trabajar con ellas. Tenga en cuenta que no necesariamente tendrá permiso para trabajar con todas ellas, sólo aquellas en las que su usuario tenga permisos podrán ser realmente accedidas. Las demás le darán simplemente un error.<br />
-Todas las acciones se refieren siempre a la base de datos seleccionada en este desplegable.</p>
-
-<ul>
-	<h6><?php echo $lang['home']?></h6>
-	<p>Aquí encontrará algunas propiedades de su sistema, como las versiones instaladas y algunos detalles de la base de datos.<br />
-    Los botones superiores le permitirán acceder a las diferentes opciones, que tendrán más o menos sentido según el nivel de privilegios de su usuario de base de datos:</p>
-	<ul><li><b><?php echo $lang['Statusinformationen']?></b> le mostrará las informaciones genéricas, pudiendo además acceder a algunas de ellas en particular, para ampliarlas.</li>
-	  <li><b><?php echo $lang['dbs']?></b> le llevará a la lista de las mismas, pudiendo crear otras nuevas. Si hace click en alguna de ellas, se le llevará a un menú avanzado dónde se le mostrarán las tablas que contiene y distintas opciones para con ellas. </li>
-	  <li><b><?php echo $lang['mysqlvars']?></b> le mostrará respectivamente los procesos, el estado y las opciones y definiciones del servidor de base de datos MySQL. </li>
-	  <li><b><?php echo $lang['mysqlsys']?></b> le permitirá acceder a una pseudoconsola del servidor de bases de datos y realizar operaciones complejas con el mismo. Nota: para poder utilizar dichas opciones, deberá tener los privilegios adecuados en el servidor MySQL.</li>
-	</ul>
-	<p>Otra de las opciones importantes de este menú, es la creación o modificación de los ficheros .htaccess. Dichos ficheros gestionan directamente la seguridad de los directorios y es importante por ejemplo, que no cualquier visitante pueda acceder a los datos de su base de datos mediante este programa. Por ello se recomienda encarecidamente utilizar dicha opción (o cualquier otra de que disponga) para proteger esta aplicación de usos indebidos. No obstante tenga en cuenta que hacerlo de forma errónea puede impedirle a Vd. mismo el acceso. Si le sucede esto, no se preocupe, acceda al directorio mediante FTP o mediante su gestor de archivos habitual, y elimine el fichero .htaccess para desprotegerlo y poder volver a acceder normalmente al mismo.</p>
-	<h6><?php echo $lang['config']?></h6>
-	<p>Aquí puede cambiar todos los datos de configuración del programa, guardar una copia de seguridad de la configuración, cargar una configuración preexistente, o volver a los valores iniciales de instalación.</p>
-	<ul>
-		<li><b><?php echo $lang['dbs']?></b> le permite cambiar los parámetros de conexión (haga click en mostrar / esconder) del usuario de base de datos.  Si hay más de una base de datos, puede elegir hacer un volcado múltiple e incluir más de una bases de datos en la copia de seguridad (la base de datos actual se muestra siempre en <b>negrita</b>). Además, podrá seleccionar las tablas que serán incluidas en la copia de seguridad mediante un prefijo.</li>
-		<ul>
-		  <li><a name="conf1"></a><b><?php echo $lang['help_db']?></b> muestra un listado de todas las bases de datos accesibles. Si ha especificado en los parámetros de conexión, que solamente se muestre un tipo una base de datos, solamente aparecerá ésta. Si hay más de una base de datos accesible, puede elegir hacer un volcado múltiple e incluir más de una bases de datos en la copia de seguridad (la base de datos actual se muestra siempre en <b>negrita</b>). Además, podrá seleccionar las tablas de cada base de datos que deben ser incluidas en la copia de seguridad mediante un prefijo, excluyendo las que no contengan el mismo.</li>
-		  <li><a name="conf2"></a><?php echo $lang['help_praefix']?> es el prefijo que puede especificar para seleccionar tablas de una base de datos. Por ejemplo puede especificar solamente aquellas tablas que empiecen con el prefijo "phpBB_". Si desea hacer una copia de seguridad de toda la base de datos, deje este campo en blanco.</li>
-		</ul>
-		<li><b><?php echo $lang['general']?></b> sirve para elegir las características genéricas de las copias de seguridad (compresión, memoria, velocidad [ALERTA: la velocidad excesiva puede provocar que el servidor deje de responder (timeout)], archivos de registro o logs, si se deben optimizar las tablas antes de hacer la copia, etc...) y de la restauración de datos (si se deben vaciar las tablas antes de hacerla, si se debe detener la importación en caso de errores).</li>
-		<ul>
-		  <li><a name="conf3"></a><b><?php echo $lang['gzip']?></b> permite activar la compresión de los archivos. Se recomienda activarla, si el módulo GZIP está disponible en su servidor, ya que el tamaño de los archivos se reduce sensiblemente.</li>
-		  <li><a name="conf4"></a><?php echo $lang['empty_db_before_restore']?>
-       permite vaciar el contenido de la base de datos totalmente antes de realizar la recuperación de datos de una copia de seguridad existente. Es recomendable en caso de recuperar una serie de tablas que se hayan corrompido. En caso de duda, se recomienda dejarlo desactivado, puesto que si realiza una recuperación parcial de algunas tablas, se eliminarían antes todas las tablas existentes, aunque no se encuentren presentes en la copia de seguridad a recuperar.</li>
-		</ul>
-		<li><b><?php echo $lang['config_interface']?></b> permite elegir las características gráficas de la interfaz del programa. Puede elegir idioma, tema, definir algunos tamaños de ventana, incluso decidir si desea que aparezca el nombre del servidor en que se encuentra en este momento, y en qué lugar. La elección del navegador que utiliza es importante, ya que si lo hace de forma incorrecta, el programa no funcionará correctamente. </li>
-		<ul>
-			<li><a name="conf11"></a><b><?php echo $lang['help_lang']?>:</b> aquí puede seleccionar el idioma para el interfaz gráfico.</li>
-		</ul>
-		<li><b><?php echo $lang['config_autodelete']?></b> define los parámetros que determinan si se van a eliminar archivos de copia de seguridad de forma automática o no.</li>
-		<ul>
-			<li><a name="conf8"></a><b><?php echo $lang['help_ad1']?>:</b> activa o desactiva la eliminación augomática. Si está activado, se eliminarán los archivos necesarios (según las reglas definidas a continuación) antes de iniciar una nueva copia de seguridad. Es una opción útil para ahorrar espacio en el servidor, pero le recomendamos que no la active antes de haber podido probar el funcionamiento correcto del programa.</li>
-			<li><a name="conf10"></a><b><?php echo $lang['help_ad3']?>:</b> un valor mayor que cero elimina todos los archivos de copia de seguridad en exceso del número especificado, bien en total, bien para cada base de datos distinta.</li>
-		</ul>
-		<li><b><?php echo $lang['config_email']?></b> define los parámetros que determinan si se va a enviar un email tras haber completado una copia de seguridad, así como si se deberá adjuntar dicha copia de seguridad y en qué forma.</li>
-		<ul>
-			<li><a name="conf8"></a><b><?php echo $lang['help_mail1']?>:</b> activa o desactiva el envío de un email al haberse terminado la copia de seguridad, sea con o sin éxito.</li>
-			<li><a name="conf9"></a><b><?php echo $lang['help_mail2']?>:</b> es la dirección de email a dónde se enviará el mensaje.</li>
-			<li><a name="conf10"></a><b><?php echo $lang['help_mail3']?>:</b> es la dirección de email desde donde se enviará el mensaje. Recuerde permitirle el paso a través de su filtro anti-spam, si dispone de uno.</li>
-		</ul>
-		<li><b><?php echo $lang['config_ftp']?></b> permite definir una (o varias) transferencias por FTP del archivo de copia de seguridad una vez terminada la misma. Si se activa, se deben especificar las parámetros necesarios para realizar la conexión. Además, deberá tener los derechos apropiados en el servidor de destino de la copia.</li>
-		<ul>
-			<li><a name="conf13"></a><b><?php echo $lang['help_ftptransfer']?>:</b> activa o desactiva el envío de la copia de seguridad realizada con éxito, por FTP.</li>
-			<li><a name="conf14"></a><b><?php echo $lang['help_ftpserver']?>:</b> es la dirección del servidor de FTP destinatario del archivo (por ejemplo ftp.misbackups.com).</li>
-			<li><a name="conf15"></a><b><?php echo $lang['help_ftpport']?>:</b> es el puerto de conexión del servidor FTP (generalmente, el puerto 21).</li>
-			<li><a name="conf16"></a><b><?php echo $lang['help_ftpuser']?>:</b> es el nombre de usuario con el que debe realizarse la conexión.</li>
-			<li><a name="conf17"></a><b><?php echo $lang['help_ftppass']?>:</b> es el password a utilizar para establecer la conexión.</li>
-			<li><a name="conf18"></a><b><?php echo $lang['help_ftpdir']?>:</b> es el directorio de destino del archivo a almacenar. Puede ser un camino absoluto o relativo (pero debe tener derechos de escritura en el mismo).</li>
-		</ul>
-		<li><b><?php echo $lang['config_cronperl']?></b> permite definir las características de la copia de seguridad utilizando el script Perl. La mayoría de las opciones son muy parecidas a las establecidas para el interfaz gráfico, pero para el script Perl, que actúa de forma independiente.</li>
-	</ul>
-	<h6><?php echo $lang['dump']?></h6>
-	<p>Esta es la parte más importante del programa. Desde aquí puede realizar una copia de seguridad de sus datos según las opciones establecidas anteriormente. Además, podrá seleccionar (si así lo desea) solamente algunas tablas para hacer dicha copia, de forma que no todos los datos de la base de datos sean copiados. </p>
-	<h6><?php echo $lang['restore']?></h6>
-	<p>Desde esta opción, podrá restaurar una copia de seguridad existente, a la base de datos seleccionada actualmente. </p>
-	<h6><?php echo $lang['file_manage']?></h6>
-	<p>En esta página se encuentran los archivos de copia de seguridad generados por el programa.<br>
-  Podrá eliminarlos de uno en uno o en grupo, ejecutar el borrado automático de forma manual, descargar los archivos o subir un archivos para poder restaurarlo posteriormente.</p>
-	<h6><?php echo $lang['mini-sql']?></h6>
-	<p>Aquí podrá ejecutar comandos SQL contra la base de datos, así como consultar la estructura de sus tablas. Para usuarios avanzados de MySQL. </p>
-	<h6><?php echo $lang['log']?></h6>
-	<p>Aquí encontrará los informes de las operaciones realizadas y podrá borrarlos si así lo desea.</p>
-	<h6><?php echo $lang['credits']?></h6>
-	<p>La página actual.</p>
-</ul>
\ No newline at end of file
diff --git a/msd/language/es/lang.php b/msd/language/es/lang.php
index c897bcb1..f54080dc 100644
--- a/msd/language/es/lang.php
+++ b/msd/language/es/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="si";
-$lang['L_TO']="hasta";
-$lang['L_ACTIVATED']="activo";
-$lang['L_NOT_ACTIVATED']="inactivo";
-$lang['L_ERROR']="error";
-$lang['L_OF']=" de ";
-$lang['L_ADDED']="añadido";
-$lang['L_DB']="Base de datos";
-$lang['L_DBS']="Bases de datos";
-$lang['L_TABLES']="Tablas";
-$lang['L_TABLE']="Tabla";
-$lang['L_RECORDS']="registros";
-$lang['L_COMPRESSED']="comprimido (gz)";
-$lang['L_NOTCOMPRESSED']="normal (sin comprimir)";
-$lang['L_GENERAL']="general";
-$lang['L_COMMENT']="comentario";
-$lang['L_FILESIZE']="Tamaño de archivo";
-$lang['L_ALL']="todos";
-$lang['L_NONE']="ninguno";
-$lang['L_WITH']=" con ";
-$lang['L_DIR']="directorio";
-$lang['L_RECHTE']="derechos";
-$lang['L_STATUS']="Estado";
-$lang['L_FINISHED']="finalizado";
-$lang['L_FILE']="archivo";
-$lang['L_FIELDS']="campos";
-$lang['L_NEW']="nuevo";
-$lang['L_CHARSET']="juego de caracteres";
-$lang['L_COLLATION']="orden";
-$lang['L_CHANGE']="cambiar";
-$lang['L_IN']="en";
-$lang['L_DO']="iniciar";
-$lang['L_VIEW']="ver";
-$lang['L_EXISTING']="existentes";
-$lang['L_BACK']="atrás";
-$lang['L_DB_HOST']="Host";
-$lang['L_DB_USER']="Usuario";
-$lang['L_DB_PASS']="Password";
-$lang['L_INFO_SCRIPTDIR']="Directorio de MySQLDumper";
-$lang['L_INFO_ACTDB']="Base de datos actual";
-$lang['L_WRONGCONNECTIONPARS']="Conexión errónea o sin parámetros !";
-$lang['L_CONN_NOT_POSSIBLE']="Conexión imposible !";
-$lang['L_SERVERCAPTION']="Nombre del servidor";
-$lang['L_HELP_SERVERCAPTION']="Al utilizar varios sistemas, puede ser útil mostrar la dirección del servidor actual";
-$lang['L_ACTIVATE_MULTIDUMP']="activar volcados múltiples (MultiDump)";
-$lang['L_SAVE']="Guardar";
-$lang['L_RESET']="Volver";
-$lang['L_PRAEFIX']="prefijo de las tablas";
-$lang['L_AUTODELETE']="eliminación automática de las copias de seguridad";
-$lang['L_MAX_BACKUP_FILES_EACH2']="para cada base de datos";
-$lang['L_SAVING_DB_FORM']="Base de datos";
-$lang['L_TESTCONNECTION']="Probar conexión";
-$lang['L_BACK_TO_MINISQL']="editar base de datos";
-$lang['L_CREATE']="crear";
-$lang['L_VARIABELN']="Variables";
-$lang['L_STATUSINFORMATIONEN']="Estado";
-$lang['L_VERSIONSINFORMATIONEN']="Versión";
-$lang['L_MSD_INFO']="Información sobre MyOOS [Dumper]";
-$lang['L_BACKUPFILESANZAHL']="En el directorio de copias de seguridad se encuentran";
-$lang['L_LASTBACKUP']="Última copia de seguridad";
-$lang['L_NOTAVAIL']="<em>no disponible</em>";
-$lang['L_VOM']="de";
-$lang['L_MYSQLVARS']="Variables de MySQL";
-$lang['L_MYSQLSYS']="Datos de MySQL";
-$lang['L_STATUS']="Estado";
-$lang['L_PROZESSE']="Proceso";
-$lang['L_INFO_NOVARS']="no hay variables disponibles";
-$lang['L_INHALT']="Contenido";
-$lang['L_INFO_NOSTATUS']="no hay estados disponibles";
-$lang['L_INFO_NOPROCESSES']="no hay procesos corriendo";
-$lang['L_FM_FREESPACE']="Espacio libre en el servidor";
-$lang['L_LOAD_DATABASE']="Refrescar la lista de BdD";
-$lang['L_HOME']="Inicio";
-$lang['L_CONFIG']="Configuración";
-$lang['L_DUMP']="Copia de seguridad";
-$lang['L_RESTORE']="Restaurar";
-$lang['L_FILE_MANAGE']="Archivos";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="elegir base de datos";
-$lang['L_CREDITS']="Créditos / Ayuda";
-$lang['L_MULTI_PART']="Copia de seguridad en múltiples archivos";
-$lang['L_LOGFILENOTWRITABLE']="No se puede escribir en el fichero de historial (log)!";
-$lang['L_SQL_ERROR1']="Error de ejecución:";
-$lang['L_SQL_ERROR2']="MySQL informa:";
-$lang['L_UNKNOWN']="desconocido";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="desconocido";
-$lang['L_OK']="Ok";
-$lang['L_CRON_COMPLETELOG']="Registrar todas las operaciones";
-$lang['L_NO']="no";
-$lang['L_CREATE_DATABASE']="crear nueva base de datos";
-$lang['L_EXPORTFINISHED']="Exportación finalizada.";
-$lang['L_SQL_BROWSER']="Navegador-SQL";
-$lang['L_SERVER']="Servidor";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Codificación por defecto para MySQL-Server";
-$lang['L_TITLE_SHOW_DATA']="Ver datos";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="¿Realmente desea eliminar la clave principal?";
-$lang['L_SETPRIMARYKEYSFOR']="Establecer nueva clave principal para la tabla";
-$lang['L_PRIMARYKEY_FIELD']="Campo de clave principal";
-$lang['L_PRIMARYKEYS_SAVE']="Guardar las claves principales";
-$lang['L_CANCEL']="Cancelar";
-$lang['L_VISIT_HOMEPAGE']="Visite el sitio web";
-$lang['L_SECONDS']="Segundos";
-$lang['L_BACKUPS']="cantidad de copias de seguridad";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'si';
+$lang['L_TO'] = 'hasta';
+$lang['L_ACTIVATED'] = 'activo';
+$lang['L_NOT_ACTIVATED'] = 'inactivo';
+$lang['L_ERROR'] = 'error';
+$lang['L_OF'] = ' de ';
+$lang['L_ADDED'] = 'añadido';
+$lang['L_DB'] = 'Base de datos';
+$lang['L_DBS'] = 'Bases de datos';
+$lang['L_TABLES'] = 'Tablas';
+$lang['L_TABLE'] = 'Tabla';
+$lang['L_RECORDS'] = 'registros';
+$lang['L_COMPRESSED'] = 'comprimido (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (sin comprimir)';
+$lang['L_COMMENT'] = 'comentario';
+$lang['L_FILESIZE'] = 'Tamaño de archivo';
+$lang['L_ALL'] = 'todos';
+$lang['L_NONE'] = 'ninguno';
+$lang['L_WITH'] = ' con ';
+$lang['L_DIR'] = 'directorio';
+$lang['L_RECHTE'] = 'derechos';
+$lang['L_STATUS'] = 'Estado';
+$lang['L_FINISHED'] = 'finalizado';
+$lang['L_FILE'] = 'archivo';
+$lang['L_FIELDS'] = 'campos';
+$lang['L_NEW'] = 'nuevo';
+$lang['L_CHARSET'] = 'juego de caracteres';
+$lang['L_COLLATION'] = 'orden';
+$lang['L_CHANGE'] = 'cambiar';
+$lang['L_IN'] = 'en';
+$lang['L_DO'] = 'iniciar';
+$lang['L_VIEW'] = 'ver';
+$lang['L_EXISTING'] = 'existentes';
+$lang['L_BACK'] = 'atrás';
+$lang['L_DB_HOST'] = 'Host';
+$lang['L_DB_USER'] = 'Usuario';
+$lang['L_DB_PASS'] = 'Password';
+$lang['L_INFO_SCRIPTDIR'] = 'Directorio de MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Base de datos actual';
+$lang['L_WRONGCONNECTIONPARS'] = 'Conexión errónea o sin parámetros !';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Conexión imposible !';
+$lang['L_SERVERCAPTION'] = 'Nombre del servidor';
+$lang['L_HELP_SERVERCAPTION'] = 'Al utilizar varios sistemas, puede ser útil mostrar la dirección del servidor actual';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'activar volcados múltiples (MultiDump)';
+$lang['L_SAVE'] = 'Guardar';
+$lang['L_RESET'] = 'Volver';
+$lang['L_PRAEFIX'] = 'prefijo de las tablas';
+$lang['L_AUTODELETE'] = 'eliminación automática de las copias de seguridad';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'para cada base de datos';
+$lang['L_SAVING_DB_FORM'] = 'Base de datos';
+$lang['L_TESTCONNECTION'] = 'Probar conexión';
+$lang['L_BACK_TO_MINISQL'] = 'editar base de datos';
+$lang['L_CREATE'] = 'crear';
+$lang['L_VARIABELN'] = 'Variables';
+$lang['L_STATUSINFORMATIONEN'] = 'Estado';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versión';
+$lang['L_MOD_INFO'] = 'Información sobre MyOOS [Dumper]';
+$lang['L_BACKUPFILESANZAHL'] = 'En el directorio de copias de seguridad se encuentran';
+$lang['L_LASTBACKUP'] = 'Última copia de seguridad';
+$lang['L_NOTAVAIL'] = '<em>no disponible</em>';
+$lang['L_VOM'] = 'de';
+$lang['L_MYSQLVARS'] = 'Variables de MySQL';
+$lang['L_MYSQLSYS'] = 'Datos de MySQL';
+$lang['L_STATUS'] = 'Estado';
+$lang['L_PROZESSE'] = 'Proceso';
+$lang['L_INFO_NOVARS'] = 'no hay variables disponibles';
+$lang['L_INHALT'] = 'Contenido';
+$lang['L_INFO_NOSTATUS'] = 'no hay estados disponibles';
+$lang['L_INFO_NOPROCESSES'] = 'no hay procesos corriendo';
+$lang['L_FM_FREESPACE'] = 'Espacio libre en el servidor';
+$lang['L_LOAD_DATABASE'] = 'Refrescar la lista de BdD';
+$lang['L_HOME'] = 'Inicio';
+$lang['L_CONFIG'] = 'Configuración';
+$lang['L_DUMP'] = 'Copia de seguridad';
+$lang['L_RESTORE'] = 'Restaurar';
+$lang['L_FILE_MANAGE'] = 'Archivos';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'elegir base de datos';
+$lang['L_CREDITS'] = 'Créditos / Ayuda';
+$lang['L_MULTI_PART'] = 'Copia de seguridad en múltiples archivos';
+$lang['L_LOGFILENOTWRITABLE'] = 'No se puede escribir en el fichero de historial (log)!';
+$lang['L_SQL_ERROR1'] = 'Error de ejecución:';
+$lang['L_SQL_ERROR2'] = 'MySQL informa:';
+$lang['L_UNKNOWN'] = 'desconocido';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'desconocido';
+$lang['L_OK'] = 'Ok';
+$lang['L_CRON_COMPLETELOG'] = 'Registrar todas las operaciones';
+$lang['L_NO'] = 'no';
+$lang['L_CREATE_DATABASE'] = 'crear nueva base de datos';
+$lang['L_EXPORTFINISHED'] = 'Exportación finalizada.';
+$lang['L_SQL_BROWSER'] = 'Navegador-SQL';
+$lang['L_SERVER'] = 'Servidor';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Codificación por defecto para MySQL-Server';
+$lang['L_TITLE_SHOW_DATA'] = 'Ver datos';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = '¿Realmente desea eliminar la clave principal?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Establecer nueva clave principal para la tabla';
+$lang['L_PRIMARYKEY_FIELD'] = 'Campo de clave principal';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Guardar las claves principales';
+$lang['L_CANCEL'] = 'Cancelar';
+$lang['L_VISIT_HOMEPAGE'] = 'Visite el sitio web';
+$lang['L_SECONDS'] = 'Segundos';
+$lang['L_BACKUPS'] = 'cantidad de copias de seguridad';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/es/lang_config_overview.php b/msd/language/es/lang_config_overview.php
index 68ad5b07..e275a7a7 100644
--- a/msd/language/es/lang_config_overview.php
+++ b/msd/language/es/lang_config_overview.php
@@ -1,111 +1,128 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Configuración";
-$lang['L_SAVE_SUCCESS']="La configuración se ha guardado con éxito en el archivo de configuración \"%s\".";
-$lang['L_CONFIG_LOADED']="La configuración \"%s\" se importó correctamente.";
-$lang['L_SAVE_ERROR']="¡La configuración no ha podido ser guardada!";
-$lang['L_CONFIG_EMAIL']="Notificación por email";
-$lang['L_CONFIG_AUTODELETE']="Eliminación automática";
-$lang['L_CONFIG_INTERFACE']="Interfaz";
-$lang['L_MULTI_PART_GROESSE']="tamaño máximo del archivo";
-$lang['L_HELP_MULTIPART']="Si selecciona archivos múltiples, se crearán varios archivos de copia de seguridad, el tamaño máximo de los cuales quedará determinado por las propiedades elegidas debajo";
-$lang['L_HELP_MULTIPARTGROESSE']="El tamaño máximo de los archivos individuales de copia de seguridad en caso de activar la copia de seguridad en archivos múltiples, queda determinado por este valor";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Vaciar la base de datos antes de recuperar los valores";
-$lang['L_ALLPARS']="todos los parámetros";
-$lang['L_CRON_EXTENDER']="Extensión de los scripts";
-$lang['L_CRON_SAVEPATH']="Archivo de configuración";
-$lang['L_CRON_PRINTOUT']="Salida de texto";
-$lang['L_CONFIG_CRONPERL']="Propiedades de Crondump como script perl";
-$lang['L_CRON_MAILPRG']="Programa de email";
-$lang['L_OPTIMIZE']="Optimizar las tablas antes del backup";
-$lang['L_HELP_OPTIMIZE']="Si esta opción está activada, se optimizarán todas las tablas antes de cada copia de seguridad";
-$lang['L_HELP_FTPTIMEOUT']="Tiempo de inactividad que tarda en cancelarse la conexión, 90 segundos por defecto.";
-$lang['L_FTP_TIMEOUT']="Cancelación de la conexión";
-$lang['L_HELP_FTPSSL']="Seleccione si la conexión debe ser establecida a través de SSL.";
-$lang['L_CONFIG_ASKLOAD']="Desea realmente sobreescribir la configuración actual con la configuración inicial?";
-$lang['L_LOAD']="Cargar config. inicial.";
-$lang['L_LOAD_SUCCESS']="La configuración inicial ha sido cargada.";
-$lang['L_CRON_CRONDBINDEX']="Base de datos";
-$lang['L_WITHATTACH']=" con fichero adjunto";
-$lang['L_WITHOUTATTACH']=" sin fichero adjunto";
-$lang['L_MULTIDUMPCONF']="=Propiedades de Multidump=";
-$lang['L_MULTIDUMPALL']="=Todas las bases de datos=";
-$lang['L_GZIP']="Compresión GZip";
-$lang['L_SEND_MAIL_FORM']="enviar un email";
-$lang['L_SEND_MAIL_DUMP']="Adjuntar copia de seguridad";
-$lang['L_EMAIL_ADRESS']="Dirección de email";
-$lang['L_EMAIL_SENDER']="Email desde donde se envía";
-$lang['L_EMAIL_MAXSIZE']="tamaño máximo del fichero adjunto";
-$lang['L_NUMBER_OF_FILES_FORM']="Cantidad de archivos de copia de seguridad";
-$lang['L_LANGUAGE']="Idioma";
-$lang['L_LIST_DB']="Bases de datos configuradas:";
-$lang['L_CONFIG_FTP']="Transferencia por FTP de los backups";
-$lang['L_FTP_TRANSFER']="Transferencia FTP";
-$lang['L_FTP_SERVER']="Servidor";
-$lang['L_FTP_PORT']="Puerto";
-$lang['L_FTP_USER']="Usuario";
-$lang['L_FTP_PASS']="Password";
-$lang['L_FTP_DIR']="Directorio de subida";
-$lang['L_FTP_SSL']="Conexión segura mediante SSL-FTP";
-$lang['L_FTP_USESSL']="conexión SSL usada";
-$lang['L_SQLBOXHEIGHT']="Altura del cuadro de SQL";
-$lang['L_SQLLIMIT']="Cantidad de registros por página";
-$lang['L_BBPARAMS']="Propiedades del código BB";
-$lang['L_BBTEXTCOLOR']="Color de texto";
-$lang['L_HELP_COMMANDS']="Antes y después de la copia de seguridad, puede hacer que se ejecute algún comando.\n
+
+$lang['L_CONFIG_HEADLINE'] = 'Configuración';
+$lang['L_SAVE_SUCCESS'] = 'La configuración se ha guardado con éxito en el archivo de configuración "%s".';
+$lang['L_CONFIG_LOADED'] = 'La configuración "%s" se importó correctamente.';
+$lang['L_SAVE_ERROR'] = '¡La configuración no ha podido ser guardada!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Notificación por email';
+$lang['L_CONFIG_AUTODELETE'] = 'Eliminación automática';
+$lang['L_CONFIG_INTERFACE'] = 'Interfaz';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'tamaño máximo del archivo';
+$lang['L_HELP_MULTIPART'] = 'Si selecciona archivos múltiples, se crearán varios archivos de copia de seguridad, el tamaño máximo de los cuales quedará determinado por las propiedades elegidas debajo';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'El tamaño máximo de los archivos individuales de copia de seguridad en caso de activar la copia de seguridad en archivos múltiples, queda determinado por este valor';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Vaciar la base de datos antes de recuperar los valores';
+$lang['L_ALLPARS'] = 'todos los parámetros';
+$lang['L_CRON_EXTENDER'] = 'Extensión de los scripts';
+$lang['L_CRON_SAVEPATH'] = 'Archivo de configuración';
+$lang['L_CRON_PRINTOUT'] = 'Salida de texto';
+$lang['L_CONFIG_CRONPERL'] = 'Propiedades de Crondump como script perl';
+$lang['L_CRON_MAILPRG'] = 'Programa de email';
+$lang['L_OPTIMIZE'] = 'Optimizar las tablas antes del backup';
+$lang['L_HELP_OPTIMIZE'] = 'Si esta opción está activada, se optimizarán todas las tablas antes de cada copia de seguridad';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'Tiempo de inactividad que tarda en cancelarse la conexión, 90 segundos por defecto.';
+$lang['L_FTP_TIMEOUT'] = 'Cancelación de la conexión';
+$lang['L_HELP_FTPSSL'] = 'Seleccione si la conexión debe ser establecida a través de SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Cancelación de la conexión';
+$lang['L_HELP_SFTPSSL'] = 'Seleccione si la conexión debe ser establecida a través de SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'Desea realmente sobreescribir la configuración actual con la configuración inicial?';
+$lang['L_LOAD'] = 'Cargar config. inicial.';
+$lang['L_LOAD_SUCCESS'] = 'La configuración inicial ha sido cargada.';
+$lang['L_CRON_CRONDBINDEX'] = 'Base de datos';
+$lang['L_WITHATTACH'] = ' con fichero adjunto';
+$lang['L_WITHOUTATTACH'] = ' sin fichero adjunto';
+$lang['L_MULTIDUMPCONF'] = '=Propiedades de Multidump=';
+$lang['L_MULTIDUMPALL'] = '=Todas las bases de datos=';
+$lang['L_GZIP'] = 'Compresión GZip';
+$lang['L_SEND_MAIL_FORM'] = 'enviar un email';
+$lang['L_SEND_MAIL_DUMP'] = 'Adjuntar copia de seguridad';
+$lang['L_EMAIL_ADRESS'] = 'Dirección de email';
+$lang['L_EMAIL_SENDER'] = 'Email desde donde se envía';
+$lang['L_EMAIL_MAXSIZE'] = 'tamaño máximo del fichero adjunto';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Cantidad de archivos de copia de seguridad';
+$lang['L_LANGUAGE'] = 'Idioma';
+$lang['L_LIST_DB'] = 'Bases de datos configuradas:';
+$lang['L_CONFIG_FTP'] = 'Transferencia por FTP de los backups';
+$lang['L_FTP_TRANSFER'] = 'Transferencia FTP';
+$lang['L_FTP_SERVER'] = 'Servidor';
+$lang['L_FTP_PORT'] = 'Puerto';
+$lang['L_FTP_USER'] = 'Usuario';
+$lang['L_FTP_PASS'] = 'Password';
+$lang['L_FTP_DIR'] = 'Directorio de subida';
+$lang['L_FTP_SSL'] = 'Conexión segura mediante SSL-FTP';
+$lang['L_FTP_USESSL'] = 'conexión SSL usada';
+$lang['L_CONFIG_SFTP'] = 'Transferencia por SFTP de los backups';
+$lang['L_SFTP_TRANSFER'] = 'Transferencia SFTP';
+$lang['L_SFTP_SERVER'] = 'Servidor';
+$lang['L_SFTP_PORT'] = 'Puerto';
+$lang['L_SFTP_USER'] = 'Usuario';
+$lang['L_SFTP_PASS'] = 'Password';
+$lang['L_SFTP_DIR'] = 'Directorio de subida';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Altura del cuadro de SQL';
+$lang['L_SQLLIMIT'] = 'Cantidad de registros por página';
+$lang['L_BBPARAMS'] = 'Propiedades del código BB';
+$lang['L_BBTEXTCOLOR'] = 'Color de texto';
+$lang['L_HELP_COMMANDS'] = "Antes y después de la copia de seguridad, puede hacer que se ejecute algún comando.\n
 Puede tratarse de una sentencia SQL o de un archivo de comandos de sistema (por ejemplo, un script)";
-$lang['L_COMMAND']="Comando";
-$lang['L_WRONG_CONNECTIONPARS']="¡Parámetros de conexión incorrectos!";
-$lang['L_CONNECTIONPARS']="Parámetros de conexión";
-$lang['L_EXTENDEDPARS']="Parámetros extendidos";
-$lang['L_FADE_IN_OUT']="mostrar/ocultar";
-$lang['L_DB_BACKUPPARS']="Propiedades de la copia de seguridad de la base de datos";
-$lang['L_GENERAL']="Genéricas";
-$lang['L_MAXSIZE']="tamaño máx.";
-$lang['L_ERRORHANDLING_RESTORE']="Tratamiento de los errores en la recuperación de datos";
-$lang['L_EHRESTORE_CONTINUE']="informar de los errores y seguir";
-$lang['L_EHRESTORE_STOP']="detenerse";
-$lang['L_IN_MAINFRAME']="en ventana principal";
-$lang['L_IN_LEFTFRAME']="en ventana de menu";
-$lang['L_WIDTH']="ancho";
-$lang['L_SQL_BEFEHLE']="Comandos SQL";
-$lang['L_DOWNLOAD_LANGUAGES']="Descargar otros idiomas";
-$lang['L_DOWNLOAD_STYLES']="Descargar otros temas";
-$lang['L_CONNECT_TO']="Conectarse a ";
-$lang['L_CHANGEDIR']="Cambiando al directorio";
-$lang['L_CHANGEDIRERROR']="No se ha podido cambiar el directorio";
-$lang['L_FTP_OK']="La conexión se ha realizado correctamente";
-$lang['L_INSTALL']="Instalación";
-$lang['L_NOFTPPOSSIBLE']="Las funciones de FTP no están disponibles!";
-$lang['L_FOUND_DB']="Encontrada BdD:";
-$lang['L_FTP_CHOOSE_MODE']="FTP Transfer Mode";
-$lang['L_FTP_PASSIVE']="use passive mode";
-$lang['L_HELP_FTP_MODE']="Choose the passive mode when you discover problems while using the active mode.";
-$lang['L_DB_IN_LIST']="The database '%s' couldn't be added because it is allready existing. ";
-$lang['L_ADD_DB_MANUALLY']="Add database manually";
-$lang['L_DB_MANUAL_ERROR']="Sorry, couldn't connect to database '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Fileerror: couldn't insert database '%s'!";
-$lang['L_NO_DB_FOUND']="I couldn't find any database automatically!
+$lang['L_COMMAND'] = 'Comando';
+$lang['L_WRONG_CONNECTIONPARS'] = '¡Parámetros de conexión incorrectos!';
+$lang['L_CONNECTIONPARS'] = 'Parámetros de conexión';
+$lang['L_EXTENDEDPARS'] = 'Parámetros extendidos';
+$lang['L_FADE_IN_OUT'] = 'mostrar/ocultar';
+$lang['L_DB_BACKUPPARS'] = 'Propiedades de la copia de seguridad de la base de datos';
+$lang['L_GENERAL'] = 'Genéricas';
+$lang['L_MAXSIZE'] = 'tamaño máx.';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Tratamiento de los errores en la recuperación de datos';
+$lang['L_EHRESTORE_CONTINUE'] = 'informar de los errores y seguir';
+$lang['L_EHRESTORE_STOP'] = 'detenerse';
+$lang['L_IN_MAINFRAME'] = 'en ventana principal';
+$lang['L_IN_LEFTFRAME'] = 'en ventana de menu';
+$lang['L_WIDTH'] = 'ancho';
+$lang['L_SQL_BEFEHLE'] = 'Comandos SQL';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'Descargar otros idiomas';
+$lang['L_DOWNLOAD_STYLES'] = 'Descargar otros temas';
+$lang['L_CONNECT_TO'] = 'Conectarse a ';
+$lang['L_CHANGEDIR'] = 'Cambiando al directorio';
+$lang['L_CHANGEDIRERROR'] = 'No se ha podido cambiar el directorio';
+$lang['L_FTP_OK'] = 'La conexión se ha realizado correctamente';
+$lang['L_INSTALL'] = 'Instalación';
+$lang['L_NOFTPPOSSIBLE'] = 'Las funciones de FTP no están disponibles!';
+$lang['L_FOUND_DB'] = 'Encontrada BdD:';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP Transfer Mode';
+$lang['L_FTP_PASSIVE'] = 'use passive mode';
+$lang['L_HELP_FTP_MODE'] = 'Choose the passive mode when you discover problems while using the active mode.';
+$lang['L_SFTP_PASSIVE'] = 'use passive mode';
+$lang['L_DB_IN_LIST'] = "The database '%s' couldn't be added because it is allready existing. ";
+$lang['L_ADD_DB_MANUALLY'] = 'Add database manually';
+$lang['L_DB_MANUAL_ERROR'] = "Sorry, couldn't connect to database '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Fileerror: couldn't insert database '%s'!";
+$lang['L_NO_DB_FOUND'] = "I couldn't find any database automatically!
 Please blend in the connection paramter and enter the name of your database manually.";
-$lang['L_CONFIGFILES']="Archivos de configuración";
-$lang['L_CONFIGFILE']="Archivo de configuración";
-$lang['L_MYSQL_DATA']="Datos MySQL";
-$lang['L_CONFIGURATIONS']="Preferencias";
-$lang['L_ACTION']="Acción";
-$lang['L_FTP_SEND_TO']="para <strong>%s</strong><br>en <strong>%s</s>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Destinatarios";
-$lang['L_NAME']="Nombre";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="¿Está seguro de que desea borrar el archivo de configuración %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="¡Error: el archivo de configuración %s no ha podido ser eliminado!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="El archivo de configuración %s ha sido eliminado.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="El archivo de configuración %s se ha creado correctamente.";
-$lang['L_ERROR_CONFIGFILE_NAME']="El nombre del archivo \"%s\" contiene caracteres no válidos.";
-$lang['L_CREATE_CONFIGFILE']="Crear un nuevo archivo de configuración";
-$lang['L_ERROR_LOADING_CONFIGFILE']="No se pudo cargar el archivo de configuración \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="BDs a copiar (PHP)";
-$lang['L_BACKUP_DBS_PERL']="BDs a copiar (PERL)";
-$lang['L_CRON_COMMENT']="Enter Comment";
-$lang['L_AUTODETECT']="Identificar automáticamente";
-
-
-?>
\ No newline at end of file
+$lang['L_CONFIGFILES'] = 'Archivos de configuración';
+$lang['L_CONFIGFILE'] = 'Archivo de configuración';
+$lang['L_MYSQL_DATA'] = 'Datos MySQL';
+$lang['L_CONFIGURATIONS'] = 'Preferencias';
+$lang['L_ACTION'] = 'Acción';
+$lang['L_FTP_SEND_TO'] = 'para <strong>%s</strong><br>en <strong>%s</s>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'para <strong>%s</strong><br>en <strong>%s</s>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Destinatarios';
+$lang['L_NAME'] = 'Nombre';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = '¿Está seguro de que desea borrar el archivo de configuración %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = '¡Error: el archivo de configuración %s no ha podido ser eliminado!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'El archivo de configuración %s ha sido eliminado.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'El archivo de configuración %s se ha creado correctamente.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'El nombre del archivo "%s" contiene caracteres no válidos.';
+$lang['L_CREATE_CONFIGFILE'] = 'Crear un nuevo archivo de configuración';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'No se pudo cargar el archivo de configuración "%s".';
+$lang['L_BACKUP_DBS_PHP'] = 'BDs a copiar (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'BDs a copiar (PERL)';
+$lang['L_CRON_COMMENT'] = 'Enter Comment';
+$lang['L_AUTODETECT'] = 'Identificar automáticamente';
diff --git a/msd/language/es/lang_dump.php b/msd/language/es/lang_dump.php
index 534ffaaf..8c5b217f 100644
--- a/msd/language/es/lang_dump.php
+++ b/msd/language/es/lang_dump.php
@@ -1,56 +1,57 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Creando copia de seguridad...";
-$lang['L_GZIP_COMPRESSION']="La compresión GZip";
-$lang['L_SAVING_TABLE']="Guardando tabla ";
-$lang['L_OF']="de";
-$lang['L_ACTUAL_TABLE']="Tabla actual";
-$lang['L_PROGRESS_TABLE']="Progreso de la tabla actual";
-$lang['L_PROGRESS_OVER_ALL']="Progreso total";
-$lang['L_ENTRY']="Registro";
-$lang['L_DONE']="Finalizado!";
-$lang['L_DUMP_SUCCESSFUL']=" ha sido realizado con éxito.";
-$lang['L_UPTO']="hasta";
-$lang['L_EMAIL_WAS_SEND']="Se ha enviado un email a ";
-$lang['L_BACK_TO_CONTROL']="seguir";
-$lang['L_BACK_TO_OVERVIEW']="vista de base de datos";
-$lang['L_DUMP_FILENAME']="Archivo de backup: ";
-$lang['L_WITHPRAEFIX']="con prefijo";
-$lang['L_DUMP_NOTABLES']="No se han encontrado tablas en la base de datos `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="<b>%s</b> Tablas con un total de <b>%s</b> registros, han sido guardadas con éxito.<br>";
-$lang['L_MAILERROR']="Se ha producido un error al intentar enviar el email!";
-$lang['L_EMAILBODY_ATTACH']="En el fichero adjunto encontrará la copia de seguridad de su base de datos MySQL.<br>Copia de seguridad de la base de datos `%s`
-<br><br>Se ha creado el siguiente archivo:<br><br>%s <br><br><br>Saludos de<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Se ha realizado un backup de archivos múltiples.<br>Los archivos no se adjuntan a este email!<br>Copia de seguridad de la base de datos `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'Creando copia de seguridad...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'La compresión GZip';
+$lang['L_SAVING_TABLE'] = 'Guardando tabla ';
+$lang['L_OF'] = 'de';
+$lang['L_ACTUAL_TABLE'] = 'Tabla actual';
+$lang['L_PROGRESS_TABLE'] = 'Progreso de la tabla actual';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progreso total';
+$lang['L_ENTRY'] = 'Registro';
+$lang['L_DONE'] = 'Finalizado!';
+$lang['L_DUMP_SUCCESSFUL'] = ' ha sido realizado con éxito.';
+$lang['L_UPTO'] = 'hasta';
+$lang['L_EMAIL_WAS_SEND'] = 'Se ha enviado un email a ';
+$lang['L_BACK_TO_CONTROL'] = 'seguir';
+$lang['L_BACK_TO_OVERVIEW'] = 'vista de base de datos';
+$lang['L_DUMP_FILENAME'] = 'Archivo de backup: ';
+$lang['L_WITHPRAEFIX'] = 'con prefijo';
+$lang['L_DUMP_NOTABLES'] = 'No se han encontrado tablas en la base de datos `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = '<b>%s</b> Tablas con un total de <b>%s</b> registros, han sido guardadas con éxito.<br>';
+$lang['L_MAILERROR'] = 'Se ha producido un error al intentar enviar el email!';
+$lang['L_EMAILBODY_ATTACH'] = 'En el fichero adjunto encontrará la copia de seguridad de su base de datos MySQL.<br>Copia de seguridad de la base de datos `%s`
+<br><br>Se ha creado el siguiente archivo:<br><br>%s <br><br><br>Saludos de<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Se ha realizado un backup de archivos múltiples.<br>Los archivos no se adjuntan a este email!<br>Copia de seguridad de la base de datos `%s`
 <br><br>Los siguientes archivos han sido adjuntados:<br><br>%s
-<br><br><br>Saludos de<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Se ha realizado un backup de archivos múltiples.<br>Los archivos se adjuntan a emails separados!<br>Copia de seguridad de la base de datos `%s`
-<br><br>Los siguientes archivos han sido adjuntados:<br><br>%s <br><br><br>Saludos de<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Saludos de<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="La copia de seguridad ha sobrepasado el tamaño máximo de %s y por lo tanto no ha sido adjuntada.<br>Copia de seguridad de la base de datos `%s`
-<br><br>Se ha creado el siguiente archivo:<br><br>%s <br><br><br>Saludos de<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="No se adjunta el archivo de copia de seguridad.<br>Copia de seguridad de la base de datos `%s`
-<br><br>Se ha creado el siguiente archivo:<br><br>%s <br><br><br>Saludos de<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... solamente el fichero adjunto";
-$lang['L_TABLESELECTION']="Elección de tablas";
-$lang['L_SELECTALL']="seleccionar todas
-";
-$lang['L_DESELECTALL']="seleccionar todas";
-$lang['L_STARTDUMP']="iniciar copia de seguridad";
-$lang['L_LASTBUFROM']="última actualización el";
-$lang['L_NOT_SUPPORTED']="Esta copia de seguridad no comprende esta función.";
-$lang['L_MULTIDUMP']="Copia múltiple, copia de seguridad de <b>%d</b> bases de datos resalizada.";
-$lang['L_FILESENDFTP']="envío del archivo vía FTP... tenga un poco de paciencia, por favor. ";
-$lang['L_FTPCONNERROR']="Conexión no establecida! Conectarse a ";
-$lang['L_FTPCONNERROR1']=" con el usuario ";
-$lang['L_FTPCONNERROR2']=" ha sido imposible";
-$lang['L_FTPCONNERROR3']="El envío por FTP ha fallado! ";
-$lang['L_FTPCONNECTED1']="Conectado con ";
-$lang['L_FTPCONNECTED2']=" en ";
-$lang['L_FTPCONNECTED3']=" escritos";
-$lang['L_NR_TABLES_SELECTED']="- con %s tablas seleccionadas";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tablas optimizadas.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">Ha(n) ocurrido %s error(es): <a href=\"log.php?r=3\">visualizar</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="¡Error fatal: las instrucciones para crear la tabla '%s' en la base de datos '%s' no se pueden leer!";
-
-
-?>
\ No newline at end of file
+<br><br><br>Saludos de<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Se ha realizado un backup de archivos múltiples.<br>Los archivos se adjuntan a emails separados!<br>Copia de seguridad de la base de datos `%s`
+<br><br>Los siguientes archivos han sido adjuntados:<br><br>%s <br><br><br>Saludos de<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Saludos de<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'La copia de seguridad ha sobrepasado el tamaño máximo de %s y por lo tanto no ha sido adjuntada.<br>Copia de seguridad de la base de datos `%s`
+<br><br>Se ha creado el siguiente archivo:<br><br>%s <br><br><br>Saludos de<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'No se adjunta el archivo de copia de seguridad.<br>Copia de seguridad de la base de datos `%s`
+<br><br>Se ha creado el siguiente archivo:<br><br>%s <br><br><br>Saludos de<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... solamente el fichero adjunto';
+$lang['L_TABLESELECTION'] = 'Elección de tablas';
+$lang['L_SELECTALL'] = 'seleccionar todas
+';
+$lang['L_DESELECTALL'] = 'seleccionar todas';
+$lang['L_STARTDUMP'] = 'iniciar copia de seguridad';
+$lang['L_LASTBUFROM'] = 'última actualización el';
+$lang['L_NOT_SUPPORTED'] = 'Esta copia de seguridad no comprende esta función.';
+$lang['L_MULTIDUMP'] = 'Copia múltiple, copia de seguridad de <b>%d</b> bases de datos resalizada.';
+$lang['L_FILESENDFTP'] = 'envío del archivo vía FTP... tenga un poco de paciencia, por favor. ';
+$lang['L_FTPCONNERROR'] = 'Conexión no establecida! Conectarse a ';
+$lang['L_FTPCONNERROR1'] = ' con el usuario ';
+$lang['L_FTPCONNERROR2'] = ' ha sido imposible';
+$lang['L_FTPCONNERROR3'] = 'El envío por FTP ha fallado! ';
+$lang['L_FTPCONNECTED1'] = 'Conectado con ';
+$lang['L_FTPCONNECTED2'] = ' en ';
+$lang['L_FTPCONNECTED3'] = ' escritos';
+$lang['L_FILESENDSFTP'] = 'envío del archivo vía SFTP... tenga un poco de paciencia, por favor. ';
+$lang['L_SFTPCONNERROR'] = 'Conexión no establecida! Conectarse a ';
+$lang['L_NR_TABLES_SELECTED'] = '- con %s tablas seleccionadas';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tablas optimizadas.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">Ha(n) ocurrido %s error(es): <a href="log.php?r=3">visualizar</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "¡Error fatal: las instrucciones para crear la tabla '%s' en la base de datos '%s' no se pueden leer!";
diff --git a/msd/language/es/lang_filemanagement.php b/msd/language/es/lang_filemanagement.php
index ab00d611..6bfaa825 100644
--- a/msd/language/es/lang_filemanagement.php
+++ b/msd/language/es/lang_filemanagement.php
@@ -1,79 +1,79 @@
 <?php
-$lang['L_CONVERT_START']="Iniciar conversión";
-$lang['L_CONVERT_TITLE']="Convertir copia de seguridad al formato MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="¡Parámetros incorrectos!  La conversión no es posible.";
-$lang['L_FM_UPLOADFILEREQUEST']="Por favor, elija un archivo.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Esta clase de archivo no está permitida.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Los tipos de archivo permitidos son: *.gz y *.sql";
-$lang['L_FM_UPLOADMOVEERROR']="No se ha podido copiar el archivo enviado al directorio correcto.";
-$lang['L_FM_UPLOADFAILED']="¡El envío del archivo ha fallado!";
-$lang['L_FM_UPLOADFILEEXISTS']="¡ Ya existe un archivo con este nombre !";
-$lang['L_FM_NOFILE']="No ha elegido ningún archivo!";
-$lang['L_FM_DELETE1']="El archivo ";
-$lang['L_FM_DELETE2']=" ha sido eliminado.";
-$lang['L_FM_DELETE3']=" no ha podido ser eliminado!";
-$lang['L_FM_CHOOSE_FILE']="archivo elegido:";
-$lang['L_FM_FILESIZE']="tamaño";
-$lang['L_FM_FILEDATE']="fecha";
-$lang['L_FM_NOFILESFOUND']="No se han encontrado archivos.";
-$lang['L_FM_TABLES']="tablas";
-$lang['L_FM_RECORDS']="registros";
-$lang['L_FM_ALL_BU']="Lista de todas las copias de seguridad";
-$lang['L_FM_ANZ_BU']="cantidad de copias de seguridad";
-$lang['L_FM_LAST_BU']="última copia de seguridad";
-$lang['L_FM_TOTALSIZE']="tamaño total";
-$lang['L_FM_SELECTTABLES']="Selección de tablas";
-$lang['L_FM_COMMENT']="Enter Comment";
-$lang['L_FM_RESTORE']="Restaurar";
-$lang['L_FM_ALERTRESTORE1']="¿Desea llenar la base de datos ";
-$lang['L_FM_ALERTRESTORE2']="con el contenido del archivo";
-$lang['L_FM_ALERTRESTORE3']="?";
-$lang['L_FM_DELETE']="Eliminar";
-$lang['L_FM_ASKDELETE1']="Desea realmente eliminar el archivo ";
-$lang['L_FM_ASKDELETE2']="en serio borrar?";
-$lang['L_FM_ASKDELETE3']="¿Desea ejecutar el borrado automático según las reglas especificadas?";
-$lang['L_FM_ASKDELETE4']="¿Desea eliminar todos los archivos de copia de seguridad?";
-$lang['L_FM_ASKDELETE5']="¿Desea eliminar todos los archivos con el prefijo ";
-$lang['L_FM_ASKDELETE5_2']="_*?";
-$lang['L_FM_DELETEAUTO']="Ejecutar borrado automático manualmente";
-$lang['L_FM_DELETEALL']="eliminar todas las copias de seguridad";
-$lang['L_FM_DELETEALLFILTER']="eliminar todos los archivos con ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Iniciar nueva copia de seguridad";
-$lang['L_FM_FILEUPLOAD']="Subir archivo";
-$lang['L_FM_DBNAME']="Nombre de la base de datos";
-$lang['L_FM_FILES1']="Copias de seguridad";
-$lang['L_FM_FILES2']="Estructuras de base de datos";
-$lang['L_FM_AUTODEL1']="Eliminado automático: Los siguientes archivos han sido eliminados al superarse la cantidad máxima de ficheros:";
-$lang['L_DELETE_FILE_SUCCESS']="El archivo \"%s\" se ha eliminado con éxito.";
-$lang['L_FM_DUMPSETTINGS']="Propiedades de la copia de seguridad";
-$lang['L_FM_OLDBACKUP']="(desconocido)";
-$lang['L_FM_RESTORE_HEADER']="Recuperación de la base de datos \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="¡No fue posible borrar el archivo \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Copia de seguridad";
-$lang['L_DOCRONBUTTON']="Ejecutar Cronscript Perl";
-$lang['L_DOPERLTEST']="Comprobar Módulos Perl";
-$lang['L_DOSIMPLETEST']="Comprobar Perl";
-$lang['L_PERLOUTPUT1']="Línea a escribir en crondump.pl para absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Ejecutar desde el navegador o desde un Cronjob externo al servidor";
-$lang['L_PERLOUTPUT3']="Ejecutar desde Shell o como entrada en Crontab";
-$lang['L_RESTORE_OF_TABLES']="Elija las tablas a restaurar";
-$lang['L_CONVERTER']="Copia de seguridad-Conversor";
-$lang['L_CONVERT_FILE']="archivo que se convertirá";
-$lang['L_CONVERT_FILENAME']="Nombre del archivo de destino (sin extensión)";
-$lang['L_CONVERTING']="La conversión";
-$lang['L_CONVERT_FILEREAD']="Leyendo el archivo '%s'";
-$lang['L_CONVERT_FINISHED']="Conversión finalizada: '%s' se ha guardado correctamente.";
-$lang['L_NO_MSD_BACKUPFILE']="Copias de seguridad de otros programas";
-$lang['L_MAX_UPLOAD_SIZE']="Tamaño máximo del fichero";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Si el archivo de copia de seguridad es mayor que el límite fijado, entonces debe cargarlo a través de FTP en la carpeta \"work/backup\".
-Después ese archivo se mostrará aquí, y podrá ser elegido para restaurar.";
-$lang['L_ENCODING']="Codificación";
-$lang['L_FM_CHOOSE_ENCODING']="Seleccione la codificación de la copia de seguridad";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper no pudo detectar la codificación de los archivos de la copia de seguridad de forma automática.<br>
+
+$lang['L_CONVERT_START'] = 'Iniciar conversión';
+$lang['L_CONVERT_TITLE'] = 'Convertir copia de seguridad al formato MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = '¡Parámetros incorrectos!  La conversión no es posible.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Por favor, elija un archivo.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Esta clase de archivo no está permitida.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Los tipos de archivo permitidos son: *.gz y *.sql';
+$lang['L_FM_UPLOADMOVEERROR'] = 'No se ha podido copiar el archivo enviado al directorio correcto.';
+$lang['L_FM_UPLOADFAILED'] = '¡El envío del archivo ha fallado!';
+$lang['L_FM_UPLOADFILEEXISTS'] = '¡ Ya existe un archivo con este nombre !';
+$lang['L_FM_NOFILE'] = 'No ha elegido ningún archivo!';
+$lang['L_FM_DELETE1'] = 'El archivo ';
+$lang['L_FM_DELETE2'] = ' ha sido eliminado.';
+$lang['L_FM_DELETE3'] = ' no ha podido ser eliminado!';
+$lang['L_FM_CHOOSE_FILE'] = 'archivo elegido:';
+$lang['L_FM_FILESIZE'] = 'tamaño';
+$lang['L_FM_FILEDATE'] = 'fecha';
+$lang['L_FM_NOFILESFOUND'] = 'No se han encontrado archivos.';
+$lang['L_FM_TABLES'] = 'tablas';
+$lang['L_FM_RECORDS'] = 'registros';
+$lang['L_FM_ALL_BU'] = 'Lista de todas las copias de seguridad';
+$lang['L_FM_ANZ_BU'] = 'cantidad de copias de seguridad';
+$lang['L_FM_LAST_BU'] = 'última copia de seguridad';
+$lang['L_FM_TOTALSIZE'] = 'tamaño total';
+$lang['L_FM_SELECTTABLES'] = 'Selección de tablas';
+$lang['L_FM_COMMENT'] = 'Enter Comment';
+$lang['L_FM_RESTORE'] = 'Restaurar';
+$lang['L_FM_ALERTRESTORE1'] = '¿Desea llenar la base de datos ';
+$lang['L_FM_ALERTRESTORE2'] = 'con el contenido del archivo';
+$lang['L_FM_ALERTRESTORE3'] = '?';
+$lang['L_FM_DELETE'] = 'Eliminar';
+$lang['L_FM_ASKDELETE1'] = 'Desea realmente eliminar el archivo ';
+$lang['L_FM_ASKDELETE2'] = 'en serio borrar?';
+$lang['L_FM_ASKDELETE3'] = '¿Desea ejecutar el borrado automático según las reglas especificadas?';
+$lang['L_FM_ASKDELETE4'] = '¿Desea eliminar todos los archivos de copia de seguridad?';
+$lang['L_FM_ASKDELETE5'] = '¿Desea eliminar todos los archivos con el prefijo ';
+$lang['L_FM_ASKDELETE5_2'] = '_*?';
+$lang['L_FM_DELETEAUTO'] = 'Ejecutar borrado automático manualmente';
+$lang['L_FM_DELETEALL'] = 'eliminar todas las copias de seguridad';
+$lang['L_FM_DELETEALLFILTER'] = 'eliminar todos los archivos con ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Iniciar nueva copia de seguridad';
+$lang['L_FM_FILEUPLOAD'] = 'Subir archivo';
+$lang['L_FM_DBNAME'] = 'Nombre de la base de datos';
+$lang['L_FM_FILES1'] = 'Copias de seguridad';
+$lang['L_FM_FILES2'] = 'Estructuras de base de datos';
+$lang['L_FM_AUTODEL1'] = 'Eliminado automático: Los siguientes archivos han sido eliminados al superarse la cantidad máxima de ficheros:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'El archivo "%s" se ha eliminado con éxito.';
+$lang['L_FM_DUMPSETTINGS'] = 'Propiedades de la copia de seguridad';
+$lang['L_FM_OLDBACKUP'] = '(desconocido)';
+$lang['L_FM_RESTORE_HEADER'] = 'Recuperación de la base de datos "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = '¡No fue posible borrar el archivo "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Copia de seguridad';
+$lang['L_DOCRONBUTTON'] = 'Ejecutar Cronscript Perl';
+$lang['L_DOPERLTEST'] = 'Comprobar Módulos Perl';
+$lang['L_DOSIMPLETEST'] = 'Comprobar Perl';
+$lang['L_PERLOUTPUT1'] = 'Línea a escribir en crondump.pl para absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Ejecutar desde el navegador o desde un Cronjob externo al servidor';
+$lang['L_PERLOUTPUT3'] = 'Ejecutar desde Shell o como entrada en Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Elija las tablas a restaurar';
+$lang['L_CONVERTER'] = 'Copia de seguridad-Conversor';
+$lang['L_CONVERT_FILE'] = 'archivo que se convertirá';
+$lang['L_CONVERT_FILENAME'] = 'Nombre del archivo de destino (sin extensión)';
+$lang['L_CONVERTING'] = 'La conversión';
+$lang['L_CONVERT_FILEREAD'] = "Leyendo el archivo '%s'";
+$lang['L_CONVERT_FINISHED'] = "Conversión finalizada: '%s' se ha guardado correctamente.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Copias de seguridad de otros programas';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Tamaño máximo del fichero';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Si el archivo de copia de seguridad es mayor que el límite fijado, entonces debe cargarlo a través de FTP en la carpeta "work/backup".
+Después ese archivo se mostrará aquí, y podrá ser elegido para restaurar.';
+$lang['L_ENCODING'] = 'Codificación';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Seleccione la codificación de la copia de seguridad';
+$lang['L_CHOOSE_CHARSET'] = 'MyOOS [Dumper] no pudo detectar la codificación de los archivos de la copia de seguridad de forma automática.<br>
 Usted debe elegir el conjunto de caracteres con el que se guardó la copia de seguridad.<br>
 Si usted descubre algún problema con algunos caracteres después de la restauración, puede repetir la restauración de la copia de seguridad con otro conjunto de caracteres. <br>
-Buena suerte. ;)";
-$lang['L_DOWNLOAD_FILE']="Descargos ficheros";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+Buena suerte. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Descargos ficheros';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/es/lang_help.php b/msd/language/es/lang_help.php
index 83bf4ec4..bd749331 100644
--- a/msd/language/es/lang_help.php
+++ b/msd/language/es/lang_help.php
@@ -1,32 +1,36 @@
 <?php
-$lang['L_HELP_DB']="Aquí está la lista de las bases de datos existentes.";
-$lang['L_HELP_PRAEFIX']="El prefijo sirve para filtrar las tablas, sólo se mostrarán aquellas que empiezen con él.";
-$lang['L_HELP_ZIP']="Compresión con GZip - se recomienda activarla";
-$lang['L_HELP_MEMORYLIMIT']="El tamaño máximo en Bytes, que el script puede almacenar en la memoria RAM\n0 = desactivado";
-$lang['L_MEMORY_LIMIT']="Límite de memoria";
-$lang['L_HELP_AD1']="Si está activado, se eliminarán automáticamente las copias de seguridad.";
-$lang['L_HELP_AD3']="El máximo de ficheros, que se guardarán en el directorio de copias de seguridad (para el borrado automático)
-0 = desactivado";
-$lang['L_HELP_LANG']="Elija el idioma adecuado.";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Para evitar registros redundantes, se puede hacer que la base de datos se vacíe completamente antes de la recuperación de datos";
-$lang['L_HELP_CRONEXTENDER']="La extensión de los scripts perl, el estándar es '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="El nombre del archivo de configuración del script perl.";
-$lang['L_HELP_CRONPRINTOUT']="Si está desactivado, no se mostrarán los resultados en pantalla. Es independiente de guardar en el archivo histórico.";
-$lang['L_HELP_CRONSAMEDB']="Debe usarse para Cronjob la misma base de datos que está definida en las propiedades?";
-$lang['L_HELP_CRONDBINDEX']="Elija la base de datos para Cronjob";
-$lang['L_HELP_FTPTRANSFER']="Si está activado, se enviará el archivo de copia de seguridad por FTP.";
-$lang['L_HELP_FTPSERVER']="Dirección del servidor de FTP.";
-$lang['L_HELP_FTPPORT']="Puerto del servidor de FTP, estándar es 21 .";
-$lang['L_HELP_FTPUSER']="Escriba el nombre del usuario de la conexión FTP.";
-$lang['L_HELP_FTPPASS']="Escriba el password de la conexión FTP.";
-$lang['L_HELP_FTPDIR']="¿A qué directorio debe ser enviado el archivo?";
-$lang['L_HELP_SPEED']="Velocidades máxima y mínima, estándar es 100 hasta 5000 (velocidades demasiado altas pueden conllevar pérdidas de conexión!)";
-$lang['L_SPEED']="Control de velocidad.";
-$lang['L_HELP_CRONEXECPATH']="El lugar en que se encuentra el script.\nSe parte de la dirección HTTP (como en el navegador). \nSe permiten caminos relativos y absolutos.";
-$lang['L_CRON_EXECPATH']="Ubicación del Cronscript.";
-$lang['L_HELP_CRONCOMPLETELOG']="Si está activada, se guardará el detalle completo de la operación en complete_log.
-Ésta función es independiente de la salida de texto.";
-$lang['L_HELP_FTP_MODE']="Si experimenta cualquier problema con la transferencia por FTP, intente utilizar el modo pasivo.";
 
-
-?>
\ No newline at end of file
+$lang['L_HELP_DB'] = 'Aquí está la lista de las bases de datos existentes.';
+$lang['L_HELP_PRAEFIX'] = 'El prefijo sirve para filtrar las tablas, sólo se mostrarán aquellas que empiezen con él.';
+$lang['L_HELP_ZIP'] = 'Compresión con GZip - se recomienda activarla';
+$lang['L_HELP_MEMORYLIMIT'] = "El tamaño máximo en Bytes, que el script puede almacenar en la memoria RAM\n0 = desactivado";
+$lang['L_MEMORY_LIMIT'] = 'Límite de memoria';
+$lang['L_HELP_AD1'] = 'Si está activado, se eliminarán automáticamente las copias de seguridad.';
+$lang['L_HELP_AD3'] = 'El máximo de ficheros, que se guardarán en el directorio de copias de seguridad (para el borrado automático)
+0 = desactivado';
+$lang['L_HELP_LANG'] = 'Elija el idioma adecuado.';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Para evitar registros redundantes, se puede hacer que la base de datos se vacíe completamente antes de la recuperación de datos';
+$lang['L_HELP_CRONEXTENDER'] = "La extensión de los scripts perl, el estándar es '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'El nombre del archivo de configuración del script perl.';
+$lang['L_HELP_CRONPRINTOUT'] = 'Si está desactivado, no se mostrarán los resultados en pantalla. Es independiente de guardar en el archivo histórico.';
+$lang['L_HELP_CRONSAMEDB'] = 'Debe usarse para Cronjob la misma base de datos que está definida en las propiedades?';
+$lang['L_HELP_CRONDBINDEX'] = 'Elija la base de datos para Cronjob';
+$lang['L_HELP_FTPTRANSFER'] = 'Si está activado, se enviará el archivo de copia de seguridad por FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Dirección del servidor de FTP.';
+$lang['L_HELP_FTPPORT'] = 'Puerto del servidor de FTP, estándar es 21 .';
+$lang['L_HELP_FTPUSER'] = 'Escriba el nombre del usuario de la conexión FTP.';
+$lang['L_HELP_FTPPASS'] = 'Escriba el password de la conexión FTP.';
+$lang['L_HELP_FTPDIR'] = '¿A qué directorio debe ser enviado el archivo?';
+$lang['L_HELP_SFTPTRANSFER'] = 'Si está activado, se enviará el archivo de copia de seguridad por SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Dirección del servidor de SFTP.';
+$lang['L_HELP_SFTPPORT'] = 'Puerto del servidor de SFTP, estándar es 22.';
+$lang['L_HELP_SFTPUSER'] = 'Escriba el nombre del usuario de la conexión SFTP.';
+$lang['L_HELP_SFTPPASS'] = 'Escriba el password de la conexión SFTP.';
+$lang['L_HELP_SFTPDIR'] = '¿A qué directorio debe ser enviado el archivo?';
+$lang['L_HELP_SPEED'] = 'Velocidades máxima y mínima, estándar es 100 hasta 5000 (velocidades demasiado altas pueden conllevar pérdidas de conexión!)';
+$lang['L_SPEED'] = 'Control de velocidad.';
+$lang['L_HELP_CRONEXECPATH'] = "El lugar en que se encuentra el script.\nSe parte de la dirección HTTP (como en el navegador). \nSe permiten caminos relativos y absolutos.";
+$lang['L_CRON_EXECPATH'] = 'Ubicación del Cronscript.';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Si está activada, se guardará el detalle completo de la operación en complete_log.
+Ésta función es independiente de la salida de texto.';
+$lang['L_HELP_FTP_MODE'] = 'Si experimenta cualquier problema con la transferencia por FTP, intente utilizar el modo pasivo.';
diff --git a/msd/language/es/lang_install.php b/msd/language/es/lang_install.php
index 4c3cba79..977d0e0e 100644
--- a/msd/language/es/lang_install.php
+++ b/msd/language/es/lang_install.php
@@ -1,89 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>La Instalación ha terminado --> <a href=\"index.php\">MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="al menú principal";
-$lang['L_INSTALLMENU']="Menú principal";
-$lang['L_STEP']="Paso";
-$lang['L_INSTALL']="Instalación";
-$lang['L_UNINSTALL']="Desinstalación";
-$lang['L_TOOLS']="Herramientas";
-$lang['L_EDITCONF']="modificar configuración";
-$lang['L_OSWEITER']="seguir sin guardar";
-$lang['L_ERRORMAN']="<strong>Error al escribir la configuración!</b><br>Por favor, edite Vd. el fichero ";
-$lang['L_MANUELL']="manualmente";
-$lang['L_CREATEDIRS']="Directorios creados";
-$lang['L_INSTALL_CONTINUE']="seguir con la instalación";
-$lang['L_CONNECTTOMYSQL']=" conectarse a MySQL ";
-$lang['L_DBPARAMETER']="Parámetros de la base de datos";
-$lang['L_CONFIGNOTWRITABLE']="No se ha podido modificar el fichero \"config.php\".
-Por favor, utilice su programa de FTP y ejecute chmod de dicho fichero a 0777.";
-$lang['L_DBCONNECTION']="Conexión a la base de datos";
-$lang['L_CONNECTIONERROR']="Error: no se pudo realizar la conexión.";
-$lang['L_CONNECTION_OK']="La conexión a la base de datos ha sido realizada con éxito.";
-$lang['L_SAVEANDCONTINUE']="guardar y seguir con la instalación";
-$lang['L_CONFBASIC']="Propiedades básicas";
-$lang['L_INSTALL_STEP2FINISHED']="Los datos de acceso a la base de datos han sido guardados.";
-$lang['L_INSTALL_STEP2_1']="seguir con propiedades estándar";
-$lang['L_LASTSTEP']="Fin de la instalación";
-$lang['L_FTPMODE']="Crear directorios por FTP (en modo seguro)";
-$lang['L_IDOMANUAL']="Crearé los directorios manualmente";
-$lang['L_DOFROM']="hacer desde";
-$lang['L_FTPMODE2']="Creación de los directorios por FTP:";
-$lang['L_CONNECT']="conectar";
-$lang['L_DIRS_CREATED']="Los directorios han sido correctamente creados.";
-$lang['L_CONNECT_TO']="conectar a";
-$lang['L_CHANGEDIR']="cambiar al directorio";
-$lang['L_CHANGEDIRERROR']="No ha sido posible realizar el cambio de directorio";
-$lang['L_FTP_OK']="Los parámetros de FTP son correctos";
-$lang['L_CREATEDIRS2']="Crear directorios";
-$lang['L_FTP_NOTCONNECTED']="Conexión por FTP no realizada!";
-$lang['L_CONNWITH']="Conectar con";
-$lang['L_ASUSER']="como usuario";
-$lang['L_NOTPOSSIBLE']="imposible";
-$lang['L_DIRCR1']="cree el directorio de trabajo ";
-$lang['L_DIRCR2']="cree el directorio de copias de seguridad ";
-$lang['L_DIRCR4']="cree el directorio de informes ";
-$lang['L_DIRCR5']="cree el directorio de configuración ";
-$lang['L_INDIR']="está en el directorio";
-$lang['L_CHECK_DIRS']="comprobar";
-$lang['L_DISABLEDFUNCTIONS']="Funciones deshabilitadas";
-$lang['L_NOFTPPOSSIBLE']="Las funciones de FTP no están disponibles!";
-$lang['L_NOGZPOSSIBLE']="Las funciones de compressión no están disponibles!";
-$lang['L_UI1']="Se van a eliminar todos los directorios de trabajo, incluídos aquellos que contengan copias de seguridad.";
-$lang['L_UI2']="Está seguro de que desea realizar la operación ?";
-$lang['L_UI3']="no, abortar inmediatamente";
-$lang['L_UI4']="si, deseo continuar";
-$lang['L_UI5']="eliminar directorio de trabajo";
-$lang['L_UI6']="todo ha sido eliminado satisfactoriamente.";
-$lang['L_UI7']="Por favor, elimine el directorio de los scripts";
-$lang['L_UI8']="subir un directorio";
-$lang['L_UI9']="Se ha producido un error, no ha sido posible eliminarlo</p>Error en el directorio ";
-$lang['L_IMPORT']="importar configuración";
-$lang['L_IMPORT3']="La configuración ha sido cargada ...";
-$lang['L_IMPORT4']="La configuración ha sido guardada.";
-$lang['L_IMPORT5']="Iniciar MySQLDumper";
-$lang['L_IMPORT6']="Menú de instalación";
-$lang['L_IMPORT7']="subir configuración";
-$lang['L_IMPORT8']="volver a subir";
-$lang['L_IMPORT9']="Este no es ningun fichero de configuración !";
-$lang['L_IMPORT10']="La configuración ha sido cargada con éxito ...";
-$lang['L_IMPORT11']="<strong>ERROR: </strong>Ha habido problemas al guardar sql_statements";
-$lang['L_IMPORT12']="<strong>ERROR: </strong>Ha habido problemas al guardar config.php";
-$lang['L_INSTALL_HELP_PORT']="(vacío = Puerto estándar)";
-$lang['L_INSTALL_HELP_SOCKET']="(vacío = Socket estándar)";
-$lang['L_TRYAGAIN']="intentar nuevamente";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Puerto";
-$lang['L_FOUND_DB']="Encontrada BdD:";
-$lang['L_FM_FILEUPLOAD']="Subir archivo";
-$lang['L_PASS']="Password";
-$lang['L_NO_DB_FOUND_INFO']="The connection to the database was successfully established.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>La Instalación ha terminado --> <a href="index.php">MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'al menú principal';
+$lang['L_INSTALLMENU'] = 'Menú principal';
+$lang['L_STEP'] = 'Paso';
+$lang['L_INSTALL'] = 'Instalación';
+$lang['L_UNINSTALL'] = 'Desinstalación';
+$lang['L_TOOLS'] = 'Herramientas';
+$lang['L_EDITCONF'] = 'modificar configuración';
+$lang['L_OSWEITER'] = 'seguir sin guardar';
+$lang['L_ERRORMAN'] = '<strong>Error al escribir la configuración!</b><br>Por favor, edite Vd. el fichero ';
+$lang['L_MANUELL'] = 'manualmente';
+$lang['L_CREATEDIRS'] = 'Directorios creados';
+$lang['L_INSTALL_CONTINUE'] = 'seguir con la instalación';
+$lang['L_CONNECTTOMYSQL'] = ' conectarse a MySQL ';
+$lang['L_DBPARAMETER'] = 'Parámetros de la base de datos';
+$lang['L_CONFIGNOTWRITABLE'] = 'No se ha podido modificar el fichero "config.php".
+Por favor, utilice su programa de FTP y ejecute chmod de dicho fichero a 0777.';
+$lang['L_DBCONNECTION'] = 'Conexión a la base de datos';
+$lang['L_CONNECTIONERROR'] = 'Error: no se pudo realizar la conexión.';
+$lang['L_CONNECTION_OK'] = 'La conexión a la base de datos ha sido realizada con éxito.';
+$lang['L_SAVEANDCONTINUE'] = 'guardar y seguir con la instalación';
+$lang['L_CONFBASIC'] = 'Propiedades básicas';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Los datos de acceso a la base de datos han sido guardados.';
+$lang['L_INSTALL_STEP2_1'] = 'seguir con propiedades estándar';
+$lang['L_LASTSTEP'] = 'Fin de la instalación';
+$lang['L_FTPMODE'] = 'Crear directorios por FTP (en modo seguro)';
+$lang['L_IDOMANUAL'] = 'Crearé los directorios manualmente';
+$lang['L_DOFROM'] = 'hacer desde';
+$lang['L_FTPMODE2'] = 'Creación de los directorios por FTP:';
+$lang['L_CONNECT'] = 'conectar';
+$lang['L_DIRS_CREATED'] = 'Los directorios han sido correctamente creados.';
+$lang['L_CONNECT_TO'] = 'conectar a';
+$lang['L_CHANGEDIR'] = 'cambiar al directorio';
+$lang['L_CHANGEDIRERROR'] = 'No ha sido posible realizar el cambio de directorio';
+$lang['L_FTP_OK'] = 'Los parámetros de FTP son correctos';
+$lang['L_CREATEDIRS2'] = 'Crear directorios';
+$lang['L_FTP_NOTCONNECTED'] = 'Conexión por FTP no realizada!';
+$lang['L_CONNWITH'] = 'Conectar con';
+$lang['L_ASUSER'] = 'como usuario';
+$lang['L_NOTPOSSIBLE'] = 'imposible';
+$lang['L_DIRCR1'] = 'cree el directorio de trabajo ';
+$lang['L_DIRCR2'] = 'cree el directorio de copias de seguridad ';
+$lang['L_DIRCR4'] = 'cree el directorio de informes ';
+$lang['L_DIRCR5'] = 'cree el directorio de configuración ';
+$lang['L_INDIR'] = 'está en el directorio';
+$lang['L_CHECK_DIRS'] = 'comprobar';
+$lang['L_DISABLEDFUNCTIONS'] = 'Funciones deshabilitadas';
+$lang['L_NOFTPPOSSIBLE'] = 'Las funciones de FTP no están disponibles!';
+$lang['L_NOGZPOSSIBLE'] = 'Las funciones de compressión no están disponibles!';
+$lang['L_UI1'] = 'Se van a eliminar todos los directorios de trabajo, incluídos aquellos que contengan copias de seguridad.';
+$lang['L_UI2'] = 'Está seguro de que desea realizar la operación ?';
+$lang['L_UI3'] = 'no, abortar inmediatamente';
+$lang['L_UI4'] = 'si, deseo continuar';
+$lang['L_UI5'] = 'eliminar directorio de trabajo';
+$lang['L_UI6'] = 'todo ha sido eliminado satisfactoriamente.';
+$lang['L_UI7'] = 'Por favor, elimine el directorio de los scripts';
+$lang['L_UI8'] = 'subir un directorio';
+$lang['L_UI9'] = 'Se ha producido un error, no ha sido posible eliminarlo</p>Error en el directorio ';
+$lang['L_IMPORT'] = 'importar configuración';
+$lang['L_IMPORT3'] = 'La configuración ha sido cargada ...';
+$lang['L_IMPORT4'] = 'La configuración ha sido guardada.';
+$lang['L_IMPORT5'] = 'Iniciar MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Menú de instalación';
+$lang['L_IMPORT7'] = 'subir configuración';
+$lang['L_IMPORT8'] = 'volver a subir';
+$lang['L_IMPORT9'] = 'Este no es ningun fichero de configuración !';
+$lang['L_IMPORT10'] = 'La configuración ha sido cargada con éxito ...';
+$lang['L_IMPORT11'] = '<strong>ERROR: </strong>Ha habido problemas al guardar sql_statements';
+$lang['L_IMPORT12'] = '<strong>ERROR: </strong>Ha habido problemas al guardar config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(vacío = Puerto estándar)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(vacío = Socket estándar)';
+$lang['L_TRYAGAIN'] = 'intentar nuevamente';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Puerto';
+$lang['L_FOUND_DB'] = 'Encontrada BdD:';
+$lang['L_FM_FILEUPLOAD'] = 'Subir archivo';
+$lang['L_PASS'] = 'Password';
+$lang['L_NO_DB_FOUND_INFO'] = 'The connection to the database was successfully established.<br>
 Your userdata is valid and was accepted by the MySQL-Server.<br>
-But MySQLDumper was not able to find any database.<br>
+But MyOOS [Dumper] was not able to find any database.<br>
 The automatic detection via script is blocked on some server.<br>
 You must enter your databasename manually after the installation is finished.
-Click on \"configuration\" \"Connection Parameter - display\" and enter the databasename there.";
-$lang['L_SAFEMODEDESC']="Debido a que en este servidor está ejecutándose PHP en modo seguro (safe_mode),necesita crear los siguientes directorios manualmente utilizando su programa de FTP:";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+Click on "configuration" "Connection Parameter - display" and enter the databasename there.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/es/lang_log.php b/msd/language/es/lang_log.php
index e5f496b6..0be33414 100644
--- a/msd/language/es/lang_log.php
+++ b/msd/language/es/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Eliminar fichero de historial (log)";
-$lang['L_LOGFILEFORMAT']="Formato del fichero de historial (log)";
-$lang['L_LOGFILENOTWRITABLE']="No se puede escribir en el fichero de historial (log)!";
-$lang['L_NOREVERSE']="Mostrar las entradas más antiguas primero";
-$lang['L_REVERSE']="Mostrar las entradas más nuevas primero";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Eliminar fichero de historial (log)';
+$lang['L_LOGFILEFORMAT'] = 'Formato del fichero de historial (log)';
+$lang['L_LOGFILENOTWRITABLE'] = 'No se puede escribir en el fichero de historial (log)!';
+$lang['L_NOREVERSE'] = 'Mostrar las entradas más antiguas primero';
+$lang['L_REVERSE'] = 'Mostrar las entradas más nuevas primero';
diff --git a/msd/language/es/lang_main.php b/msd/language/es/lang_main.php
index 81538cca..6ce0ed39 100644
--- a/msd/language/es/lang_main.php
+++ b/msd/language/es/lang_main.php
@@ -1,78 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Las funciones de FTP no están disponibles!";
-$lang['L_INFO_LOCATION']="Se encuentra en ";
-$lang['L_INFO_DATABASES']="Las siguentes bases de datos se encuentran en el servidor de MySQL:";
-$lang['L_INFO_NODB']="Base de datos inexistente";
-$lang['L_INFO_DBDETAIL']="Vista detallada de la base de datos ";
-$lang['L_INFO_DBEMPTY']="La base de datos está vacía !";
-$lang['L_INFO_RECORDS']="Registros";
-$lang['L_INFO_SIZE']="Tamaño";
-$lang['L_INFO_LASTUPDATE']="última actualización";
-$lang['L_INFO_SUM']="total";
-$lang['L_INFO_OPTIMIZED']="optimizado";
-$lang['L_OPTIMIZE_DATABASES']="Optimizar tablas";
-$lang['L_CHECK_TABLES']="Comprobar tablas";
-$lang['L_CLEAR_DATABASE']="Vaciar base de datos";
-$lang['L_DELETE_DATABASE']="Eliminar base de datos";
-$lang['L_INFO_CLEARED']="ha sido vaciada";
-$lang['L_INFO_DELETED']="ha sido eliminada";
-$lang['L_INFO_EMPTYDB1']="Debe ser la base de datos";
-$lang['L_INFO_EMPTYDB2']=" verdaderamente vaciada? (ALERTA: los datos se perderán irremisiblemente)";
-$lang['L_INFO_KILLDB']=" verdaderamente eliminada? (ALERTA: los datos se perderán irremisiblemente)";
-$lang['L_PROCESSKILL1']="Se intentará, terminar el proceso ";
-$lang['L_PROCESSKILL2']=".";
-$lang['L_PROCESSKILL3']="Se ha intentado desde hace ";
-$lang['L_PROCESSKILL4']=" seg. para eliminar el proceso";
-$lang['L_HTACC_CREATE']="Crear protección de directorio";
-$lang['L_ENCRYPTION_TYPE']="Tipo de encriptación";
-$lang['L_HTACC_CRYPT']="Crypt )Linux y sistemas Unix)";
-$lang['L_HTACC_MD5']="MD5 (Linux y sistemas Unix)";
-$lang['L_HTACC_NO_ENCRYPTION']="sin encriptación (Windows)";
-$lang['L_HTACCESS8']="Ya existe actualmente una protección del directorio. ¡Si crea una nueva, la antigua será sobreescrita!";
-$lang['L_HTACC_NO_USERNAME']="Debe darle un nombre!";
-$lang['L_PASSWORDS_UNEQUAL']="¡Los passwords no son idénticos o están vacíos! ";
-$lang['L_HTACC_CONFIRM_DELETE']="¿Desea crear ahora la protección del directorio?";
-$lang['L_HTACC_CREATED']="La protección del directorio ha sido creada.";
-$lang['L_HTACC_CONTENT']="Contenido del archivo";
-$lang['L_HTACC_CREATE_ERROR']="Se ha producido un error al crear la protección del directorio!<br>Por favor, coloque en él el siguiente archivo, con el contenido especificado";
-$lang['L_HTACC_PROPOSED']="¡Altamente recomendado";
-$lang['L_HTACC_EDIT']="editar .htaccess";
-$lang['L_HTACCESS18']="crear .htaccess en ";
-$lang['L_HTACCESS19']="cargar de nuevo ";
-$lang['L_HTACCESS20']="Ejecutar script";
-$lang['L_HTACCESS21']="Escriba el proveedor";
-$lang['L_HTACCESS22']="Permitir ejecución";
-$lang['L_HTACCESS23']="Listado de directorios";
-$lang['L_HTACCESS24']="Documentos de error";
-$lang['L_HTACCESS25']="Activar la reescritura";
-$lang['L_HTACCESS26']="Denegar / Permitir";
-$lang['L_HTACCESS27']="Redirecccionar";
-$lang['L_HTACCESS28']="Historial de errores";
-$lang['L_HTACCESS29']="otros ejemplos y documentación";
-$lang['L_HTACCESS30']="Proveedor";
-$lang['L_HTACCESS31']="conjunto";
-$lang['L_HTACCESS32']="Alerta! El fichero .htaccess influye directamente el comportamiento de los navegadores.<br>Si lo crea de forma incorrecta, estas páginas no serán accesibles.";
-$lang['L_PHPBUG']="¡Bug en zlib! No es posible comprimir archivos!";
-$lang['L_DISABLEDFUNCTIONS']="Funciones deshabilitadas";
-$lang['L_NOGZPOSSIBLE']="Dado que Zlib no está instalado, no puede usar las funciones de compresión GZip!";
-$lang['L_DELETE_HTACCESS']="Remove directory protection (delete .htaccess)";
-$lang['L_WRONG_RIGHTS']="El archivo o directorio '%s' no tiene permisos de escritura para mi.<br>
+
+$lang['L_NOFTPPOSSIBLE'] = 'Las funciones de FTP no están disponibles!';
+$lang['L_INFO_LOCATION'] = 'Se encuentra en ';
+$lang['L_INFO_DATABASES'] = 'Las siguentes bases de datos se encuentran en el servidor de MySQL:';
+$lang['L_INFO_NODB'] = 'Base de datos inexistente';
+$lang['L_INFO_DBDETAIL'] = 'Vista detallada de la base de datos ';
+$lang['L_INFO_DBEMPTY'] = 'La base de datos está vacía !';
+$lang['L_INFO_RECORDS'] = 'Registros';
+$lang['L_INFO_SIZE'] = 'Tamaño';
+$lang['L_INFO_LASTUPDATE'] = 'última actualización';
+$lang['L_INFO_SUM'] = 'total';
+$lang['L_INFO_OPTIMIZED'] = 'optimizado';
+$lang['L_OPTIMIZE_DATABASES'] = 'Optimizar tablas';
+$lang['L_CHECK_TABLES'] = 'Comprobar tablas';
+$lang['L_CLEAR_DATABASE'] = 'Vaciar base de datos';
+$lang['L_DELETE_DATABASE'] = 'Eliminar base de datos';
+$lang['L_INFO_CLEARED'] = 'ha sido vaciada';
+$lang['L_INFO_DELETED'] = 'ha sido eliminada';
+$lang['L_INFO_EMPTYDB1'] = 'Debe ser la base de datos';
+$lang['L_INFO_EMPTYDB2'] = ' verdaderamente vaciada? (ALERTA: los datos se perderán irremisiblemente)';
+$lang['L_INFO_KILLDB'] = ' verdaderamente eliminada? (ALERTA: los datos se perderán irremisiblemente)';
+$lang['L_PROCESSKILL1'] = 'Se intentará, terminar el proceso ';
+$lang['L_PROCESSKILL2'] = '.';
+$lang['L_PROCESSKILL3'] = 'Se ha intentado desde hace ';
+$lang['L_PROCESSKILL4'] = ' seg. para eliminar el proceso';
+$lang['L_HTACC_CREATE'] = 'Crear protección de directorio';
+$lang['L_ENCRYPTION_TYPE'] = 'Tipo de encriptación';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Ya existe actualmente una protección del directorio. ¡Si crea una nueva, la antigua será sobreescrita!';
+$lang['L_HTACC_NO_USERNAME'] = 'Debe darle un nombre!';
+$lang['L_PASSWORDS_UNEQUAL'] = '¡Los passwords no son idénticos o están vacíos! ';
+$lang['L_HTACC_CONFIRM_CREATE'] = '¿Desea crear ahora la protección del directorio?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'La protección del directorio ha sido creada.';
+$lang['L_HTACC_CONTENT'] = 'Contenido del archivo';
+$lang['L_HTACC_CREATE_ERROR'] = 'Se ha producido un error al crear la protección del directorio!<br>Por favor, coloque en él el siguiente archivo, con el contenido especificado';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'editar .htaccess';
+$lang['L_HTACCESS18'] = 'crear .htaccess en ';
+$lang['L_HTACCESS19'] = 'cargar de nuevo ';
+$lang['L_HTACCESS20'] = 'Ejecutar script';
+$lang['L_HTACCESS21'] = 'Escriba el proveedor';
+$lang['L_HTACCESS22'] = 'Permitir ejecución';
+$lang['L_HTACCESS23'] = 'Listado de directorios';
+$lang['L_HTACCESS24'] = 'Documentos de error';
+$lang['L_HTACCESS25'] = 'Activar la reescritura';
+$lang['L_HTACCESS26'] = 'Denegar / Permitir';
+$lang['L_HTACCESS27'] = 'Redirecccionar';
+$lang['L_HTACCESS28'] = 'Historial de errores';
+$lang['L_HTACCESS29'] = 'otros ejemplos y documentación';
+$lang['L_HTACCESS30'] = 'Proveedor';
+$lang['L_HTACCESS31'] = 'conjunto';
+$lang['L_HTACCESS32'] = 'Alerta! El fichero .htaccess influye directamente el comportamiento de los navegadores.<br>Si lo crea de forma incorrecta, estas páginas no serán accesibles.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Funciones deshabilitadas';
+$lang['L_NOGZPOSSIBLE'] = 'Dado que Zlib no está instalado, no puede usar las funciones de compresión GZip!';
+$lang['L_DELETE_HTACCESS'] = 'Remove directory protection (delete .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "El archivo o directorio '%s' no tiene permisos de escritura para mi.<br>
 Los permisos (chmod) están mal configurados o el propietario no es correcto.<br>
 Por favor, compruebe los atributos utilizando su software de FTP.<br>
 El archivo o directorio debe ser configurado a %s.";
-$lang['L_CANT_CREATE_DIR']="No se puede crear el directorio '%s'.
+$lang['L_CANT_CREATE_DIR'] = "No se puede crear el directorio '%s'.
 Cree este directorio manualmente utilizando un programa de FTP.";
-$lang['L_TABLE_TYPE']="Tipo";
-$lang['L_CHECK']="comprobar";
-$lang['L_HTACC_SHA1']="SHA1 (todos los sistemas)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MySQLDumper-Versión";
-$lang['L_MYSQL_VERSION']="MySQL-Versión";
-$lang['L_PHP_VERSION']="PHP-Versión";
-$lang['L_MAX_EXECUTION_TIME']="El máximo de ejecución";
-$lang['L_PHP_EXTENSIONS']="Extensiones de PHP";
-$lang['L_MEMORY']="Memoria";
-$lang['L_FILE_MISSING']="no se encuentra el fichero";
-
-
-?>
\ No newline at end of file
+$lang['L_TABLE_TYPE'] = 'Tipo';
+$lang['L_CHECK'] = 'comprobar';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper]-Versión';
+$lang['L_NEW_MOD_VERSION'] = 'Nueva versión';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'Hay una nueva versión de MyOOS [Dumper] disponible';
+$lang['L_UPDATED_IMPORTANT'] = 'Importante: Antes de actualizar, haga una copia de seguridad de sus archivos';
+$lang['L_UPDATE'] = 'Actualice ahora';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Versión';
+$lang['L_PHP_VERSION'] = 'PHP-Versión';
+$lang['L_MAX_EXECUTION_TIME'] = 'El máximo de ejecución';
+$lang['L_PHP_EXTENSIONS'] = 'Extensiones de PHP';
+$lang['L_MEMORY'] = 'Memoria';
+$lang['L_FILE_MISSING'] = 'no se encuentra el fichero';
+$lang['L_INSTALLING_UPDATES'] = 'Instalando actualizaciones';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Actualización exitosa';
+$lang['L_UPDATE_FAILED'] = 'Actualización fallida';
+$lang['L_UP_TO_DATE'] = 'La versión actual está actualizada';
diff --git a/msd/language/es/lang_restore.php b/msd/language/es/lang_restore.php
index 7e177006..5c731ddd 100644
--- a/msd/language/es/lang_restore.php
+++ b/msd/language/es/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Hasta el momento, se han recuperado <b>%d</b> tablas.";
-$lang['L_FILE_MISSING']="no se encuentra el fichero";
-$lang['L_RESTORE_DB']="la base de datos '<b>%s</b>' en '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> Las tablas han sido importadas.";
-$lang['L_RESTORE_RUN1']="<br>Hasta ahora se han importado <b>%s</b> de <b>%s</b> registros";
-$lang['L_RESTORE_RUN2']="<br/>Se está llenando de datos la tabla '<b>%s</b>'.<br/><br/>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> registros insertados.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Hasta el momento, se han recuperado <b>%d</b> de <b>%d</b> tablas.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Felicidades.</b><br><br>La base de datos ha sido completamente restaurada.<br>Todos los datos de la copia de seguridad han sido importados con éxito.<br><br>He terminado. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Error:<br>La selección de la base de datos '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' ha fallado!";
-$lang['L_FILE_OPEN_ERROR']="Error: no he podido abrir el fichero.";
-$lang['L_PROGRESS_OVER_ALL']="Progreso total";
-$lang['L_BACK_TO_OVERVIEW']="vista de base de datos";
-$lang['L_RESTORE_RUN0']="Hasta el momento, se han recuperado <b>%s</b> de tablas.";
-$lang['L_UNKNOWN_SQLCOMMAND']="comando SQL desconocido";
-$lang['L_NOTICES']="Avisos";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Hasta el momento, se han recuperado <b>%d</b> tablas.';
+$lang['L_FILE_MISSING'] = 'no se encuentra el fichero';
+$lang['L_RESTORE_DB'] = "la base de datos '<b>%s</b>' en '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> Las tablas han sido importadas.';
+$lang['L_RESTORE_RUN1'] = '<br>Hasta ahora se han importado <b>%s</b> de <b>%s</b> registros';
+$lang['L_RESTORE_RUN2'] = "<br/>Se está llenando de datos la tabla '<b>%s</b>'.<br/><br/>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> registros insertados.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Hasta el momento, se han recuperado <b>%d</b> de <b>%d</b> tablas.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Felicidades.</b><br><br>La base de datos ha sido completamente restaurada.<br>Todos los datos de la copia de seguridad han sido importados con éxito.<br><br>He terminado. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Error:<br>La selección de la base de datos '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' ha fallado!";
+$lang['L_FILE_OPEN_ERROR'] = 'Error: no he podido abrir el fichero.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progreso total';
+$lang['L_BACK_TO_OVERVIEW'] = 'vista de base de datos';
+$lang['L_RESTORE_RUN0'] = 'Hasta el momento, se han recuperado <b>%s</b> de tablas.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'comando SQL desconocido';
+$lang['L_NOTICES'] = 'Avisos';
diff --git a/msd/language/es/lang_sql.php b/msd/language/es/lang_sql.php
index 53d06b5b..e319d53f 100644
--- a/msd/language/es/lang_sql.php
+++ b/msd/language/es/lang_sql.php
@@ -1,193 +1,190 @@
 <?php
-$lang['L_COMMAND']="comando";
-$lang['L_IMPORT_NOTABLE']="¡No ha seleccionado ninguna tabla para importar!";
-$lang['L_PASSWORD_STRENGTH']="Fortaleza de la contraseña";
-$lang['L_SQL_WARNING']="La ejecución de comandos SQL sirve para manipular directamente los datos de la base de datos. Los autores no se responsabilizarán de la pérdida de datos ocurrida debido al uso de esta utilidad.";
-$lang['L_SQL_EXEC']="ejecutar comando SQL";
-$lang['L_SQL_DATAVIEW']="Vista de datos";
-$lang['L_SQL_TABLEVIEW']="Vista de tablas";
-$lang['L_SQL_VONINS']="de un total de";
-$lang['L_SQL_NODATA']="No hay registros que mostrar";
-$lang['L_SQL_RECORDUPDATED']="Registro actualizado";
-$lang['L_SQL_RECORDINSERTED']="Registro insertado";
-$lang['L_SQL_BACKDBOVERVIEW']="volver a la vista de bases de datos";
-$lang['L_SQL_RECORDDELETED']="Registro eliminado";
-$lang['L_ASKTABLEEMPTY']="¿Desea vaciar la tabla `%s`?";
-$lang['L_SQL_RECORDEDIT']="editar registro";
-$lang['L_SQL_RECORDNEW']="insertar registro";
-$lang['L_ASKDELETERECORD']="¿Desea eliminar el registro?";
-$lang['L_ASKDELETETABLE']="Desea eliminar la tabla `%s`?";
-$lang['L_SQL_BEFEHLE']="Comandos SQL";
-$lang['L_SQL_BEFEHLNEU']="nuevo comando";
-$lang['L_SQL_BEFEHLSAVED1']="El comando SQL";
-$lang['L_SQL_BEFEHLSAVED2']="ha sido insertado";
-$lang['L_SQL_BEFEHLSAVED3']="ha sido guardado";
-$lang['L_SQL_BEFEHLSAVED4']="ha sido desplazado hacia arriba";
-$lang['L_SQL_BEFEHLSAVED5']="ha sido eliminado";
-$lang['L_SQL_QUERYENTRY']="La consulta contiene";
-$lang['L_SQL_COLUMNS']="columnas";
-$lang['L_ASKDBDELETE']="¿Desea realmente eliminar la base de datos `%s` así como todos sus contenidos?";
-$lang['L_ASKDBEMPTY']="¿Desea realmente vaciar la base de datos `%s` ?";
-$lang['L_ASKDBCOPY']="¿Desea copiar el contenido de la base de datos `%s` a la base de datos `%s`?";
-$lang['L_SQL_TABLENEW']="Modificar tabla";
-$lang['L_SQL_OUTPUT']="Salida de SQL";
-$lang['L_DO_NOW']="ejecutar ahora";
-$lang['L_SQL_NAMEDEST_MISSING']="¡Falta el nombre de destino!";
-$lang['L_ASKDELETEFIELD']="¿Desea eliminar el campo?";
-$lang['L_SQL_COMMANDS_IN']=" líneas en ";
-$lang['L_SQL_COMMANDS_IN2']=" registros modificados por segundo.";
-$lang['L_SQL_OUT1']="Se han ejecutado ";
-$lang['L_SQL_OUT2']="comandos";
-$lang['L_SQL_OUT3']="Hubo ";
-$lang['L_SQL_OUT4']="comentarios";
-$lang['L_SQL_OUT5']="Dado que el comando afecta más de 5000 registros, no se mostrarán los resultados.";
-$lang['L_SQL_SELECDB']="Elija la base de datos";
-$lang['L_SQL_TABLESOFDB']="Tablas de la base de datos";
-$lang['L_SQL_EDIT']="editar";
-$lang['L_SQL_NOFIELDDELETE']="Eliminación imposible, ya que la tabla debe contener al menos un campo.";
-$lang['L_SQL_FIELDDELETE1']="El campo";
-$lang['L_SQL_DELETED']="ha sido eliminado";
-$lang['L_SQL_CHANGED']="ha sido modificado.";
-$lang['L_SQL_CREATED']="ha sido insertado.";
-$lang['L_SQL_NODEST_COPY']="¡Sin destino, no se puede copiar nada!";
-$lang['L_SQL_DESTTABLE_EXISTS']="¡La tabla de destino ya existe!";
-$lang['L_SQL_SCOPY']="La estructura de tabla de `%s` ha sido copiada en la tabla `%s`.";
-$lang['L_SQL_TCOPY']="La tabla `%s` ha sido copiada (con sus datos), en la tabla `%s`.";
-$lang['L_SQL_TABLENONAME']="¡La tabla necesita un nombre!";
-$lang['L_SQL_TBLNAMEEMPTY']="¡El nombre de la tabla no puede estar vacío!";
-$lang['L_SQL_COLLATENOTMATCH']="¡Este juego de caracteres y el orden solicitado no pueden funcionar juntos!";
-$lang['L_SQL_FIELDNAMENOTVALID']="ERROR: nombre de campo inválido";
-$lang['L_SQL_CREATETABLE']="Crear tabla";
-$lang['L_SQL_COPYTABLE']="Copiar tabla";
-$lang['L_SQL_STRUCTUREONLY']="solamente estructura";
-$lang['L_SQL_STRUCTUREDATA']="estructura y datos";
-$lang['L_SQL_NOTABLESINDB']="No hay ninguna tabla en la base de datos";
-$lang['L_SQL_SELECTTABLE']="elegir tabla";
-$lang['L_SQL_SHOWDATATABLE']="mostrar los datos de la tabla";
-$lang['L_SQL_TBLPROPSOF']="Propiedades de tabla de";
-$lang['L_SQL_EDITFIELD']="editar campo";
-$lang['L_SQL_NEWFIELD']="nuevo campo";
-$lang['L_SQL_INDEXES']="índices";
-$lang['L_SQL_ATPOSITION']="insertar en la posición";
-$lang['L_SQL_FIRST']="primero";
-$lang['L_SQL_AFTER']="siguiente";
-$lang['L_SQL_CHANGEFIELD']="modificar campo";
-$lang['L_SQL_INSERTFIELD']="insertar campo";
-$lang['L_SQL_INSERTNEWFIELD']="insertar nuevo campo";
-$lang['L_SQL_TABLEINDEXES']="Índices de la tabla";
-$lang['L_SQL_ALLOWDUPS']="Se permiten duplicados";
-$lang['L_SQL_CARDINALITY']="Cardinalidad";
-$lang['L_SQL_TABLENOINDEXES']="La tabla no contiene ningún índice";
-$lang['L_SQL_CREATEINDEX']="crear nuevo índice";
-$lang['L_SQL_WASEMPTIED']="ha sido vaciada";
-$lang['L_SQL_RENAMEDTO']="ha sido renombrada a";
-$lang['L_SQL_DBCOPY']="El contenido de la base de datos `%s` ha sido copiado a la base de datos `%s`.";
-$lang['L_SQL_DBSCOPY']="La estructura de la base de datos `%s` ha sido copiado a la base de datos `%s`.";
-$lang['L_SQL_WASCREATED']="ha sido creada con éxito";
-$lang['L_SQL_RENAMEDB']="renombrar base de datos";
-$lang['L_SQL_ACTIONS']="Acciones";
-$lang['L_SQL_CHOOSEACTION']="Elija una acción";
-$lang['L_SQL_DELETEDB']="eliminar base de datos";
-$lang['L_SQL_EMPTYDB']="vaciar base de datos";
-$lang['L_SQL_COPYDATADB']="Copiar contenido de la base de datos";
-$lang['L_SQL_COPYSDB']="Copiar estructura en la base de datos";
-$lang['L_SQL_IMEXPORT']="Im-/Exportar";
-$lang['L_INFO_RECORDS']="Registros";
-$lang['L_NAME']="Nombre";
-$lang['L_ASKTABLEEMPTYKEYS']="¿Desea vaciar la tabla `%s` y resetear sus índices?";
-$lang['L_EDIT']="editar";
-$lang['L_DELETE']="eliminar";
-$lang['L_EMPTY']="vaciar";
-$lang['L_EMPTYKEYS']="vaciar y resetear los índices";
-$lang['L_SQL_TABLEEMPTIED']="La tabla `%s` ha sido vaciada.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="La tabla `%s` ha sido eliminada, y los índices reinicializados.";
-$lang['L_SQL_LIBRARY']="Librería SQL";
-$lang['L_SQL_ATTRIBUTES']="Atributos";
-$lang['L_SQL_UPLOADEDFILE']="Fichero cargado: ";
-$lang['L_SQL_IMPORT']="Importar a la base de datos `%s`";
-$lang['L_EXPORT']="Exportar";
-$lang['L_IMPORT']="Importar";
-$lang['L_IMPORTOPTIONS']="Opciones de importación";
-$lang['L_CSVOPTIONS']="Opciones CSV";
-$lang['L_IMPORTTABLE']="Importar a tabla";
-$lang['L_NEWTABLE']="nueva tabla";
-$lang['L_IMPORTSOURCE']="Origen de la importación";
-$lang['L_FROMTEXTBOX']="del campo de texto";
-$lang['L_FROMFILE']="de un fichero";
-$lang['L_EMPTYTABLEBEFORE']="Vaciar la tabla antes de la operación";
-$lang['L_CREATEAUTOINDEX']="Crear índice automático";
-$lang['L_CSV_NAMEFIRSTLINE']="Nombres de campo en la primera línea";
-$lang['L_CSV_FIELDSEPERATE']="Campos separados por";
-$lang['L_CSV_FIELDSENCLOSED']="Campos delimitados por";
-$lang['L_CSV_FIELDSESCAPE']="Campos 'escapeados' con";
-$lang['L_CSV_EOL']="separar líneas con";
-$lang['L_CSV_NULL']="reemplazar NULL con";
-$lang['L_CSV_FILEOPEN']="abrir fichero CSV";
-$lang['L_IMPORTIEREN']="Importar";
-$lang['L_SQL_EXPORT']="Exportar la base de datos `%s`";
-$lang['L_EXPORTOPTIONS']="Opciones de exportación";
-$lang['L_EXCEL2003']="Excel a partir de la versión 2003";
-$lang['L_SHOWRESULT']="Mostrar resultados";
-$lang['L_SENDRESULTASFILE']="Enviar resultados como archivo";
-$lang['L_EXPORTLINES']="<strong>%s</strong> líneas exportadas";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="El número de campos no coincide con el de los datos a importar (%d en vez de  %d).";
-$lang['L_CSV_FIELDSLINES']="%d campos reconocidos, totalizando %d líneas";
-$lang['L_CSV_ERRORCREATETABLE']="¡Error al crear la tabla `%s`!";
-$lang['L_FM_UPLOADFILEREQUEST']="Por favor, elija un archivo.";
-$lang['L_CSV_NODATA']="¡No se han encontrado datos que importar!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="funciones generales";
-$lang['L_SQLLIB_RESETAUTO']="reinicializar autoincremento";
-$lang['L_SQLLIB_BOARDS']="Foros";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="desactivar foro";
-$lang['L_SQLLIB_ACTIVATEBOARD']="activar foro";
-$lang['L_SQL_NOTABLESSELECTED']="¡No se han seleccionado tablas!";
-$lang['L_TOOLS']="Herramientas";
-$lang['L_TOOLS_TOOLBOX']="Elección de base de datos / Funciones de base de datos / Im- y Exportar ";
-$lang['L_SQL_OPENFILE']="Abrir archivo SQL";
-$lang['L_SQL_OPENFILE_BUTTON']="Subir";
-$lang['L_MAX_UPLOAD_SIZE']="Tamaño máximo del fichero";
-$lang['L_SQL_SEARCH']="Búsqueda";
-$lang['L_SQL_SEARCHWORDS']="Palabra(s) de búsqueda";
-$lang['L_START_SQL_SEARCH']="Iniciar búsqueda";
-$lang['L_RESET_SEARCHWORDS']="Reinicializar criterios de búsqueda";
-$lang['L_SEARCH_OPTIONS']="Opciones de búsqueda";
-$lang['L_SEARCH_RESULTS']="La búsqueda para \"<b>%s</b>\" en la tabla \"<b>%s</b>\" produjo los siguientes resultados";
-$lang['L_SEARCH_NO_RESULTS']="¡La búsqueda para \"<b>%s</b>\" en la tabla \"<b>%s</b>\" no produjo ningún resultado!";
-$lang['L_NO_ENTRIES']="La tabla \"<b>%s</b>\" está vacía y no contiene ninguna entrada.";
-$lang['L_SEARCH_ACCESS_KEYS']="Navegar:
-Adelante=ALT+V
-Atrás=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="Una columna debe contener al menos un criterio de búsqueda (O-Búsqueda)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="Una línea debe contener todos los términos de búsqueda, pero estos puede ser en cualquiera de las columnas (¡podría tardar!)";
-$lang['L_SEARCH_OPTIONS_AND']="una columna debe contener todos los términos de búsqueda (Y-Búsqueda)";
-$lang['L_SEARCH_IN_TABLE']="Buscar en la tabla";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Modificar la estructura de la tabla";
-$lang['L_DEFAULT_CHARSET']="Conjunto de caracteres por defecto";
-$lang['L_TITLE_KEY_PRIMARY']="Clave principal";
-$lang['L_TITLE_KEY_UNIQUE']="Clave única";
-$lang['L_TITLE_INDEX']="Índice";
-$lang['L_TITLE_KEY_FULLTEXT']="Clave texto completo";
-$lang['L_TITLE_NOKEY']="No hay clave";
-$lang['L_TITLE_SEARCH']="Búsqueda";
-$lang['L_TITLE_MYSQL_HELP']="Documentación de MySQL";
-$lang['L_TITLE_UPLOAD']="Subir archivo SQL";
-$lang['L_PRIMARYKEY_DELETED']="Clave principal eliminada";
-$lang['L_PRIMARYKEY_NOTFOUND']="Clave principal no encontrada";
-$lang['L_PRIMARYKEYS_CHANGED']="Clave principal cambiada";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error al cambiar la clave principal";
-$lang['L_SQL_VIEW_COMPACT']="Ver: Compacto";
-$lang['L_SQL_VIEW_STANDARD']="Ver: Normal";
-$lang['L_FIELDS_OF_TABLE']="Campos de la tabla";
-$lang['L_ENGINE']="Máquina";
-$lang['L_USERNAME']="Nombre de usuario";
-$lang['L_PASSWORD']="Contraseña";
-$lang['L_PASSWORD_REPEAT']="Contraseña (repetición)";
-$lang['L_INFO_SIZE']="Tamaño";
-$lang['L_TABLE_TYPE']="Tipo";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'comando';
+$lang['L_IMPORT_NOTABLE'] = '¡No ha seleccionado ninguna tabla para importar!';
+$lang['L_PASSWORD_STRENGTH'] = 'Fortaleza de la contraseña';
+$lang['L_SQL_WARNING'] = 'La ejecución de comandos SQL sirve para manipular directamente los datos de la base de datos. Los autores no se responsabilizarán de la pérdida de datos ocurrida debido al uso de esta utilidad.';
+$lang['L_SQL_EXEC'] = 'ejecutar comando SQL';
+$lang['L_SQL_DATAVIEW'] = 'Vista de datos';
+$lang['L_SQL_TABLEVIEW'] = 'Vista de tablas';
+$lang['L_SQL_VONINS'] = 'de un total de';
+$lang['L_SQL_NODATA'] = 'No hay registros que mostrar';
+$lang['L_SQL_RECORDUPDATED'] = 'Registro actualizado';
+$lang['L_SQL_RECORDINSERTED'] = 'Registro insertado';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'volver a la vista de bases de datos';
+$lang['L_SQL_RECORDDELETED'] = 'Registro eliminado';
+$lang['L_ASKTABLEEMPTY'] = '¿Desea vaciar la tabla `%s`?';
+$lang['L_SQL_RECORDEDIT'] = 'editar registro';
+$lang['L_SQL_RECORDNEW'] = 'insertar registro';
+$lang['L_ASKDELETERECORD'] = '¿Desea eliminar el registro?';
+$lang['L_ASKDELETETABLE'] = 'Desea eliminar la tabla `%s`?';
+$lang['L_SQL_BEFEHLE'] = 'Comandos SQL';
+$lang['L_SQL_BEFEHLNEU'] = 'nuevo comando';
+$lang['L_SQL_BEFEHLSAVED1'] = 'El comando SQL';
+$lang['L_SQL_BEFEHLSAVED2'] = 'ha sido insertado';
+$lang['L_SQL_BEFEHLSAVED3'] = 'ha sido guardado';
+$lang['L_SQL_BEFEHLSAVED4'] = 'ha sido desplazado hacia arriba';
+$lang['L_SQL_BEFEHLSAVED5'] = 'ha sido eliminado';
+$lang['L_SQL_QUERYENTRY'] = 'La consulta contiene';
+$lang['L_SQL_COLUMNS'] = 'columnas';
+$lang['L_ASKDBDELETE'] = '¿Desea realmente eliminar la base de datos `%s` así como todos sus contenidos?';
+$lang['L_ASKDBEMPTY'] = '¿Desea realmente vaciar la base de datos `%s` ?';
+$lang['L_ASKDBCOPY'] = '¿Desea copiar el contenido de la base de datos `%s` a la base de datos `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Modificar tabla';
+$lang['L_SQL_OUTPUT'] = 'Salida de SQL';
+$lang['L_DO_NOW'] = 'ejecutar ahora';
+$lang['L_SQL_NAMEDEST_MISSING'] = '¡Falta el nombre de destino!';
+$lang['L_ASKDELETEFIELD'] = '¿Desea eliminar el campo?';
+$lang['L_SQL_COMMANDS_IN'] = ' líneas en ';
+$lang['L_SQL_COMMANDS_IN2'] = ' registros modificados por segundo.';
+$lang['L_SQL_OUT1'] = 'Se han ejecutado ';
+$lang['L_SQL_OUT2'] = 'comandos';
+$lang['L_SQL_OUT3'] = 'Hubo ';
+$lang['L_SQL_OUT4'] = 'comentarios';
+$lang['L_SQL_OUT5'] = 'Dado que el comando afecta más de 5000 registros, no se mostrarán los resultados.';
+$lang['L_SQL_SELECDB'] = 'Elija la base de datos';
+$lang['L_SQL_TABLESOFDB'] = 'Tablas de la base de datos';
+$lang['L_SQL_EDIT'] = 'editar';
+$lang['L_SQL_NOFIELDDELETE'] = 'Eliminación imposible, ya que la tabla debe contener al menos un campo.';
+$lang['L_SQL_FIELDDELETE1'] = 'El campo';
+$lang['L_SQL_DELETED'] = 'ha sido eliminado';
+$lang['L_SQL_CHANGED'] = 'ha sido modificado.';
+$lang['L_SQL_CREATED'] = 'ha sido insertado.';
+$lang['L_SQL_NODEST_COPY'] = '¡Sin destino, no se puede copiar nada!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = '¡La tabla de destino ya existe!';
+$lang['L_SQL_SCOPY'] = 'La estructura de tabla de `%s` ha sido copiada en la tabla `%s`.';
+$lang['L_SQL_TCOPY'] = 'La tabla `%s` ha sido copiada (con sus datos), en la tabla `%s`.';
+$lang['L_SQL_TABLENONAME'] = '¡La tabla necesita un nombre!';
+$lang['L_SQL_TBLNAMEEMPTY'] = '¡El nombre de la tabla no puede estar vacío!';
+$lang['L_SQL_COLLATENOTMATCH'] = '¡Este juego de caracteres y el orden solicitado no pueden funcionar juntos!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'ERROR: nombre de campo inválido';
+$lang['L_SQL_CREATETABLE'] = 'Crear tabla';
+$lang['L_SQL_COPYTABLE'] = 'Copiar tabla';
+$lang['L_SQL_STRUCTUREONLY'] = 'solamente estructura';
+$lang['L_SQL_STRUCTUREDATA'] = 'estructura y datos';
+$lang['L_SQL_NOTABLESINDB'] = 'No hay ninguna tabla en la base de datos';
+$lang['L_SQL_SELECTTABLE'] = 'elegir tabla';
+$lang['L_SQL_SHOWDATATABLE'] = 'mostrar los datos de la tabla';
+$lang['L_SQL_TBLPROPSOF'] = 'Propiedades de tabla de';
+$lang['L_SQL_EDITFIELD'] = 'editar campo';
+$lang['L_SQL_NEWFIELD'] = 'nuevo campo';
+$lang['L_SQL_INDEXES'] = 'índices';
+$lang['L_SQL_ATPOSITION'] = 'insertar en la posición';
+$lang['L_SQL_FIRST'] = 'primero';
+$lang['L_SQL_AFTER'] = 'siguiente';
+$lang['L_SQL_CHANGEFIELD'] = 'modificar campo';
+$lang['L_SQL_INSERTFIELD'] = 'insertar campo';
+$lang['L_SQL_INSERTNEWFIELD'] = 'insertar nuevo campo';
+$lang['L_SQL_TABLEINDEXES'] = 'Índices de la tabla';
+$lang['L_SQL_ALLOWDUPS'] = 'Se permiten duplicados';
+$lang['L_SQL_CARDINALITY'] = 'Cardinalidad';
+$lang['L_SQL_TABLENOINDEXES'] = 'La tabla no contiene ningún índice';
+$lang['L_SQL_CREATEINDEX'] = 'crear nuevo índice';
+$lang['L_SQL_WASEMPTIED'] = 'ha sido vaciada';
+$lang['L_SQL_RENAMEDTO'] = 'ha sido renombrada a';
+$lang['L_SQL_DBCOPY'] = 'El contenido de la base de datos `%s` ha sido copiado a la base de datos `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'La estructura de la base de datos `%s` ha sido copiado a la base de datos `%s`.';
+$lang['L_SQL_WASCREATED'] = 'ha sido creada con éxito';
+$lang['L_SQL_RENAMEDB'] = 'renombrar base de datos';
+$lang['L_SQL_ACTIONS'] = 'Acciones';
+$lang['L_SQL_CHOOSEACTION'] = 'Elija una acción';
+$lang['L_SQL_DELETEDB'] = 'eliminar base de datos';
+$lang['L_SQL_EMPTYDB'] = 'vaciar base de datos';
+$lang['L_SQL_COPYDATADB'] = 'Copiar contenido de la base de datos';
+$lang['L_SQL_COPYSDB'] = 'Copiar estructura en la base de datos';
+$lang['L_SQL_IMEXPORT'] = 'Im-/Exportar';
+$lang['L_INFO_RECORDS'] = 'Registros';
+$lang['L_NAME'] = 'Nombre';
+$lang['L_ASKTABLEEMPTYKEYS'] = '¿Desea vaciar la tabla `%s` y resetear sus índices?';
+$lang['L_EDIT'] = 'editar';
+$lang['L_DELETE'] = 'eliminar';
+$lang['L_EMPTY'] = 'vaciar';
+$lang['L_EMPTYKEYS'] = 'vaciar y resetear los índices';
+$lang['L_SQL_TABLEEMPTIED'] = 'La tabla `%s` ha sido vaciada.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'La tabla `%s` ha sido eliminada, y los índices reinicializados.';
+$lang['L_SQL_LIBRARY'] = 'Librería SQL';
+$lang['L_SQL_ATTRIBUTES'] = 'Atributos';
+$lang['L_SQL_UPLOADEDFILE'] = 'Fichero cargado: ';
+$lang['L_SQL_IMPORT'] = 'Importar a la base de datos `%s`';
+$lang['L_EXPORT'] = 'Exportar';
+$lang['L_IMPORT'] = 'Importar';
+$lang['L_IMPORTOPTIONS'] = 'Opciones de importación';
+$lang['L_CSVOPTIONS'] = 'Opciones CSV';
+$lang['L_IMPORTTABLE'] = 'Importar a tabla';
+$lang['L_NEWTABLE'] = 'nueva tabla';
+$lang['L_IMPORTSOURCE'] = 'Origen de la importación';
+$lang['L_FROMTEXTBOX'] = 'del campo de texto';
+$lang['L_FROMFILE'] = 'de un fichero';
+$lang['L_EMPTYTABLEBEFORE'] = 'Vaciar la tabla antes de la operación';
+$lang['L_CREATEAUTOINDEX'] = 'Crear índice automático';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Nombres de campo en la primera línea';
+$lang['L_CSV_FIELDSEPERATE'] = 'Campos separados por';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Campos delimitados por';
+$lang['L_CSV_FIELDSESCAPE'] = "Campos 'escapeados' con";
+$lang['L_CSV_EOL'] = 'separar líneas con';
+$lang['L_CSV_NULL'] = 'reemplazar NULL con';
+$lang['L_CSV_FILEOPEN'] = 'abrir fichero CSV';
+$lang['L_IMPORTIEREN'] = 'Importar';
+$lang['L_SQL_EXPORT'] = 'Exportar la base de datos `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Opciones de exportación';
+$lang['L_EXCEL2003'] = 'Excel a partir de la versión 2003';
+$lang['L_SHOWRESULT'] = 'Mostrar resultados';
+$lang['L_SENDRESULTASFILE'] = 'Enviar resultados como archivo';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> líneas exportadas';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'El número de campos no coincide con el de los datos a importar (%d en vez de  %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d campos reconocidos, totalizando %d líneas';
+$lang['L_CSV_ERRORCREATETABLE'] = '¡Error al crear la tabla `%s`!';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Por favor, elija un archivo.';
+$lang['L_CSV_NODATA'] = '¡No se han encontrado datos que importar!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'funciones generales';
+$lang['L_SQLLIB_RESETAUTO'] = 'reinicializar autoincremento';
+$lang['L_SQLLIB_BOARDS'] = 'Foros';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'desactivar foro';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'activar foro';
+$lang['L_SQL_NOTABLESSELECTED'] = '¡No se han seleccionado tablas!';
+$lang['L_TOOLS'] = 'Herramientas';
+$lang['L_TOOLS_TOOLBOX'] = 'Elección de base de datos / Funciones de base de datos / Im- y Exportar ';
+$lang['L_SQL_OPENFILE'] = 'Abrir archivo SQL';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Subir';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Tamaño máximo del fichero';
+$lang['L_SQL_SEARCH'] = 'Búsqueda';
+$lang['L_SQL_SEARCHWORDS'] = 'Palabra(s) de búsqueda';
+$lang['L_START_SQL_SEARCH'] = 'Iniciar búsqueda';
+$lang['L_RESET_SEARCHWORDS'] = 'Reinicializar criterios de búsqueda';
+$lang['L_SEARCH_OPTIONS'] = 'Opciones de búsqueda';
+$lang['L_SEARCH_RESULTS'] = 'La búsqueda para "<b>%s</b>" en la tabla "<b>%s</b>" produjo los siguientes resultados';
+$lang['L_SEARCH_NO_RESULTS'] = '¡La búsqueda para "<b>%s</b>" en la tabla "<b>%s</b>" no produjo ningún resultado!';
+$lang['L_NO_ENTRIES'] = 'La tabla "<b>%s</b>" está vacía y no contiene ninguna entrada.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Navegar: Adelante=ALT+V, Atrás=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'Una columna debe contener al menos un criterio de búsqueda (O-Búsqueda)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'Una línea debe contener todos los términos de búsqueda, pero estos puede ser en cualquiera de las columnas (¡podría tardar!)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'una columna debe contener todos los términos de búsqueda (Y-Búsqueda)';
+$lang['L_SEARCH_IN_TABLE'] = 'Buscar en la tabla';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Modificar la estructura de la tabla';
+$lang['L_DEFAULT_CHARSET'] = 'Conjunto de caracteres por defecto';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Clave principal';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Clave única';
+$lang['L_TITLE_INDEX'] = 'Índice';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Clave texto completo';
+$lang['L_TITLE_NOKEY'] = 'No hay clave';
+$lang['L_TITLE_SEARCH'] = 'Búsqueda';
+$lang['L_TITLE_MYSQL_HELP'] = 'Documentación de MySQL';
+$lang['L_TITLE_UPLOAD'] = 'Subir archivo SQL';
+$lang['L_PRIMARYKEY_DELETED'] = 'Clave principal eliminada';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Clave principal no encontrada';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Clave principal cambiada';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error al cambiar la clave principal';
+$lang['L_SQL_VIEW_COMPACT'] = 'Ver: Compacto';
+$lang['L_SQL_VIEW_STANDARD'] = 'Ver: Normal';
+$lang['L_FIELDS_OF_TABLE'] = 'Campos de la tabla';
+$lang['L_ENGINE'] = 'Máquina';
+$lang['L_USERNAME'] = 'Nombre de usuario';
+$lang['L_PASSWORD'] = 'Contraseña';
+$lang['L_PASSWORD_REPEAT'] = 'Contraseña (repetición)';
+$lang['L_INFO_SIZE'] = 'Tamaño';
+$lang['L_TABLE_TYPE'] = 'Tipo';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/fr/help.html b/msd/language/fr/help.html
new file mode 100644
index 00000000..2eb3c0da
--- /dev/null
+++ b/msd/language/fr/help.html
@@ -0,0 +1,148 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> basé sur MySQLDumper 1.24.4</h3>
+
+<h3>A propos de ce projet</h3>
+<p><strong>MyOOS [Dumper]</strong> est une version améliorée de MySQLDumper 1.24.4 (24 janvier 2011). Cette évolution prend en compte le développement du PHP.
+<p>MyOOS [Dumper]</strong> se préoccupe avant tout de stabilité, de sécurité et de maniabilité. Mais un modèle attrayant est également inclus, qui peut être modifié et adapté à vos propres besoins.</p>
+
+
+<p><strong>MyOOS [Dumper]</strong> est un programme de sauvegarde pour les bases de données MySQL, écrit en PHP et Perl. Il permet de créer des copies de sauvegarde des données (boutique, blog, etc.) et de les restaurer si nécessaire. En particulier pour les espaces web sans accès au shell, MyOOS [Dumper] s'offre comme une alternative judicieuse.</p>. 
+
+<p>L'idée de MySQLDumper vient de Daniel Schlichtholz. Il a ouvert le forum MySQLDumper en 2004, à la suite de quoi les programmeurs ont écrit de nouveaux scripts et étendu les scripts existants.</p>
+
+
+<h3>Liste de souhaits / Attractions futures</h3>.
+<p>Avez-vous des suggestions d'amélioration ? N'hésitez pas à contacter l'équipe de développement via le forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>.
+
+
+<h3>Contribuer</h3>.
+</p> <p>Si vous souhaitez nous aider à améliorer le projet MyOOS, nous accueillons vos demandes de pull via GitHub ici.</p> <p>.
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Soutien financier</h3>
+<p>Vous pouvez utiliser PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p>. 
+
+<p>ou via le code QR<br>.  
+<img src="images/qrcode.png" alt="Soutien financier à MyOOS [Dumper]"></p>
+
+Envoyez de l'argent au projet MyOOS. <br>
+
+<p>Nous espérons que ce projet vous plaira.<br><p><h4>L'équipe MyOOS [Dumper]</h4>.
+
+<img src="css/mod/pics/h1_logo.gif" alt="MyOOS [Dumper]"><br>
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+
+<h3>MyOOS [Dumper] Aide</h3>
+
+<h4>Téléchargement</h4>
+<p>Vous pouvez toujours obtenir les dernières versions sur GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>.
+
+
+<h4>Système requis</h4>
+<p>Le script fonctionne sur n'importe quel serveur (Windows, Linux, ...) <br>.
+avec PHP >= version 7.4 avec support GZip, MySQL (version 4.1 ou supérieure), JavaScript (doit être activé).</p>
+<p>Copier le dossier mod de l'archive MyOOS dans un dossier de travail séparé.</p>.
+
+<h4>Installation</h4></a>
+L'installation est simple.
+<p>À partir de l'archive MyOOS, copiez le dossier du mod dans n'importe quel dossier.<br>
+Téléchargez tous les fichiers du dossier mod sur votre serveur Web. (par exemple, au niveau le plus bas de [répertoire web du serveur/]mod)<br>.
+... fait!<br>
+Vous pouvez maintenant appeler MyOOS [Dumper] dans votre navigateur web en allant sur "https://example.com/mod/"<br>.
+pour terminer l'installation. Il suffit de suivre les instructions. <br>
+<br><b>Note:</b><br><i>Si sur votre serveur le script n'est pas autorisé à créer des répertoires,<br>.
+vous devrez le faire manuellement, car MyOOS [Dumper] stocke les données dans des répertoires.
+répertoires.<br> 
+Le script se termine par une déclaration appropriée !<br>
+Une fois que vous avez créé les répertoires (selon l'indication), il fonctionne normalement et sans restrictions.</i>
+
+<a name="perl"></a><h4>Instructions pour le script Perl</h4>
+La plupart ont un répertoire cgi-bin où Perl peut être exécuté. <br>
+Il est généralement accessible par le navigateur via http://www.example.com/cgi-bin/. <br>
+<br>
+Dans ce cas, veuillez effectuer les étapes suivantes :<br><br> 1.
+
+1. Appelez la page de sauvegarde dans MyOOS [Dumper] et cliquez sur "Backup Perl". <br>
+2. copiez le chemin derrière l'entrée dans crondump.pl pour $absolute_path_of_configdir :. <br>
+3. ouvrez le fichier "crondump.pl" dans l'éditeur.<br>
+4. saisissez le chemin copié à cet endroit à absolute_path_of_configdir (sans espace).<br>
+5. sauvegarder crondump.pl.<br>
+Copiez crondump.pl, perltest.pl et simpletest.pl dans le répertoire cgi-bin (mode ascii en FTP).
+7. donnez aux fichiers les permissions 755. <br>
+7b. Si la terminaison cgi est souhaitée, changez la terminaison des 3 fichiers de pl -> cgi (renommer). <br>
+Appelez la configuration dans MyOOS [Dumper].
+9. sélectionnez la page Cronscript. <br>
+10. changer le chemin d'exécution de Perl en /cgi-bin/ .<br>
+10b. Si les scripts ont un .pl, changez l'extension du fichier en .cgi .<br>
+11. Enregistrez la configuration. <br><br>
+
+C'est fait, les scripts peuvent maintenant être appelés à partir de la page de sauvegarde.<br><br>.
+
+Pour ceux qui peuvent exécuter Perl dans tous les répertoires, les étapes suivantes sont suffisantes:<br><br>.
+
+1. Appelez la page Sauvegarde dans MyOOS [Dumper]. <br>
+2. copiez le chemin derrière l'entrée dans crondump.pl pour $absolute_path_of_configdir :. <br>
+Ouvrez le fichier "crondump.pl" dans l'éditeur. <br>
+4. entrez le chemin copié à cet endroit à absolute_path_of_configdir (sans espace). <br>
+5. sauvegarder crondump.pl .<br>
+6. donnez aux fichiers les permissions 755. <br>
+6b. Si la terminaison cgi est souhaitée, changez la terminaison des 3 fichiers de pl -> cgi (renommer). <br>
+(ev. 10b+11 du dessus)<br>
+<br>
+
+Les utilisateurs de Windows doivent modifier la première ligne de tous les scripts, où se trouve le chemin de Perl. Exemple : <br>
+au lieu de : #!/usr/bin/perl -w <br>
+maintenant : #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Opération</h4><ul>.
+
+<h6>Menu</h6>.
+Dans la liste de sélection ci-dessus, vous définissez la base de données.<br>
+Toutes les actions se réfèrent à la base de données définie ici.
+
+<h6>Accueil</h6>
+Vous y trouverez des informations sur votre système, les différentes versions installées et les détails des bases de données configurées.
+versions installées et des détails sur les bases de données configurées.<br>
+Si vous cliquez sur le nom de la base de données, vous verrez une liste des tables avec le nombre d'entrées.
+avec le nombre d'entrées, la taille et la date de la dernière mise à jour.
+
+<h6>Configuration</h6>
+Vous pouvez y modifier votre configuration, l'enregistrer ou restaurer la configuration initiale.
+pour revenir à la configuration initiale.
+<ul><br>
+	<li><a name="conf1"></a><strong>Bases de données configurées:</strong> la liste des bases de données configurées. La base de données active est indiquée en <b>gras</b>. </li>
+	<li><a name="conf2"></a><strong>Préfixe de table:</strong> ici vous pouvez spécifier un préfixe (pour chaque base de données). Il s'agit d'un filtre qui ne prend en compte que les tables commençant par ce préfixe lors du vidage (par exemple, toutes les tables commençant par "phpBB_"). Si vous voulez que toutes les tables de cette base de données soient enregistrées, laissez le champ vide.</li>.
+	<li><a name="conf3"></a><strong>Compression GZip:</strong> Ici, vous pouvez activer la compression. Il est recommandé de l'activer, car les fichiers deviennent beaucoup plus petits et l'espace de stockage est toujours rare.
+	<li><a name="conf5"></a><strong>Email avec fichier dump:</strong> Si cette option est activée, un email avec le dump en pièce jointe est envoyé après la fin de la sauvegarde (attention, la compression doit absolument être activée, sinon la pièce jointe sera trop grande et risque de ne pas être envoyée !)
+	<li><a name="conf6"></a><strong>Adresse e-mail:</strong>Adresse du destinataire de l'e-mail.</li>
+	<li><a name="conf7"></a><strong>Envoyeur du courriel:</strong> cette adresse apparaît comme l'expéditeur dans le courriel.</li>
+	<li><a name="conf13"></a><strong>Transfert FTP : </strong>Si cette option est activée, le fichier de sauvegarde sera envoyé par FTP une fois la sauvegarde terminée.</li>.
+	<li><a name="conf14"></a><strong>Serveur FTP : </strong>L'adresse du serveur FTP (par exemple ftp.mybackups.de).</li>
+	<li><a name="conf15"></a><strong>Port du serveur FTP : </strong>Le port du serveur FTP (généralement 21).</li>
+	<li><a name="conf16"></a><strong>Utilisateur FTP : </strong>Le nom d'utilisateur du compte FTP. </li>
+	<li><a name="conf17"></a><strong>Mot de passe FTP : </strong>Le mot de passe du compte FTP. </li>
+	<li><a name="conf18"></a><strong>Dossier de téléchargement FTP : </strong>Le répertoire où le fichier de sauvegarde doit aller (les autorisations de téléchargement doivent exister !).</li>.
+	<li><a name="conf8"></a><strong>Suppression automatique des sauvegardes:</strong>Si cette option est activée, les anciennes sauvegardes seront supprimées automatiquement selon les règles suivantes.</li>
+	<li><a name="conf10"></a><strong>Nombre de fichiers de sauvegarde :</strong> Une valeur > 0 supprime tous les fichiers de sauvegarde sauf le nombre spécifié ici.</li>.
+	<li><a name="conf11"></a><strong>Langue:</strong> ici vous définissez la langue de l'interface.</li>
+</ul>
+
+<h6>Administration</h6>
+C'est là que les actions réelles sont effectuées.
+Tous les fichiers du répertoire de sauvegarde sont affichés.
+Pour les actions "Restaurer" et "Supprimer", un fichier doit être sélectionné.
+<UL>
+	<li><strong>Restauration:</strong> Ceci met à jour la base de données avec le fichier de sauvegarde sélectionné.</li>
+	<li><strong>Supprimer:</strong> Cela vous permet de supprimer le fichier de sauvegarde sélectionné.</li>.
+	<li><strong>Démarrer une nouvelle sauvegarde :</strong> Vous pouvez ici démarrer une nouvelle sauvegarde (dump) selon les paramètres définis dans la configuration.
+</UL>
+
+<h6>Log</h6>
+Ici, vous pouvez voir et supprimer les entrées du journal.
+<h6>Crédits / Aide</h6>
+cette page.
+</ul>
diff --git a/msd/language/fr/help.php b/msd/language/fr/help.php
deleted file mode 100644
index 432dd609..00000000
--- a/msd/language/fr/help.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Sur ce projet</h3>
-L'idée pour ce projet est venue de Daniel Schlichtholz.<p>Il a ouvert en 2004 le forum <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> et rapidement d'autres développeurs ont écrit de nouveaux scripts ou bien élargi les scripts de Daniel. En peu de temps le simple script de sauvegarde est devenu un imposant projet.<p>Si vous avez des propositions d'améliorations vous pouvez les communiquer dans le Forum MySQLDumper <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>. <p>Nous vous souhaitons beaucoup de plaisir avec ce projet.<br><p><h4>L'équipe de MySQLDumper</h4>
-
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
-
-<h3>Aide MySQLDumper</h3>
-
-<h4>Téléchargement</h4>
-Vous venez de télécharger ce script sur le page d'accueil de MySQLDumper.<br>
-Nous vous conseillons de visiter régulièrement la page d'accueil, afin d'accéder aux mises à jour et au support.<br>
-L'adresse est: <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>Système requis</h4>
-Le script travaille sur tous les serveurs (Windows, Linux...)<br>
-ayant PHP >= version 4.3.4 avec GZip, MySQL (à partir de la version 3.23), JavaScript (doit être activé).
-
-<a href="install.php?language=fr" target="_top"><h4>Installation</h4></a>
-L'installation est simple.
-Décompresser l'archive dans un répertoire quelconque.<br>
-Envoyer tous les fichiers sur votre espace web. (exemple:Dans le niveau le plus bas [Répertoire du serveur/]MySQLDumper)<br>
-... c'est terminé!<br>
-Maintenant il suffit d'appeler MySQLDumper en saisissant l'adresse suivante dans votre navigateur "http://mon-site-web/MySQLDumper"<br>
-afin de terminer l'installation. Il suffit maintenant de suivre les instructions.<br>
-<br><b>Remarque:</b><br><i>Si votre espace web à la fonction PHP Safemode activé, le script ne pourra pas créer les répertoires.<br>
-Vous devrez le faire manuellement afin que MySqlDump puisse sauvegarder les données dans les répertoires.<br> 
-Le script s'arrêtera avec un message en conséquence!<br>
-Après avoir crée les répertoires (d'après les informations reçues), le programme fonctionnera normalement et sans restrictions.</i>
-
-<a name="perl"></a><h4>Mode d'emploi du script Perl</h4>
-La plupart ont un répertoire cgi-bin, qui permet d'exécuter en Perl. <br>
-Vous pouvez y accéder dans la majeur partie des cas en saisissant l'adresse suivante dans votre navigateur http://www.domaine.com/cgi-bin/. <br>
-<br>
-Dans ce cas veuillez suivre les étapes suivantes:<br><br>
-
-1. Appeler la page 'Sauvegarde' dans MySQLDumper. <br>
-2. Copier le chemin qui se trouve derrière le texte: crondump.pl pour $absolute_path_of_configdir: <br>
-3. Ouvrir le fichier "crondump.pl" dans un éditeur <br>
-4. et transmettre le chemin que vous venez de copier près de absolute_path_of_configdir (sans espace) <br>
-5. Sauvegarder crondump.pl <br>
-6. Copier crondump.pl, ainsi que perltest.pl et simpletest.pl dans le répertoire cgi-bin (Mode-ASCII par FTP) <br>
-7. Donner les droits CHMOD 755 <br>
-7b. Si l'extension .cgi est désirée, changer pour les trois fichiers l'extension de .pl vers .cgi (action renommer) <br>
-8. Appeller la configuraion dans MySQLDumper<br>
-9. Choisir la page script Cron <br>
-10. Changer le chemin d'exécution Perl vers /cgi-bin/ <br>
-10b. Si les scripts ont l'extension .cgi, changer l'extension vers .cgi <br>
-11. et sauvegarder la configuration <br><br>
-
-Voila, c'est terminé, les scripts s'exécutent maintenant d'après la page de sauvegarde.<br><br>
-
-Si vous pouvez exécuter Perl de tous les fichiers, il vous suffit de suivre les étapes suivantes:<br><br>
-
-1. Appeler dans MySQLDumper la page 'Sauvegarde' et cliquer "Backup Perl". <br>
-2. Copier le chemin qui se trouve derrière le texte: crondump.pl pour $absolute_path_of_configdir: <br>
-3. Ouvrir le fichier "crondump.pl" dans un éditeur <br>
-4. et transmettre le chemin que vous avez copié près de absolute_path_of_configdir (sans espace) <br>
-5. Sauvegarder crondump.pl <br>
-6. Donner les droits CHMOD 755 <br>
-6b. Si l'extension .cgi est désirée, changer pour les trois fichiers l'extension de .pl vers .cgi (action renommer)  <br>
-(eventuellement 10b+11 ci-desus)<br>
-<br>
-
-Les utilisateurs de Windows doivent changer pour tous les scripts la première ligne où est stipulé le chemin du programme Perl. Exemple: <br>
-à la place de: #!/usr/bin/perl -w <br>
-remplacer par: #!C:\perl\bin\perl.exe -w <br>
-
-<h4>Navigation</h4><ul>
-
-<h6>Menu déroulant</h6>
-Dans le menu déroulant vous sélectionnez la base de données.<br>
-Toutes les actions suivantes se rapportent cette base de données.
-
-<h6>Page d'accueil</h6>
-Vous trouverez ici des informations sur votre système, les différentes versions installées et des détails sur la configuration des bases de données.<br>
-La sélection d'une base de données vous donnent de plus amples informations sur le nombre de tables, le nombre de paquets, la taille et la dernière mise à jour.
-
-<h6>Configuration</h6>
-Ici vous pouvez éditer, sauvegarder votre configuration ou bien réinstaller la configuration standard.
-<ul><br>
-	<li><a name="conf1"></a><strong>Configurer la base de données:</strong> Liste des bases de données configurées. La base de données active est listée en <b>caractères gras</b>. </li>
-	<li><a name="conf2"></a><strong>Préfix des tables:</strong> Ici vous pouvez définir (pour chaque base de donnée) un préfix. C'est un filtre, qui permet de sélectionner lors de la sauvegarde les tables contenant le préfix défini (exemple: Toutes les tables qui commencent avec "phpBB_"). Si vous désirer sauvgarder toutes les tables, laisser ce champ libre.</li>
-	<li><a name="conf3"></a><strong>Compression GZip:</strong> Ici vous pouvez activer la compression de fichier. Nous vous conseillons la compression, car les fichiers sont plus petit et nécessitent moins de place.</li>
-	<li><a name="conf5"></a><strong>Courriel avec pièces jointes:</strong> Si vous avez activé cette option, vous recevrez après la création de la copie de sauvegarde un courriel avec la copie de sauvegarde en pièce jointe (Attention, la compression doit être impérativement activée, sinon la pièce jointe risque d'être trop volumineuse et ne pourra eventuellement pas être envoyée avec le courriel!)</li>
-	<li><a name="conf6"></a><strong>Adresse électronique:</strong> Destinataire du courriel</li>
-	<li><a name="conf7"></a><strong>Expéditeur du courriel:</strong> C'est l'adresse de l'expéditeur qui apparaitra dans le courriel</li>
-	<li><a name="conf13"></a><strong>Transfert FTP: </strong>Si cette option est activée, après la création de la copie de sauvegarde, celle-ci sera envoyée par FTP sur un serveur.</li>
-	<li><a name="conf14"></a><strong>Serveur FTP: </strong>L'adresse du serveur FTP (exemple: ftp.mybackups.com)</li>
-	<li><a name="conf15"></a><strong>Port du serveur FTP: </strong>Port du serveur FTP (en général 21)</li>
-	<li><a name="conf16"></a><strong>Utilisateur FTP: </strong>Le nom de l'utilisateur du compte FTP</li>
-	<li><a name="conf17"></a><strong>Mot de passe FTP: </strong>Le mot de passe du compte FTP </li>
-	<li><a name="conf18"></a><strong>Répertoire de téléchargement FTP: </strong>Le répertoire dans lequel la copie de sauvegarde doit être copiée (il doit exister des droits afin de pouvoir télécharger vers le serveur!)</li>
-	<li><a name="conf8"></a><strong>Suppression automatique de la copie de sauvegarde:</strong> Si cette option est activée, les sauvegardes les plus anciennes seront supprimée d'après les options choisies. La combinaison d'options n'est pas possible.</li>
-	<li><a name="conf10"></a><strong>Nombre de copie de sauvegarde:</strong> La valeur > 0 supprime toutes les copies de sauvegardes les plus anciennes excepté le nombre défini dans ce champ</li>
-	<li><a name="conf11"></a><strong>Langue:</strong> Ici vous définissez la langue de votre interface.</li>
-</ul>
-
-<h6>Administration</h6>
-Ici s'exécutent les actions.<br>
-Toutes les copies de sauvegarde sont visibles ici.
-Pour les actions de restauration ou de suppression on doit sélectionner un fichier.
-<UL>
-	<li><strong>Restauration:</strong> La copie de sauvegarde sélectionnée sera restaurée.</li>
-	<li><strong>Suppression:</strong> La copie de sauvegarde sélectionnée sera supprimée.</li>
-	<li><strong>Exécuter une nouvelle copie de sauvegarde:</strong> Exécution d'une nouvelle copie de sauvegarde (Dump) d'après les paramètres du menu "Configuration".</li>
-</UL>
-
-<h6>Journal</h6>
-Le journal vous permet de voir et de supprimer les entrées.
-
-<h6>Crédits / Aide</h6>
-Cette page.
-</ul>
\ No newline at end of file
diff --git a/msd/language/fr/lang.php b/msd/language/fr/lang.php
index c5a47ec1..10c45149 100644
--- a/msd/language/fr/lang.php
+++ b/msd/language/fr/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="oui";
-$lang['L_TO']="jusqu'à";
-$lang['L_ACTIVATED']="activé";
-$lang['L_NOT_ACTIVATED']="désactivé";
-$lang['L_ERROR']="Erreur";
-$lang['L_OF']=" de ";
-$lang['L_ADDED']="ajouter";
-$lang['L_DB']="Base de données";
-$lang['L_DBS']="Bases de données";
-$lang['L_TABLES']="Tables";
-$lang['L_TABLE']="Table";
-$lang['L_RECORDS']="Enregistrement";
-$lang['L_COMPRESSED']="fichier compressé (gz)";
-$lang['L_NOTCOMPRESSED']="normal (non compressé)";
-$lang['L_GENERAL']="généralités";
-$lang['L_COMMENT']="Commentaire";
-$lang['L_FILESIZE']="Taille du fichier";
-$lang['L_ALL']="tout";
-$lang['L_NONE']="sans";
-$lang['L_WITH']=" avec ";
-$lang['L_DIR']="Répertoire";
-$lang['L_RECHTE']="Droits";
-$lang['L_STATUS']="État";
-$lang['L_FINISHED']="fini";
-$lang['L_FILE']="Fichier";
-$lang['L_FIELDS']="Champs";
-$lang['L_NEW']="nouveau";
-$lang['L_CHARSET']="Police de caractères";
-$lang['L_COLLATION']="Tri";
-$lang['L_CHANGE']="modifier";
-$lang['L_IN']="dans";
-$lang['L_DO']="Exécuter";
-$lang['L_VIEW']="voir";
-$lang['L_EXISTING']="existe";
-$lang['L_BACK']="retour";
-$lang['L_DB_HOST']="Serveur de la base de données";
-$lang['L_DB_USER']="Utilisateur";
-$lang['L_DB_PASS']="Mot de passe";
-$lang['L_INFO_SCRIPTDIR']="Répertoire de MySQLDumper";
-$lang['L_INFO_ACTDB']="Base de données actuelle";
-$lang['L_WRONGCONNECTIONPARS']="Aucun ou mauvais paramètre de connexion !";
-$lang['L_CONN_NOT_POSSIBLE']="Connexion impossible !";
-$lang['L_SERVERCAPTION']="Visualisation du serveur";
-$lang['L_HELP_SERVERCAPTION']="Lors de l'utilisation de plusieurs systèmes il peut-être utile de marquer l'adresse du serveur d'une couleur";
-$lang['L_ACTIVATE_MULTIDUMP']="activer en plusieurs parties";
-$lang['L_SAVE']="Sauvegarder";
-$lang['L_RESET']="Réinitialisation";
-$lang['L_PRAEFIX']="Préfixe des tables";
-$lang['L_AUTODELETE']="Supprimer automatiquement la copie de sauvegarde";
-$lang['L_MAX_BACKUP_FILES_EACH2']="pour chaque base de données";
-$lang['L_SAVING_DB_FORM']="Base de données";
-$lang['L_TESTCONNECTION']="Essayer la connexion";
-$lang['L_BACK_TO_MINISQL']="Éditer la base de données";
-$lang['L_CREATE']="créer";
-$lang['L_VARIABELN']="Variables";
-$lang['L_STATUSINFORMATIONEN']="Informations";
-$lang['L_VERSIONSINFORMATIONEN']="Informations sur la version";
-$lang['L_MSD_INFO']="Informations sur MyOOS [Dumper]";
-$lang['L_BACKUPFILESANZAHL']="Dans le répertoire des sauvegardes se trouve";
-$lang['L_LASTBACKUP']="Dernière sauvegarde";
-$lang['L_NOTAVAIL']="<em>indisponible</em>";
-$lang['L_VOM']="de";
-$lang['L_MYSQLVARS']="Variables MySQL";
-$lang['L_MYSQLSYS']="Ordre MySQL";
-$lang['L_STATUS']="État";
-$lang['L_PROZESSE']="Processus";
-$lang['L_INFO_NOVARS']="aucunes variables disponibles";
-$lang['L_INHALT']="Contenu";
-$lang['L_INFO_NOSTATUS']="aucun état disponible";
-$lang['L_INFO_NOPROCESSES']="aucun processus en cours";
-$lang['L_FM_FREESPACE']="Espace libre sur le serveur";
-$lang['L_LOAD_DATABASE']="Rafraîchir bases de données";
-$lang['L_HOME']="Page d'accueil";
-$lang['L_CONFIG']="Configuration";
-$lang['L_DUMP']="Sauvegarde";
-$lang['L_RESTORE']="Restauration";
-$lang['L_FILE_MANAGE']="Administration";
-$lang['L_LOG']="Journal";
-$lang['L_CHOOSE_DB']="Choisir la base de données";
-$lang['L_CREDITS']="Crédits / Aide";
-$lang['L_MULTI_PART']="Sauvegarde en plusieurs parties";
-$lang['L_LOGFILENOTWRITABLE']="Écriture du fichier journal impossible!";
-$lang['L_SQL_ERROR1']="Erreur de demande:";
-$lang['L_SQL_ERROR2']="MySQL déclare:";
-$lang['L_UNKNOWN']="inconnu";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="inconnu";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Sauvegarder toutes les sorties dans le journal";
-$lang['L_NO']="non";
-$lang['L_CREATE_DATABASE']="Créer une nouvelle base de données";
-$lang['L_EXPORTFINISHED']="Exportation terminée.";
-$lang['L_SQL_BROWSER']="Navigateur-SQL";
-$lang['L_SERVER']="Serveur";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Encodage standard du serveur MySql";
-$lang['L_TITLE_SHOW_DATA']="Afficher les données";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="Cancel";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Nombres de sauvegardes";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'oui';
+$lang['L_TO'] = "jusqu'à";
+$lang['L_ACTIVATED'] = 'activé';
+$lang['L_NOT_ACTIVATED'] = 'désactivé';
+$lang['L_ERROR'] = 'Erreur';
+$lang['L_OF'] = ' de ';
+$lang['L_ADDED'] = 'ajouter';
+$lang['L_DB'] = 'Base de données';
+$lang['L_DBS'] = 'Bases de données';
+$lang['L_TABLES'] = 'Tables';
+$lang['L_TABLE'] = 'Table';
+$lang['L_RECORDS'] = 'Enregistrement';
+$lang['L_COMPRESSED'] = 'fichier compressé (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (non compressé)';
+$lang['L_COMMENT'] = 'Commentaire';
+$lang['L_FILESIZE'] = 'Taille du fichier';
+$lang['L_ALL'] = 'tout';
+$lang['L_NONE'] = 'sans';
+$lang['L_WITH'] = ' avec ';
+$lang['L_DIR'] = 'Répertoire';
+$lang['L_RECHTE'] = 'Droits';
+$lang['L_STATUS'] = 'État';
+$lang['L_FINISHED'] = 'fini';
+$lang['L_FILE'] = 'Fichier';
+$lang['L_FIELDS'] = 'Champs';
+$lang['L_NEW'] = 'nouveau';
+$lang['L_CHARSET'] = 'Police de caractères';
+$lang['L_COLLATION'] = 'Tri';
+$lang['L_CHANGE'] = 'modifier';
+$lang['L_IN'] = 'dans';
+$lang['L_DO'] = 'Exécuter';
+$lang['L_VIEW'] = 'voir';
+$lang['L_EXISTING'] = 'existe';
+$lang['L_BACK'] = 'retour';
+$lang['L_DB_HOST'] = 'Serveur de la base de données';
+$lang['L_DB_USER'] = 'Utilisateur';
+$lang['L_DB_PASS'] = 'Mot de passe';
+$lang['L_INFO_SCRIPTDIR'] = 'Répertoire de MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Base de données actuelle';
+$lang['L_WRONGCONNECTIONPARS'] = 'Aucun ou mauvais paramètre de connexion !';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Connexion impossible !';
+$lang['L_SERVERCAPTION'] = 'Visualisation du serveur';
+$lang['L_HELP_SERVERCAPTION'] = "Lors de l'utilisation de plusieurs systèmes il peut-être utile de marquer l'adresse du serveur d'une couleur";
+$lang['L_ACTIVATE_MULTIDUMP'] = 'activer en plusieurs parties';
+$lang['L_SAVE'] = 'Sauvegarder';
+$lang['L_RESET'] = 'Réinitialisation';
+$lang['L_PRAEFIX'] = 'Préfixe des tables';
+$lang['L_AUTODELETE'] = 'Supprimer automatiquement la copie de sauvegarde';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'pour chaque base de données';
+$lang['L_SAVING_DB_FORM'] = 'Base de données';
+$lang['L_TESTCONNECTION'] = 'Essayer la connexion';
+$lang['L_BACK_TO_MINISQL'] = 'Éditer la base de données';
+$lang['L_CREATE'] = 'créer';
+$lang['L_VARIABELN'] = 'Variables';
+$lang['L_STATUSINFORMATIONEN'] = 'Informations';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Informations sur la version';
+$lang['L_MOD_INFO'] = 'Informations sur MyOOS [Dumper]';
+$lang['L_BACKUPFILESANZAHL'] = 'Dans le répertoire des sauvegardes se trouve';
+$lang['L_LASTBACKUP'] = 'Dernière sauvegarde';
+$lang['L_NOTAVAIL'] = '<em>indisponible</em>';
+$lang['L_VOM'] = 'de';
+$lang['L_MYSQLVARS'] = 'Variables MySQL';
+$lang['L_MYSQLSYS'] = 'Ordre MySQL';
+$lang['L_STATUS'] = 'État';
+$lang['L_PROZESSE'] = 'Processus';
+$lang['L_INFO_NOVARS'] = 'aucunes variables disponibles';
+$lang['L_INHALT'] = 'Contenu';
+$lang['L_INFO_NOSTATUS'] = 'aucun état disponible';
+$lang['L_INFO_NOPROCESSES'] = 'aucun processus en cours';
+$lang['L_FM_FREESPACE'] = 'Espace libre sur le serveur';
+$lang['L_LOAD_DATABASE'] = 'Rafraîchir bases de données';
+$lang['L_HOME'] = "Page d'accueil";
+$lang['L_CONFIG'] = 'Configuration';
+$lang['L_DUMP'] = 'Sauvegarde';
+$lang['L_RESTORE'] = 'Restauration';
+$lang['L_FILE_MANAGE'] = 'Administration';
+$lang['L_LOG'] = 'Journal';
+$lang['L_CHOOSE_DB'] = 'Choisir la base de données';
+$lang['L_CREDITS'] = 'Crédits / Aide';
+$lang['L_MULTI_PART'] = 'Sauvegarde en plusieurs parties';
+$lang['L_LOGFILENOTWRITABLE'] = 'Écriture du fichier journal impossible!';
+$lang['L_SQL_ERROR1'] = 'Erreur de demande:';
+$lang['L_SQL_ERROR2'] = 'MySQL déclare:';
+$lang['L_UNKNOWN'] = 'inconnu';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'inconnu';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Sauvegarder toutes les sorties dans le journal';
+$lang['L_NO'] = 'non';
+$lang['L_CREATE_DATABASE'] = 'Créer une nouvelle base de données';
+$lang['L_EXPORTFINISHED'] = 'Exportation terminée.';
+$lang['L_SQL_BROWSER'] = 'Navigateur-SQL';
+$lang['L_SERVER'] = 'Serveur';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Encodage standard du serveur MySql';
+$lang['L_TITLE_SHOW_DATA'] = 'Afficher les données';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'Cancel';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Nombres de sauvegardes';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/fr/lang_config_overview.php b/msd/language/fr/lang_config_overview.php
index b3c5d63a..f31c79c1 100644
--- a/msd/language/fr/lang_config_overview.php
+++ b/msd/language/fr/lang_config_overview.php
@@ -1,113 +1,130 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Configuration";
-$lang['L_SAVE_SUCCESS']="La configuration a été sauvegardée avec succès dans le fichier \"%s\".";
-$lang['L_CONFIG_LOADED']="La configuration \"%s\" a été importée avec succès.";
-$lang['L_SAVE_ERROR']="Les configurations n'ont pas pu être sauvegardées !";
-$lang['L_CONFIG_EMAIL']="Envoyer courriel";
-$lang['L_CONFIG_AUTODELETE']="Suppression automatique";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="Taille maximale par fichier";
-$lang['L_HELP_MULTIPART']="Lors d'une sauvegarde en plusieurs parties plusieurs fichiers seront créés, dont la taille maximale s'oriente aux configurations ci-dessous";
-$lang['L_HELP_MULTIPARTGROESSE']="La taille maximale par fichiers de sauvergarde lors d'une sauvegarde en plusieurs parties peut être défini ici";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Supprimer la base de données avant la restauration";
-$lang['L_ALLPARS']="Tous les paramètres";
-$lang['L_CRON_EXTENDER']="Extension du nom de fichier";
-$lang['L_CRON_SAVEPATH']="Fichier de configuration";
-$lang['L_CRON_PRINTOUT']="Format d'impression";
-$lang['L_CONFIG_CRONPERL']="Configuration Cron pour le script Perl";
-$lang['L_CRON_MAILPRG']="Programme du courriel";
-$lang['L_OPTIMIZE']="Optimiser les tables avant la sauvegarde";
-$lang['L_HELP_OPTIMIZE']="Si cette option est activée, avant chaque sauvegarde les tables seront optimisées";
-$lang['L_HELP_FTPTIMEOUT']="Temps avant temporisation si aucun transfert n'est effectué, par défaut 90 sec.";
-$lang['L_FTP_TIMEOUT']="Erreur de temporisation";
-$lang['L_HELP_FTPSSL']="Choisir si la connexion doit être établie via SSL.";
-$lang['L_CONFIG_ASKLOAD']="Voulez-vous vraiment écraser les configurations actuelles avec les configurations par défaut?";
-$lang['L_LOAD']="Charger config par défaut";
-$lang['L_LOAD_SUCCESS']="Les configurations par défaut ont été chargées.";
-$lang['L_CRON_CRONDBINDEX']="Base de données";
-$lang['L_WITHATTACH']=" avec fichier joint";
-$lang['L_WITHOUTATTACH']=" sans fichier joint";
-$lang['L_MULTIDUMPCONF']="=Configuration de la sauvegarde en plusieurs parties=";
-$lang['L_MULTIDUMPALL']="=toutes les bases de données=";
-$lang['L_GZIP']="Compression GZip des données";
-$lang['L_SEND_MAIL_FORM']="Envoyer un courriel";
-$lang['L_SEND_MAIL_DUMP']="Joindre le fichier de sauvegarde";
-$lang['L_EMAIL_ADRESS']="Adresse électronique";
-$lang['L_EMAIL_SENDER']="Expéditeur du courriel";
-$lang['L_EMAIL_MAXSIZE']="Taille maximale du fichier joint";
-$lang['L_NUMBER_OF_FILES_FORM']="Nombre de fichier de sauvegarde";
-$lang['L_LANGUAGE']="Langue";
-$lang['L_LIST_DB']="Base de données configurée:";
-$lang['L_CONFIG_FTP']="Tranfert FTP du fichier de sauvegarde";
-$lang['L_FTP_TRANSFER']="Transfert FTP";
-$lang['L_FTP_SERVER']="Serveur";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="Utilisateur";
-$lang['L_FTP_PASS']="Mot de passe";
-$lang['L_FTP_DIR']="Répertoire de téléchargement vers le serveur";
-$lang['L_FTP_SSL']="Connexion SSL vers le serveur FTP";
-$lang['L_FTP_USESSL']="utiliser une connexion SSL";
-$lang['L_SQLBOXHEIGHT']="Hauteur du cadre SQL";
-$lang['L_SQLLIMIT']="Nombre d'enregistrements par page";
-$lang['L_BBPARAMS']="Configuration pour le code BB";
-$lang['L_BBTEXTCOLOR']="Couleur du texte";
-$lang['L_HELP_COMMANDS']="On peut avant et après chaque sauvegarde exécuter une requête.
-Ceci peut-être un ordre SQL ou bien une requête de système (p. ex. un script)";
-$lang['L_COMMAND']="Requête";
-$lang['L_WRONG_CONNECTIONPARS']="Les paramètres de connexion sont faux !";
-$lang['L_CONNECTIONPARS']="Paramètres de connexion";
-$lang['L_EXTENDEDPARS']="Paramètres avancés";
-$lang['L_FADE_IN_OUT']="afficher / masquer";
-$lang['L_DB_BACKUPPARS']="Configuration des bases de données sauvegardées";
-$lang['L_GENERAL']="Général";
-$lang['L_MAXSIZE']="Taille maximale";
-$lang['L_ERRORHANDLING_RESTORE']="Traitement des erreurs lors d'une restauration";
-$lang['L_EHRESTORE_CONTINUE']="continuer et consigner par écrit les erreurs";
-$lang['L_EHRESTORE_STOP']="arrêter";
-$lang['L_IN_MAINFRAME']="dans le cadre principal";
-$lang['L_IN_LEFTFRAME']="dans le cadre de gauche";
-$lang['L_WIDTH']="Largeur";
-$lang['L_SQL_BEFEHLE']="Requête SQL";
-$lang['L_DOWNLOAD_LANGUAGES']="télécharger d'autres langues";
-$lang['L_DOWNLOAD_STYLES']="télécharger d'autres thèmes";
-$lang['L_CONNECT_TO']="Connecter à";
-$lang['L_CHANGEDIR']="Changer vers répertoire";
-$lang['L_CHANGEDIRERROR']="N'a pas pu changer vers le répertoire!";
-$lang['L_FTP_OK']="La connexion a été établie avec succès.";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="Il n'y a pas de fonction FTP à disposition!";
-$lang['L_FOUND_DB']="Base de données trouvée";
-$lang['L_FTP_CHOOSE_MODE']="Mode de transfert FTP";
-$lang['L_FTP_PASSIVE']="utiliser le mode passif";
-$lang['L_HELP_FTP_MODE']="Choisissez le mode passif quand vous avez des problèmes en utilisant le mode actif.";
-$lang['L_DB_IN_LIST']="la base de données '%s' ne peut pas être ajoutée car elle existe déjà. ";
-$lang['L_ADD_DB_MANUALLY']="Ajouter une base de données manuellement";
-$lang['L_DB_MANUAL_ERROR']="Désolé, impossible de se connecter à la base de données '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Erreur fichier: Impossible à insérer à la base de données '%s'!";
-$lang['L_NO_DB_FOUND']="Impossible de trouver une base de données automatiquement!
-Veuillez vérifier les paramètres de connexion et entrer le nom de votre base de données manuellement.";
-$lang['L_CONFIGFILES']="fichiers de configuration";
-$lang['L_CONFIGFILE']="fichier de configuration";
-$lang['L_MYSQL_DATA']="Données-MySQL";
-$lang['L_CONFIGURATIONS']="Configurations";
-$lang['L_ACTION']="Action";
-$lang['L_FTP_SEND_TO']="vers <strong>%s</strong><br> dans <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="Récepteur-CC";
-$lang['L_NAME']="Nom";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Etes vous sûr de vouloir supprimer le fichier de configuration %s ?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Erreur: Le fichier de configuration %s ne peut pas être supprimé !";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Le fichier de configuration %s a été supprimé avec succès.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Le fichier de configuration %s a été créé avec succès.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Le nom du fichier \"%s\" contient des caractères invalides.";
-$lang['L_CREATE_CONFIGFILE']="Créer un nouveau fichier de configuration";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Impossible de lire le fichier de configuration \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="Sauvegarde DBs
-(PHP)";
-$lang['L_BACKUP_DBS_PERL']="Sauvegarde Dbs
-(PERL)";
-$lang['L_CRON_COMMENT']="Ajouter un commentaire";
-$lang['L_AUTODETECT']="auto detect";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Configuration';
+$lang['L_SAVE_SUCCESS'] = 'La configuration a été sauvegardée avec succès dans le fichier "%s".';
+$lang['L_CONFIG_LOADED'] = 'La configuration "%s" a été importée avec succès.';
+$lang['L_SAVE_ERROR'] = "Les configurations n'ont pas pu être sauvegardées !";
+$lang['L_EMAIL_NOTIFICATION'] = 'Envoyer courriel';
+$lang['L_CONFIG_AUTODELETE'] = 'Suppression automatique';
+$lang['L_CONFIG_INTERFACE'] = 'Interface';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'Taille maximale par fichier';
+$lang['L_HELP_MULTIPART'] = "Lors d'une sauvegarde en plusieurs parties plusieurs fichiers seront créés, dont la taille maximale s'oriente aux configurations ci-dessous";
+$lang['L_HELP_MULTIPARTGROESSE'] = "La taille maximale par fichiers de sauvergarde lors d'une sauvegarde en plusieurs parties peut être défini ici";
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Supprimer la base de données avant la restauration';
+$lang['L_ALLPARS'] = 'Tous les paramètres';
+$lang['L_CRON_EXTENDER'] = 'Extension du nom de fichier';
+$lang['L_CRON_SAVEPATH'] = 'Fichier de configuration';
+$lang['L_CRON_PRINTOUT'] = "Format d'impression";
+$lang['L_CONFIG_CRONPERL'] = 'Configuration Cron pour le script Perl';
+$lang['L_CRON_MAILPRG'] = 'Programme du courriel';
+$lang['L_OPTIMIZE'] = 'Optimiser les tables avant la sauvegarde';
+$lang['L_HELP_OPTIMIZE'] = 'Si cette option est activée, avant chaque sauvegarde les tables seront optimisées';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = "Temps avant temporisation si aucun transfert n'est effectué, par défaut 90 sec.";
+$lang['L_FTP_TIMEOUT'] = 'Erreur de temporisation';
+$lang['L_HELP_FTPSSL'] = 'Choisir si la connexion doit être établie via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Erreur de temporisation';
+$lang['L_HELP_SFTPSSL'] = 'Choisir si la connexion doit être établie via SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'Voulez-vous vraiment écraser les configurations actuelles avec les configurations par défaut?';
+$lang['L_LOAD'] = 'Charger config par défaut';
+$lang['L_LOAD_SUCCESS'] = 'Les configurations par défaut ont été chargées.';
+$lang['L_CRON_CRONDBINDEX'] = 'Base de données';
+$lang['L_WITHATTACH'] = ' avec fichier joint';
+$lang['L_WITHOUTATTACH'] = ' sans fichier joint';
+$lang['L_MULTIDUMPCONF'] = '=Configuration de la sauvegarde en plusieurs parties=';
+$lang['L_MULTIDUMPALL'] = '=toutes les bases de données=';
+$lang['L_GZIP'] = 'Compression GZip des données';
+$lang['L_SEND_MAIL_FORM'] = 'Envoyer un courriel';
+$lang['L_SEND_MAIL_DUMP'] = 'Joindre le fichier de sauvegarde';
+$lang['L_EMAIL_ADRESS'] = 'Adresse électronique';
+$lang['L_EMAIL_SENDER'] = 'Expéditeur du courriel';
+$lang['L_EMAIL_MAXSIZE'] = 'Taille maximale du fichier joint';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Nombre de fichier de sauvegarde';
+$lang['L_LANGUAGE'] = 'Langue';
+$lang['L_LIST_DB'] = 'Base de données configurée:';
+$lang['L_CONFIG_FTP'] = 'Tranfert FTP du fichier de sauvegarde';
+$lang['L_FTP_TRANSFER'] = 'Transfert FTP';
+$lang['L_FTP_SERVER'] = 'Serveur';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'Utilisateur';
+$lang['L_FTP_PASS'] = 'Mot de passe';
+$lang['L_FTP_DIR'] = 'Répertoire de téléchargement vers le serveur';
+$lang['L_FTP_SSL'] = 'Connexion SSL vers le serveur FTP';
+$lang['L_FTP_USESSL'] = 'utiliser une connexion SSL';
+$lang['L_CONFIG_SFTP'] = 'Tranfert SFTP du fichier de sauvegarde';
+$lang['L_SFTP_TRANSFER'] = 'Transfert SFTP';
+$lang['L_SFTP_SERVER'] = 'Serveur';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'Utilisateur';
+$lang['L_SFTP_PASS'] = 'Mot de passe';
+$lang['L_SFTP_DIR'] = 'Répertoire de téléchargement vers le serveur';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Hauteur du cadre SQL';
+$lang['L_SQLLIMIT'] = "Nombre d'enregistrements par page";
+$lang['L_BBPARAMS'] = 'Configuration pour le code BB';
+$lang['L_BBTEXTCOLOR'] = 'Couleur du texte';
+$lang['L_HELP_COMMANDS'] = 'On peut avant et après chaque sauvegarde exécuter une requête.
+Ceci peut-être un ordre SQL ou bien une requête de système (p. ex. un script)';
+$lang['L_COMMAND'] = 'Requête';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Les paramètres de connexion sont faux !';
+$lang['L_CONNECTIONPARS'] = 'Paramètres de connexion';
+$lang['L_EXTENDEDPARS'] = 'Paramètres avancés';
+$lang['L_FADE_IN_OUT'] = 'afficher / masquer';
+$lang['L_DB_BACKUPPARS'] = 'Configuration des bases de données sauvegardées';
+$lang['L_GENERAL'] = 'Général';
+$lang['L_MAXSIZE'] = 'Taille maximale';
+$lang['L_ERRORHANDLING_RESTORE'] = "Traitement des erreurs lors d'une restauration";
+$lang['L_EHRESTORE_CONTINUE'] = 'continuer et consigner par écrit les erreurs';
+$lang['L_EHRESTORE_STOP'] = 'arrêter';
+$lang['L_IN_MAINFRAME'] = 'dans le cadre principal';
+$lang['L_IN_LEFTFRAME'] = 'dans le cadre de gauche';
+$lang['L_WIDTH'] = 'Largeur';
+$lang['L_SQL_BEFEHLE'] = 'Requête SQL';
+$lang['L_DOWNLOAD_LANGUAGES'] = "télécharger d'autres langues";
+$lang['L_DOWNLOAD_STYLES'] = "télécharger d'autres thèmes";
+$lang['L_CONNECT_TO'] = 'Connecter à';
+$lang['L_CHANGEDIR'] = 'Changer vers répertoire';
+$lang['L_CHANGEDIRERROR'] = "N'a pas pu changer vers le répertoire!";
+$lang['L_FTP_OK'] = 'La connexion a été établie avec succès.';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = "Il n'y a pas de fonction FTP à disposition!";
+$lang['L_FOUND_DB'] = 'Base de données trouvée';
+$lang['L_FTP_CHOOSE_MODE'] = 'Mode de transfert FTP';
+$lang['L_FTP_PASSIVE'] = 'utiliser le mode passif';
+$lang['L_HELP_FTP_MODE'] = 'Choisissez le mode passif quand vous avez des problèmes en utilisant le mode actif.';
+$lang['L_SFTP_PASSIVE'] = 'utiliser le mode passif';
+$lang['L_DB_IN_LIST'] = "la base de données '%s' ne peut pas être ajoutée car elle existe déjà. ";
+$lang['L_ADD_DB_MANUALLY'] = 'Ajouter une base de données manuellement';
+$lang['L_DB_MANUAL_ERROR'] = "Désolé, impossible de se connecter à la base de données '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Erreur fichier: Impossible à insérer à la base de données '%s'!";
+$lang['L_NO_DB_FOUND'] = 'Impossible de trouver une base de données automatiquement!
+Veuillez vérifier les paramètres de connexion et entrer le nom de votre base de données manuellement.';
+$lang['L_CONFIGFILES'] = 'fichiers de configuration';
+$lang['L_CONFIGFILE'] = 'fichier de configuration';
+$lang['L_MYSQL_DATA'] = 'Données-MySQL';
+$lang['L_CONFIGURATIONS'] = 'Configurations';
+$lang['L_ACTION'] = 'Action';
+$lang['L_FTP_SEND_TO'] = 'vers <strong>%s</strong><br> dans <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'vers <strong>%s</strong><br> dans <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'Récepteur-CC';
+$lang['L_NAME'] = 'Nom';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Etes vous sûr de vouloir supprimer le fichier de configuration %s ?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Erreur: Le fichier de configuration %s ne peut pas être supprimé !';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Le fichier de configuration %s a été supprimé avec succès.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Le fichier de configuration %s a été créé avec succès.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Le nom du fichier "%s" contient des caractères invalides.';
+$lang['L_CREATE_CONFIGFILE'] = 'Créer un nouveau fichier de configuration';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Impossible de lire le fichier de configuration "%s".';
+$lang['L_BACKUP_DBS_PHP'] = 'Sauvegarde DBs
+(PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'Sauvegarde Dbs
+(PERL)';
+$lang['L_CRON_COMMENT'] = 'Ajouter un commentaire';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/fr/lang_dump.php b/msd/language/fr/lang_dump.php
index 4dbbe52c..48483cf0 100644
--- a/msd/language/fr/lang_dump.php
+++ b/msd/language/fr/lang_dump.php
@@ -1,56 +1,57 @@
 <?php
-$lang['L_DUMP_HEADLINE']="créer copie de sauvegarde...";
-$lang['L_GZIP_COMPRESSION']="La compression GZip";
-$lang['L_SAVING_TABLE']="Sauvegarder les tables ";
-$lang['L_OF']="de";
-$lang['L_ACTUAL_TABLE']="Table actuelle";
-$lang['L_PROGRESS_TABLE']="Progression de la table";
-$lang['L_PROGRESS_OVER_ALL']="Progression totale";
-$lang['L_ENTRY']="Point d'entrée";
-$lang['L_DONE']="Terminé!";
-$lang['L_DUMP_SUCCESSFUL']=" crée avec succès.";
-$lang['L_UPTO']="jusqu'à";
-$lang['L_EMAIL_WAS_SEND']="Le courriel a été envoyé avec succès à ";
-$lang['L_BACK_TO_CONTROL']="Continuer";
-$lang['L_BACK_TO_OVERVIEW']="Aperçu général des\nbases de données";
-$lang['L_DUMP_FILENAME']="Nom du fichier de sauvegarde: ";
-$lang['L_WITHPRAEFIX']="avec préfixe";
-$lang['L_DUMP_NOTABLES']="Aucune table n'a été trouvée dans la base de donnée `<b>%s</b>`.";
-$lang['L_DUMP_ENDERGEBNIS']="<b>%s</b> table(s) avec en tout <b>%s</b> enregistrement(s) a/ont été sauvegardée(s).<br>";
-$lang['L_MAILERROR']="Malheureusement une erreur est apparue lors de l'envoie par courriel!";
-$lang['L_EMAILBODY_ATTACH']="Dans le fichier joint vous trouverez une sauvegarde de votre base de données MySQL.<br>Copie de sauvegarde de la base de données `%s`
-<br><br>Les fichiers suivants ont été créés:<br><br>%s <br><br>Cordialement<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Une sauvegarde en plusieurs parties a été créé.<br>Les sauvegardes ne sont pas envoyées en pièces jointes!<br>Copie de sauvegarde de la base de données `%s`
-<br><br>Les fichiers suivants ont été créés:<br><br>%s<br><br><br>Cordialemene<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Une sauvegarde en plusieurs parties a été créé.<br>Les sauvegardes sont envoyées en pièces jointes!<br>Copie de sauvegarde de la base de données `%s`
-<br><br>Les fichiers suivants ont été créés:<br><br>%s<br><br><br>Cordialemene<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Cordialement<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="La copie de sauvegarde dépasse la taille maximale de %s. Pour cette raison elle n'a pas été envoyée en pièces jointes.<br>Copie de sauvegarde de la base de données `%s`
-<br><br>Les fichiers suivants ont été créés:<br><br>%s
-<br><br>Cordialement<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="La copie de sauvegarde n'est pas jointe.<br>Copie de sauvegarde de la base de données `%s`
-<br><br>Les fichiers suivants ont été créés:<br><br>%s
-<br><br>Cordialement<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... seulement la pièce jointe";
-$lang['L_TABLESELECTION']="Sélection de la table";
-$lang['L_SELECTALL']="Tout sélectionner";
-$lang['L_DESELECTALL']="Tout désélectionner";
-$lang['L_STARTDUMP']="Démarrer la sauvegarde";
-$lang['L_LASTBUFROM']="dernière sauvegarde du";
-$lang['L_NOT_SUPPORTED']="Cette sauvegarde ne supporte pas cette fonction.";
-$lang['L_MULTIDUMP']="Sauvegarde en plusieurs parties: Les bases de données <b>%d</b> ont été sauvegardées.";
-$lang['L_FILESENDFTP']="Les fichiers sont envoyés par FTP... Veuillez patienter. ";
-$lang['L_FTPCONNERROR']="Aucune connexion FTP n'a pu être établie! Connecter avec ";
-$lang['L_FTPCONNERROR1']=" comme utilisateur ";
-$lang['L_FTPCONNERROR2']=" impossible";
-$lang['L_FTPCONNERROR3']="Téléchargement vers le serveur FTP est erroné! ";
-$lang['L_FTPCONNECTED1']="Connecté avec ";
-$lang['L_FTPCONNECTED2']=" sur ";
-$lang['L_FTPCONNECTED3']=" a été écrit";
-$lang['L_NR_TABLES_SELECTED']="- avec %s des tables sélectionnées";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tables ont été optimisées.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s erreurs rencontrées: <a href=\"log.php?r=3\">verdere</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Erreur fatale: Le rapport de création de la table '%s' de la base de données '%s' ne peut pas être lu !";
 
-
-?>
\ No newline at end of file
+$lang['L_DUMP_HEADLINE'] = 'créer copie de sauvegarde...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'La compression GZip';
+$lang['L_SAVING_TABLE'] = 'Sauvegarder les tables ';
+$lang['L_OF'] = 'de';
+$lang['L_ACTUAL_TABLE'] = 'Table actuelle';
+$lang['L_PROGRESS_TABLE'] = 'Progression de la table';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progression totale';
+$lang['L_ENTRY'] = "Point d'entrée";
+$lang['L_DONE'] = 'Terminé!';
+$lang['L_DUMP_SUCCESSFUL'] = ' crée avec succès.';
+$lang['L_UPTO'] = "jusqu'à";
+$lang['L_EMAIL_WAS_SEND'] = 'Le courriel a été envoyé avec succès à ';
+$lang['L_BACK_TO_CONTROL'] = 'Continuer';
+$lang['L_BACK_TO_OVERVIEW'] = "Aperçu général des\nbases de données";
+$lang['L_DUMP_FILENAME'] = 'Nom du fichier de sauvegarde: ';
+$lang['L_WITHPRAEFIX'] = 'avec préfixe';
+$lang['L_DUMP_NOTABLES'] = "Aucune table n'a été trouvée dans la base de donnée `<b>%s</b>`.";
+$lang['L_DUMP_ENDERGEBNIS'] = '<b>%s</b> table(s) avec en tout <b>%s</b> enregistrement(s) a/ont été sauvegardée(s).<br>';
+$lang['L_MAILERROR'] = "Malheureusement une erreur est apparue lors de l'envoie par courriel!";
+$lang['L_EMAILBODY_ATTACH'] = 'Dans le fichier joint vous trouverez une sauvegarde de votre base de données MySQL.<br>Copie de sauvegarde de la base de données `%s`
+<br><br>Les fichiers suivants ont été créés:<br><br>%s <br><br>Cordialement<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Une sauvegarde en plusieurs parties a été créé.<br>Les sauvegardes ne sont pas envoyées en pièces jointes!<br>Copie de sauvegarde de la base de données `%s`
+<br><br>Les fichiers suivants ont été créés:<br><br>%s<br><br><br>Cordialemene<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Une sauvegarde en plusieurs parties a été créé.<br>Les sauvegardes sont envoyées en pièces jointes!<br>Copie de sauvegarde de la base de données `%s`
+<br><br>Les fichiers suivants ont été créés:<br><br>%s<br><br><br>Cordialemene<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Cordialement<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = "La copie de sauvegarde dépasse la taille maximale de %s. Pour cette raison elle n'a pas été envoyée en pièces jointes.<br>Copie de sauvegarde de la base de données `%s`
+<br><br>Les fichiers suivants ont été créés:<br><br>%s
+<br><br>Cordialement<br><br>MyOOS [Dumper]<br>";
+$lang['L_EMAILBODY_NOATTACH'] = "La copie de sauvegarde n'est pas jointe.<br>Copie de sauvegarde de la base de données `%s`
+<br><br>Les fichiers suivants ont été créés:<br><br>%s
+<br><br>Cordialement<br><br>MyOOS [Dumper]<br>";
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... seulement la pièce jointe';
+$lang['L_TABLESELECTION'] = 'Sélection de la table';
+$lang['L_SELECTALL'] = 'Tout sélectionner';
+$lang['L_DESELECTALL'] = 'Tout désélectionner';
+$lang['L_STARTDUMP'] = 'Démarrer la sauvegarde';
+$lang['L_LASTBUFROM'] = 'dernière sauvegarde du';
+$lang['L_NOT_SUPPORTED'] = 'Cette sauvegarde ne supporte pas cette fonction.';
+$lang['L_MULTIDUMP'] = 'Sauvegarde en plusieurs parties: Les bases de données <b>%d</b> ont été sauvegardées.';
+$lang['L_FILESENDFTP'] = 'Les fichiers sont envoyés par FTP... Veuillez patienter. ';
+$lang['L_FTPCONNERROR'] = "Aucune connexion FTP n'a pu être établie! Connecter avec ";
+$lang['L_FTPCONNERROR1'] = ' comme utilisateur ';
+$lang['L_FTPCONNERROR2'] = ' impossible';
+$lang['L_FTPCONNERROR3'] = 'Téléchargement vers le serveur FTP est erroné! ';
+$lang['L_FTPCONNECTED1'] = 'Connecté avec ';
+$lang['L_FTPCONNECTED2'] = ' sur ';
+$lang['L_FTPCONNECTED3'] = ' a été écrit';
+$lang['L_FILESENDSFTP'] = 'Les fichiers sont envoyés par SFTP... Veuillez patienter. ';
+$lang['L_SFTPCONNERROR'] = "Aucune connexion SFTP n'a pu être établie! Connecter avec ";
+$lang['L_NR_TABLES_SELECTED'] = '- avec %s des tables sélectionnées';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tables ont été optimisées.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s erreurs rencontrées: <a href="log.php?r=3">verdere</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Erreur fatale: Le rapport de création de la table '%s' de la base de données '%s' ne peut pas être lu !";
diff --git a/msd/language/fr/lang_filemanagement.php b/msd/language/fr/lang_filemanagement.php
index 9159ca29..abeed207 100644
--- a/msd/language/fr/lang_filemanagement.php
+++ b/msd/language/fr/lang_filemanagement.php
@@ -1,75 +1,75 @@
 <?php
-$lang['L_CONVERT_START']="Démarrer la conversion";
-$lang['L_CONVERT_TITLE']="Convertir copie de sauvegarde vers Format MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Mauvais paramètres! Conversion impossible.";
-$lang['L_FM_UPLOADFILEREQUEST']="Veuillez entrer un fichier.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Ce type de fichier n'est pas permis.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Les types valides sont les fichiers: *.gz et *.sql";
-$lang['L_FM_UPLOADMOVEERROR']="Le fichier téléchargé sur le serveur n'a pas pu être déplacé dans le répertoire désiré.";
-$lang['L_FM_UPLOADFAILED']="Le téléchargement sur le serveur a échoué!";
-$lang['L_FM_UPLOADFILEEXISTS']="Il existe déjà un fichier avec ce nom !";
-$lang['L_FM_NOFILE']="Vous n'avez sélectionné aucun fichier!";
-$lang['L_FM_DELETE1']="Le fichier ";
-$lang['L_FM_DELETE2']=" a été supprimé avec succès.";
-$lang['L_FM_DELETE3']=" n'a pas pu être supprimé!";
-$lang['L_FM_CHOOSE_FILE']="Fichier sélectionné:";
-$lang['L_FM_FILESIZE']="Taille du fichier";
-$lang['L_FM_FILEDATE']="Date";
-$lang['L_FM_NOFILESFOUND']="Aucun fichier trouvé.";
-$lang['L_FM_TABLES']="Tables";
-$lang['L_FM_RECORDS']="Enregistrements";
-$lang['L_FM_ALL_BU']="toutes les sauvegardes";
-$lang['L_FM_ANZ_BU']="Nombres de sauvegardes";
-$lang['L_FM_LAST_BU']="dernière sauvegarde";
-$lang['L_FM_TOTALSIZE']="taille totale";
-$lang['L_FM_SELECTTABLES']="Nombres de tables";
-$lang['L_FM_COMMENT']="Ajouter un commentaire";
-$lang['L_FM_RESTORE']="Restauration";
-$lang['L_FM_ALERTRESTORE1']="Voulez-vous que la base de données ";
-$lang['L_FM_ALERTRESTORE2']="avec le contenu des fichiers";
-$lang['L_FM_ALERTRESTORE3']="soit restaurée?";
-$lang['L_FM_DELETE']="Supprimer les fichiers sélectionnés";
-$lang['L_FM_ASKDELETE1']="Voulez-vous vraiment supprimer le fichier ";
-$lang['L_FM_ASKDELETE2']="really be deleted?";
-$lang['L_FM_ASKDELETE3']="Voulez-vous exécuter la suppression automatique d'après les règles sauvegardées?";
-$lang['L_FM_ASKDELETE4']="Voulez-vous supprimer toutes les copies de sauvegarde?";
-$lang['L_FM_ASKDELETE5']="Voulez-vous supprimer toutes les copies de sauvegarde avec ";
-$lang['L_FM_ASKDELETE5_2']="_* ?";
-$lang['L_FM_DELETEAUTO']="Exécuter manuellement\nsuppression automatique";
-$lang['L_FM_DELETEALL']="Supprimer toutes les\ncopies de sauvegarde";
-$lang['L_FM_DELETEALLFILTER']="Supprimer tout avec ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Exécuter une nouvelle\ncopie de sauvegarde";
-$lang['L_FM_FILEUPLOAD']="Télécharger un fichier vers le serveur";
-$lang['L_FM_DBNAME']="Nom de la base de données";
-$lang['L_FM_FILES1']="Copie de sauvegarde de la base de données";
-$lang['L_FM_FILES2']="Structure de la base de données";
-$lang['L_FM_AUTODEL1']="Suppression automatique: Les fichiers suivant ont été supprimés du fait du nombre limité de fichiers:";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="Configuration pour la copie de sauvegarde";
-$lang['L_FM_OLDBACKUP']="(inconnu)";
-$lang['L_FM_RESTORE_HEADER']="Restauration de la base de donnée \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Copie de sauvegarde";
-$lang['L_DOCRONBUTTON']="Exécuter le script Cron";
-$lang['L_DOPERLTEST']="Tester le module Perl";
-$lang['L_DOSIMPLETEST']="Tester Perl";
-$lang['L_PERLOUTPUT1']="Saisie dans crondump.pl pour absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Saisie dans un navigateur ou pour exécuter un script Cron externe";
-$lang['L_PERLOUTPUT3']="Saisie pour 'Shell' ou pour la crontab";
-$lang['L_RESTORE_OF_TABLES']="Choisissez les tables à restaurer";
-$lang['L_CONVERTER']="Convertir la copie de sauvegarde";
-$lang['L_CONVERT_FILE']="fichier qui doit être converti";
-$lang['L_CONVERT_FILENAME']="Nom du fichier final (sans extensions)";
-$lang['L_CONVERTING']="En cours de convertion";
-$lang['L_CONVERT_FILEREAD']="Lire fichier '%s'";
-$lang['L_CONVERT_FINISHED']="Convertion terminée, fichier '%s' créé avec succès.";
-$lang['L_NO_MSD_BACKUPFILE']="Copies de sécurités d'autres programmes";
-$lang['L_MAX_UPLOAD_SIZE']="Taille maximale du fichier";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Si votre fichier Dump est plus grand que la taille mentionnée plus haut, vous devez alors l'envoyer sur le serveur dans le répertoire en utilisant votre programme FTP.";
-$lang['L_ENCODING']="encodage";
-$lang['L_FM_CHOOSE_ENCODING']="Choisissez le type d'encodage de la sauvegarde";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper n'a pas pu détecter automatiquement le type d'encodage de la sauvegarde <br>Vous devez choisir le jeux de caractères qui a été utilisé pour la sauvegarde<br> Si vous découvrez des problèmes avec quelques caractères suite à la restauration, vous pouvez répéter l'opération en choisissant un autre jeux de caractères.<br>Bonne chance ;-)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+
+$lang['L_CONVERT_START'] = 'Démarrer la conversion';
+$lang['L_CONVERT_TITLE'] = 'Convertir copie de sauvegarde vers Format MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Mauvais paramètres! Conversion impossible.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Veuillez entrer un fichier.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = "Ce type de fichier n'est pas permis.";
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Les types valides sont les fichiers: *.gz et *.sql';
+$lang['L_FM_UPLOADMOVEERROR'] = "Le fichier téléchargé sur le serveur n'a pas pu être déplacé dans le répertoire désiré.";
+$lang['L_FM_UPLOADFAILED'] = 'Le téléchargement sur le serveur a échoué!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Il existe déjà un fichier avec ce nom !';
+$lang['L_FM_NOFILE'] = "Vous n'avez sélectionné aucun fichier!";
+$lang['L_FM_DELETE1'] = 'Le fichier ';
+$lang['L_FM_DELETE2'] = ' a été supprimé avec succès.';
+$lang['L_FM_DELETE3'] = " n'a pas pu être supprimé!";
+$lang['L_FM_CHOOSE_FILE'] = 'Fichier sélectionné:';
+$lang['L_FM_FILESIZE'] = 'Taille du fichier';
+$lang['L_FM_FILEDATE'] = 'Date';
+$lang['L_FM_NOFILESFOUND'] = 'Aucun fichier trouvé.';
+$lang['L_FM_TABLES'] = 'Tables';
+$lang['L_FM_RECORDS'] = 'Enregistrements';
+$lang['L_FM_ALL_BU'] = 'toutes les sauvegardes';
+$lang['L_FM_ANZ_BU'] = 'Nombres de sauvegardes';
+$lang['L_FM_LAST_BU'] = 'dernière sauvegarde';
+$lang['L_FM_TOTALSIZE'] = 'taille totale';
+$lang['L_FM_SELECTTABLES'] = 'Nombres de tables';
+$lang['L_FM_COMMENT'] = 'Ajouter un commentaire';
+$lang['L_FM_RESTORE'] = 'Restauration';
+$lang['L_FM_ALERTRESTORE1'] = 'Voulez-vous que la base de données ';
+$lang['L_FM_ALERTRESTORE2'] = 'avec le contenu des fichiers';
+$lang['L_FM_ALERTRESTORE3'] = 'soit restaurée?';
+$lang['L_FM_DELETE'] = 'Supprimer les fichiers sélectionnés';
+$lang['L_FM_ASKDELETE1'] = 'Voulez-vous vraiment supprimer le fichier ';
+$lang['L_FM_ASKDELETE2'] = 'really be deleted?';
+$lang['L_FM_ASKDELETE3'] = "Voulez-vous exécuter la suppression automatique d'après les règles sauvegardées?";
+$lang['L_FM_ASKDELETE4'] = 'Voulez-vous supprimer toutes les copies de sauvegarde?';
+$lang['L_FM_ASKDELETE5'] = 'Voulez-vous supprimer toutes les copies de sauvegarde avec ';
+$lang['L_FM_ASKDELETE5_2'] = '_* ?';
+$lang['L_FM_DELETEAUTO'] = "Exécuter manuellement\nsuppression automatique";
+$lang['L_FM_DELETEALL'] = "Supprimer toutes les\ncopies de sauvegarde";
+$lang['L_FM_DELETEALLFILTER'] = 'Supprimer tout avec ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = "Exécuter une nouvelle\ncopie de sauvegarde";
+$lang['L_FM_FILEUPLOAD'] = 'Télécharger un fichier vers le serveur';
+$lang['L_FM_DBNAME'] = 'Nom de la base de données';
+$lang['L_FM_FILES1'] = 'Copie de sauvegarde de la base de données';
+$lang['L_FM_FILES2'] = 'Structure de la base de données';
+$lang['L_FM_AUTODEL1'] = 'Suppression automatique: Les fichiers suivant ont été supprimés du fait du nombre limité de fichiers:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'Configuration pour la copie de sauvegarde';
+$lang['L_FM_OLDBACKUP'] = '(inconnu)';
+$lang['L_FM_RESTORE_HEADER'] = 'Restauration de la base de donnée "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Copie de sauvegarde';
+$lang['L_DOCRONBUTTON'] = 'Exécuter le script Cron';
+$lang['L_DOPERLTEST'] = 'Tester le module Perl';
+$lang['L_DOSIMPLETEST'] = 'Tester Perl';
+$lang['L_PERLOUTPUT1'] = 'Saisie dans crondump.pl pour absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Saisie dans un navigateur ou pour exécuter un script Cron externe';
+$lang['L_PERLOUTPUT3'] = "Saisie pour 'Shell' ou pour la crontab";
+$lang['L_RESTORE_OF_TABLES'] = 'Choisissez les tables à restaurer';
+$lang['L_CONVERTER'] = 'Convertir la copie de sauvegarde';
+$lang['L_CONVERT_FILE'] = 'fichier qui doit être converti';
+$lang['L_CONVERT_FILENAME'] = 'Nom du fichier final (sans extensions)';
+$lang['L_CONVERTING'] = 'En cours de convertion';
+$lang['L_CONVERT_FILEREAD'] = "Lire fichier '%s'";
+$lang['L_CONVERT_FINISHED'] = "Convertion terminée, fichier '%s' créé avec succès.";
+$lang['L_NO_MOD_BACKUPFILE'] = "Copies de sécurités d'autres programmes";
+$lang['L_MAX_UPLOAD_SIZE'] = 'Taille maximale du fichier';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = "Si votre fichier Dump est plus grand que la taille mentionnée plus haut, vous devez alors l'envoyer sur le serveur dans le répertoire en utilisant votre programme FTP.";
+$lang['L_ENCODING'] = 'encodage';
+$lang['L_FM_CHOOSE_ENCODING'] = "Choisissez le type d'encodage de la sauvegarde";
+$lang['L_CHOOSE_CHARSET'] = "MyOOS [Dumper] n'a pas pu détecter automatiquement le type d'encodage de la sauvegarde <br>Vous devez choisir le jeux de caractères qui a été utilisé pour la sauvegarde<br> Si vous découvrez des problèmes avec quelques caractères suite à la restauration, vous pouvez répéter l'opération en choisissant un autre jeux de caractères.<br>Bonne chance ;-)";
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/fr/lang_help.php b/msd/language/fr/lang_help.php
index 8ab0c268..14bb8dcc 100644
--- a/msd/language/fr/lang_help.php
+++ b/msd/language/fr/lang_help.php
@@ -1,37 +1,41 @@
 <?php
-$lang['L_HELP_DB']="Ceci est la liste des bases de données existantes";
-$lang['L_HELP_PRAEFIX']="Le préfixe est une suite pour le début de tables et sert comme filtre.";
-$lang['L_HELP_ZIP']="Compression avec GZip - 'activé' est recommandé";
-$lang['L_HELP_MEMORYLIMIT']="C'est la taille maximale en octets que la mémoire donne au scripte
+
+$lang['L_HELP_DB'] = 'Ceci est la liste des bases de données existantes';
+$lang['L_HELP_PRAEFIX'] = 'Le préfixe est une suite pour le début de tables et sert comme filtre.';
+$lang['L_HELP_ZIP'] = "Compression avec GZip - 'activé' est recommandé";
+$lang['L_HELP_MEMORYLIMIT'] = "C'est la taille maximale en octets que la mémoire donne au scripte
 0 = désactivé";
-$lang['L_MEMORY_LIMIT']="Limite de la mémoire";
-$lang['L_HELP_AD1']="Si activé alors les copies de sauvegarde seront automatiquement supprimées.";
-$lang['L_HELP_AD3']="le nombre maximum de fichier dans le répertoire des copies de sauvegardes (pour le cas de suppression automatique)
-0 = déactivé";
-$lang['L_HELP_LANG']="change sur la langue désirée";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Pour éliminer les données superflues on peut définir que la base de données soit vidée complètement avant la restauration";
-$lang['L_HELP_CRONEXTENDER']="L'extension standard du script Perl est '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="Le nom du fichier de configuration pour le script Perl";
-$lang['L_HELP_CRONPRINTOUT']="Si la sortie de texte est désactivée, aucun texte n'est donné.
+$lang['L_MEMORY_LIMIT'] = 'Limite de la mémoire';
+$lang['L_HELP_AD1'] = 'Si activé alors les copies de sauvegarde seront automatiquement supprimées.';
+$lang['L_HELP_AD3'] = 'le nombre maximum de fichier dans le répertoire des copies de sauvegardes (pour le cas de suppression automatique)
+0 = déactivé';
+$lang['L_HELP_LANG'] = 'change sur la langue désirée';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Pour éliminer les données superflues on peut définir que la base de données soit vidée complètement avant la restauration';
+$lang['L_HELP_CRONEXTENDER'] = "L'extension standard du script Perl est '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'Le nom du fichier de configuration pour le script Perl';
+$lang['L_HELP_CRONPRINTOUT'] = "Si la sortie de texte est désactivée, aucun texte n'est donné.
 Cette fonction est indépendante du journal.";
-$lang['L_HELP_CRONSAMEDB']="Voulez-vous que la même base de données de la configuration soit utilisée pour le script Cron?";
-$lang['L_HELP_CRONDBINDEX']="sélectionne la base de données pour le script Cron";
-$lang['L_HELP_FTPTRANSFER']="si activé, alors après la sauvegarde la copie de sauvegarde est envoyée par FTP.";
-$lang['L_HELP_FTPSERVER']="Adresse FTP du serveur";
-$lang['L_HELP_FTPPORT']="Port FTP du serveur, Port Standard: 21";
-$lang['L_HELP_FTPUSER']="Entrer le nom de l'utilisateur de la connexion FTP";
-$lang['L_HELP_FTPPASS']="entrer le mot de passe de la connexion FTP";
-$lang['L_HELP_FTPDIR']="où doit-être envoyé le fichier?";
-$lang['L_HELP_SPEED']="Vitesse minimale et maximale, Standard est de 50 jusqu'à 5000
+$lang['L_HELP_CRONSAMEDB'] = 'Voulez-vous que la même base de données de la configuration soit utilisée pour le script Cron?';
+$lang['L_HELP_CRONDBINDEX'] = 'sélectionne la base de données pour le script Cron';
+$lang['L_HELP_FTPTRANSFER'] = 'si activé, alors après la sauvegarde la copie de sauvegarde est envoyée par FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Adresse FTP du serveur';
+$lang['L_HELP_FTPPORT'] = 'Port FTP du serveur, Port Standard: 21';
+$lang['L_HELP_FTPUSER'] = "Entrer le nom de l'utilisateur de la connexion FTP";
+$lang['L_HELP_FTPPASS'] = 'entrer le mot de passe de la connexion FTP';
+$lang['L_HELP_FTPDIR'] = 'où doit-être envoyé le fichier?';
+$lang['L_HELP_SFTPTRANSFER'] = 'si activé, alors après la sauvegarde la copie de sauvegarde est envoyée par SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Adresse SFTP du serveur';
+$lang['L_HELP_SFTPPORT'] = 'Port SFTP du serveur, Port Standard: 22';
+$lang['L_HELP_SFTPUSER'] = "Entrer le nom de l'utilisateur de la connexion SFTP";
+$lang['L_HELP_SFTPPASS'] = 'entrer le mot de passe de la connexion SFTP';
+$lang['L_HELP_SFTPDIR'] = 'où doit-être envoyé le fichier?';
+$lang['L_HELP_SPEED'] = "Vitesse minimale et maximale, Standard est de 50 jusqu'à 5000
 (des vitesses trop élevées peuvent provoquer des temporisations!)";
-$lang['L_SPEED']="Contrôle de vitesse";
-$lang['L_HELP_CRONEXECPATH']="L'endroit où se trouve les scripts Perl.
+$lang['L_SPEED'] = 'Contrôle de vitesse';
+$lang['L_HELP_CRONEXECPATH'] = "L'endroit où se trouve les scripts Perl.
 Point de départ est l'adresse HTTP (dans le navigateur)
 Autorisé sont les chemins absolus et relatifs.";
-$lang['L_CRON_EXECPATH']="Chemin du script Perl";
-$lang['L_HELP_CRONCOMPLETELOG']="Si la fonction est activée alors la sortie complète est écrite dans le journal 'complete_log'. 
+$lang['L_CRON_EXECPATH'] = 'Chemin du script Perl';
+$lang['L_HELP_CRONCOMPLETELOG'] = "Si la fonction est activée alors la sortie complète est écrite dans le journal 'complete_log'. 
 Cette fonction est indépendante de la fonction sortie de texte.";
-$lang['L_HELP_FTP_MODE']="Si vous avez des problèmes durant le transfert FTP, essayez en choisissant passif comme mode de transfert.";
-
-
-?>
\ No newline at end of file
+$lang['L_HELP_FTP_MODE'] = 'Si vous avez des problèmes durant le transfert FTP, essayez en choisissant passif comme mode de transfert.';
diff --git a/msd/language/fr/lang_install.php b/msd/language/fr/lang_install.php
index 48ce78d7..7442ce5b 100644
--- a/msd/language/fr/lang_install.php
+++ b/msd/language/fr/lang_install.php
@@ -1,89 +1,85 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Installation terminée  --> <a href=\"index.php\">start MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Retour au menu principal";
-$lang['L_INSTALLMENU']="Menu principal";
-$lang['L_STEP']="Étape";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Désinstallation";
-$lang['L_TOOLS']="Outils";
-$lang['L_EDITCONF']="Éditer la configuration";
-$lang['L_OSWEITER']="continuer sans sauvegarde";
-$lang['L_ERRORMAN']="<strong>Erreur lors de l'écriture de la configuration!</strong><br>Veuillez éditer le fichier ";
-$lang['L_MANUELL']="manuellement";
-$lang['L_CREATEDIRS']="créer répertoire";
-$lang['L_INSTALL_CONTINUE']="continuer avec l'installation";
-$lang['L_CONNECTTOMYSQL']=" connecter à MySQL ";
-$lang['L_DBPARAMETER']="Paramètre de la base de données";
-$lang['L_CONFIGNOTWRITABLE']="Impossible d'écrire le fichier \"config.php\".
+
+$lang['L_INSTALLFINISHED'] = '<br>Installation terminée  --> <a href="index.php">start MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Retour au menu principal';
+$lang['L_INSTALLMENU'] = 'Menu principal';
+$lang['L_STEP'] = 'Étape';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Désinstallation';
+$lang['L_TOOLS'] = 'Outils';
+$lang['L_EDITCONF'] = 'Éditer la configuration';
+$lang['L_OSWEITER'] = 'continuer sans sauvegarde';
+$lang['L_ERRORMAN'] = "<strong>Erreur lors de l'écriture de la configuration!</strong><br>Veuillez éditer le fichier ";
+$lang['L_MANUELL'] = 'manuellement';
+$lang['L_CREATEDIRS'] = 'créer répertoire';
+$lang['L_INSTALL_CONTINUE'] = "continuer avec l'installation";
+$lang['L_CONNECTTOMYSQL'] = ' connecter à MySQL ';
+$lang['L_DBPARAMETER'] = 'Paramètre de la base de données';
+$lang['L_CONFIGNOTWRITABLE'] = "Impossible d'écrire le fichier \"config.php\".
 Veuillez utiliser votre programme FTP et chmoder ce fichier en 0777.";
-$lang['L_DBCONNECTION']="Connexion base de données";
-$lang['L_CONNECTIONERROR']="Erreur: aucune connexion n'a pu être créée.";
-$lang['L_CONNECTION_OK']="Connexion avec la base de données a été établie.";
-$lang['L_SAVEANDCONTINUE']="sauvegarder et continuer l'installation";
-$lang['L_CONFBASIC']="Configuration de base";
-$lang['L_INSTALL_STEP2FINISHED']="Configuration de la base de données a été sauvegardée.";
-$lang['L_INSTALL_STEP2_1']="Continuer l'installation avec la configuration standart";
-$lang['L_LASTSTEP']="Terminer l'installation";
-$lang['L_FTPMODE']="Créer les répertoires par FTP (safe_mode)";
-$lang['L_IDOMANUAL']="Créer un répertoire manuellement";
-$lang['L_DOFROM']="terminer par";
-$lang['L_FTPMODE2']="Créer un répertoire par FTP:";
-$lang['L_CONNECT']="connecter";
-$lang['L_DIRS_CREATED']="Les répertoires ont été créés avec succès.";
-$lang['L_CONNECT_TO']="connexion vers";
-$lang['L_CHANGEDIR']="muter vers le répertoire";
-$lang['L_CHANGEDIRERROR']="Mutation dans le répertoire non possible";
-$lang['L_FTP_OK']="Paramètres FTP sont ok";
-$lang['L_CREATEDIRS2']="Créer répertoires";
-$lang['L_FTP_NOTCONNECTED']="Connexion Ftp non établie!";
-$lang['L_CONNWITH']="Connexion avec";
-$lang['L_ASUSER']="comme utilisateur";
-$lang['L_NOTPOSSIBLE']="impossible";
-$lang['L_DIRCR1']="créer répertoire de travail";
-$lang['L_DIRCR2']="créer répertoire de sauvegarde";
-$lang['L_DIRCR4']="créer répertoire du journal";
-$lang['L_DIRCR5']="créer répertoire de configuration";
-$lang['L_INDIR']="je suis dans le répertoire";
-$lang['L_CHECK_DIRS']="vérifier";
-$lang['L_DISABLEDFUNCTIONS']="Fonctions désactivées";
-$lang['L_NOFTPPOSSIBLE']="Il n'y a pas de fonction FTP à disposition!";
-$lang['L_NOGZPOSSIBLE']="Il n'y a pas de fonction de compression à disposition!";
-$lang['L_UI1']="Supprimer tous les répertoires de travail avec les sauvegardes incluses.";
-$lang['L_UI2']="Êtes-vous sûr d´exécuter l'opération ?";
-$lang['L_UI3']="Non, arrêter immédiatement";
-$lang['L_UI4']="Oui, veuillez continuer";
-$lang['L_UI5']="Supprimer répertoire de travail";
-$lang['L_UI6']="tout a été supprimé avec succès.";
-$lang['L_UI7']="Veuillez supprimer le répertoire de script";
-$lang['L_UI8']="un niveau supérieur";
-$lang['L_UI9']="Une erreur est apparue, suppression impossible</p>Erreur dans le répertoire ";
-$lang['L_IMPORT']="Importer la configuration";
-$lang['L_IMPORT3']="La configuration a été chargée...";
-$lang['L_IMPORT4']="La configuration a été sauvegardée.";
-$lang['L_IMPORT5']="Démarrer MySQLDumper";
-$lang['L_IMPORT6']="Menu d'installation;";
-$lang['L_IMPORT7']="Télécharger vers le serveur la configuration";
-$lang['L_IMPORT8']="retourner vers le téléchargement";
-$lang['L_IMPORT9']="Ceci n'est pas une sauvegarde de la configuration !";
-$lang['L_IMPORT10']="La configuration a été téléchargée vers le serveur avec succès ...";
-$lang['L_IMPORT11']="<strong>Erreur: </strong>Il y a des problèmes d'écriture pour les sql_statements";
-$lang['L_IMPORT12']="<strong>Erreur: </strong>Il y a des problèmes d'écriture pour le fichier config.php";
-$lang['L_INSTALL_HELP_PORT']="(vide = Port standart)";
-$lang['L_INSTALL_HELP_SOCKET']="(vide = Socket standart)";
-$lang['L_TRYAGAIN']="Réessayer";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="Base de données trouvée";
-$lang['L_FM_FILEUPLOAD']="Télécharger un fichier vers le serveur";
-$lang['L_PASS']="Mot de passe";
-$lang['L_NO_DB_FOUND_INFO']="La connexion avec la base de données a été établie avec succès.<br>
+$lang['L_DBCONNECTION'] = 'Connexion base de données';
+$lang['L_CONNECTIONERROR'] = "Erreur: aucune connexion n'a pu être créée.";
+$lang['L_CONNECTION_OK'] = 'Connexion avec la base de données a été établie.';
+$lang['L_SAVEANDCONTINUE'] = "sauvegarder et continuer l'installation";
+$lang['L_CONFBASIC'] = 'Configuration de base';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Configuration de la base de données a été sauvegardée.';
+$lang['L_INSTALL_STEP2_1'] = "Continuer l'installation avec la configuration standart";
+$lang['L_LASTSTEP'] = "Terminer l'installation";
+$lang['L_IDOMANUAL'] = 'Créer un répertoire manuellement';
+$lang['L_DOFROM'] = 'terminer par';
+$lang['L_FTPMODE2'] = 'Créer un répertoire par FTP:';
+$lang['L_CONNECT'] = 'connecter';
+$lang['L_DIRS_CREATED'] = 'Les répertoires ont été créés avec succès.';
+$lang['L_CONNECT_TO'] = 'connexion vers';
+$lang['L_CHANGEDIR'] = 'muter vers le répertoire';
+$lang['L_CHANGEDIRERROR'] = 'Mutation dans le répertoire non possible';
+$lang['L_FTP_OK'] = 'Paramètres FTP sont ok';
+$lang['L_CREATEDIRS2'] = 'Créer répertoires';
+$lang['L_FTP_NOTCONNECTED'] = 'Connexion Ftp non établie!';
+$lang['L_CONNWITH'] = 'Connexion avec';
+$lang['L_ASUSER'] = 'comme utilisateur';
+$lang['L_NOTPOSSIBLE'] = 'impossible';
+$lang['L_DIRCR1'] = 'créer répertoire de travail';
+$lang['L_DIRCR2'] = 'créer répertoire de sauvegarde';
+$lang['L_DIRCR4'] = 'créer répertoire du journal';
+$lang['L_DIRCR5'] = 'créer répertoire de configuration';
+$lang['L_INDIR'] = 'je suis dans le répertoire';
+$lang['L_CHECK_DIRS'] = 'vérifier';
+$lang['L_DISABLEDFUNCTIONS'] = 'Fonctions désactivées';
+$lang['L_NOFTPPOSSIBLE'] = "Il n'y a pas de fonction FTP à disposition!";
+$lang['L_NOGZPOSSIBLE'] = "Il n'y a pas de fonction de compression à disposition!";
+$lang['L_UI1'] = 'Supprimer tous les répertoires de travail avec les sauvegardes incluses.';
+$lang['L_UI2'] = "Êtes-vous sûr d´exécuter l'opération ?";
+$lang['L_UI3'] = 'Non, arrêter immédiatement';
+$lang['L_UI4'] = 'Oui, veuillez continuer';
+$lang['L_UI5'] = 'Supprimer répertoire de travail';
+$lang['L_UI6'] = 'tout a été supprimé avec succès.';
+$lang['L_UI7'] = 'Veuillez supprimer le répertoire de script';
+$lang['L_UI8'] = 'un niveau supérieur';
+$lang['L_UI9'] = 'Une erreur est apparue, suppression impossible</p>Erreur dans le répertoire ';
+$lang['L_IMPORT'] = 'Importer la configuration';
+$lang['L_IMPORT3'] = 'La configuration a été chargée...';
+$lang['L_IMPORT4'] = 'La configuration a été sauvegardée.';
+$lang['L_IMPORT5'] = 'Démarrer MyOOS [Dumper]';
+$lang['L_IMPORT6'] = "Menu d'installation;";
+$lang['L_IMPORT7'] = 'Télécharger vers le serveur la configuration';
+$lang['L_IMPORT8'] = 'retourner vers le téléchargement';
+$lang['L_IMPORT9'] = "Ceci n'est pas une sauvegarde de la configuration !";
+$lang['L_IMPORT10'] = 'La configuration a été téléchargée vers le serveur avec succès ...';
+$lang['L_IMPORT11'] = "<strong>Erreur: </strong>Il y a des problèmes d'écriture pour les sql_statements";
+$lang['L_IMPORT12'] = "<strong>Erreur: </strong>Il y a des problèmes d'écriture pour le fichier config.php";
+$lang['L_INSTALL_HELP_PORT'] = '(vide = Port standart)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(vide = Socket standart)';
+$lang['L_TRYAGAIN'] = 'Réessayer';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'Base de données trouvée';
+$lang['L_FM_FILEUPLOAD'] = 'Télécharger un fichier vers le serveur';
+$lang['L_PASS'] = 'Mot de passe';
+$lang['L_NO_DB_FOUND_INFO'] = "La connexion avec la base de données a été établie avec succès.<br>
 Vos données utilisateur sont valides et ont été acceptées par le serveur MySQL.<br>
-Mais, MySQLDumper n'a pas été capable de trouver une base de données.<br>
+Mais, MyOOS [Dumper] n'a pas été capable de trouver une base de données.<br>
 La détection automatique via le script est dans quelques cas bloquée par certains serveurs.<br>
 Vous devez alors entrer manuellement le nom de votre base de données après la fin de l'installation.
 Cliquer sur \"configuration\" \"Affichage des paramêtres de connexion\" et entrer le nom de votre base de données.";
-$lang['L_SAFEMODEDESC']="La configuration de ce serveur étant avec l'option \"safe_mode=on\", les listes suivantes doivent être envoyées manuellement. Utilisez votre logiciel FTP pour effectuer cette opération):";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/fr/lang_log.php b/msd/language/fr/lang_log.php
index a2308b85..38525579 100644
--- a/msd/language/fr/lang_log.php
+++ b/msd/language/fr/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Supprimer le journal";
-$lang['L_LOGFILEFORMAT']="Format du journal";
-$lang['L_LOGFILENOTWRITABLE']="Écriture du Journal impossible!";
-$lang['L_NOREVERSE']="Montrer les entrées les plus anciennes en premier";
-$lang['L_REVERSE']="Montrer les entrées les plus récentes en premier";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Supprimer le journal';
+$lang['L_LOGFILEFORMAT'] = 'Format du journal';
+$lang['L_LOGFILENOTWRITABLE'] = 'Écriture du Journal impossible!';
+$lang['L_NOREVERSE'] = 'Montrer les entrées les plus anciennes en premier';
+$lang['L_REVERSE'] = 'Montrer les entrées les plus récentes en premier';
diff --git a/msd/language/fr/lang_main.php b/msd/language/fr/lang_main.php
index 2a8bb594..2d2084e5 100644
--- a/msd/language/fr/lang_main.php
+++ b/msd/language/fr/lang_main.php
@@ -1,74 +1,85 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Il n'y a pas de fonction FTP à disposition!";
-$lang['L_INFO_LOCATION']="Vous vous trouvez sur ";
-$lang['L_INFO_DATABASES']="Les bases de données suivantes sont sur le serveur MySQL:";
-$lang['L_INFO_NODB']="Base de données n'existe pas";
-$lang['L_INFO_DBDETAIL']="Informations détaillées de la base de données ";
-$lang['L_INFO_DBEMPTY']="La base de données est vide !";
-$lang['L_INFO_RECORDS']="Enregistrements";
-$lang['L_INFO_SIZE']="Taille";
-$lang['L_INFO_LASTUPDATE']="dernière mise à jour";
-$lang['L_INFO_SUM']="total";
-$lang['L_INFO_OPTIMIZED']="optimiser";
-$lang['L_OPTIMIZE_DATABASES']="Tables optimisées";
-$lang['L_CHECK_TABLES']="Vérifier les tables";
-$lang['L_CLEAR_DATABASE']="Vider la base de données";
-$lang['L_DELETE_DATABASE']="Supprimer la base de données";
-$lang['L_INFO_CLEARED']="a été vidée";
-$lang['L_INFO_DELETED']="a été supprimé";
-$lang['L_INFO_EMPTYDB1']="Voulez-vous que la base de données";
-$lang['L_INFO_EMPTYDB2']=" soit vraiment vidée? (ATTENTION: Toutes les données seront supprimées à jamais)";
-$lang['L_INFO_KILLDB']=" soit vraiment supprimée? (ATTENTION: Toutes les données seront supprimées à jamais)";
-$lang['L_PROCESSKILL1']="On essaye de terminer le processus ";
-$lang['L_PROCESSKILL2']=" .";
-$lang['L_PROCESSKILL3']="On essaye depuis ";
-$lang['L_PROCESSKILL4']=" sec. de terminer le processus ";
-$lang['L_HTACC_CREATE']="Créer une protection de répertoire";
-$lang['L_ENCRYPTION_TYPE']="Type de cryptage";
-$lang['L_HTACC_CRYPT']="Crypt (Linux ou système Unix)";
-$lang['L_HTACC_MD5']="MD5 (Linux ou système Unix)";
-$lang['L_HTACC_NO_ENCRYPTION']="sans cryptage (Windows)";
-$lang['L_HTACCESS8']="Il existe déjà une protection de répertoire. Si vous créez un nouveau, l'ancien sera écrasé !";
-$lang['L_HTACC_NO_USERNAME']="Vous devez saisir votre nom!";
-$lang['L_PASSWORDS_UNEQUAL']="Les mots de passes ne sont pas identiques ou bien vide!";
-$lang['L_HTACC_CONFIRM_DELETE']="Voulez-vous créer maintenant la protection de répertoire?";
-$lang['L_HTACC_CREATED']="La protection de répertoire a été créée.";
-$lang['L_HTACC_CONTENT']="Contenu du fichier";
-$lang['L_HTACC_CREATE_ERROR']="Une erreur est apparue lors de la création du fichier de protection!<br>Veuillez créer manuellement un fichier avec les informations suivantes";
-$lang['L_HTACC_PROPOSED']="Conseil d'urgence";
-$lang['L_HTACC_EDIT']="Éditer .htaccess";
-$lang['L_HTACCESS18']="Créer .htaccess dans ";
-$lang['L_HTACCESS19']="Réinitialiser ";
-$lang['L_HTACCESS20']="Exécuter le script";
-$lang['L_HTACCESS21']="Ajouter le fournisseur";
-$lang['L_HTACCESS22']="Permettre l'exécution";
-$lang['L_HTACCESS23']="Listes des répertoires";
-$lang['L_HTACCESS24']="Document des erreurs";
-$lang['L_HTACCESS25']="Activer 'Rewrite'";
-$lang['L_HTACCESS26']="Refusé / Accepté";
-$lang['L_HTACCESS27']="Redirection";
-$lang['L_HTACCESS28']="Journal d'erreur";
-$lang['L_HTACCESS29']="autres exemples et documentations";
-$lang['L_HTACCESS30']="Fournisseur";
-$lang['L_HTACCESS31']="Général";
-$lang['L_HTACCESS32']="Attention! Le fichier .htaccess a une influence directe sur le navigateur.<br>Lors d'un mauvais emploi les pages ne sont plus accessibles.";
-$lang['L_PHPBUG']="Bogue dans zlib ! Aucune compression possible!";
-$lang['L_DISABLEDFUNCTIONS']="Fonctions désactivées";
-$lang['L_NOGZPOSSIBLE']="Comme Zlib n'est pas installé, vous ne pouvez pas utiliser les fonctions GZip!";
-$lang['L_DELETE_HTACCESS']="Supprimer la protection des répertoires (suppression .htaccess)";
-$lang['L_WRONG_RIGHTS']="Impossible d'écrire le fichier ou le répertoire '%s' .<br> Les chmods ne sont mal configurés ou le propriétaire n'est pas bon.<br>Veuillez vérifier les attributs en utilisant votre logiciel FTP.<br>Le fichier ou le répertoire doivent être sur %s.";
-$lang['L_CANT_CREATE_DIR']="Impossible de créer le répertoire '%s'. Veuillez créer ce répertoire manuellement avec votre logiciel FTP.";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="le fichier n'a pas été trouvé";
 
-
-?>
\ No newline at end of file
+$lang['L_NOFTPPOSSIBLE'] = "Il n'y a pas de fonction FTP à disposition!";
+$lang['L_INFO_LOCATION'] = 'Vous vous trouvez sur ';
+$lang['L_INFO_DATABASES'] = 'Les bases de données suivantes sont sur le serveur MySQL:';
+$lang['L_INFO_NODB'] = "Base de données n'existe pas";
+$lang['L_INFO_DBDETAIL'] = 'Informations détaillées de la base de données ';
+$lang['L_INFO_DBEMPTY'] = 'La base de données est vide !';
+$lang['L_INFO_RECORDS'] = 'Enregistrements';
+$lang['L_INFO_SIZE'] = 'Taille';
+$lang['L_INFO_LASTUPDATE'] = 'dernière mise à jour';
+$lang['L_INFO_SUM'] = 'total';
+$lang['L_INFO_OPTIMIZED'] = 'optimiser';
+$lang['L_OPTIMIZE_DATABASES'] = 'Tables optimisées';
+$lang['L_CHECK_TABLES'] = 'Vérifier les tables';
+$lang['L_CLEAR_DATABASE'] = 'Vider la base de données';
+$lang['L_DELETE_DATABASE'] = 'Supprimer la base de données';
+$lang['L_INFO_CLEARED'] = 'a été vidée';
+$lang['L_INFO_DELETED'] = 'a été supprimé';
+$lang['L_INFO_EMPTYDB1'] = 'Voulez-vous que la base de données';
+$lang['L_INFO_EMPTYDB2'] = ' soit vraiment vidée? (ATTENTION: Toutes les données seront supprimées à jamais)';
+$lang['L_INFO_KILLDB'] = ' soit vraiment supprimée? (ATTENTION: Toutes les données seront supprimées à jamais)';
+$lang['L_PROCESSKILL1'] = 'On essaye de terminer le processus ';
+$lang['L_PROCESSKILL2'] = ' .';
+$lang['L_PROCESSKILL3'] = 'On essaye depuis ';
+$lang['L_PROCESSKILL4'] = ' sec. de terminer le processus ';
+$lang['L_HTACC_CREATE'] = 'Créer une protection de répertoire';
+$lang['L_ENCRYPTION_TYPE'] = 'Type de cryptage';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = "Il existe déjà une protection de répertoire. Si vous créez un nouveau, l'ancien sera écrasé !";
+$lang['L_HTACC_NO_USERNAME'] = 'Vous devez saisir votre nom!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Les mots de passes ne sont pas identiques ou bien vide!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Voulez-vous créer maintenant la protection de répertoire?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'La protection de répertoire a été créée.';
+$lang['L_HTACC_CONTENT'] = 'Contenu du fichier';
+$lang['L_HTACC_CREATE_ERROR'] = 'Une erreur est apparue lors de la création du fichier de protection!<br>Veuillez créer manuellement un fichier avec les informations suivantes';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'Éditer .htaccess';
+$lang['L_HTACCESS18'] = 'Créer .htaccess dans ';
+$lang['L_HTACCESS19'] = 'Réinitialiser ';
+$lang['L_HTACCESS20'] = 'Exécuter le script';
+$lang['L_HTACCESS21'] = 'Ajouter le fournisseur';
+$lang['L_HTACCESS22'] = "Permettre l'exécution";
+$lang['L_HTACCESS23'] = 'Listes des répertoires';
+$lang['L_HTACCESS24'] = 'Document des erreurs';
+$lang['L_HTACCESS25'] = "Activer 'Rewrite'";
+$lang['L_HTACCESS26'] = 'Refusé / Accepté';
+$lang['L_HTACCESS27'] = 'Redirection';
+$lang['L_HTACCESS28'] = "Journal d'erreur";
+$lang['L_HTACCESS29'] = 'autres exemples et documentations';
+$lang['L_HTACCESS30'] = 'Fournisseur';
+$lang['L_HTACCESS31'] = 'Général';
+$lang['L_HTACCESS32'] = "Attention! Le fichier .htaccess a une influence directe sur le navigateur.<br>Lors d'un mauvais emploi les pages ne sont plus accessibles.";
+$lang['L_DISABLEDFUNCTIONS'] = 'Fonctions désactivées';
+$lang['L_NOGZPOSSIBLE'] = "Comme Zlib n'est pas installé, vous ne pouvez pas utiliser les fonctions GZip!";
+$lang['L_DELETE_HTACCESS'] = 'Supprimer la protection des répertoires (suppression .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "Impossible d'écrire le fichier ou le répertoire '%s' .<br> Les chmods ne sont mal configurés ou le propriétaire n'est pas bon.<br>Veuillez vérifier les attributs en utilisant votre logiciel FTP.<br>Le fichier ou le répertoire doivent être sur %s.";
+$lang['L_CANT_CREATE_DIR'] = "Impossible de créer le répertoire '%s'. Veuillez créer ce répertoire manuellement avec votre logiciel FTP.";
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'Nouvelle version' ;
+$lang['L_NEW_MOD_VERSION_INFO'] = 'Il y a une nouvelle version de MyOOS [Dumper] disponible';
+$lang['L_UPDATED_IMPORTANT'] = 'Important : veuillez sauvegarder vos fichiers avant la mise à jour.';
+$lang['L_UPDATE'] = 'Mettre à jour maintenant';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = "le fichier n'a pas été trouvé";
+$lang['L_INSTALLING_UPDATES'] = 'Installation des mises à jour' ;
+$lang['L_UPDATE_SUCCESSFUL'] = 'Mise à jour réussie' ;
+$lang['L_UPDATE_FAILED'] = 'Update failed' ;
+$lang['L_UP_TO_DATE'] = 'La version actuelle est à jour' ;
diff --git a/msd/language/fr/lang_restore.php b/msd/language/fr/lang_restore.php
index d7d542b2..7f733ac4 100644
--- a/msd/language/fr/lang_restore.php
+++ b/msd/language/fr/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Jusqu'à présent <b>%d</b> tables ont été créés.";
-$lang['L_FILE_MISSING']="le fichier n'a pas été trouvé";
-$lang['L_RESTORE_DB']="Base de données '<b>%s</b>' sur le serveur '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> tables ont été créés.";
-$lang['L_RESTORE_RUN1']="<br>Jusqu'à présent <b>%s</b> de <b>%s</b> enregistrements ont été enregistrés.";
-$lang['L_RESTORE_RUN2']="<br>En ce moment la table '<b>%s</b>' avec ces enregistrements est en cours de traitement.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> enregistrements ont été enregistrés.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Jusqu'à présent <b>%d</b> de <b>%d</b> tables ont été créés.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Toutes nos félicitations.</b><br><br>La base de données a été restaurée complètement.<br>Tous les fichiers de la copie de sauvegarde ont été enregistrés avec succès dans la base de données.<br><br>Restauration terminée. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Erreur:<br>Choix de la base de données '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' échoué!";
-$lang['L_FILE_OPEN_ERROR']="Erreur: Le fichier n'a pas pu être ouvert.";
-$lang['L_PROGRESS_OVER_ALL']="Progression totale";
-$lang['L_BACK_TO_OVERVIEW']="Aperçu général des bases de données";
-$lang['L_RESTORE_RUN0']="<br>Jusqu'à présent <b>%s</b> enregistrements ont été enregistrés avec succès.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Commande SQL inconnue";
-$lang['L_NOTICES']="Notices";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = "Jusqu'à présent <b>%d</b> tables ont été créés.";
+$lang['L_FILE_MISSING'] = "le fichier n'a pas été trouvé";
+$lang['L_RESTORE_DB'] = "Base de données '<b>%s</b>' sur le serveur '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> tables ont été créés.';
+$lang['L_RESTORE_RUN1'] = "<br>Jusqu'à présent <b>%s</b> de <b>%s</b> enregistrements ont été enregistrés.";
+$lang['L_RESTORE_RUN2'] = "<br>En ce moment la table '<b>%s</b>' avec ces enregistrements est en cours de traitement.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> enregistrements ont été enregistrés.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = "Jusqu'à présent <b>%d</b> de <b>%d</b> tables ont été créés.";
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Toutes nos félicitations.</b><br><br>La base de données a été restaurée complètement.<br>Tous les fichiers de la copie de sauvegarde ont été enregistrés avec succès dans la base de données.<br><br>Restauration terminée. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Erreur:<br>Choix de la base de données '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' échoué!";
+$lang['L_FILE_OPEN_ERROR'] = "Erreur: Le fichier n'a pas pu être ouvert.";
+$lang['L_PROGRESS_OVER_ALL'] = 'Progression totale';
+$lang['L_BACK_TO_OVERVIEW'] = 'Aperçu général des bases de données';
+$lang['L_RESTORE_RUN0'] = "<br>Jusqu'à présent <b>%s</b> enregistrements ont été enregistrés avec succès.";
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Commande SQL inconnue';
+$lang['L_NOTICES'] = 'Notices';
diff --git a/msd/language/fr/lang_sql.php b/msd/language/fr/lang_sql.php
index 4efd4c22..2955aad6 100644
--- a/msd/language/fr/lang_sql.php
+++ b/msd/language/fr/lang_sql.php
@@ -1,194 +1,190 @@
 <?php
-$lang['L_COMMAND']="Requête";
-$lang['L_IMPORT_NOTABLE']="Aucune table n'a été sélectionné pour l'import!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="L'exécution de requête SQL peut influencer les données. L'auteur dénie toute responsabilité pour des pertes de données.";
-$lang['L_SQL_EXEC']="Exécuter la requête SQL";
-$lang['L_SQL_DATAVIEW']="Aperçu données";
-$lang['L_SQL_TABLEVIEW']="Aperçu des tables";
-$lang['L_SQL_VONINS']="d'un total de";
-$lang['L_SQL_NODATA']="aucunes données";
-$lang['L_SQL_RECORDUPDATED']="L'enregistrement a été modifié";
-$lang['L_SQL_RECORDINSERTED']="L'enregistrement a été sauvegardé";
-$lang['L_SQL_BACKDBOVERVIEW']="retourner vers l'aperçu général des bases de données";
-$lang['L_SQL_RECORDDELETED']="L'enregistrement a été supprimé";
-$lang['L_ASKTABLEEMPTY']="Voulez-vous vider la table `%s`?";
-$lang['L_SQL_RECORDEDIT']="Éditer l'enregistrement";
-$lang['L_SQL_RECORDNEW']="Insérer un nouvel enregistrement ";
-$lang['L_ASKDELETERECORD']="Voulez-vous supprimer l'enregistrement?";
-$lang['L_ASKDELETETABLE']="voulez-vous supprimer la table `%s`?";
-$lang['L_SQL_BEFEHLE']="Requête SQL";
-$lang['L_SQL_BEFEHLNEU']="nouvelle requête";
-$lang['L_SQL_BEFEHLSAVED1']="Requête SQL";
-$lang['L_SQL_BEFEHLSAVED2']="a été ajouté";
-$lang['L_SQL_BEFEHLSAVED3']="a été sauvegardé";
-$lang['L_SQL_BEFEHLSAVED4']="a été placé plus haut";
-$lang['L_SQL_BEFEHLSAVED5']="a été supprimé";
-$lang['L_SQL_QUERYENTRY']="L'intérrogation contient";
-$lang['L_SQL_COLUMNS']="colonnes";
-$lang['L_ASKDBDELETE']="Voulez-vous vraiment supprimer la base de données `%s` avec son contenu?";
-$lang['L_ASKDBEMPTY']="Voulez-vous vraiment vider la base de données  `%s`?";
-$lang['L_ASKDBCOPY']="Voulez-vous copier le contenu de la base de données  `%s` dans la base de données  %s`?";
-$lang['L_SQL_TABLENEW']="Éditer les tables";
-$lang['L_SQL_OUTPUT']="Sortie SQL";
-$lang['L_DO_NOW']="Exécuter maintenant";
-$lang['L_SQL_NAMEDEST_MISSING']="Nom de la base de données manque!";
-$lang['L_ASKDELETEFIELD']="Voulez-vous supprimer le champ?";
-$lang['L_SQL_COMMANDS_IN']=" Ligne a été travaillé en ";
-$lang['L_SQL_COMMANDS_IN2']="  sec.";
-$lang['L_SQL_OUT1']="Il y a eu ";
-$lang['L_SQL_OUT2']="Requêtes exécutées";
-$lang['L_SQL_OUT3']="Il y a eu ";
-$lang['L_SQL_OUT4']="Commentaire";
-$lang['L_SQL_OUT5']="Comme la sortie contient plus de 5000 lignes celles-ci ne sont pas affichées.";
-$lang['L_SQL_SELECDB']="Sélectionner la base de données";
-$lang['L_SQL_TABLESOFDB']="Tables de la base de données";
-$lang['L_SQL_EDIT']="éditer";
-$lang['L_SQL_NOFIELDDELETE']="Suppression impossible, car une table doit avoir au minimum 1 champ.";
-$lang['L_SQL_FIELDDELETE1']="Le champ";
-$lang['L_SQL_DELETED']="a été supprimé";
-$lang['L_SQL_CHANGED']="a été modifié.";
-$lang['L_SQL_CREATED']="a été créé.";
-$lang['L_SQL_NODEST_COPY']="Sans destination on ne peut pas copier !";
-$lang['L_SQL_DESTTABLE_EXISTS']="La table de destination existe déjà !";
-$lang['L_SQL_SCOPY']="Structure de la table `%s` a été copié dans la table `%s`.";
-$lang['L_SQL_TCOPY']="La table `%s` a été copié avec les données de la table `%s`.";
-$lang['L_SQL_TABLENONAME']="La table doit avoir un nom !";
-$lang['L_SQL_TBLNAMEEMPTY']="Le nom de la table ne peut pas être vide !";
-$lang['L_SQL_COLLATENOTMATCH']="Police de caractères et triage ne sont pas compatibles !";
-$lang['L_SQL_FIELDNAMENOTVALID']="Erreur: Nom de champs invalidee";
-$lang['L_SQL_CREATETABLE']="créer table";
-$lang['L_SQL_COPYTABLE']="copier table";
-$lang['L_SQL_STRUCTUREONLY']="seulement la structure";
-$lang['L_SQL_STRUCTUREDATA']="Structure et données";
-$lang['L_SQL_NOTABLESINDB']="Il n'y a pas de table dans la base de données";
-$lang['L_SQL_SELECTTABLE']="Sélectionner la table";
-$lang['L_SQL_SHOWDATATABLE']="Montrer les données dans la table";
-$lang['L_SQL_TBLPROPSOF']="Propriétés de la table";
-$lang['L_SQL_EDITFIELD']="Éditer champs";
-$lang['L_SQL_NEWFIELD']="Nouveau champ";
-$lang['L_SQL_INDEXES']="Indices";
-$lang['L_SQL_ATPOSITION']="créer à la position";
-$lang['L_SQL_FIRST']="en premier";
-$lang['L_SQL_AFTER']="après";
-$lang['L_SQL_CHANGEFIELD']="Changer les champs";
-$lang['L_SQL_INSERTFIELD']="Créer champs";
-$lang['L_SQL_INSERTNEWFIELD']="créer nouveau champs";
-$lang['L_SQL_TABLEINDEXES']="Indices de la table";
-$lang['L_SQL_ALLOWDUPS']="Permettre la duplication";
-$lang['L_SQL_CARDINALITY']="Cardinalité";
-$lang['L_SQL_TABLENOINDEXES']="La table ne contient aucun indice";
-$lang['L_SQL_CREATEINDEX']="créer nouveau index";
-$lang['L_SQL_WASEMPTIED']="a été vidé";
-$lang['L_SQL_RENAMEDTO']="a été renommé par";
-$lang['L_SQL_DBCOPY']="Le contenue de la base de données `%s` a été copié dans la base de données `%s`.";
-$lang['L_SQL_DBSCOPY']="La structure de la  base de données `%s` a été copié dans la base de données `%s`.";
-$lang['L_SQL_WASCREATED']="a été créé";
-$lang['L_SQL_RENAMEDB']="Renommer la base de données";
-$lang['L_SQL_ACTIONS']="Actions";
-$lang['L_SQL_CHOOSEACTION']="Sélectionner l'action";
-$lang['L_SQL_DELETEDB']="Supprimer la base de données";
-$lang['L_SQL_EMPTYDB']="Vider la base de données";
-$lang['L_SQL_COPYDATADB']="Copier le contenu dans la base de données";
-$lang['L_SQL_COPYSDB']="Copier la structure dans la base de données";
-$lang['L_SQL_IMEXPORT']="Import/Export";
-$lang['L_INFO_RECORDS']="Enregistrements";
-$lang['L_NAME']="Nom";
-$lang['L_ASKTABLEEMPTYKEYS']="Voulez-vous vider la table `%s` et remettre les indices?";
-$lang['L_EDIT']="éditer";
-$lang['L_DELETE']="supprimer";
-$lang['L_EMPTY']="vider";
-$lang['L_EMPTYKEYS']="vider et remettre les indices";
-$lang['L_SQL_TABLEEMPTIED']="Table `%s` a été vidée.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Table `%s` a été vidée et les indices ont été remis.";
-$lang['L_SQL_LIBRARY']="Bibliothèque SQL";
-$lang['L_SQL_ATTRIBUTES']="Attributs";
-$lang['L_SQL_UPLOADEDFILE']="Fichier chargé: ";
-$lang['L_SQL_IMPORT']="Import dans la base de données `%s`";
-$lang['L_EXPORT']="Export";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Options d'import";
-$lang['L_CSVOPTIONS']="Options CSV";
-$lang['L_IMPORTTABLE']="Import dans la table";
-$lang['L_NEWTABLE']="nouvelle table";
-$lang['L_IMPORTSOURCE']="Source d'import";
-$lang['L_FROMTEXTBOX']="de la zone de texte";
-$lang['L_FROMFILE']="du fichier";
-$lang['L_EMPTYTABLEBEFORE']="Vider avant les tables";
-$lang['L_CREATEAUTOINDEX']="Créer index automatique";
-$lang['L_CSV_NAMEFIRSTLINE']="Nom du champ dans la première ligne";
-$lang['L_CSV_FIELDSEPERATE']="Séparer les champs avec";
-$lang['L_CSV_FIELDSENCLOSED']="Inclure les champs avec";
-$lang['L_CSV_FIELDSESCAPE']="Champs d'échappement";
-$lang['L_CSV_EOL']="Ligne séparée avec";
-$lang['L_CSV_NULL']="Remplace ZÉRO par";
-$lang['L_CSV_FILEOPEN']="Ouvrir fichier CSV";
-$lang['L_IMPORTIEREN']="importer";
-$lang['L_SQL_EXPORT']="Export de la base de données `%s`";
-$lang['L_EXPORTOPTIONS']="Options d'export";
-$lang['L_EXCEL2003']="à partir d'Excel 2003";
-$lang['L_SHOWRESULT']="Montrer le résultat";
-$lang['L_SENDRESULTASFILE']="Envoyer le résultat comme fichier";
-$lang['L_EXPORTLINES']="<strong>%s</strong> lignes exportées";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Le nombre de tables ne correspondent pas au nombre de données à importer (%d à la place de %d).";
-$lang['L_CSV_FIELDSLINES']="%d champs calculer, en tout %d lignes";
-$lang['L_CSV_ERRORCREATETABLE']="Erreur lors de la création de la table `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="Veuillez entrer un fichier.";
-$lang['L_CSV_NODATA']="Aucun fichier à importer a été trouvé!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="Fonctions générales";
-$lang['L_SQLLIB_RESETAUTO']="Remettre valeur par défaut";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="Désactiver Board";
-$lang['L_SQLLIB_ACTIVATEBOARD']="Activer Board";
-$lang['L_SQL_NOTABLESSELECTED']="Aucune table n'est sélectionnée !";
-$lang['L_TOOLS']="Outils";
-$lang['L_TOOLS_TOOLBOX']="Sélectionner la base de données / Fonctions de la base de données / Import et export";
-$lang['L_SQL_OPENFILE']="Ouvrir le fichier SQL";
-$lang['L_SQL_OPENFILE_BUTTON']="Envoyer";
-$lang['L_MAX_UPLOAD_SIZE']="Taille maximale du fichier";
-$lang['L_SQL_SEARCH']="Rechercher";
-$lang['L_SQL_SEARCHWORDS']="rechercher le(s) mot(s)";
-$lang['L_START_SQL_SEARCH']="Commencer la recherche";
-$lang['L_RESET_SEARCHWORDS']="Purge des critères de recherche";
-$lang['L_SEARCH_OPTIONS']="Options de recherches";
-$lang['L_SEARCH_RESULTS']="La recherche pour \"<b>%s</b>\" dans la table \"<b>%s</b>\" a donné les résultats suivants.";
-$lang['L_SEARCH_NO_RESULTS']="Aucun résultat pour la recherche de \"<b>%s</b>\" dans la table \"<b>%s</b>\" !";
-$lang['L_NO_ENTRIES']="La table \"<b>%s</b>\" est vide ou ne contient aucune entrée.";
-$lang['L_SEARCH_ACCESS_KEYS']="Parcourir:
-Vers l'avant:ALT+V,
-Vers l'arrière:ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="une colonne doit contenir au moins un critère de recherche
-(OU-Recherche)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="une ligne doit contenir tous les critères de recherche, mais ceux-ci peuvent toutefois être indiqués dans n'importe quelle colonne (Peut prendre du temps de calcul !)";
-$lang['L_SEARCH_OPTIONS_AND']="une colonne doit contenir tous les critères de recherche (ET-Recherche)";
-$lang['L_SEARCH_IN_TABLE']="Rechercher dans la table";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Modifier la structure des tables";
-$lang['L_DEFAULT_CHARSET']="Jeux de caractères par défaut";
-$lang['L_TITLE_KEY_PRIMARY']="Clé primaire";
-$lang['L_TITLE_KEY_UNIQUE']="Clé unique";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Clé texte plein";
-$lang['L_TITLE_NOKEY']="Aucune clé";
-$lang['L_TITLE_SEARCH']="Rechercher";
-$lang['L_TITLE_MYSQL_HELP']="Documentation MySQL";
-$lang['L_TITLE_UPLOAD']="Envoyer un fichier SQL";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="Taille";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Requête';
+$lang['L_IMPORT_NOTABLE'] = "Aucune table n'a été sélectionné pour l'import!";
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = "L'exécution de requête SQL peut influencer les données. L'auteur dénie toute responsabilité pour des pertes de données.";
+$lang['L_SQL_EXEC'] = 'Exécuter la requête SQL';
+$lang['L_SQL_DATAVIEW'] = 'Aperçu données';
+$lang['L_SQL_TABLEVIEW'] = 'Aperçu des tables';
+$lang['L_SQL_VONINS'] = "d'un total de";
+$lang['L_SQL_NODATA'] = 'aucunes données';
+$lang['L_SQL_RECORDUPDATED'] = "L'enregistrement a été modifié";
+$lang['L_SQL_RECORDINSERTED'] = "L'enregistrement a été sauvegardé";
+$lang['L_SQL_BACKDBOVERVIEW'] = "retourner vers l'aperçu général des bases de données";
+$lang['L_SQL_RECORDDELETED'] = "L'enregistrement a été supprimé";
+$lang['L_ASKTABLEEMPTY'] = 'Voulez-vous vider la table `%s`?';
+$lang['L_SQL_RECORDEDIT'] = "Éditer l'enregistrement";
+$lang['L_SQL_RECORDNEW'] = 'Insérer un nouvel enregistrement ';
+$lang['L_ASKDELETERECORD'] = "Voulez-vous supprimer l'enregistrement?";
+$lang['L_ASKDELETETABLE'] = 'voulez-vous supprimer la table `%s`?';
+$lang['L_SQL_BEFEHLE'] = 'Requête SQL';
+$lang['L_SQL_BEFEHLNEU'] = 'nouvelle requête';
+$lang['L_SQL_BEFEHLSAVED1'] = 'Requête SQL';
+$lang['L_SQL_BEFEHLSAVED2'] = 'a été ajouté';
+$lang['L_SQL_BEFEHLSAVED3'] = 'a été sauvegardé';
+$lang['L_SQL_BEFEHLSAVED4'] = 'a été placé plus haut';
+$lang['L_SQL_BEFEHLSAVED5'] = 'a été supprimé';
+$lang['L_SQL_QUERYENTRY'] = "L'intérrogation contient";
+$lang['L_SQL_COLUMNS'] = 'colonnes';
+$lang['L_ASKDBDELETE'] = 'Voulez-vous vraiment supprimer la base de données `%s` avec son contenu?';
+$lang['L_ASKDBEMPTY'] = 'Voulez-vous vraiment vider la base de données  `%s`?';
+$lang['L_ASKDBCOPY'] = 'Voulez-vous copier le contenu de la base de données  `%s` dans la base de données  %s`?';
+$lang['L_SQL_TABLENEW'] = 'Éditer les tables';
+$lang['L_SQL_OUTPUT'] = 'Sortie SQL';
+$lang['L_DO_NOW'] = 'Exécuter maintenant';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Nom de la base de données manque!';
+$lang['L_ASKDELETEFIELD'] = 'Voulez-vous supprimer le champ?';
+$lang['L_SQL_COMMANDS_IN'] = ' Ligne a été travaillé en ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sec.';
+$lang['L_SQL_OUT1'] = 'Il y a eu ';
+$lang['L_SQL_OUT2'] = 'Requêtes exécutées';
+$lang['L_SQL_OUT3'] = 'Il y a eu ';
+$lang['L_SQL_OUT4'] = 'Commentaire';
+$lang['L_SQL_OUT5'] = 'Comme la sortie contient plus de 5000 lignes celles-ci ne sont pas affichées.';
+$lang['L_SQL_SELECDB'] = 'Sélectionner la base de données';
+$lang['L_SQL_TABLESOFDB'] = 'Tables de la base de données';
+$lang['L_SQL_EDIT'] = 'éditer';
+$lang['L_SQL_NOFIELDDELETE'] = 'Suppression impossible, car une table doit avoir au minimum 1 champ.';
+$lang['L_SQL_FIELDDELETE1'] = 'Le champ';
+$lang['L_SQL_DELETED'] = 'a été supprimé';
+$lang['L_SQL_CHANGED'] = 'a été modifié.';
+$lang['L_SQL_CREATED'] = 'a été créé.';
+$lang['L_SQL_NODEST_COPY'] = 'Sans destination on ne peut pas copier !';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'La table de destination existe déjà !';
+$lang['L_SQL_SCOPY'] = 'Structure de la table `%s` a été copié dans la table `%s`.';
+$lang['L_SQL_TCOPY'] = 'La table `%s` a été copié avec les données de la table `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'La table doit avoir un nom !';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Le nom de la table ne peut pas être vide !';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Police de caractères et triage ne sont pas compatibles !';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Erreur: Nom de champs invalidee';
+$lang['L_SQL_CREATETABLE'] = 'créer table';
+$lang['L_SQL_COPYTABLE'] = 'copier table';
+$lang['L_SQL_STRUCTUREONLY'] = 'seulement la structure';
+$lang['L_SQL_STRUCTUREDATA'] = 'Structure et données';
+$lang['L_SQL_NOTABLESINDB'] = "Il n'y a pas de table dans la base de données";
+$lang['L_SQL_SELECTTABLE'] = 'Sélectionner la table';
+$lang['L_SQL_SHOWDATATABLE'] = 'Montrer les données dans la table';
+$lang['L_SQL_TBLPROPSOF'] = 'Propriétés de la table';
+$lang['L_SQL_EDITFIELD'] = 'Éditer champs';
+$lang['L_SQL_NEWFIELD'] = 'Nouveau champ';
+$lang['L_SQL_INDEXES'] = 'Indices';
+$lang['L_SQL_ATPOSITION'] = 'créer à la position';
+$lang['L_SQL_FIRST'] = 'en premier';
+$lang['L_SQL_AFTER'] = 'après';
+$lang['L_SQL_CHANGEFIELD'] = 'Changer les champs';
+$lang['L_SQL_INSERTFIELD'] = 'Créer champs';
+$lang['L_SQL_INSERTNEWFIELD'] = 'créer nouveau champs';
+$lang['L_SQL_TABLEINDEXES'] = 'Indices de la table';
+$lang['L_SQL_ALLOWDUPS'] = 'Permettre la duplication';
+$lang['L_SQL_CARDINALITY'] = 'Cardinalité';
+$lang['L_SQL_TABLENOINDEXES'] = 'La table ne contient aucun indice';
+$lang['L_SQL_CREATEINDEX'] = 'créer nouveau index';
+$lang['L_SQL_WASEMPTIED'] = 'a été vidé';
+$lang['L_SQL_RENAMEDTO'] = 'a été renommé par';
+$lang['L_SQL_DBCOPY'] = 'Le contenue de la base de données `%s` a été copié dans la base de données `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'La structure de la  base de données `%s` a été copié dans la base de données `%s`.';
+$lang['L_SQL_WASCREATED'] = 'a été créé';
+$lang['L_SQL_RENAMEDB'] = 'Renommer la base de données';
+$lang['L_SQL_ACTIONS'] = 'Actions';
+$lang['L_SQL_CHOOSEACTION'] = "Sélectionner l'action";
+$lang['L_SQL_DELETEDB'] = 'Supprimer la base de données';
+$lang['L_SQL_EMPTYDB'] = 'Vider la base de données';
+$lang['L_SQL_COPYDATADB'] = 'Copier le contenu dans la base de données';
+$lang['L_SQL_COPYSDB'] = 'Copier la structure dans la base de données';
+$lang['L_SQL_IMEXPORT'] = 'Import/Export';
+$lang['L_INFO_RECORDS'] = 'Enregistrements';
+$lang['L_NAME'] = 'Nom';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Voulez-vous vider la table `%s` et remettre les indices?';
+$lang['L_EDIT'] = 'éditer';
+$lang['L_DELETE'] = 'supprimer';
+$lang['L_EMPTY'] = 'vider';
+$lang['L_EMPTYKEYS'] = 'vider et remettre les indices';
+$lang['L_SQL_TABLEEMPTIED'] = 'Table `%s` a été vidée.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Table `%s` a été vidée et les indices ont été remis.';
+$lang['L_SQL_LIBRARY'] = 'Bibliothèque SQL';
+$lang['L_SQL_ATTRIBUTES'] = 'Attributs';
+$lang['L_SQL_UPLOADEDFILE'] = 'Fichier chargé: ';
+$lang['L_SQL_IMPORT'] = 'Import dans la base de données `%s`';
+$lang['L_EXPORT'] = 'Export';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = "Options d'import";
+$lang['L_CSVOPTIONS'] = 'Options CSV';
+$lang['L_IMPORTTABLE'] = 'Import dans la table';
+$lang['L_NEWTABLE'] = 'nouvelle table';
+$lang['L_IMPORTSOURCE'] = "Source d'import";
+$lang['L_FROMTEXTBOX'] = 'de la zone de texte';
+$lang['L_FROMFILE'] = 'du fichier';
+$lang['L_EMPTYTABLEBEFORE'] = 'Vider avant les tables';
+$lang['L_CREATEAUTOINDEX'] = 'Créer index automatique';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Nom du champ dans la première ligne';
+$lang['L_CSV_FIELDSEPERATE'] = 'Séparer les champs avec';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Inclure les champs avec';
+$lang['L_CSV_FIELDSESCAPE'] = "Champs d'échappement";
+$lang['L_CSV_EOL'] = 'Ligne séparée avec';
+$lang['L_CSV_NULL'] = 'Remplace ZÉRO par';
+$lang['L_CSV_FILEOPEN'] = 'Ouvrir fichier CSV';
+$lang['L_IMPORTIEREN'] = 'importer';
+$lang['L_SQL_EXPORT'] = 'Export de la base de données `%s`';
+$lang['L_EXPORTOPTIONS'] = "Options d'export";
+$lang['L_EXCEL2003'] = "à partir d'Excel 2003";
+$lang['L_SHOWRESULT'] = 'Montrer le résultat';
+$lang['L_SENDRESULTASFILE'] = 'Envoyer le résultat comme fichier';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> lignes exportées';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Le nombre de tables ne correspondent pas au nombre de données à importer (%d à la place de %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d champs calculer, en tout %d lignes';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Erreur lors de la création de la table `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Veuillez entrer un fichier.';
+$lang['L_CSV_NODATA'] = 'Aucun fichier à importer a été trouvé!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'Fonctions générales';
+$lang['L_SQLLIB_RESETAUTO'] = 'Remettre valeur par défaut';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'Désactiver Board';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'Activer Board';
+$lang['L_SQL_NOTABLESSELECTED'] = "Aucune table n'est sélectionnée !";
+$lang['L_TOOLS'] = 'Outils';
+$lang['L_TOOLS_TOOLBOX'] = 'Sélectionner la base de données / Fonctions de la base de données / Import et export';
+$lang['L_SQL_OPENFILE'] = 'Ouvrir le fichier SQL';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Envoyer';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Taille maximale du fichier';
+$lang['L_SQL_SEARCH'] = 'Rechercher';
+$lang['L_SQL_SEARCHWORDS'] = 'rechercher le(s) mot(s)';
+$lang['L_START_SQL_SEARCH'] = 'Commencer la recherche';
+$lang['L_RESET_SEARCHWORDS'] = 'Purge des critères de recherche';
+$lang['L_SEARCH_OPTIONS'] = 'Options de recherches';
+$lang['L_SEARCH_RESULTS'] = 'La recherche pour "<b>%s</b>" dans la table "<b>%s</b>" a donné les résultats suivants.';
+$lang['L_SEARCH_NO_RESULTS'] = 'Aucun résultat pour la recherche de "<b>%s</b>" dans la table "<b>%s</b>" !';
+$lang['L_NO_ENTRIES'] = 'La table "<b>%s</b>" est vide ou ne contient aucune entrée.';
+$lang['L_SEARCH_ACCESS_KEYS'] = "Parcourir: Vers l'avant:ALT+V, Vers l'arrière:ALT+C";
+$lang['L_SEARCH_OPTIONS_OR'] = 'une colonne doit contenir au moins un critère de recherche (OU-Recherche)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = "une ligne doit contenir tous les critères de recherche, mais ceux-ci peuvent toutefois être indiqués dans n'importe quelle colonne (Peut prendre du temps de calcul !)";
+$lang['L_SEARCH_OPTIONS_AND'] = 'une colonne doit contenir tous les critères de recherche (ET-Recherche)';
+$lang['L_SEARCH_IN_TABLE'] = 'Rechercher dans la table';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Modifier la structure des tables';
+$lang['L_DEFAULT_CHARSET'] = 'Jeux de caractères par défaut';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Clé primaire';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Clé unique';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Clé texte plein';
+$lang['L_TITLE_NOKEY'] = 'Aucune clé';
+$lang['L_TITLE_SEARCH'] = 'Rechercher';
+$lang['L_TITLE_MYSQL_HELP'] = 'Documentation MySQL';
+$lang['L_TITLE_UPLOAD'] = 'Envoyer un fichier SQL';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'Taille';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/it/help.html b/msd/language/it/help.html
new file mode 100644
index 00000000..3483501a
--- /dev/null
+++ b/msd/language/it/help.html
@@ -0,0 +1,149 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> basato su MySQLDumper 1.24.4</h3>
+
+<h3>Su questo progetto</h3>
+<p><strong>MyOOS [Dumper]</strong> è una versione migliorata di MySQLDumper 1.24.4 (24 gennaio 2011). Questo ulteriore sviluppo tiene conto dello sviluppo di PHP.
+<p>MyOOS [Dumper]</strong> si occupa principalmente di stabilità, sicurezza e gestione. Ma è anche incluso un modello attraente, che può essere modificato e adattato alle proprie esigenze.</p>
+
+
+<p><strong>MyOOS [Dumper]</strong> è un programma di backup per database MySQL, scritto in PHP e Perl. Con esso, le copie di backup dei dati (negozio, blog, ecc.) possono essere create e anche ripristinate se necessario. Specialmente per gli spazi web senza accesso alla shell, MyOOS [Dumper] si offre come un'alternativa sensata.</p> 
+
+<p>L'idea di MySQLDumper è venuta a Daniel Schlichtholz. Ha aperto il forum MySQLDumper nel 2004, dove i programmatori hanno scritto nuovi script ed esteso quelli esistenti.</p>
+
+
+
+<h3>Lista dei desideri / Attrazioni future</h3>.
+<p>Hai qualche suggerimento per migliorare? Sentitevi liberi di contattare il team di sviluppo tramite il forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribuire</h3>
+<p>Se vuoi aiutarci a migliorare il progetto MyOOS, accogliamo le tue richieste di pull via GitHub qui.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Sostegno finanziario</h3>
+<p>Puoi usare PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>o tramite il codice QR<br>.  
+<img src="images/qrcode.png" alt="Supporto finanziario per MyOOS [Dumper]"></p>
+
+Invia denaro al progetto MyOOS. <br>
+
+<p>Speriamo che questo progetto ti piaccia.<br><p><h4>La squadra di MyOOS [Dumper]</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>Aiuto di MyOOS [Dumper]</h3>
+
+<h4>Scaricare</h4>
+<p>Puoi sempre ottenere le ultime versioni da GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>Requisiti di sistema</h4>
+<p>Lo script funziona su qualsiasi server (Windows, Linux, ...) <br>
+con PHP >= versione 7.4 con supporto GZip, MySQL (versione 4.1 o superiore), JavaScript (deve essere abilitato).</p>
+<p>Copia la cartella mod dall'archivio MyOOS in una cartella di lavoro separata.</p>
+
+<h4>Installazione</h4></a>
+L'installazione è semplice.
+<p>Dall'archivio MyOOS, copiate la cartella mod in qualsiasi cartella.<br>
+Carica tutti i file dalla cartella mod al tuo server web. (per esempio al livello più basso in [directory web del server/]mod)<br>.
+... fatto!<br>
+Ora puoi richiamare MyOOS [Dumper] nel tuo browser web andando su "https://example.com/mod/"<br>.
+per completare l'installazione. Basta seguire le istruzioni.
+<br><b>Nota:</b><br><i>Se sul tuo server lo script non è autorizzato a creare directory,<br>
+dovrai farlo manualmente, poiché MyOOS [Dumper] memorizza i dati in directory.
+directory.<br> 
+Lo script termina con una dichiarazione appropriata!
+Dopo aver creato le directory (secondo il suggerimento), funziona normalmente e senza restrizioni.
+
+<a name="perl"></a><h4>Istruzioni per lo script Perl</h4>.
+La maggior parte ha una directory cgi-bin dove il perl può essere eseguito. <br>
+Questo è di solito accessibile dal browser tramite http://www.example.com/cgi-bin/. <br>
+<br>
+In questo caso, eseguite i seguenti passi:<br><br> 1.
+
+1. richiamare la pagina del Backup in MyOOS [Dumper] e cliccare su "Backup Perl". <br>
+2. copiare il percorso dietro la voce in crondump.pl per $absolute_path_of_configdir:. <br>
+3. aprire il file "crondump.pl" nell'editor.<br>
+4. inserire il percorso copiato lì a absolute_path_of_configdir (senza spazi).<br>
+5. salvare crondump.pl.<br>
+Copia crondump.pl, perltest.pl e simpletest.pl nella directory cgi-bin (modalità ascii in FTP).
+7. dare ai file i permessi 755. <br>
+7b. Se si desidera il finale cgi, cambiare il finale di tutti e 3 i file da pl -> cgi (rinominare). <br>
+Richiamate la configurazione in MyOOS [Dumper].
+9. selezionare la pagina Cronscript. <br>
+10. cambiare il percorso di esecuzione di Perl in /cgi-bin/ .<br>
+10b. Se gli script hanno .pl, cambia l'estensione del file in .cgi .<br>
+11. salvare la configurazione. <br><br>
+
+Fatto, gli script possono ora essere chiamati dalla pagina di backup.<br><br>
+
+Per coloro che possono eseguire Perl in tutte le directory, i seguenti passi sono sufficienti:<br><br> 1.
+
+1. richiamare la pagina Backup in MyOOS [Dumper]. <br>
+Copiare il percorso dietro la voce in crondump.pl per $absolute_path_of_configdir:. <br>
+Aprite il file "crondump.pl" nell'editor. <br>
+4. inserire il percorso copiato lì a absolute_path_of_configdir (senza spazi). <br>
+5. salvare crondump.pl .<br>
+6. Date ai file i permessi 755. <br>
+6b. Se si desidera il finale cgi, cambiare il finale di tutti e 3 i file da pl -> cgi (rinominare). <br>
+(ev. 10b+11 da sopra)<br>
+<br>
+
+Gli utenti di Windows devono cambiare la prima riga di tutti gli script, c'è il percorso di Perl. Esempio: <br>
+invece di: #!/usr/bin/perl -w <br>
+ora: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operazione</h4><ul>
+
+<h6>Menu</h6>.
+Nell'elenco di selezione di cui sopra si imposta il database.<br>
+Tutte le azioni si riferiscono al database impostato qui.
+
+<h6>Casa</h6>
+Qui puoi trovare informazioni sul tuo sistema, le varie versioni installate e i dettagli dei database configurati.
+versioni installate e dettagli sui database configurati.<br>
+Se cliccate sul nome del database, vedrete un elenco delle tabelle con il numero di voci
+con il numero di voci, la dimensione e la data dell'ultimo aggiornamento.
+
+<h6>Configurazione</h6>
+Qui puoi modificare la tua configurazione, salvarla o ripristinare la configurazione iniziale.
+ripristinare la configurazione iniziale.
+<ul><br>
+	<li><a name="conf1"></a><strong>Basi di dati configurate:</strong> la lista delle basi di dati configurate. Il database attivo è elencato in <b>grigio</b>. </li>
+	<li><a name="conf2"></a><strong>Table Prefix:</strong> qui puoi specificare un prefisso (per ogni database). Questo è un filtro che considera solo le tabelle che iniziano con questo prefisso quando si fa il dumping (ad esempio tutte le tabelle che iniziano con "phpBB_"). Se vuoi che tutte le tabelle di questo database siano salvate, lascia semplicemente il campo vuoto.
+	<li><a name="conf3"></a><strong>compressione GZip:</strong> Qui puoi attivare la compressione. Si raccomanda di attivarlo, perché i file diventano molto più piccoli e lo spazio di archiviazione è sempre scarso.
+	<li><a name="conf5"></a><strong>Email con file di dump:</strong> Se questa opzione è attivata, un'email con il dump come allegato viene inviata dopo che il backup è stato completato (attenzione, la compressione dovrebbe essere assolutamente attiva, altrimenti l'allegato sarà troppo grande e potrebbe non essere inviato!)
+	<li><a name="conf6"></a><strong>Indirizzo e-mail:</strong> Indirizzo del destinatario dell'e-mail.
+	<li><a name="conf7"></a><strong>Mittente dell'email:</strong> questo indirizzo appare come mittente nell'email.</li>
+	<li><a name="conf13"></a><strong>Trasferimento FTP: </strong>Se questa opzione è attivata, il file di backup sarà inviato via FTP dopo che il backup è stato completato.</li>
+	<li><a name="conf14"></a><strong>ServerFTP: </strong>L'indirizzo del server FTP (es. ftp.mybackups.de).</li>
+	<li><a name="conf15"></a><strong>Porta del server FTP: </strong>La porta del server FTP (di solito 21).</li>
+	<li><a name="conf16"></a><strong>Utente FTP: </strong>Il nome utente dell'account FTP. </li>
+	<li><a name="conf17"></a><strong>Password FTP: </strong>La password dell'account FTP. </li>
+	<li><a name="conf18"></a><strong>Cartella di caricamentoFTP: </strong>La directory dove il file di backup dovrebbe andare (i permessi di caricamento devono esistere!).</li>
+	<li><a name="conf8"></a><strong>Eliminazione automatica dei backup:</strong> Se questa opzione è attivata, i vecchi backup saranno eliminati automaticamente secondo le seguenti regole.</li>
+	<li><a name="conf10"></a><strong>Numero di file di backup:</strong> Un valore > 0 cancella tutti i file di backup tranne il numero specificato qui.</li>
+	<li><a name="conf11"></a><strong>Lingua:</strong> qui si imposta la lingua per l'interfaccia.</li>
+</ul>
+
+<h6>Amministrazione</h6>
+Qui è dove vengono eseguite le azioni effettive.<br>
+Vengono visualizzati tutti i file nella directory di backup.
+Per le azioni "Restore" e "Delete" deve essere selezionato un file.
+<UL>
+	<li><strong>Ripristino:</strong> Questo aggiorna il database con il file di backup selezionato.</li>
+	<li><strong>Elimina:</strong> Questo ti permette di eliminare il file di backup selezionato.</li>
+	<li><strong>Avvia nuovo backup:</strong> Qui si avvia un nuovo backup (dump) secondo i parametri impostati nella configurazione.
+</UL>
+
+<h6>Log</h6>
+Qui potete vedere e cancellare le voci di registro.
+<h6>Crediti / Aiuto</h6>
+questa pagina.
+</ul>
+
+Tradotto con www.DeepL.com/Translator (versione gratuita)
\ No newline at end of file
diff --git a/msd/language/it/help.php b/msd/language/it/help.php
deleted file mode 100644
index bd867c04..00000000
--- a/msd/language/it/help.php
+++ /dev/null
@@ -1,126 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Riguarda questo progetto</h3>
-L'idea di questo progetto viene da Daniel Schlichtholz.<p>
-Nel 2004 ha aperto il seguente forum <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a>
-<br>
-in seguito ha incontrato dei programmatori liberi professionisti che elaboravano nuovi script e completavano quelli di Daniel.<br>
-In brevissimo tempo nasceva da un piccolo backupscript un considerevolo progetto.<br>
-
-<p>Se hai proposte di miglioramento rivolgiti al MySQLDumper-Forum: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>
-<p>Ti auguriamo buon divertimento con questo progetto.<br><p><h4>Il Team di MySQLDumper</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" 
-width="160" height="42" border="1"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
-
-<h3> MySQLDumper Aiuto</h3>
-
-<h4>Scarica</h4>
-Da questo script ottenete la homepage di MySQLDumper.<br>
-Si raccomanda di visitate frequentemente la homepage per ottenere sempre le ultime informazioni, aggiornamenti ed aiuto.<br>
-L'indirizzo è <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de
-</a>
-
-<h4>Presupposto del sistema</h4>
-Lo script lavora su tutti i server (Windows, Linux,…)<br>
-e PHP versione >= 4.3.4 con assistenza GZip, MySQL (>= 3.23), 
-
-Javascript (deve essere attivato).<br> 
-
-<a href="install.php?language=de" target="_top"><h4>Installazione</h4></a>
-L'installazione è molto facile. Spacchettate l'archivio in una cartella a vostra scelta e caricatela sul vostro spazio web provider (server).<br>
-(per esempio  [rootdir/] MySQLDumper )<br>
-…fatto!<br>
-
-Adesso potete aprire MySQLDumper nel vostro Browser “chiamando http://webserver/MySQLDumper„ in seguito potete finire la installazione seguendo gli avvisi di istruzione.<br>
-<br><b>Nota:</b><br><i>Se il vostro web server funziona con il safemode=ON, gli script del MySqlDump non possono costruire gli elenchi.<br>
-Lo dovete fare manualmente, poichè MySqlDump mette i dati in ordine negli elenchi.<br>
-Lo script si ferma automaticamente con una adeguata istruzione.<br>
-Quando avete effettuato le indicazioni con le adeguate istruzioni.<br> 
-MySqlDump funzionerà normalmente.</i>
-
-<a name="perl"></a><h4> Istruzioni Perlskript </h4>
-Molti hanno un elenco con cartella cgi-bin in cui puo essere efettuato Perl. <br>
-A maggior parte dei casi questo e raggingibile tramite Browser http://www.domain.de/cgi-bin/. <br>
-<br>
-In questo caso consigliamo di effettuare i seguenti passi:<br>
-<br>
-1. Chiama nel MySQLDumper la pagina Backup e clicca "Backup Perl". <br>
-2. Copia il percorso, che è scritto nella crondump.pl per $absolute_path_of_configdir: <br>
-3. Apri il dato "crondump.pl" in editor <br>
-4. Porta il percorso dove c`è absolute_path_of_configdir (senza spazi) <br>
-5. Salva crondump.pl <br>
-6. Copia crondump.pl, perltest.pl e simpletest.pl nel elenco cgi-bin (nel modo Ascii con FTP) <br>
-7. Metti i permessi dei dati in CHMOD 755 <br>
-7b. Se preferite cgi come nome del dato, allora cambiate tutti i 3 dati da pl -> cgi (rinominare) <br>
-8. Chiama la configurazione nel MySQLDumper <br>
-9. Scegli la pagina Cronscript <br>
-10. Cambia l`esecuzione del percorso di Perl in /cgi-bin/ <br>
-10b. Se gli script hanno .pl, cambiali in .cgi <br>
-11. Salva la configurazione. <br>
-<br>
-Hai finito, i tuoi script si fanno caricare nella tua pagina backup.<br>
-<br>
-Chi puo usare Perl in tutti gli elenchi deve seguire semplicemente i seguenti passi:<br>
-<br>
-1. Chiama nel MySQLDumper la pagina Backup. <br>
-2. Copia il percorso, che è scritto nella crondump.pl per $absolute_path_of_configdir. <br>
-3. Apri il dato "crondump.pl" in editor <br>
-4. Porta il percorso dove c`è absolute_path_of_configdir (senza spazi) <br>
-5. Salva crondump.pl <br>
-6. Metti i permessi dei dati a CHMOD 755 <br>
-6b. Se preferite cgi, cambiate tutti i 3 dati da pl -> cgi (rinominare) <br>
-(ev. 10b+11 da sopra)<br>
-<br>
-Se usate Windows dovete cambiare in tutti i dati la prima riga;dove trovate il percorso di Perl. Esempio: <br>
-aposto di: #!/usr/bin/perl -w <br>
-adesso #!C:\perl\bin\perl.exe -w <br>
-
-<h4>Come si usa</h4><ul>
-
-<h6>Menu</h6>
-Nella lista di sopra configurate la banca dati.<br>
-Tutte le azioni seguono la configurazione fatta nella banca dati.<br>
-
-<h6>Pagina iniziale</h6>
-Qui potete sapere qualcosa sul vostro sistema, installazioni diverseversioni e dettagli sulla configurazione delle banche dati.<br>
-Quando selezionate il nome della banca dati vedete una lista delle tabelle specificato in quantità,grandezza e l`ultima data di aggiornamento.<br>
-
-<h6>Configurazione</h6>
-Qui potete elaborare, salvare o ripristinare la vostra configurazione.
-<ul><br>
-	<li><a name="conf1"></a><strong>Banca dati configurata:</strong> la lista delle banche dati configurati. La banca dati attiva viene visualizata in <b>bold</b>. </li>
-	<li><a name="conf2"></a><strong>Prefix-tabelle:</strong> qui potete (per ogni banca dati) mettere un prefix.Questo è un filtro che nel Dumps viene considerato solo nelle tabelle con il prefix (esempio: tutte le tabelle che cominciano con "phpBB_" ). Se volete salvare tutta la banca dati lasciate libera questa casella.</li>
-	<li><a name="conf3"></a><strong>compressione-GZip:</strong> Qui potete selezionare la compressione. È consigliato selezionare questa opzione, perche cosi i dati vengono ristretti per risparmiare spazio sul disco rigido .</li>
-	<li><a name="conf5"></a><strong>Email con Dumpfile:</strong> Se avete selezionato questa opzione viene spedita una e-mail con allegato dopo il backup(attenzione, la compressione in questo caso e consigliata, altrimenti la e-mail non potrebbe essere spedita!)</li>
-	<li><a name="conf6"></a><strong>Indrizzo-e-mail:</strong> Mittente della e-mail</li>
-	<li><a name="conf7"></a><strong>Destinatario della e-mail:</strong> questo indrizzo e visibile nella e-mail come destinatario</li>
-	<li><a name="conf13"></a><strong>FTP-Transfer: </strong>Se è selezionata questa opzione, al termine del backup viene spedito il dato tramite FTP.</li>
-	<li><a name="conf14"></a><strong>FTP Server: </strong>l`indirizzo del server-FTP (esempio: ftp.mybackups.it)</li>
-	<li><a name="conf15"></a><strong>FTP Server Port: </strong>la porta del FTP-server (in regola 21)</li>
-	<li><a name="conf16"></a><strong>FTP User: </strong>nome del conto-FTP in uso  </li>
-	<li><a name="conf17"></a><strong>FTP parola d`ordine (password): </strong>La parola d`ordine del conto FTP </li>
-	<li><a name="conf18"></a><strong>FTP cartella - upload: </strong>l`elenco in cui viene spedito il dato del backup (dovete avere il permesso per scaricare (upload)!)</li>
-	<li><a name="conf8"></a><strong>Cancellare automaticamente i backups:</strong> 
-Quando è selezionata questa opzione vengono cancellati automaticamente i backups piu vecchi..</li>
-	<li><a name="conf10"></a><strong>Quantità dei dati backup:</strong> Un valore  > 0 cancella tutti i backup, fino al valore selezionato</li>
-	<li><a name="conf11"></a><strong>Lingua:</strong> qui scegli la lingua per l`interfaccia.</li>
-</ul>
-
-<h6>Amministrazione</h6>
-qui vengono efettuate le vostre azioni.<br>
-Ti vengono mostrati tutti i dati nell` elenco backup. Per le azioni "Restore" e "Delete" deve essere selezionato un dato.<br>
-<UL>
-	<li><strong>Restore:</strong> la banca dati viene aggiornata con il backup scelto.</strong></li>
-	<li><strong>Delete:</strong> cancellare il backup selezionato.</strong></li>
-	<li><strong>Partenza nuovo backup:</strong> qui fai partire un nuovo backup (Dump) secondo</strong> </li>
-         <li>i parametri della tua configurazione.</li>
-</UL>
-
-<h6>Log</h6>
-Qui puoi vedere e cancellare i log (connessioni effettuati).<br>
-
-<h6>Credito / Auito</h6>
-questa pagina
\ No newline at end of file
diff --git a/msd/language/it/lang.php b/msd/language/it/lang.php
index 72185c03..3f08d002 100644
--- a/msd/language/it/lang.php
+++ b/msd/language/it/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="sì";
-$lang['L_TO']="fino a";
-$lang['L_ACTIVATED']="attivato";
-$lang['L_NOT_ACTIVATED']="non attivato";
-$lang['L_ERROR']="Errore";
-$lang['L_OF']=" di ";
-$lang['L_ADDED']="aggiunto";
-$lang['L_DB']="Database";
-$lang['L_DBS']="Database";
-$lang['L_TABLES']="Tabelle";
-$lang['L_TABLE']="Tabella";
-$lang['L_RECORDS']="Record";
-$lang['L_COMPRESSED']="compresso (gz)";
-$lang['L_NOTCOMPRESSED']="normale (non compresso)";
-$lang['L_GENERAL']="generale";
-$lang['L_COMMENT']="commento";
-$lang['L_FILESIZE']="Grandezza file";
-$lang['L_ALL']="tutti";
-$lang['L_NONE']="nessuno";
-$lang['L_WITH']=" con ";
-$lang['L_DIR']="Directory";
-$lang['L_RECHTE']="Diritti";
-$lang['L_STATUS']="Stato ";
-$lang['L_FINISHED']="terminato";
-$lang['L_FILE']="File";
-$lang['L_FIELDS']="campi";
-$lang['L_NEW']="nuovo";
-$lang['L_CHARSET']="Set di caratteri";
-$lang['L_COLLATION']="Ordinamento";
-$lang['L_CHANGE']="cambia";
-$lang['L_IN']="in";
-$lang['L_DO']="esegui";
-$lang['L_VIEW']="visualizza";
-$lang['L_EXISTING']="esistente";
-$lang['L_BACK']="indietro";
-$lang['L_DB_HOST']="Hostname del database";
-$lang['L_DB_USER']="User del database";
-$lang['L_DB_PASS']="Password del database";
-$lang['L_INFO_SCRIPTDIR']="Indice di MySQLDumper";
-$lang['L_INFO_ACTDB']="Database selezionato";
-$lang['L_WRONGCONNECTIONPARS']="Parametri di connessione assenti o errati!";
-$lang['L_CONN_NOT_POSSIBLE']="Collegamento non possibile !";
-$lang['L_SERVERCAPTION']="Visualizzazione del server";
-$lang['L_HELP_SERVERCAPTION']="Con l`uso di sistemi differenti potrebbe essere di aiuto visualizzare l'indirizzo del server in un altro colore ";
-$lang['L_ACTIVATE_MULTIDUMP']="Attiva multidump";
-$lang['L_SAVE']="Salva";
-$lang['L_RESET']="Resetta";
-$lang['L_PRAEFIX']="Prefissi tabella";
-$lang['L_AUTODELETE']="cancella backups automaticamente";
-$lang['L_MAX_BACKUP_FILES_EACH2']="per ogni database";
-$lang['L_SAVING_DB_FORM']="Database";
-$lang['L_TESTCONNECTION']="Verifica la connessione";
-$lang['L_BACK_TO_MINISQL']="Elaborare database";
-$lang['L_CREATE']="crea";
-$lang['L_VARIABELN']="Variabili";
-$lang['L_STATUSINFORMATIONEN']="Informazioni sullo stato";
-$lang['L_VERSIONSINFORMATIONEN']="Informazioni sulla versione";
-$lang['L_MSD_INFO']="Informazioni su MyOOS [Dumper]";
-$lang['L_BACKUPFILESANZAHL']="Nella directory dei backup ci sono";
-$lang['L_LASTBACKUP']="Ultimo backup";
-$lang['L_NOTAVAIL']="<em>non disponibile</em>";
-$lang['L_VOM']="dal";
-$lang['L_MYSQLVARS']="Variabili Mysql";
-$lang['L_MYSQLSYS']="Comandi Mysql";
-$lang['L_STATUS']="Stato";
-$lang['L_PROZESSE']="Processi";
-$lang['L_INFO_NOVARS']="nessuna variabile disponibile";
-$lang['L_INHALT']="Contenuto";
-$lang['L_INFO_NOSTATUS']="stato non disponibile";
-$lang['L_INFO_NOPROCESSES']="nessun processo in corso";
-$lang['L_FM_FREESPACE']="Memoria disponibile sul server";
-$lang['L_LOAD_DATABASE']="Ricarica database";
-$lang['L_HOME']="Pagina iniziale";
-$lang['L_CONFIG']="Configurazione";
-$lang['L_DUMP']="Backup";
-$lang['L_RESTORE']="Ripristina";
-$lang['L_FILE_MANAGE']="Amministrazione file";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Seleziona database";
-$lang['L_CREDITS']="Crediti/Aiuto";
-$lang['L_MULTI_PART']="Backup in più parti";
-$lang['L_LOGFILENOTWRITABLE']="Il logfile non può essere scritto!";
-$lang['L_SQL_ERROR1']="Errore nella richiesta:";
-$lang['L_SQL_ERROR2']="MySQL dice:";
-$lang['L_UNKNOWN']="sconosciuto";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="sconosciuto";
-$lang['L_OK']="OK.";
-$lang['L_CRON_COMPLETELOG']="Salvare tutte le operazioni";
-$lang['L_NO']="no";
-$lang['L_CREATE_DATABASE']="Crea nuovo database";
-$lang['L_EXPORTFINISHED']="Esportazione completata.";
-$lang['L_SQL_BROWSER']="SQL-Browser";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Codifica standard dei MySQL-Servers";
-$lang['L_TITLE_SHOW_DATA']="Visualizza dati";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Vuoi cancellare veramente la chiave primaria?";
-$lang['L_SETPRIMARYKEYSFOR']="Inserisci nuova chiave primaria per la tabella";
-$lang['L_PRIMARYKEY_FIELD']="Campo chiave primaria";
-$lang['L_PRIMARYKEYS_SAVE']="Salva chiave primaria";
-$lang['L_CANCEL']="Cancella";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Backups";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'sì';
+$lang['L_TO'] = 'fino a';
+$lang['L_ACTIVATED'] = 'attivato';
+$lang['L_NOT_ACTIVATED'] = 'non attivato';
+$lang['L_ERROR'] = 'Errore';
+$lang['L_OF'] = ' di ';
+$lang['L_ADDED'] = 'aggiunto';
+$lang['L_DB'] = 'Database';
+$lang['L_DBS'] = 'Database';
+$lang['L_TABLES'] = 'Tabelle';
+$lang['L_TABLE'] = 'Tabella';
+$lang['L_RECORDS'] = 'Record';
+$lang['L_COMPRESSED'] = 'compresso (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normale (non compresso)';
+$lang['L_COMMENT'] = 'commento';
+$lang['L_FILESIZE'] = 'Grandezza file';
+$lang['L_ALL'] = 'tutti';
+$lang['L_NONE'] = 'nessuno';
+$lang['L_WITH'] = ' con ';
+$lang['L_DIR'] = 'Directory';
+$lang['L_RECHTE'] = 'Diritti';
+$lang['L_STATUS'] = 'Stato ';
+$lang['L_FINISHED'] = 'terminato';
+$lang['L_FILE'] = 'File';
+$lang['L_FIELDS'] = 'campi';
+$lang['L_NEW'] = 'nuovo';
+$lang['L_CHARSET'] = 'Set di caratteri';
+$lang['L_COLLATION'] = 'Ordinamento';
+$lang['L_CHANGE'] = 'cambia';
+$lang['L_IN'] = 'in';
+$lang['L_DO'] = 'esegui';
+$lang['L_VIEW'] = 'visualizza';
+$lang['L_EXISTING'] = 'esistente';
+$lang['L_BACK'] = 'indietro';
+$lang['L_DB_HOST'] = 'Hostname del database';
+$lang['L_DB_USER'] = 'User del database';
+$lang['L_DB_PASS'] = 'Password del database';
+$lang['L_INFO_SCRIPTDIR'] = 'Indice di MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Database selezionato';
+$lang['L_WRONGCONNECTIONPARS'] = 'Parametri di connessione assenti o errati!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Collegamento non possibile !';
+$lang['L_SERVERCAPTION'] = 'Visualizzazione del server';
+$lang['L_HELP_SERVERCAPTION'] = "Con l`uso di sistemi differenti potrebbe essere di aiuto visualizzare l'indirizzo del server in un altro colore ";
+$lang['L_ACTIVATE_MULTIDUMP'] = 'Attiva multidump';
+$lang['L_SAVE'] = 'Salva';
+$lang['L_RESET'] = 'Resetta';
+$lang['L_PRAEFIX'] = 'Prefissi tabella';
+$lang['L_AUTODELETE'] = 'cancella backups automaticamente';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'per ogni database';
+$lang['L_SAVING_DB_FORM'] = 'Database';
+$lang['L_TESTCONNECTION'] = 'Verifica la connessione';
+$lang['L_BACK_TO_MINISQL'] = 'Elaborare database';
+$lang['L_CREATE'] = 'crea';
+$lang['L_VARIABELN'] = 'Variabili';
+$lang['L_STATUSINFORMATIONEN'] = 'Informazioni sullo stato';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Informazioni sulla versione';
+$lang['L_MOD_INFO'] = 'Informazioni su MyOOS [Dumper]';
+$lang['L_BACKUPFILESANZAHL'] = 'Nella directory dei backup ci sono';
+$lang['L_LASTBACKUP'] = 'Ultimo backup';
+$lang['L_NOTAVAIL'] = '<em>non disponibile</em>';
+$lang['L_VOM'] = 'dal';
+$lang['L_MYSQLVARS'] = 'Variabili Mysql';
+$lang['L_MYSQLSYS'] = 'Comandi Mysql';
+$lang['L_STATUS'] = 'Stato';
+$lang['L_PROZESSE'] = 'Processi';
+$lang['L_INFO_NOVARS'] = 'nessuna variabile disponibile';
+$lang['L_INHALT'] = 'Contenuto';
+$lang['L_INFO_NOSTATUS'] = 'stato non disponibile';
+$lang['L_INFO_NOPROCESSES'] = 'nessun processo in corso';
+$lang['L_FM_FREESPACE'] = 'Memoria disponibile sul server';
+$lang['L_LOAD_DATABASE'] = 'Ricarica database';
+$lang['L_HOME'] = 'Pagina iniziale';
+$lang['L_CONFIG'] = 'Configurazione';
+$lang['L_DUMP'] = 'Backup';
+$lang['L_RESTORE'] = 'Ripristina';
+$lang['L_FILE_MANAGE'] = 'Amministrazione file';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Seleziona database';
+$lang['L_CREDITS'] = 'Crediti/Aiuto';
+$lang['L_MULTI_PART'] = 'Backup in più parti';
+$lang['L_LOGFILENOTWRITABLE'] = 'Il logfile non può essere scritto!';
+$lang['L_SQL_ERROR1'] = 'Errore nella richiesta:';
+$lang['L_SQL_ERROR2'] = 'MySQL dice:';
+$lang['L_UNKNOWN'] = 'sconosciuto';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'sconosciuto';
+$lang['L_OK'] = 'OK.';
+$lang['L_CRON_COMPLETELOG'] = 'Salvare tutte le operazioni';
+$lang['L_NO'] = 'no';
+$lang['L_CREATE_DATABASE'] = 'Crea nuovo database';
+$lang['L_EXPORTFINISHED'] = 'Esportazione completata.';
+$lang['L_SQL_BROWSER'] = 'SQL-Browser';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Codifica standard dei MySQL-Servers';
+$lang['L_TITLE_SHOW_DATA'] = 'Visualizza dati';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Vuoi cancellare veramente la chiave primaria?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Inserisci nuova chiave primaria per la tabella';
+$lang['L_PRIMARYKEY_FIELD'] = 'Campo chiave primaria';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Salva chiave primaria';
+$lang['L_CANCEL'] = 'Cancella';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Backups';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/it/lang_config_overview.php b/msd/language/it/lang_config_overview.php
index 2db06794..a208047b 100644
--- a/msd/language/it/lang_config_overview.php
+++ b/msd/language/it/lang_config_overview.php
@@ -1,109 +1,126 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Configurazione";
-$lang['L_SAVE_SUCCESS']="La configurazione è stata salvata con successo nel file di configurazione \"%s\".";
-$lang['L_CONFIG_LOADED']="La configurazione \"%s\" è stata caricata con successo.";
-$lang['L_SAVE_ERROR']="Errore: impossibile salvare la configurazione.";
-$lang['L_CONFIG_EMAIL']="Notifica via e-email";
-$lang['L_CONFIG_AUTODELETE']="Cancellare in automatico";
-$lang['L_CONFIG_INTERFACE']="Interfaccia";
-$lang['L_MULTI_PART_GROESSE']="grandezza massima file";
-$lang['L_HELP_MULTIPART']="Se viene selezionata la partizione multipla (multipart), vengono creati diversi file per il backup che dipendono dalla grandezza inserita nella casella di sotto.";
-$lang['L_HELP_MULTIPARTGROESSE']="La grandezza massima per i singoli backup è inseribile solo se è selezionato partizione multipla (multipart). ";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Cancella database prima del ripristino";
-$lang['L_ALLPARS']="tutti i parametri";
-$lang['L_CRON_EXTENDER']="Estensione del file di script";
-$lang['L_CRON_SAVEPATH']="File di configurazione";
-$lang['L_CRON_PRINTOUT']="Visualizza i risultati";
-$lang['L_CONFIG_CRONPERL']="Configurazione Crondump per lo script Perl";
-$lang['L_CRON_MAILPRG']="Programma per le e-mail";
-$lang['L_OPTIMIZE']="Ottimizza tabelle prima del backup";
-$lang['L_HELP_OPTIMIZE']="Tutte le tabelle vengono ottimizzate prima del backup, se questa opzione è selezionata .";
-$lang['L_HELP_FTPTIMEOUT']="Il timeout per dichiarare fallita la connessione, Default 90 sec.";
-$lang['L_FTP_TIMEOUT']="Timeout Connessione FTP";
-$lang['L_HELP_FTPSSL']="Scegli se la connessione deve essere stabilita tramite SSL (connessione sicura).";
-$lang['L_CONFIG_ASKLOAD']="Sei sicuro di volere sovrascrivere la configurazione iniziale?";
-$lang['L_LOAD']="Carica config iniziale";
-$lang['L_LOAD_SUCCESS']="La configurazione iniziale è stata caricata.";
-$lang['L_CRON_CRONDBINDEX']="Banca dati";
-$lang['L_WITHATTACH']="con allegati";
-$lang['L_WITHOUTATTACH']="senza allegati";
-$lang['L_MULTIDUMPCONF']="=Configurazione Multidump =";
-$lang['L_MULTIDUMPALL']="=tutti i database=";
-$lang['L_GZIP']="Compressione GZip ";
-$lang['L_SEND_MAIL_FORM']="Spedisci e-mail";
-$lang['L_SEND_MAIL_DUMP']="Allega backup";
-$lang['L_EMAIL_ADRESS']="Destinatario dell'e-mail";
-$lang['L_EMAIL_SENDER']="Mittente dell'e-mail";
-$lang['L_EMAIL_MAXSIZE']="Grandezza massima dei allegati";
-$lang['L_NUMBER_OF_FILES_FORM']="Cancella secondo la quantità dei file di backup (i backup multipart NON sono intesi come un unico file)";
-$lang['L_LANGUAGE']="Lingua";
-$lang['L_LIST_DB']="Database configurati:";
-$lang['L_CONFIG_FTP']="Trasferimento dei file di backup via FTP";
-$lang['L_FTP_TRANSFER']="Trasferimento FTP";
-$lang['L_FTP_SERVER']="Server FTP";
-$lang['L_FTP_PORT']="Porta FTP";
-$lang['L_FTP_USER']="Utente FTP";
-$lang['L_FTP_PASS']="Password FTP";
-$lang['L_FTP_DIR']="Directory per il trasferimento FTP";
-$lang['L_FTP_SSL']="Connessione sicura SSL-FTP ";
-$lang['L_FTP_USESSL']="usa connessione SSL";
-$lang['L_SQLBOXHEIGHT']="Altezza del SQL-Box";
-$lang['L_SQLLIMIT']="Numero di record per pagina";
-$lang['L_BBPARAMS']="Configurazione per il BB-code";
-$lang['L_BBTEXTCOLOR']="Colore del testo";
-$lang['L_HELP_COMMANDS']="Puoi eseguire un comando prima di fare il backup. Può essere un comando SQL oppure di sistema (ad esempio: un script)";
-$lang['L_COMMAND']="Comando";
-$lang['L_WRONG_CONNECTIONPARS']="I parametri di connessione sono errati!";
-$lang['L_CONNECTIONPARS']="Parametri di connessione";
-$lang['L_EXTENDEDPARS']="Parametri estesi";
-$lang['L_FADE_IN_OUT']="visualizzare/nascondere";
-$lang['L_DB_BACKUPPARS']="Parametri database per il backup";
-$lang['L_GENERAL']="Generale";
-$lang['L_MAXSIZE']="grandezza massima";
-$lang['L_ERRORHANDLING_RESTORE']="Trattamento degli errori durante il ripristino dei dati";
-$lang['L_EHRESTORE_CONTINUE']="continuare e protocollare errori";
-$lang['L_EHRESTORE_STOP']="ferma";
-$lang['L_IN_MAINFRAME']="nel frame principale";
-$lang['L_IN_LEFTFRAME']="nel frame sinistro";
-$lang['L_WIDTH']="Larghezza";
-$lang['L_SQL_BEFEHLE']="Comando SQL";
-$lang['L_DOWNLOAD_LANGUAGES']="scaricare altre lingue";
-$lang['L_DOWNLOAD_STYLES']="scaricare altri temi";
-$lang['L_CONNECT_TO']="Connetti con";
-$lang['L_CHANGEDIR']="Cambia directory";
-$lang['L_CHANGEDIRERROR']="Impossibile cambiare directory!";
-$lang['L_FTP_OK']="La connessione è stata eseguita con successo.";
-$lang['L_INSTALL']="Installazione";
-$lang['L_NOFTPPOSSIBLE']="Non puoi utilizzare la funzione FTP!";
-$lang['L_FOUND_DB']="Database trovato";
-$lang['L_FTP_CHOOSE_MODE']="Modalità di trasferimento FTP";
-$lang['L_FTP_PASSIVE']="usa modalità passiva";
-$lang['L_HELP_FTP_MODE']="Scegli la modalità di trasferimento FTP. Se si verificano dei problemi con la modalità attiva prova con quella passiva.";
-$lang['L_DB_IN_LIST']="Il database '%s' non può essere aggiunto, perchè è già esistente. ";
-$lang['L_ADD_DB_MANUALLY']="Aggiungi database manualmente.";
-$lang['L_DB_MANUAL_ERROR']="Spiacente, la connessione con il database '%s' è fallita!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Errore sul file: non si può inserire il database '%s'!";
-$lang['L_NO_DB_FOUND']="Non sono stati trovati database. Inserisci i parametri di connessione e il nome del database manualmente! ";
-$lang['L_CONFIGFILES']="File di configurazione";
-$lang['L_CONFIGFILE']="File di configurazione";
-$lang['L_MYSQL_DATA']="Dati MySQL";
-$lang['L_CONFIGURATIONS']="Configurazioni";
-$lang['L_ACTION']="Azione";
-$lang['L_FTP_SEND_TO']="a <strong>%s</strong><br>in <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="Destinatario dell'e-mail in CC";
-$lang['L_NAME']="Nome";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Sicuro di voler cancellare il file di configurazione %s ?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Errore: il file di configurazione %s non può essere cancellato!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Il file di configurazione %s è stato cancellato con successo.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Il file di configurazione %s è stato creato con successo.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Il nome del file \"%s\" contiene dei caratteri non ammessi.";
-$lang['L_CREATE_CONFIGFILE']="Crea un nuovo file di configurazione ";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Il file di configurazione \"%s\" non può essere caricato.";
-$lang['L_BACKUP_DBS_PHP']="database di cui fare il backup (PHP)";
-$lang['L_BACKUP_DBS_PERL']="database di cui fare il backup (PERL)";
-$lang['L_CRON_COMMENT']="Inserisci commento";
-$lang['L_AUTODETECT']="riconoscimento automatico";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Configurazione';
+$lang['L_SAVE_SUCCESS'] = 'La configurazione è stata salvata con successo nel file di configurazione "%s".';
+$lang['L_CONFIG_LOADED'] = 'La configurazione "%s" è stata caricata con successo.';
+$lang['L_SAVE_ERROR'] = 'Errore: impossibile salvare la configurazione.';
+$lang['L_EMAIL_NOTIFICATION'] = 'Notifica via e-email';
+$lang['L_CONFIG_AUTODELETE'] = 'Cancellare in automatico';
+$lang['L_CONFIG_INTERFACE'] = 'Interfaccia';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'grandezza massima file';
+$lang['L_HELP_MULTIPART'] = 'Se viene selezionata la partizione multipla (multipart), vengono creati diversi file per il backup che dipendono dalla grandezza inserita nella casella di sotto.';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'La grandezza massima per i singoli backup è inseribile solo se è selezionato partizione multipla (multipart). ';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Cancella database prima del ripristino';
+$lang['L_ALLPARS'] = 'tutti i parametri';
+$lang['L_CRON_EXTENDER'] = 'Estensione del file di script';
+$lang['L_CRON_SAVEPATH'] = 'File di configurazione';
+$lang['L_CRON_PRINTOUT'] = 'Visualizza i risultati';
+$lang['L_CONFIG_CRONPERL'] = 'Configurazione Crondump per lo script Perl';
+$lang['L_CRON_MAILPRG'] = 'Programma per le e-mail';
+$lang['L_OPTIMIZE'] = 'Ottimizza tabelle prima del backup';
+$lang['L_HELP_OPTIMIZE'] = 'Tutte le tabelle vengono ottimizzate prima del backup, se questa opzione è selezionata .';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'Il timeout per dichiarare fallita la connessione, Default 90 sec.';
+$lang['L_FTP_TIMEOUT'] = 'Timeout Connessione FTP';
+$lang['L_HELP_FTPSSL'] = 'Scegli se la connessione deve essere stabilita tramite SSL (connessione sicura).';
+$lang['L_SFTP_TIMEOUT'] = 'Timeout Connessione FTP';
+$lang['L_HELP_SFTPSSL'] = 'Scegli se la connessione deve essere stabilita tramite SSL (connessione sicura).';
+$lang['L_CONFIG_ASKLOAD'] = 'Sei sicuro di volere sovrascrivere la configurazione iniziale?';
+$lang['L_LOAD'] = 'Carica config iniziale';
+$lang['L_LOAD_SUCCESS'] = 'La configurazione iniziale è stata caricata.';
+$lang['L_CRON_CRONDBINDEX'] = 'Banca dati';
+$lang['L_WITHATTACH'] = 'con allegati';
+$lang['L_WITHOUTATTACH'] = 'senza allegati';
+$lang['L_MULTIDUMPCONF'] = '=Configurazione Multidump =';
+$lang['L_MULTIDUMPALL'] = '=tutti i database=';
+$lang['L_GZIP'] = 'Compressione GZip ';
+$lang['L_SEND_MAIL_FORM'] = 'Spedisci e-mail';
+$lang['L_SEND_MAIL_DUMP'] = 'Allega backup';
+$lang['L_EMAIL_ADRESS'] = "Destinatario dell'e-mail";
+$lang['L_EMAIL_SENDER'] = "Mittente dell'e-mail";
+$lang['L_EMAIL_MAXSIZE'] = 'Grandezza massima dei allegati';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Cancella secondo la quantità dei file di backup (i backup multipart NON sono intesi come un unico file)';
+$lang['L_LANGUAGE'] = 'Lingua';
+$lang['L_LIST_DB'] = 'Database configurati:';
+$lang['L_CONFIG_FTP'] = 'Trasferimento dei file di backup via FTP';
+$lang['L_FTP_TRANSFER'] = 'Trasferimento FTP';
+$lang['L_FTP_SERVER'] = 'Server FTP';
+$lang['L_FTP_PORT'] = 'Porta FTP';
+$lang['L_FTP_USER'] = 'Utente FTP';
+$lang['L_FTP_PASS'] = 'Password FTP';
+$lang['L_FTP_DIR'] = 'Directory per il trasferimento FTP';
+$lang['L_FTP_SSL'] = 'Connessione sicura SSL-FTP ';
+$lang['L_FTP_USESSL'] = 'usa connessione SSL';
+$lang['L_CONFIG_SFTP'] = 'Trasferimento dei file di backup via SFTP';
+$lang['L_SFTP_TRANSFER'] = 'Trasferimento SFTP';
+$lang['L_SFTP_SERVER'] = 'Server SFTP';
+$lang['L_SFTP_PORT'] = 'Porta SFTP';
+$lang['L_SFTP_USER'] = 'Utente SFTP';
+$lang['L_SFTP_PASS'] = 'Password SFTP';
+$lang['L_SFTP_DIR'] = 'Directory per il trasferimento SFTP';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Altezza del SQL-Box';
+$lang['L_SQLLIMIT'] = 'Numero di record per pagina';
+$lang['L_BBPARAMS'] = 'Configurazione per il BB-code';
+$lang['L_BBTEXTCOLOR'] = 'Colore del testo';
+$lang['L_HELP_COMMANDS'] = 'Puoi eseguire un comando prima di fare il backup. Può essere un comando SQL oppure di sistema (ad esempio: un script)';
+$lang['L_COMMAND'] = 'Comando';
+$lang['L_WRONG_CONNECTIONPARS'] = 'I parametri di connessione sono errati!';
+$lang['L_CONNECTIONPARS'] = 'Parametri di connessione';
+$lang['L_EXTENDEDPARS'] = 'Parametri estesi';
+$lang['L_FADE_IN_OUT'] = 'visualizzare/nascondere';
+$lang['L_DB_BACKUPPARS'] = 'Parametri database per il backup';
+$lang['L_GENERAL'] = 'Generale';
+$lang['L_MAXSIZE'] = 'grandezza massima';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Trattamento degli errori durante il ripristino dei dati';
+$lang['L_EHRESTORE_CONTINUE'] = 'continuare e protocollare errori';
+$lang['L_EHRESTORE_STOP'] = 'ferma';
+$lang['L_IN_MAINFRAME'] = 'nel frame principale';
+$lang['L_IN_LEFTFRAME'] = 'nel frame sinistro';
+$lang['L_WIDTH'] = 'Larghezza';
+$lang['L_SQL_BEFEHLE'] = 'Comando SQL';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'scaricare altre lingue';
+$lang['L_DOWNLOAD_STYLES'] = 'scaricare altri temi';
+$lang['L_CONNECT_TO'] = 'Connetti con';
+$lang['L_CHANGEDIR'] = 'Cambia directory';
+$lang['L_CHANGEDIRERROR'] = 'Impossibile cambiare directory!';
+$lang['L_FTP_OK'] = 'La connessione è stata eseguita con successo.';
+$lang['L_INSTALL'] = 'Installazione';
+$lang['L_NOFTPPOSSIBLE'] = 'Non puoi utilizzare la funzione FTP!';
+$lang['L_FOUND_DB'] = 'Database trovato';
+$lang['L_FTP_CHOOSE_MODE'] = 'Modalità di trasferimento FTP';
+$lang['L_FTP_PASSIVE'] = 'usa modalità passiva';
+$lang['L_HELP_FTP_MODE'] = 'Scegli la modalità di trasferimento FTP. Se si verificano dei problemi con la modalità attiva prova con quella passiva.';
+$lang['L_SFTP_PASSIVE'] = 'usa modalità passiva';
+$lang['L_DB_IN_LIST'] = "Il database '%s' non può essere aggiunto, perchè è già esistente. ";
+$lang['L_ADD_DB_MANUALLY'] = 'Aggiungi database manualmente.';
+$lang['L_DB_MANUAL_ERROR'] = "Spiacente, la connessione con il database '%s' è fallita!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Errore sul file: non si può inserire il database '%s'!";
+$lang['L_NO_DB_FOUND'] = 'Non sono stati trovati database. Inserisci i parametri di connessione e il nome del database manualmente! ';
+$lang['L_CONFIGFILES'] = 'File di configurazione';
+$lang['L_CONFIGFILE'] = 'File di configurazione';
+$lang['L_MYSQL_DATA'] = 'Dati MySQL';
+$lang['L_CONFIGURATIONS'] = 'Configurazioni';
+$lang['L_ACTION'] = 'Azione';
+$lang['L_FTP_SEND_TO'] = 'a <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'a <strong>%s</strong><br>in <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = "Destinatario dell'e-mail in CC";
+$lang['L_NAME'] = 'Nome';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Sicuro di voler cancellare il file di configurazione %s ?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Errore: il file di configurazione %s non può essere cancellato!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Il file di configurazione %s è stato cancellato con successo.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Il file di configurazione %s è stato creato con successo.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Il nome del file "%s" contiene dei caratteri non ammessi.';
+$lang['L_CREATE_CONFIGFILE'] = 'Crea un nuovo file di configurazione ';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Il file di configurazione "%s" non può essere caricato.';
+$lang['L_BACKUP_DBS_PHP'] = 'database di cui fare il backup (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'database di cui fare il backup (PERL)';
+$lang['L_CRON_COMMENT'] = 'Inserisci commento';
+$lang['L_AUTODETECT'] = 'riconoscimento automatico';
diff --git a/msd/language/it/lang_dump.php b/msd/language/it/lang_dump.php
index 80944583..e03e6a6f 100644
--- a/msd/language/it/lang_dump.php
+++ b/msd/language/it/lang_dump.php
@@ -1,56 +1,57 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Crea backup...";
-$lang['L_GZIP_COMPRESSION']="Compressione-GZip";
-$lang['L_SAVING_TABLE']="Salva tabella ";
-$lang['L_OF']="da";
-$lang['L_ACTUAL_TABLE']="Tabella attuale";
-$lang['L_PROGRESS_TABLE']="Processo della tabella";
-$lang['L_PROGRESS_OVER_ALL']="Progresso totale";
-$lang['L_ENTRY']="Registrazione";
-$lang['L_DONE']="Completato!";
-$lang['L_DUMP_SUCCESSFUL']="è stato creato con successo.";
-$lang['L_UPTO']="fino a";
-$lang['L_EMAIL_WAS_SEND']="L`e-mail è stata spedita con successo a ";
-$lang['L_BACK_TO_CONTROL']="continua";
-$lang['L_BACK_TO_OVERVIEW']="Riassunto database";
-$lang['L_DUMP_FILENAME']="File di backup: ";
-$lang['L_WITHPRAEFIX']="con prefisso";
-$lang['L_DUMP_NOTABLES']="Impossibile trovare tabelle `<b>%s</b>` nel database.";
-$lang['L_DUMP_ENDERGEBNIS']="Sono state salvate <b>%s</b> tabelle con <b>%s</b> record.<br>";
-$lang['L_MAILERROR']="Spiacente, nell`inviare l`e-mail si è verificato un errore!";
-$lang['L_EMAILBODY_ATTACH']="Nell`allegato trovi il backup del tuo database MySQL.<br>Backup del database `%s`
-<br><br>Il seguente file è stato creato:<br><br>%s <br><br>Buona giornata<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="È stato creato un backup multipart.<br>Il backup non viene spedito come allegato!<br>Backup del database `%s`
-<br><br>I seguenti file sono stati creati:<br><br>%s<br><br><br>Buona giornata<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="È stato creato un backup multipart.<br>Il backup viene spedito con e-mail separate, con allegati!<br>Backup del database`%s`
-<br><br>I seguenti file sono stati creati:<br><br>%s<br><br><br>Buona giornata<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="`<br><br>Buona giornata<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="Il backup supera la grandezza massima di %s perciò i file non sono stati allegati.<br>Backup del database `%s`
-<br><br>I seguenti file sono stati creati:<br><br>%s
-<br><br>Buona giornata<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="È stato creato un backup.<br>Il backup non viene spedito come allegato!<br>Backup del database `%s`
-<br><br>I seguenti file sono stati creati:<br><br>%s
-<br><br>Buona giornata<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']="Allegati del backup";
-$lang['L_TABLESELECTION']="Seleziona tabelle";
-$lang['L_SELECTALL']="seleziona tutto";
-$lang['L_DESELECTALL']="selezionare tutto";
-$lang['L_STARTDUMP']="Fai partire il backup";
-$lang['L_LASTBUFROM']="ultimo update dal";
-$lang['L_NOT_SUPPORTED']="Questo backup non supporta questa funzione.";
-$lang['L_MULTIDUMP']="Multidump: Sono stati salvati <b>%d</b> database.";
-$lang['L_FILESENDFTP']="Invio del file via FTP in corso... un attimo di pazienza prego. ";
-$lang['L_FTPCONNERROR']="Connessione FTP non riuscita! Connessione con ";
-$lang['L_FTPCONNERROR1']="come utente ";
-$lang['L_FTPCONNERROR2']="non possibile";
-$lang['L_FTPCONNERROR3']="FTP-Upload errato! ";
-$lang['L_FTPCONNECTED1']="Connesso con ";
-$lang['L_FTPCONNECTED2']="sul ";
-$lang['L_FTPCONNECTED3']="trasferimento completato con successo";
-$lang['L_NR_TABLES_SELECTED']="- con %s tabelle selezionate";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tabelle sono state ottimizzate.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s errori riscontrati: <a href=\"log.php?r=3\">controllare gli errori</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Errore fatale: l'istruzione di creazione della tabella '%s' nel database '%s' non è leggibile! <br> Controlla se ci sono dei errori nella tabella.";
 
-
-?>
\ No newline at end of file
+$lang['L_DUMP_HEADLINE'] = 'Crea backup...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'Compressione-GZip';
+$lang['L_SAVING_TABLE'] = 'Salva tabella ';
+$lang['L_OF'] = 'da';
+$lang['L_ACTUAL_TABLE'] = 'Tabella attuale';
+$lang['L_PROGRESS_TABLE'] = 'Processo della tabella';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progresso totale';
+$lang['L_ENTRY'] = 'Registrazione';
+$lang['L_DONE'] = 'Completato!';
+$lang['L_DUMP_SUCCESSFUL'] = 'è stato creato con successo.';
+$lang['L_UPTO'] = 'fino a';
+$lang['L_EMAIL_WAS_SEND'] = 'L`e-mail è stata spedita con successo a ';
+$lang['L_BACK_TO_CONTROL'] = 'continua';
+$lang['L_BACK_TO_OVERVIEW'] = 'Riassunto database';
+$lang['L_DUMP_FILENAME'] = 'File di backup: ';
+$lang['L_WITHPRAEFIX'] = 'con prefisso';
+$lang['L_DUMP_NOTABLES'] = 'Impossibile trovare tabelle `<b>%s</b>` nel database.';
+$lang['L_DUMP_ENDERGEBNIS'] = 'Sono state salvate <b>%s</b> tabelle con <b>%s</b> record.<br>';
+$lang['L_MAILERROR'] = 'Spiacente, nell`inviare l`e-mail si è verificato un errore!';
+$lang['L_EMAILBODY_ATTACH'] = 'Nell`allegato trovi il backup del tuo database MySQL.<br>Backup del database `%s`
+<br><br>Il seguente file è stato creato:<br><br>%s <br><br>Buona giornata<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'È stato creato un backup multipart.<br>Il backup non viene spedito come allegato!<br>Backup del database `%s`
+<br><br>I seguenti file sono stati creati:<br><br>%s<br><br><br>Buona giornata<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'È stato creato un backup multipart.<br>Il backup viene spedito con e-mail separate, con allegati!<br>Backup del database`%s`
+<br><br>I seguenti file sono stati creati:<br><br>%s<br><br><br>Buona giornata<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '`<br><br>Buona giornata<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Il backup supera la grandezza massima di %s perciò i file non sono stati allegati.<br>Backup del database `%s`
+<br><br>I seguenti file sono stati creati:<br><br>%s
+<br><br>Buona giornata<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'È stato creato un backup.<br>Il backup non viene spedito come allegato!<br>Backup del database `%s`
+<br><br>I seguenti file sono stati creati:<br><br>%s
+<br><br>Buona giornata<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = 'Allegati del backup';
+$lang['L_TABLESELECTION'] = 'Seleziona tabelle';
+$lang['L_SELECTALL'] = 'seleziona tutto';
+$lang['L_DESELECTALL'] = 'selezionare tutto';
+$lang['L_STARTDUMP'] = 'Fai partire il backup';
+$lang['L_LASTBUFROM'] = 'ultimo update dal';
+$lang['L_NOT_SUPPORTED'] = 'Questo backup non supporta questa funzione.';
+$lang['L_MULTIDUMP'] = 'Multidump: Sono stati salvati <b>%d</b> database.';
+$lang['L_FILESENDFTP'] = 'Invio del file via FTP in corso... un attimo di pazienza prego. ';
+$lang['L_FTPCONNERROR'] = 'Connessione FTP non riuscita! Connessione con ';
+$lang['L_FTPCONNERROR1'] = 'come utente ';
+$lang['L_FTPCONNERROR2'] = 'non possibile';
+$lang['L_FTPCONNERROR3'] = 'FTP-Upload errato! ';
+$lang['L_FTPCONNECTED1'] = 'Connesso con ';
+$lang['L_FTPCONNECTED2'] = 'sul ';
+$lang['L_FTPCONNECTED3'] = 'trasferimento completato con successo';
+$lang['L_FILESENDSFTP'] = 'Invio del file via SFTP in corso... un attimo di pazienza prego. ';
+$lang['L_SFTPCONNERROR'] = 'Connessione SFTP non riuscita! Connessione con ';
+$lang['L_NR_TABLES_SELECTED'] = '- con %s tabelle selezionate';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tabelle sono state ottimizzate.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s errori riscontrati: <a href="log.php?r=3">controllare gli errori</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Errore fatale: l'istruzione di creazione della tabella '%s' nel database '%s' non è leggibile! <br> Controlla se ci sono dei errori nella tabella.";
diff --git a/msd/language/it/lang_filemanagement.php b/msd/language/it/lang_filemanagement.php
index 54eb2b3b..dc08131f 100644
--- a/msd/language/it/lang_filemanagement.php
+++ b/msd/language/it/lang_filemanagement.php
@@ -1,75 +1,75 @@
 <?php
-$lang['L_CONVERT_START']="Fai partire la conversione";
-$lang['L_CONVERT_TITLE']="Convertire il Dump nel formato MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Parametri errati!  Conversione non possibile.";
-$lang['L_FM_UPLOADFILEREQUEST']="Prego, selezionare un file.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Questo tipo di file non è supportato.";
-$lang['L_FM_UPLOADNOTALLOWED2']="I tipi di file validi sono: *.gz e *.sql";
-$lang['L_FM_UPLOADMOVEERROR']="Non è stato possibile spostare il file caricato nella directory di destinazione corretta.";
-$lang['L_FM_UPLOADFAILED']="Il caricamento è fallito!";
-$lang['L_FM_UPLOADFILEEXISTS']="Esiste gia un file con questo nome!";
-$lang['L_FM_NOFILE']="Non hai selezionato alcun file!";
-$lang['L_FM_DELETE1']="Il file ";
-$lang['L_FM_DELETE2']="è stato cancellato con successo.";
-$lang['L_FM_DELETE3']="non è stato cancellato!";
-$lang['L_FM_CHOOSE_FILE']="File selezionato:";
-$lang['L_FM_FILESIZE']="Grandezza file";
-$lang['L_FM_FILEDATE']="Data ";
-$lang['L_FM_NOFILESFOUND']="Nessun file trovato.";
-$lang['L_FM_TABLES']="Tabelle";
-$lang['L_FM_RECORDS']="Record";
-$lang['L_FM_ALL_BU']="tutti i backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="ultimo backup";
-$lang['L_FM_TOTALSIZE']="Grandezza totale";
-$lang['L_FM_SELECTTABLES']="Scegli tabelle";
-$lang['L_FM_COMMENT']="Inserisci commento";
-$lang['L_FM_RESTORE']="Ripristina";
-$lang['L_FM_ALERTRESTORE1']="Deve essere ripristinato";
-$lang['L_FM_ALERTRESTORE2']="il database";
-$lang['L_FM_ALERTRESTORE3']="con i dati contenuti nel file?";
-$lang['L_FM_DELETE']="Eliminare";
-$lang['L_FM_ASKDELETE1']="Vuoi cancellare ";
-$lang['L_FM_ASKDELETE2']="veramente questo file?";
-$lang['L_FM_ASKDELETE3']="Vuoi effettuare ora la cancellazione in automatico secondo le regole impostate?";
-$lang['L_FM_ASKDELETE4']="Vuoi cancellare tutti i backup?";
-$lang['L_FM_ASKDELETE5']="Vuoi cancellare tutti i file di backup con ";
-$lang['L_FM_ASKDELETE5_2']="_* adesso?";
-$lang['L_FM_DELETEAUTO']="Fai partire la cancellazione automatica manualmente";
-$lang['L_FM_DELETEALL']="cancella tutti i file di backup";
-$lang['L_FM_DELETEALLFILTER']="cancella tutti con ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Fai partire un nuovo backup";
-$lang['L_FM_FILEUPLOAD']="Carica file";
-$lang['L_FM_DBNAME']="Nome del database";
-$lang['L_FM_FILES1']="Backup Database";
-$lang['L_FM_FILES2']="Struttura database";
-$lang['L_FM_AUTODEL1']="Cancellazione automatica: i seguenti file sono stati cancellati poichè è stato raggiunto il limite di spazio impostato:";
-$lang['L_DELETE_FILE_SUCCESS']="Il file \"%s\" è stato cancellato con successo.";
-$lang['L_FM_DUMPSETTINGS']="Configurazione";
-$lang['L_FM_OLDBACKUP']="(sconosciuto)";
-$lang['L_FM_RESTORE_HEADER']="Ripristino del database \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Non è stato possibile cancellare il file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Esegui Cronscript Perl";
-$lang['L_DOPERLTEST']="Prova il modulo Perl";
-$lang['L_DOSIMPLETEST']="Prova Perl";
-$lang['L_PERLOUTPUT1']="Registrazione in crondump.pl per absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Url per il Browser oppure per Cronjob esterno";
-$lang['L_PERLOUTPUT3']="Linea di commandi nella Shell oppure per il Crontab";
-$lang['L_RESTORE_OF_TABLES']="Ripristino di tabelle specifiche";
-$lang['L_CONVERTER']="Convertitore Backup";
-$lang['L_CONVERT_FILE']="file da convertire";
-$lang['L_CONVERT_FILENAME']="Nome del file di destinazione (senza estensione)";
-$lang['L_CONVERTING']="Conversione";
-$lang['L_CONVERT_FILEREAD']="Leggi file '%s'";
-$lang['L_CONVERT_FINISHED']="Conversione eseguita, '%s' sono stati scritti con successo.";
-$lang['L_NO_MSD_BACKUPFILE']="Backup di altri programmi";
-$lang['L_MAX_UPLOAD_SIZE']="Grandezza massima del file";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Se il tuo file di backup è piu grande del limite impostato, allora lo devi caricare tramite FTP nella cartella \"work/backup\". Dopo verrà visualizzato e potrà essere scelto per il ripristino.";
-$lang['L_ENCODING']="codifica";
-$lang['L_FM_CHOOSE_ENCODING']="Scegli la codifica del file di backup";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper non ha rilevato automaticamente il codice del seti di caratteri utilizzato nel file di backup creato in precedenza.<br> Devi inserire manualmente il set di caratteri standard con cui è stato salvato questo backup.<br> Dopo aver fatto questo, MySQLDumper effettuerà la connessione verso il MySQL-Server contenente il set di caretteri scelto e avvierà il ripristino dei dati. Se dopo il ripristono si presentassero problemi nella visualizzazione dei caratteri speciali, sarà opportuno ripetere la procedura di ripistino scegliendo un altro set di caratteri.<br>Buona fortuna.;)";
-$lang['L_DOWNLOAD_FILE']="Scarica file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+
+$lang['L_CONVERT_START'] = 'Fai partire la conversione';
+$lang['L_CONVERT_TITLE'] = 'Convertire il Dump nel formato MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Parametri errati!  Conversione non possibile.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Prego, selezionare un file.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Questo tipo di file non è supportato.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'I tipi di file validi sono: *.gz e *.sql';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Non è stato possibile spostare il file caricato nella directory di destinazione corretta.';
+$lang['L_FM_UPLOADFAILED'] = 'Il caricamento è fallito!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Esiste gia un file con questo nome!';
+$lang['L_FM_NOFILE'] = 'Non hai selezionato alcun file!';
+$lang['L_FM_DELETE1'] = 'Il file ';
+$lang['L_FM_DELETE2'] = 'è stato cancellato con successo.';
+$lang['L_FM_DELETE3'] = 'non è stato cancellato!';
+$lang['L_FM_CHOOSE_FILE'] = 'File selezionato:';
+$lang['L_FM_FILESIZE'] = 'Grandezza file';
+$lang['L_FM_FILEDATE'] = 'Data ';
+$lang['L_FM_NOFILESFOUND'] = 'Nessun file trovato.';
+$lang['L_FM_TABLES'] = 'Tabelle';
+$lang['L_FM_RECORDS'] = 'Record';
+$lang['L_FM_ALL_BU'] = 'tutti i backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'ultimo backup';
+$lang['L_FM_TOTALSIZE'] = 'Grandezza totale';
+$lang['L_FM_SELECTTABLES'] = 'Scegli tabelle';
+$lang['L_FM_COMMENT'] = 'Inserisci commento';
+$lang['L_FM_RESTORE'] = 'Ripristina';
+$lang['L_FM_ALERTRESTORE1'] = 'Deve essere ripristinato';
+$lang['L_FM_ALERTRESTORE2'] = 'il database';
+$lang['L_FM_ALERTRESTORE3'] = 'con i dati contenuti nel file?';
+$lang['L_FM_DELETE'] = 'Eliminare';
+$lang['L_FM_ASKDELETE1'] = 'Vuoi cancellare ';
+$lang['L_FM_ASKDELETE2'] = 'veramente questo file?';
+$lang['L_FM_ASKDELETE3'] = 'Vuoi effettuare ora la cancellazione in automatico secondo le regole impostate?';
+$lang['L_FM_ASKDELETE4'] = 'Vuoi cancellare tutti i backup?';
+$lang['L_FM_ASKDELETE5'] = 'Vuoi cancellare tutti i file di backup con ';
+$lang['L_FM_ASKDELETE5_2'] = '_* adesso?';
+$lang['L_FM_DELETEAUTO'] = 'Fai partire la cancellazione automatica manualmente';
+$lang['L_FM_DELETEALL'] = 'cancella tutti i file di backup';
+$lang['L_FM_DELETEALLFILTER'] = 'cancella tutti con ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Fai partire un nuovo backup';
+$lang['L_FM_FILEUPLOAD'] = 'Carica file';
+$lang['L_FM_DBNAME'] = 'Nome del database';
+$lang['L_FM_FILES1'] = 'Backup Database';
+$lang['L_FM_FILES2'] = 'Struttura database';
+$lang['L_FM_AUTODEL1'] = 'Cancellazione automatica: i seguenti file sono stati cancellati poichè è stato raggiunto il limite di spazio impostato:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'Il file "%s" è stato cancellato con successo.';
+$lang['L_FM_DUMPSETTINGS'] = 'Configurazione';
+$lang['L_FM_OLDBACKUP'] = '(sconosciuto)';
+$lang['L_FM_RESTORE_HEADER'] = 'Ripristino del database "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Non è stato possibile cancellare il file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Esegui Cronscript Perl';
+$lang['L_DOPERLTEST'] = 'Prova il modulo Perl';
+$lang['L_DOSIMPLETEST'] = 'Prova Perl';
+$lang['L_PERLOUTPUT1'] = 'Registrazione in crondump.pl per absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Url per il Browser oppure per Cronjob esterno';
+$lang['L_PERLOUTPUT3'] = 'Linea di commandi nella Shell oppure per il Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Ripristino di tabelle specifiche';
+$lang['L_CONVERTER'] = 'Convertitore Backup';
+$lang['L_CONVERT_FILE'] = 'file da convertire';
+$lang['L_CONVERT_FILENAME'] = 'Nome del file di destinazione (senza estensione)';
+$lang['L_CONVERTING'] = 'Conversione';
+$lang['L_CONVERT_FILEREAD'] = "Leggi file '%s'";
+$lang['L_CONVERT_FINISHED'] = "Conversione eseguita, '%s' sono stati scritti con successo.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Backup di altri programmi';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Grandezza massima del file';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Se il tuo file di backup è piu grande del limite impostato, allora lo devi caricare tramite FTP nella cartella "work/backup". Dopo verrà visualizzato e potrà essere scelto per il ripristino.';
+$lang['L_ENCODING'] = 'codifica';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Scegli la codifica del file di backup';
+$lang['L_CHOOSE_CHARSET'] = 'MyOOS [Dumper] non ha rilevato automaticamente il codice del seti di caratteri utilizzato nel file di backup creato in precedenza.<br> Devi inserire manualmente il set di caratteri standard con cui è stato salvato questo backup.<br> Dopo aver fatto questo, MyOOS [Dumper] effettuerà la connessione verso il MySQL-Server contenente il set di caretteri scelto e avvierà il ripristino dei dati. Se dopo il ripristono si presentassero problemi nella visualizzazione dei caratteri speciali, sarà opportuno ripetere la procedura di ripistino scegliendo un altro set di caratteri.<br>Buona fortuna.;)';
+$lang['L_DOWNLOAD_FILE'] = 'Scarica file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/it/lang_help.php b/msd/language/it/lang_help.php
index fe7d3e59..296e296d 100644
--- a/msd/language/it/lang_help.php
+++ b/msd/language/it/lang_help.php
@@ -1,32 +1,30 @@
 <?php
-$lang['L_HELP_DB']="Questa è la lista dei database presenti";
-$lang['L_HELP_PRAEFIX']="Il prefisso è una serie di lettere utilizzata all`inizio del nome di una tabella che può servire come filtro.";
-$lang['L_HELP_ZIP']="Compressione con GZip - si consiglia di attivarla";
-$lang['L_HELP_MEMORYLIMIT']="Grandezza massima in Bytes della memoria assegnata allo script\n0 = disattivato";
-$lang['L_MEMORY_LIMIT']="Limite di memoria";
-$lang['L_HELP_AD1']="Se attivato, vengono cancellati automaticamente i file di backup.";
-$lang['L_HELP_AD3']="Il massimo numero di file di backup che vuoi mantenere nella directory di salvataggio per la cancellazione automatica (Attenzione: i backup multipart NON sono considerati come un unico file!)
-0 = disattivato";
-$lang['L_HELP_LANG']="Seleziona la lingua desiderata";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Per eliminare i dati inutili puoi impostare lo svuotamento totale del database prima del ripristino .";
-$lang['L_HELP_CRONEXTENDER']="L`estensione dello script Perl, lo standard è '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="Il nome del file di configurazine per lo script Perl";
-$lang['L_HELP_CRONPRINTOUT']="Quando l`output del testo viene disattivato non viene più visualizzato a video. Questa funzione è indipendente dalla distribuzione del log.";
-$lang['L_HELP_CRONSAMEDB']="Vuoi usare lo stesso database per il conjob come specificato nella configurazione?";
-$lang['L_HELP_CRONDBINDEX']="scegli il database per il cronjob";
-$lang['L_HELP_FTPTRANSFER']="Se attivato, il file di backup sarà inviato tramite FTP.";
-$lang['L_HELP_FTPSERVER']="Indirizzo del Server FTP";
-$lang['L_HELP_FTPPORT']="Porta del Server FTP, lo standard è: 21";
-$lang['L_HELP_FTPUSER']="Inserisci la user FTP";
-$lang['L_HELP_FTPPASS']="Inserisci la password per FTP";
-$lang['L_HELP_FTPDIR']="Dove devo inviare il file? Inserire il percorso!";
-$lang['L_HELP_SPEED']="Minima e massima velocità della connessione, lo standard è da 50 a 5000(Velocità troppo alte possono causare un timeout!)";
-$lang['L_SPEED']="Controllo velocità";
-$lang['L_HELP_CRONEXECPATH']="Il posto in cui si trovano gli script Perl.\nIl punto di partenza iniziale è l`indirizzo HTTP (come gli indirizzi nel Browser)\nSono permessi indirizzi assoluti e relativi.";
-$lang['L_CRON_EXECPATH']="Percorso degli script Perl";
-$lang['L_HELP_CRONCOMPLETELOG']="Se questa funzione è attivata il dettaglio di tutte le operazioni verrà memorizzato nel file complete_log. 
-Questa funzione è indipendente dall`output del testo.";
-$lang['L_HELP_FTP_MODE']="Se si verificassero dei problemi con il trasferimento tramite FTP, provare ad usare la modalità passiva.";
 
-
-?>
\ No newline at end of file
+$lang['L_HELP_DB'] = 'Questa è la lista dei database presenti';
+$lang['L_HELP_PRAEFIX'] = 'Il prefisso è una serie di lettere utilizzata all`inizio del nome di una tabella che può servire come filtro.';
+$lang['L_HELP_ZIP'] = 'Compressione con GZip - si consiglia di attivarla';
+$lang['L_HELP_MEMORYLIMIT'] = "Grandezza massima in Bytes della memoria assegnata allo script\n0 = disattivato";
+$lang['L_MEMORY_LIMIT'] = 'Limite di memoria';
+$lang['L_HELP_AD1'] = 'Se attivato, vengono cancellati automaticamente i file di backup.';
+$lang['L_HELP_AD3'] = 'Il massimo numero di file di backup che vuoi mantenere nella directory di salvataggio per la cancellazione automatica (Attenzione: i backup multipart NON sono considerati come un unico file!)
+0 = disattivato';
+$lang['L_HELP_LANG'] = 'Seleziona la lingua desiderata';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Per eliminare i dati inutili puoi impostare lo svuotamento totale del database prima del ripristino .';
+$lang['L_HELP_CRONEXTENDER'] = "L`estensione dello script Perl, lo standard è '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'Il nome del file di configurazine per lo script Perl';
+$lang['L_HELP_CRONPRINTOUT'] = 'Quando l`output del testo viene disattivato non viene più visualizzato a video. Questa funzione è indipendente dalla distribuzione del log.';
+$lang['L_HELP_CRONSAMEDB'] = 'Vuoi usare lo stesso database per il conjob come specificato nella configurazione?';
+$lang['L_HELP_CRONDBINDEX'] = 'scegli il database per il cronjob';
+$lang['L_HELP_FTPTRANSFER'] = 'Se attivato, il file di backup sarà inviato tramite FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Indirizzo del Server FTP';
+$lang['L_HELP_FTPPORT'] = 'Porta del Server FTP, lo standard è: 21';
+$lang['L_HELP_FTPUSER'] = 'Inserisci la user FTP';
+$lang['L_HELP_FTPPASS'] = 'Inserisci la password per FTP';
+$lang['L_HELP_FTPDIR'] = 'Dove devo inviare il file? Inserire il percorso!';
+$lang['L_HELP_SPEED'] = 'Minima e massima velocità della connessione, lo standard è da 50 a 5000(Velocità troppo alte possono causare un timeout!)';
+$lang['L_SPEED'] = 'Controllo velocità';
+$lang['L_HELP_CRONEXECPATH'] = "Il posto in cui si trovano gli script Perl.\nIl punto di partenza iniziale è l`indirizzo HTTP (come gli indirizzi nel Browser)\nSono permessi indirizzi assoluti e relativi.";
+$lang['L_CRON_EXECPATH'] = 'Percorso degli script Perl';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Se questa funzione è attivata il dettaglio di tutte le operazioni verrà memorizzato nel file complete_log. 
+Questa funzione è indipendente dall`output del testo.';
+$lang['L_HELP_FTP_MODE'] = 'Se si verificassero dei problemi con il trasferimento tramite FTP, provare ad usare la modalità passiva.';
diff --git a/msd/language/it/lang_install.php b/msd/language/it/lang_install.php
index 61eefc0a..726c35ce 100644
--- a/msd/language/it/lang_install.php
+++ b/msd/language/it/lang_install.php
@@ -1,83 +1,80 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>L`installazione è finita --> <a href=\"index.php\">fai partire MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Ritorna al Menu principale";
-$lang['L_INSTALLMENU']="Menu principale";
-$lang['L_STEP']="Passo";
-$lang['L_INSTALL']="Installazione";
-$lang['L_UNINSTALL']="Disinstallare";
-$lang['L_TOOLS']="Tools";
-$lang['L_EDITCONF']="Modifica la configurazione";
-$lang['L_OSWEITER']="continuare senza salvare";
-$lang['L_ERRORMAN']="<strong>Errore nel salvataggio della configurazione!</strong><br> edita il file per favore";
-$lang['L_MANUELL']="manualmente";
-$lang['L_CREATEDIRS']="crea directory";
-$lang['L_INSTALL_CONTINUE']="continua con la installazione";
-$lang['L_CONNECTTOMYSQL']="connessione a MySQL ";
-$lang['L_DBPARAMETER']="Parametri database";
-$lang['L_CONFIGNOTWRITABLE']="Il file \"config.php\" non è scrivibile. Metti per favore i permessi per scrivere (ad esempio: 0777), cosi MySQLDumper può salvare la tua configurazione. ";
-$lang['L_DBCONNECTION']="Connessione database";
-$lang['L_CONNECTIONERROR']="Errore: impossibile connettersi.";
-$lang['L_CONNECTION_OK']="Connessione al database effettuata.";
-$lang['L_SAVEANDCONTINUE']="Salvare e continuare l`installazione";
-$lang['L_CONFBASIC']="Configurazione di base";
-$lang['L_INSTALL_STEP2FINISHED']="I parametri del database sono stati salvati.";
-$lang['L_INSTALL_STEP2_1']="Continuare la installazione con i parametri standard";
-$lang['L_LASTSTEP']="Fine della installazione";
-$lang['L_FTPMODE']="Creazione directory tramite FTP (safe-mode)";
-$lang['L_IDOMANUAL']="Creare le directory manualmente";
-$lang['L_DOFROM']="partendo dal";
-$lang['L_FTPMODE2']="Creare le directory tramite FTP:";
-$lang['L_CONNECT']="connetti";
-$lang['L_DIRS_CREATED']="Le directory sono state create correttamente con i permessi appropriati.";
-$lang['L_CONNECT_TO']="connetti a";
-$lang['L_CHANGEDIR']="cambia directory";
-$lang['L_CHANGEDIRERROR']="Impossibile cambiare directory";
-$lang['L_FTP_OK']="I parametri FTP sono corretti";
-$lang['L_CREATEDIRS2']="Creare directory";
-$lang['L_FTP_NOTCONNECTED']="Connessione FTP fallita!";
-$lang['L_CONNWITH']="Connessione con";
-$lang['L_ASUSER']="come utente";
-$lang['L_NOTPOSSIBLE']="impossibile";
-$lang['L_DIRCR1']="crea directory di lavoro";
-$lang['L_DIRCR2']="crea directory di backup";
-$lang['L_DIRCR4']="crea directory di log";
-$lang['L_DIRCR5']="crea elenco di configurazione";
-$lang['L_INDIR']="sono nella directory";
-$lang['L_CHECK_DIRS']="verifica directory";
-$lang['L_DISABLEDFUNCTIONS']="Funzioni disabilitate";
-$lang['L_NOFTPPOSSIBLE']="Funzioni FTP non disponibili!";
-$lang['L_NOGZPOSSIBLE']="Funzione di compressione non disponibile!";
-$lang['L_UI1']="Tutte le directory di lavoro inclusi gli eventuali backups presenti verranno cancellati.";
-$lang['L_UI2']="Sei sicuro?";
-$lang['L_UI3']="no";
-$lang['L_UI4']="si";
-$lang['L_UI5']="cancella directory di lavoro";
-$lang['L_UI6']="è stato cancellato tutto con successo.";
-$lang['L_UI7']="cancella la direcotry degli script";
-$lang['L_UI8']="livello precedente";
-$lang['L_UI9']="Si è verificato un errore, non è stato possibile cancellare </p>Errore nella directory";
-$lang['L_IMPORT']="Importare configurazione";
-$lang['L_IMPORT3']="La configurazione è stata caricata ...";
-$lang['L_IMPORT4']="La configurazione è stata salvata.";
-$lang['L_IMPORT5']="Eseguire MySQLDumper";
-$lang['L_IMPORT6']="Menu di installazione";
-$lang['L_IMPORT7']="Caricare configurazione";
-$lang['L_IMPORT8']="torna al caricamento (upload)";
-$lang['L_IMPORT9']="Questo non è un backup di configurazione!";
-$lang['L_IMPORT10']="La configurazione è stata ripristinata con successo ...";
-$lang['L_IMPORT11']="<strong>Errore: </strong>Si sono verificati degli errori nel salvataggio delle istruzioni sql";
-$lang['L_IMPORT12']="<strong>Errore: </strong>Si sono verificati degli errori nel salvataggio di config.php";
-$lang['L_INSTALL_HELP_PORT']="(vuoto = porta-standard)";
-$lang['L_INSTALL_HELP_SOCKET']="(vuoto = Socket-standard)";
-$lang['L_TRYAGAIN']="riprova";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Porta";
-$lang['L_FOUND_DB']="database trovato:";
-$lang['L_FM_FILEUPLOAD']="Carica il file";
-$lang['L_PASS']="Password";
-$lang['L_NO_DB_FOUND_INFO']="La connesione con il database è stata effettuata con successo. <br> I tuoi dati di connessione sono stati accettati dal MySQL-Server.<br> Purtroppo MySQLDumper non ha trovato alcun database.<br>Il riconoscimento automatico per il programma è purtroppo bloccato dal provider. <br> Appena hai finito l`installazione devi andare nel menu \"Configurazione\" \"visualizza parametri di connessione\" e inserire il nome del tuo database.";
-$lang['L_SAFEMODEDESC']="Siccome PHP è eseguito in \"safe_mode\" su questo server, devono essere create manualmente le seguenti directory (queste possono essere trasferite tramite un qualsiasi programma ftp oppure inserire i dati di accesso ftp nei campi seguenti, cosicchè MySQLDumper li possa creare automaticamente):";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
 
-
-?>
\ No newline at end of file
+$lang['L_INSTALLFINISHED'] = '<br>L`installazione è finita --> <a href="index.php">fai partire MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Ritorna al Menu principale';
+$lang['L_INSTALLMENU'] = 'Menu principale';
+$lang['L_STEP'] = 'Passo';
+$lang['L_INSTALL'] = 'Installazione';
+$lang['L_UNINSTALL'] = 'Disinstallare';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_EDITCONF'] = 'Modifica la configurazione';
+$lang['L_OSWEITER'] = 'continuare senza salvare';
+$lang['L_ERRORMAN'] = '<strong>Errore nel salvataggio della configurazione!</strong><br> edita il file per favore';
+$lang['L_MANUELL'] = 'manualmente';
+$lang['L_CREATEDIRS'] = 'crea directory';
+$lang['L_INSTALL_CONTINUE'] = 'continua con la installazione';
+$lang['L_CONNECTTOMYSQL'] = 'connessione a MySQL ';
+$lang['L_DBPARAMETER'] = 'Parametri database';
+$lang['L_CONFIGNOTWRITABLE'] = 'Il file "config.php" non è scrivibile. Metti per favore i permessi per scrivere (ad esempio: 0777), cosi MyOOS [Dumper] può salvare la tua configurazione. ';
+$lang['L_DBCONNECTION'] = 'Connessione database';
+$lang['L_CONNECTIONERROR'] = 'Errore: impossibile connettersi.';
+$lang['L_CONNECTION_OK'] = 'Connessione al database effettuata.';
+$lang['L_SAVEANDCONTINUE'] = 'Salvare e continuare l`installazione';
+$lang['L_CONFBASIC'] = 'Configurazione di base';
+$lang['L_INSTALL_STEP2FINISHED'] = 'I parametri del database sono stati salvati.';
+$lang['L_INSTALL_STEP2_1'] = 'Continuare la installazione con i parametri standard';
+$lang['L_LASTSTEP'] = 'Fine della installazione';
+$lang['L_FTPMODE'] = 'Creazione directory tramite FTP (safe-mode)';
+$lang['L_IDOMANUAL'] = 'Creare le directory manualmente';
+$lang['L_DOFROM'] = 'partendo dal';
+$lang['L_FTPMODE2'] = 'Creare le directory tramite FTP:';
+$lang['L_CONNECT'] = 'connetti';
+$lang['L_DIRS_CREATED'] = 'Le directory sono state create correttamente con i permessi appropriati.';
+$lang['L_CONNECT_TO'] = 'connetti a';
+$lang['L_CHANGEDIR'] = 'cambia directory';
+$lang['L_CHANGEDIRERROR'] = 'Impossibile cambiare directory';
+$lang['L_FTP_OK'] = 'I parametri FTP sono corretti';
+$lang['L_CREATEDIRS2'] = 'Creare directory';
+$lang['L_FTP_NOTCONNECTED'] = 'Connessione FTP fallita!';
+$lang['L_CONNWITH'] = 'Connessione con';
+$lang['L_ASUSER'] = 'come utente';
+$lang['L_NOTPOSSIBLE'] = 'impossibile';
+$lang['L_DIRCR1'] = 'crea directory di lavoro';
+$lang['L_DIRCR2'] = 'crea directory di backup';
+$lang['L_DIRCR4'] = 'crea directory di log';
+$lang['L_DIRCR5'] = 'crea elenco di configurazione';
+$lang['L_INDIR'] = 'sono nella directory';
+$lang['L_CHECK_DIRS'] = 'verifica directory';
+$lang['L_DISABLEDFUNCTIONS'] = 'Funzioni disabilitate';
+$lang['L_NOFTPPOSSIBLE'] = 'Funzioni FTP non disponibili!';
+$lang['L_NOGZPOSSIBLE'] = 'Funzione di compressione non disponibile!';
+$lang['L_UI1'] = 'Tutte le directory di lavoro inclusi gli eventuali backups presenti verranno cancellati.';
+$lang['L_UI2'] = 'Sei sicuro?';
+$lang['L_UI3'] = 'no';
+$lang['L_UI4'] = 'si';
+$lang['L_UI5'] = 'cancella directory di lavoro';
+$lang['L_UI6'] = 'è stato cancellato tutto con successo.';
+$lang['L_UI7'] = 'cancella la direcotry degli script';
+$lang['L_UI8'] = 'livello precedente';
+$lang['L_UI9'] = 'Si è verificato un errore, non è stato possibile cancellare </p>Errore nella directory';
+$lang['L_IMPORT'] = 'Importare configurazione';
+$lang['L_IMPORT3'] = 'La configurazione è stata caricata ...';
+$lang['L_IMPORT4'] = 'La configurazione è stata salvata.';
+$lang['L_IMPORT5'] = 'Eseguire MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Menu di installazione';
+$lang['L_IMPORT7'] = 'Caricare configurazione';
+$lang['L_IMPORT8'] = 'torna al caricamento (upload)';
+$lang['L_IMPORT9'] = 'Questo non è un backup di configurazione!';
+$lang['L_IMPORT10'] = 'La configurazione è stata ripristinata con successo ...';
+$lang['L_IMPORT11'] = '<strong>Errore: </strong>Si sono verificati degli errori nel salvataggio delle istruzioni sql';
+$lang['L_IMPORT12'] = '<strong>Errore: </strong>Si sono verificati degli errori nel salvataggio di config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(vuoto = porta-standard)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(vuoto = Socket-standard)';
+$lang['L_TRYAGAIN'] = 'riprova';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Porta';
+$lang['L_FOUND_DB'] = 'database trovato:';
+$lang['L_FM_FILEUPLOAD'] = 'Carica il file';
+$lang['L_PASS'] = 'Password';
+$lang['L_NO_DB_FOUND_INFO'] = 'La connesione con il database è stata effettuata con successo. <br> I tuoi dati di connessione sono stati accettati dal MySQL-Server.<br> Purtroppo MyOOS [Dumper] non ha trovato alcun database.<br>Il riconoscimento automatico per il programma è purtroppo bloccato dal provider. <br> Appena hai finito l`installazione devi andare nel menu "Configurazione" "visualizza parametri di connessione" e inserire il nome del tuo database.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/it/lang_log.php b/msd/language/it/lang_log.php
index ac1365d2..b9f9f617 100644
--- a/msd/language/it/lang_log.php
+++ b/msd/language/it/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Cancella i log";
-$lang['L_LOGFILEFORMAT']="Formato del file log";
-$lang['L_LOGFILENOTWRITABLE']="Impossibile scrivere il file di log!";
-$lang['L_NOREVERSE']="Il piu vecchio come primo";
-$lang['L_REVERSE']="Il piu nuovo come primo";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Cancella i log';
+$lang['L_LOGFILEFORMAT'] = 'Formato del file log';
+$lang['L_LOGFILENOTWRITABLE'] = 'Impossibile scrivere il file di log!';
+$lang['L_NOREVERSE'] = 'Il piu vecchio come primo';
+$lang['L_REVERSE'] = 'Il piu nuovo come primo';
diff --git a/msd/language/it/lang_main.php b/msd/language/it/lang_main.php
index 7cfb2c7a..b33b1806 100644
--- a/msd/language/it/lang_main.php
+++ b/msd/language/it/lang_main.php
@@ -1,74 +1,85 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Non hai una funzione FTP disponibile!";
-$lang['L_INFO_LOCATION']="Adesso ti trovi ";
-$lang['L_INFO_DATABASES']="I seguenti database sono stati trovati sul server:";
-$lang['L_INFO_NODB']="Il database non esiste.";
-$lang['L_INFO_DBDETAIL']="Informazioni detagliate del database";
-$lang['L_INFO_DBEMPTY']="Il database è vuoto!";
-$lang['L_INFO_RECORDS']="Record";
-$lang['L_INFO_SIZE']="Grandezza";
-$lang['L_INFO_LASTUPDATE']="l`ultimo caricamento";
-$lang['L_INFO_SUM']="totale";
-$lang['L_INFO_OPTIMIZED']="ottimizzato";
-$lang['L_OPTIMIZE_DATABASES']="Ottimizza tabelle";
-$lang['L_CHECK_TABLES']="Controlla tabelle";
-$lang['L_CLEAR_DATABASE']="Svuota database";
-$lang['L_DELETE_DATABASE']="Elimina database";
-$lang['L_INFO_CLEARED']="è stato svuotato";
-$lang['L_INFO_DELETED']="è stato cancellato";
-$lang['L_INFO_EMPTYDB1']="Vuoi veramente svuotare il database?";
-$lang['L_INFO_EMPTYDB2']="(Attenzione: Tutti i dati andranno persi per sempre!)";
-$lang['L_INFO_KILLDB']=" (Attenzione: Tutti i dati andranno persi per sempre!)";
-$lang['L_PROCESSKILL1']="Lo script prova a terminare il processo ";
-$lang['L_PROCESSKILL2']="terminare il processo ";
-$lang['L_PROCESSKILL3']="Lo script prova da  ";
-$lang['L_PROCESSKILL4']=" sec. di terminare questo processo ";
-$lang['L_HTACC_CREATE']="Crea protezione directory";
-$lang['L_ENCRYPTION_TYPE']="Tipo di crittazione";
-$lang['L_HTACC_CRYPT']="Crypt (Sistemi Unix e Linux)";
-$lang['L_HTACC_MD5']="MD5 (Sistemi Unix e Linux)";
-$lang['L_HTACC_NO_ENCRYPTION']="Non crittato (Windows)";
-$lang['L_HTACCESS8']="Esiste gia una protezione per le directory, il vecchio file sarà sovrascritto se ne crei uno nuovo! ";
-$lang['L_HTACC_NO_USERNAME']="Devi inserire un nome!";
-$lang['L_PASSWORDS_UNEQUAL']="Le password non sono identiche oppure sono vuote!";
-$lang['L_HTACC_CONFIRM_DELETE']="Vuoi che venga inserita la protezione per le directory adesso?";
-$lang['L_HTACC_CREATED']="La protezione delle directory è stata inserita.";
-$lang['L_HTACC_CONTENT']="Contenuto del file";
-$lang['L_HTACC_CREATE_ERROR']="Nella creazione della protezione delle directory si è verificato un errore!<br>Crea per favore questi file manualmente con il seguente contenuto";
-$lang['L_HTACC_PROPOSED']="Urgentemente raccomandato";
-$lang['L_HTACC_EDIT']="edit .htaccess";
-$lang['L_HTACCESS18']="crea .htaccess in ";
-$lang['L_HTACCESS19']="ricarica ";
-$lang['L_HTACCESS20']="Esegui script";
-$lang['L_HTACCESS21']="aggiungi fornitore(provider)";
-$lang['L_HTACCESS22']="Rendi eseguibile";
-$lang['L_HTACCESS23']="Lista directory";
-$lang['L_HTACCESS24']="Documento errori";
-$lang['L_HTACCESS25']="Attivare rewrite";
-$lang['L_HTACCESS26']="Negare / Permettere";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Log degli errori";
-$lang['L_HTACCESS29']="Altri esempi e documentazioni";
-$lang['L_HTACCESS30']="Provider";
-$lang['L_HTACCESS31']="Generale";
-$lang['L_HTACCESS32']="Attenzione! .htaccess ha effetto direttamente sul browser.<br>Se viene usato in maniera scorretta le pagine non saranno piu accessibili.";
-$lang['L_PHPBUG']="Bug nel zlib ! Compressione impossibile!";
-$lang['L_DISABLEDFUNCTIONS']="Funzione disabilitata";
-$lang['L_NOGZPOSSIBLE']="Poiché Zlib non è installato non puoi usare la funzione GZip!";
-$lang['L_DELETE_HTACCESS']="Rimuovi la protezione (cancella .htaccess)";
-$lang['L_WRONG_RIGHTS']="Impossibile scrivere il file o la directory '%s' .<br> O ha il proprietario sbagliato (Owner) o i diritti sbagliati (Chmod).<br> Vi preghiamo di modificare gli attributi correttamente con il vostro programma FTP. <br> Il file o la directory ha bisogno dei diritti %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Impossibile creare la directory '%s'. Crearla manualmente con un programma di FTP.";
-$lang['L_TABLE_TYPE']="Tipo";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="impossibile trovare il file";
 
-
-?>
\ No newline at end of file
+$lang['L_NOFTPPOSSIBLE'] = 'Non hai una funzione FTP disponibile!';
+$lang['L_INFO_LOCATION'] = 'Adesso ti trovi ';
+$lang['L_INFO_DATABASES'] = 'I seguenti database sono stati trovati sul server:';
+$lang['L_INFO_NODB'] = 'Il database non esiste.';
+$lang['L_INFO_DBDETAIL'] = 'Informazioni detagliate del database';
+$lang['L_INFO_DBEMPTY'] = 'Il database è vuoto!';
+$lang['L_INFO_RECORDS'] = 'Record';
+$lang['L_INFO_SIZE'] = 'Grandezza';
+$lang['L_INFO_LASTUPDATE'] = 'l`ultimo caricamento';
+$lang['L_INFO_SUM'] = 'totale';
+$lang['L_INFO_OPTIMIZED'] = 'ottimizzato';
+$lang['L_OPTIMIZE_DATABASES'] = 'Ottimizza tabelle';
+$lang['L_CHECK_TABLES'] = 'Controlla tabelle';
+$lang['L_CLEAR_DATABASE'] = 'Svuota database';
+$lang['L_DELETE_DATABASE'] = 'Elimina database';
+$lang['L_INFO_CLEARED'] = 'è stato svuotato';
+$lang['L_INFO_DELETED'] = 'è stato cancellato';
+$lang['L_INFO_EMPTYDB1'] = 'Vuoi veramente svuotare il database?';
+$lang['L_INFO_EMPTYDB2'] = '(Attenzione: Tutti i dati andranno persi per sempre!)';
+$lang['L_INFO_KILLDB'] = ' (Attenzione: Tutti i dati andranno persi per sempre!)';
+$lang['L_PROCESSKILL1'] = 'Lo script prova a terminare il processo ';
+$lang['L_PROCESSKILL2'] = 'terminare il processo ';
+$lang['L_PROCESSKILL3'] = 'Lo script prova da  ';
+$lang['L_PROCESSKILL4'] = ' sec. di terminare questo processo ';
+$lang['L_HTACC_CREATE'] = 'Crea protezione directory';
+$lang['L_ENCRYPTION_TYPE'] = 'Tipo di crittazione';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Esiste gia una protezione per le directory, il vecchio file sarà sovrascritto se ne crei uno nuovo! ';
+$lang['L_HTACC_NO_USERNAME'] = 'Devi inserire un nome!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Le password non sono identiche oppure sono vuote!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Vuoi che venga inserita la protezione per le directory adesso?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'La protezione delle directory è stata inserita.';
+$lang['L_HTACC_CONTENT'] = 'Contenuto del file';
+$lang['L_HTACC_CREATE_ERROR'] = 'Nella creazione della protezione delle directory si è verificato un errore!<br>Crea per favore questi file manualmente con il seguente contenuto';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'edit .htaccess';
+$lang['L_HTACCESS18'] = 'crea .htaccess in ';
+$lang['L_HTACCESS19'] = 'ricarica ';
+$lang['L_HTACCESS20'] = 'Esegui script';
+$lang['L_HTACCESS21'] = 'aggiungi fornitore(provider)';
+$lang['L_HTACCESS22'] = 'Rendi eseguibile';
+$lang['L_HTACCESS23'] = 'Lista directory';
+$lang['L_HTACCESS24'] = 'Documento errori';
+$lang['L_HTACCESS25'] = 'Attivare rewrite';
+$lang['L_HTACCESS26'] = 'Negare / Permettere';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Log degli errori';
+$lang['L_HTACCESS29'] = 'Altri esempi e documentazioni';
+$lang['L_HTACCESS30'] = 'Provider';
+$lang['L_HTACCESS31'] = 'Generale';
+$lang['L_HTACCESS32'] = 'Attenzione! .htaccess ha effetto direttamente sul browser.<br>Se viene usato in maniera scorretta le pagine non saranno piu accessibili.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Funzione disabilitata';
+$lang['L_NOGZPOSSIBLE'] = 'Poiché Zlib non è installato non puoi usare la funzione GZip!';
+$lang['L_DELETE_HTACCESS'] = 'Rimuovi la protezione (cancella .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "Impossibile scrivere il file o la directory '%s' .<br> O ha il proprietario sbagliato (Owner) o i diritti sbagliati (Chmod).<br> Vi preghiamo di modificare gli attributi correttamente con il vostro programma FTP. <br> Il file o la directory ha bisogno dei diritti %s.<br>";
+$lang['L_CANT_CREATE_DIR'] = "Impossibile creare la directory '%s'. Crearla manualmente con un programma di FTP.";
+$lang['L_TABLE_TYPE'] = 'Tipo';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - versione';
+$lang['L_NEW_MOD_VERSION'] = 'Nuova versione';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'È disponibile una nuova versione di MyOOS [Dumper].';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'impossibile trovare il file';
+$lang['L_INSTALLING_UPDATES'] = 'Installazione degli aggiornamenti';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Aggiornamento riuscito';
+$lang['L_UPDATE_FAILED'] = 'Aggiornamento fallito';
+$lang['L_UP_TO_DATE'] = 'La versione corrente è aggiornata';
diff --git a/msd/language/it/lang_restore.php b/msd/language/it/lang_restore.php
index d50f269a..3272fb6d 100644
--- a/msd/language/it/lang_restore.php
+++ b/msd/language/it/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Finora sono stati create <b>%d</b> tabelle.";
-$lang['L_FILE_MISSING']="impossibile trovare il file";
-$lang['L_RESTORE_DB']="Database '<b>%s</b>' sul Server '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> tabelle sono state create.";
-$lang['L_RESTORE_RUN1']="<br>Finora sono stati aggiunti con successo da <b>%s</b> a <b>%s</b> record.";
-$lang['L_RESTORE_RUN2']="<br>Sto popolando la tabella '<b>%s</b>'.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> record sono stati inseriti.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Finora sono state create da <b>%d</b> a <b>%d</b> tabelle.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Congratulazioni!</b><br><br>Il database è stato ripristinato completamente.<br>Tutti i file del backup sono stati inseriti con successo.<br><br>Hai finito. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Errore:<br>Selezione del database <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> fallito!";
-$lang['L_FILE_OPEN_ERROR']="Errore: impossibile aprire il file.";
-$lang['L_PROGRESS_OVER_ALL']="Progresso totale";
-$lang['L_BACK_TO_OVERVIEW']="Riepilogo database";
-$lang['L_RESTORE_RUN0']="<br>Finora sono stati aggiunti con successo da <b>%s</b> a <b>%s</b> record.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Comando SQL sconosciuto.";
-$lang['L_NOTICES']="Avvisi";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Finora sono stati create <b>%d</b> tabelle.';
+$lang['L_FILE_MISSING'] = 'impossibile trovare il file';
+$lang['L_RESTORE_DB'] = "Database '<b>%s</b>' sul Server '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> tabelle sono state create.';
+$lang['L_RESTORE_RUN1'] = '<br>Finora sono stati aggiunti con successo da <b>%s</b> a <b>%s</b> record.';
+$lang['L_RESTORE_RUN2'] = "<br>Sto popolando la tabella '<b>%s</b>'.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> record sono stati inseriti.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Finora sono state create da <b>%d</b> a <b>%d</b> tabelle.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Congratulazioni!</b><br><br>Il database è stato ripristinato completamente.<br>Tutti i file del backup sono stati inseriti con successo.<br><br>Hai finito. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>Errore:<br>Selezione del database <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> fallito!';
+$lang['L_FILE_OPEN_ERROR'] = 'Errore: impossibile aprire il file.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progresso totale';
+$lang['L_BACK_TO_OVERVIEW'] = 'Riepilogo database';
+$lang['L_RESTORE_RUN0'] = '<br>Finora sono stati aggiunti con successo da <b>%s</b> a <b>%s</b> record.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Comando SQL sconosciuto.';
+$lang['L_NOTICES'] = 'Avvisi';
diff --git a/msd/language/it/lang_sql.php b/msd/language/it/lang_sql.php
index 76dfecea..2a9a5297 100644
--- a/msd/language/it/lang_sql.php
+++ b/msd/language/it/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="comando";
-$lang['L_IMPORT_NOTABLE']="Non è stato scelta nessuna tabella per l`importazione!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="L`esucuzione di comandi SQL potrebbe modificare i dati. L`autore non si prende alcuna responsabilità riguarda la perdita di questi dati.";
-$lang['L_SQL_EXEC']="Eseguire comandi SQL";
-$lang['L_SQL_DATAVIEW']="Visualizzare dati";
-$lang['L_SQL_TABLEVIEW']="Riepilogo tabelle";
-$lang['L_SQL_VONINS']="di totale";
-$lang['L_SQL_NODATA']="nessun record";
-$lang['L_SQL_RECORDUPDATED']="Record è stato cambiato";
-$lang['L_SQL_RECORDINSERTED']="Record è stato salvato";
-$lang['L_SQL_BACKDBOVERVIEW']="torna dal Riepilogo database";
-$lang['L_SQL_RECORDDELETED']="Record è stato cancellato";
-$lang['L_ASKTABLEEMPTY']="Vuoi svuotare la tabella `%s` ?";
-$lang['L_SQL_RECORDEDIT']="edit record";
-$lang['L_SQL_RECORDNEW']="inserire nuovo record";
-$lang['L_ASKDELETERECORD']="Vuoi cancellare questo record?";
-$lang['L_ASKDELETETABLE']="Vuoi cancellare la tabella `%s` ?";
-$lang['L_SQL_BEFEHLE']="Comandi-SQL";
-$lang['L_SQL_BEFEHLNEU']="nuovo comando";
-$lang['L_SQL_BEFEHLSAVED1']="Comando-SQL";
-$lang['L_SQL_BEFEHLSAVED2']="è stato aggiunto";
-$lang['L_SQL_BEFEHLSAVED3']="è stato salvato";
-$lang['L_SQL_BEFEHLSAVED4']="è stato spostato sopra";
-$lang['L_SQL_BEFEHLSAVED5']="è stato cancellato";
-$lang['L_SQL_QUERYENTRY']="La query contiene";
-$lang['L_SQL_COLUMNS']="Colonne";
-$lang['L_ASKDBDELETE']="Vuoi cancellare questo database `%s` con tutto il suo contenuto?";
-$lang['L_ASKDBEMPTY']="Vuoi svuotare veramente il database `%s` ?";
-$lang['L_ASKDBCOPY']="Vuoi copiare il contenuto di questo database `%s` nel database `%s`?";
-$lang['L_SQL_TABLENEW']="Edit tabella";
-$lang['L_SQL_OUTPUT']="Output SQL";
-$lang['L_DO_NOW']="esegui ora";
-$lang['L_SQL_NAMEDEST_MISSING']="Nome del database di destinazione mancante!";
-$lang['L_ASKDELETEFIELD']="Vuoi cancellare questo campo?";
-$lang['L_SQL_COMMANDS_IN']=" riga in ";
-$lang['L_SQL_COMMANDS_IN2']="  sec. parsed.";
-$lang['L_SQL_OUT1']="Eseguito";
-$lang['L_SQL_OUT2']="Comandi";
-$lang['L_SQL_OUT3']="C'erano";
-$lang['L_SQL_OUT4']="Commenti";
-$lang['L_SQL_OUT5']="Poiché il risultato contiene piu di 5000 righe, queste non sono visibili.";
-$lang['L_SQL_SELECDB']="Seleziona database";
-$lang['L_SQL_TABLESOFDB']="Tabelle del database";
-$lang['L_SQL_EDIT']="edit";
-$lang['L_SQL_NOFIELDDELETE']="Impossibile cancellare perchè una tabella deve avere almeno un campo.";
-$lang['L_SQL_FIELDDELETE1']="Il campo";
-$lang['L_SQL_DELETED']="è stato cancellato";
-$lang['L_SQL_CHANGED']="è stato cambiato.";
-$lang['L_SQL_CREATED']="è stato creato.";
-$lang['L_SQL_NODEST_COPY']="Senza destinazione non si può copiare!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Tabella di destinazione già esistente!";
-$lang['L_SQL_SCOPY']="La struttura della tabella `%s` e stata copiata in `%s`.";
-$lang['L_SQL_TCOPY']="La tabella `%s` è stata copiata con dati in tabella `%s`.";
-$lang['L_SQL_TABLENONAME']="La tabella ha bisogno di un nome!";
-$lang['L_SQL_TBLNAMEEMPTY']="Il nome della tabella non deve essere vuoto!";
-$lang['L_SQL_COLLATENOTMATCH']="Set di caratteri(Charset) ed assortimento(Collation) incompatibili!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Errore: nome del campo non valido";
-$lang['L_SQL_CREATETABLE']="crea tabella";
-$lang['L_SQL_COPYTABLE']="copia tabelle";
-$lang['L_SQL_STRUCTUREONLY']="solo struttura";
-$lang['L_SQL_STRUCTUREDATA']="Struttura e Dati";
-$lang['L_SQL_NOTABLESINDB']="Non ci sono tabelle nel database";
-$lang['L_SQL_SELECTTABLE']="Seleziona tabella";
-$lang['L_SQL_SHOWDATATABLE']="Guarda dati della tabella";
-$lang['L_SQL_TBLPROPSOF']="Proprietà della tabella da";
-$lang['L_SQL_EDITFIELD']="Edit campo";
-$lang['L_SQL_NEWFIELD']="Nuovo campo";
-$lang['L_SQL_INDEXES']="Indice";
-$lang['L_SQL_ATPOSITION']="inserire nella posizione";
-$lang['L_SQL_FIRST']="prima";
-$lang['L_SQL_AFTER']="dopo";
-$lang['L_SQL_CHANGEFIELD']="cambia campo";
-$lang['L_SQL_INSERTFIELD']="inserisci campo";
-$lang['L_SQL_INSERTNEWFIELD']="inserisci nuovo campo";
-$lang['L_SQL_TABLEINDEXES']="Indice della tabella";
-$lang['L_SQL_ALLOWDUPS']="Duplicati permessi";
-$lang['L_SQL_CARDINALITY']="Cardinalità";
-$lang['L_SQL_TABLENOINDEXES']="La tabella non contiene l`indice";
-$lang['L_SQL_CREATEINDEX']="crea nuovo indice";
-$lang['L_SQL_WASEMPTIED']="è stato svuotato";
-$lang['L_SQL_RENAMEDTO']="è stato rinominato in";
-$lang['L_SQL_DBCOPY']="Il contenuto del database `%s` è stato copiato nel database `%s`.";
-$lang['L_SQL_DBSCOPY']="La struttura del database `%s` è stata copiata nel database `%s`.";
-$lang['L_SQL_WASCREATED']="stato creato";
-$lang['L_SQL_RENAMEDB']="Rinomina database";
-$lang['L_SQL_ACTIONS']="Azioni";
-$lang['L_SQL_CHOOSEACTION']="Seleziona azione";
-$lang['L_SQL_DELETEDB']="Cancella database";
-$lang['L_SQL_EMPTYDB']="Svuota database";
-$lang['L_SQL_COPYDATADB']="Copia l`intero database in";
-$lang['L_SQL_COPYSDB']="Copia struttura in database";
-$lang['L_SQL_IMEXPORT']="Importa / Esporta";
-$lang['L_INFO_RECORDS']="Record";
-$lang['L_NAME']="Nome";
-$lang['L_ASKTABLEEMPTYKEYS']="Vuoi svuotare la tabella `%s` e cancellare l`indice?";
-$lang['L_EDIT']="edit";
-$lang['L_DELETE']="elimina";
-$lang['L_EMPTY']="svuota";
-$lang['L_EMPTYKEYS']="svuota e cancella l`indice";
-$lang['L_SQL_TABLEEMPTIED']="La tabella `%s` e stata svuotata.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="La tabella `%s` è stata svuotata e l`ìndice è stato cancellato.";
-$lang['L_SQL_LIBRARY']="SQL-Library";
-$lang['L_SQL_ATTRIBUTES']="Attributi";
-$lang['L_SQL_UPLOADEDFILE']="File caricato: ";
-$lang['L_SQL_IMPORT']="Import del database `%s`";
-$lang['L_EXPORT']="Esporta";
-$lang['L_IMPORT']="Importa";
-$lang['L_IMPORTOPTIONS']="Opzioni di importazione";
-$lang['L_CSVOPTIONS']="Opzioni-CSV";
-$lang['L_IMPORTTABLE']="Importa nella tabella";
-$lang['L_NEWTABLE']="tabella nuova";
-$lang['L_IMPORTSOURCE']="Sorgente di importazione";
-$lang['L_FROMTEXTBOX']="dal campo testo";
-$lang['L_FROMFILE']="dal file";
-$lang['L_EMPTYTABLEBEFORE']="Svuota prima la tabella";
-$lang['L_CREATEAUTOINDEX']="Creare indice automatico";
-$lang['L_CSV_NAMEFIRSTLINE']="nome del campo nella prima riga";
-$lang['L_CSV_FIELDSEPERATE']="Campi separati con";
-$lang['L_CSV_FIELDSENCLOSED']="Campi inclusi in";
-$lang['L_CSV_FIELDSESCAPE']="Campi sfuggiti da";
-$lang['L_CSV_EOL']="Linee separate con";
-$lang['L_CSV_NULL']="Cambia ZERO con";
-$lang['L_CSV_FILEOPEN']="aprire file CSV";
-$lang['L_IMPORTIEREN']="importare";
-$lang['L_SQL_EXPORT']="Esportazione del database `%s`";
-$lang['L_EXPORTOPTIONS']="Opzioni di esportazione";
-$lang['L_EXCEL2003']="Excel 2003";
-$lang['L_SHOWRESULT']="Visualizzare il risultato";
-$lang['L_SENDRESULTASFILE']="Inviare risultato come file";
-$lang['L_EXPORTLINES']="<strong>%s</strong> righe da esportare";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="La quantità dei campi della tabella non coincide con i dati da importare (%d al posto di %d).";
-$lang['L_CSV_FIELDSLINES']="%d campi trovati, totale %d righe";
-$lang['L_CSV_ERRORCREATETABLE']="Errore nella creazione della tabella `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="Scegli un file.";
-$lang['L_CSV_NODATA']="File da importare non trovato!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="funzioni generali";
-$lang['L_SQLLIB_RESETAUTO']="ripristina autoincremento";
-$lang['L_SQLLIB_BOARDS']="Board";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="disattiva Board";
-$lang['L_SQLLIB_ACTIVATEBOARD']="attivare Board";
-$lang['L_SQL_NOTABLESSELECTED']="Non ci sono tabelle selezionate !";
-$lang['L_TOOLS']="Tools";
-$lang['L_TOOLS_TOOLBOX']="Scegliere database / Funzione database / Importa e Esporta ";
-$lang['L_SQL_OPENFILE']="aprire file - SQL";
-$lang['L_SQL_OPENFILE_BUTTON']="Caricare";
-$lang['L_MAX_UPLOAD_SIZE']="Grandezza massima del file";
-$lang['L_SQL_SEARCH']="Ricerca";
-$lang['L_SQL_SEARCHWORDS']="Parola(e) di ricerca";
-$lang['L_START_SQL_SEARCH']="esegui ricerca";
-$lang['L_RESET_SEARCHWORDS']="resetta ricerca";
-$lang['L_SEARCH_OPTIONS']="Opzione di ricerca";
-$lang['L_SEARCH_RESULTS']="La ricera di \"<b>%s</b>\" nella tabella \"<b>%s</b>\" ha portato al seguente risultato";
-$lang['L_SEARCH_NO_RESULTS']="La ricera \"<b>%s</b>\" nella tabella \"<b>%s</b>\" non ha prodotto risultati!";
-$lang['L_NO_ENTRIES']="La tabella \"<b>%s</b>\" è vuota.";
-$lang['L_SEARCH_ACCESS_KEYS']="Sfogliare: avanti=ALT+V, indietro=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="una colonna deve contenere almeno una parola di ricerca";
-$lang['L_SEARCH_OPTIONS_CONCAT']="un record deve contenere tutte le parole di ricerca, però possono essere in colonne diverse (Calcolo intensivo!)";
-$lang['L_SEARCH_OPTIONS_AND']="una colonna deve contenere tutte le parole di ricerca";
-$lang['L_SEARCH_IN_TABLE']="cerca nelle tabelle";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Edit struttura tabelle";
-$lang['L_DEFAULT_CHARSET']="Set di caretteri standard";
-$lang['L_TITLE_KEY_PRIMARY']="Chiave primaria";
-$lang['L_TITLE_KEY_UNIQUE']="Chiave unica";
-$lang['L_TITLE_INDEX']="Indice";
-$lang['L_TITLE_KEY_FULLTEXT']="Chiave testo pieno";
-$lang['L_TITLE_NOKEY']="Nessuna chiave";
-$lang['L_TITLE_SEARCH']="Cerca";
-$lang['L_TITLE_MYSQL_HELP']="Documentazione MySQL";
-$lang['L_TITLE_UPLOAD']="Carica dati-SQL";
-$lang['L_PRIMARYKEY_DELETED']="Chiave primaria cancellata";
-$lang['L_PRIMARYKEY_NOTFOUND']="Chiave primaria non trovata";
-$lang['L_PRIMARYKEYS_CHANGED']="Chiave primaria cambiata";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Errore nel cambiare della chiave primaria";
-$lang['L_SQL_VIEW_COMPACT']="Visualizza: compatto";
-$lang['L_SQL_VIEW_STANDARD']="Visualizza: normale";
-$lang['L_FIELDS_OF_TABLE']="Campi della tabella";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="Grandezza";
-$lang['L_TABLE_TYPE']="Tipo";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'comando';
+$lang['L_IMPORT_NOTABLE'] = 'Non è stato scelta nessuna tabella per l`importazione!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'L`esucuzione di comandi SQL potrebbe modificare i dati. L`autore non si prende alcuna responsabilità riguarda la perdita di questi dati.';
+$lang['L_SQL_EXEC'] = 'Eseguire comandi SQL';
+$lang['L_SQL_DATAVIEW'] = 'Visualizzare dati';
+$lang['L_SQL_TABLEVIEW'] = 'Riepilogo tabelle';
+$lang['L_SQL_VONINS'] = 'di totale';
+$lang['L_SQL_NODATA'] = 'nessun record';
+$lang['L_SQL_RECORDUPDATED'] = 'Record è stato cambiato';
+$lang['L_SQL_RECORDINSERTED'] = 'Record è stato salvato';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'torna dal Riepilogo database';
+$lang['L_SQL_RECORDDELETED'] = 'Record è stato cancellato';
+$lang['L_ASKTABLEEMPTY'] = 'Vuoi svuotare la tabella `%s` ?';
+$lang['L_SQL_RECORDEDIT'] = 'edit record';
+$lang['L_SQL_RECORDNEW'] = 'inserire nuovo record';
+$lang['L_ASKDELETERECORD'] = 'Vuoi cancellare questo record?';
+$lang['L_ASKDELETETABLE'] = 'Vuoi cancellare la tabella `%s` ?';
+$lang['L_SQL_BEFEHLE'] = 'Comandi-SQL';
+$lang['L_SQL_BEFEHLNEU'] = 'nuovo comando';
+$lang['L_SQL_BEFEHLSAVED1'] = 'Comando-SQL';
+$lang['L_SQL_BEFEHLSAVED2'] = 'è stato aggiunto';
+$lang['L_SQL_BEFEHLSAVED3'] = 'è stato salvato';
+$lang['L_SQL_BEFEHLSAVED4'] = 'è stato spostato sopra';
+$lang['L_SQL_BEFEHLSAVED5'] = 'è stato cancellato';
+$lang['L_SQL_QUERYENTRY'] = 'La query contiene';
+$lang['L_SQL_COLUMNS'] = 'Colonne';
+$lang['L_ASKDBDELETE'] = 'Vuoi cancellare questo database `%s` con tutto il suo contenuto?';
+$lang['L_ASKDBEMPTY'] = 'Vuoi svuotare veramente il database `%s` ?';
+$lang['L_ASKDBCOPY'] = 'Vuoi copiare il contenuto di questo database `%s` nel database `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Edit tabella';
+$lang['L_SQL_OUTPUT'] = 'Output SQL';
+$lang['L_DO_NOW'] = 'esegui ora';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Nome del database di destinazione mancante!';
+$lang['L_ASKDELETEFIELD'] = 'Vuoi cancellare questo campo?';
+$lang['L_SQL_COMMANDS_IN'] = ' riga in ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sec. parsed.';
+$lang['L_SQL_OUT1'] = 'Eseguito';
+$lang['L_SQL_OUT2'] = 'Comandi';
+$lang['L_SQL_OUT3'] = "C'erano";
+$lang['L_SQL_OUT4'] = 'Commenti';
+$lang['L_SQL_OUT5'] = 'Poiché il risultato contiene piu di 5000 righe, queste non sono visibili.';
+$lang['L_SQL_SELECDB'] = 'Seleziona database';
+$lang['L_SQL_TABLESOFDB'] = 'Tabelle del database';
+$lang['L_SQL_EDIT'] = 'edit';
+$lang['L_SQL_NOFIELDDELETE'] = 'Impossibile cancellare perchè una tabella deve avere almeno un campo.';
+$lang['L_SQL_FIELDDELETE1'] = 'Il campo';
+$lang['L_SQL_DELETED'] = 'è stato cancellato';
+$lang['L_SQL_CHANGED'] = 'è stato cambiato.';
+$lang['L_SQL_CREATED'] = 'è stato creato.';
+$lang['L_SQL_NODEST_COPY'] = 'Senza destinazione non si può copiare!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Tabella di destinazione già esistente!';
+$lang['L_SQL_SCOPY'] = 'La struttura della tabella `%s` e stata copiata in `%s`.';
+$lang['L_SQL_TCOPY'] = 'La tabella `%s` è stata copiata con dati in tabella `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'La tabella ha bisogno di un nome!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Il nome della tabella non deve essere vuoto!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Set di caratteri(Charset) ed assortimento(Collation) incompatibili!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Errore: nome del campo non valido';
+$lang['L_SQL_CREATETABLE'] = 'crea tabella';
+$lang['L_SQL_COPYTABLE'] = 'copia tabelle';
+$lang['L_SQL_STRUCTUREONLY'] = 'solo struttura';
+$lang['L_SQL_STRUCTUREDATA'] = 'Struttura e Dati';
+$lang['L_SQL_NOTABLESINDB'] = 'Non ci sono tabelle nel database';
+$lang['L_SQL_SELECTTABLE'] = 'Seleziona tabella';
+$lang['L_SQL_SHOWDATATABLE'] = 'Guarda dati della tabella';
+$lang['L_SQL_TBLPROPSOF'] = 'Proprietà della tabella da';
+$lang['L_SQL_EDITFIELD'] = 'Edit campo';
+$lang['L_SQL_NEWFIELD'] = 'Nuovo campo';
+$lang['L_SQL_INDEXES'] = 'Indice';
+$lang['L_SQL_ATPOSITION'] = 'inserire nella posizione';
+$lang['L_SQL_FIRST'] = 'prima';
+$lang['L_SQL_AFTER'] = 'dopo';
+$lang['L_SQL_CHANGEFIELD'] = 'cambia campo';
+$lang['L_SQL_INSERTFIELD'] = 'inserisci campo';
+$lang['L_SQL_INSERTNEWFIELD'] = 'inserisci nuovo campo';
+$lang['L_SQL_TABLEINDEXES'] = 'Indice della tabella';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplicati permessi';
+$lang['L_SQL_CARDINALITY'] = 'Cardinalità';
+$lang['L_SQL_TABLENOINDEXES'] = 'La tabella non contiene l`indice';
+$lang['L_SQL_CREATEINDEX'] = 'crea nuovo indice';
+$lang['L_SQL_WASEMPTIED'] = 'è stato svuotato';
+$lang['L_SQL_RENAMEDTO'] = 'è stato rinominato in';
+$lang['L_SQL_DBCOPY'] = 'Il contenuto del database `%s` è stato copiato nel database `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'La struttura del database `%s` è stata copiata nel database `%s`.';
+$lang['L_SQL_WASCREATED'] = 'stato creato';
+$lang['L_SQL_RENAMEDB'] = 'Rinomina database';
+$lang['L_SQL_ACTIONS'] = 'Azioni';
+$lang['L_SQL_CHOOSEACTION'] = 'Seleziona azione';
+$lang['L_SQL_DELETEDB'] = 'Cancella database';
+$lang['L_SQL_EMPTYDB'] = 'Svuota database';
+$lang['L_SQL_COPYDATADB'] = 'Copia l`intero database in';
+$lang['L_SQL_COPYSDB'] = 'Copia struttura in database';
+$lang['L_SQL_IMEXPORT'] = 'Importa / Esporta';
+$lang['L_INFO_RECORDS'] = 'Record';
+$lang['L_NAME'] = 'Nome';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Vuoi svuotare la tabella `%s` e cancellare l`indice?';
+$lang['L_EDIT'] = 'edit';
+$lang['L_DELETE'] = 'elimina';
+$lang['L_EMPTY'] = 'svuota';
+$lang['L_EMPTYKEYS'] = 'svuota e cancella l`indice';
+$lang['L_SQL_TABLEEMPTIED'] = 'La tabella `%s` e stata svuotata.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'La tabella `%s` è stata svuotata e l`ìndice è stato cancellato.';
+$lang['L_SQL_LIBRARY'] = 'SQL-Library';
+$lang['L_SQL_ATTRIBUTES'] = 'Attributi';
+$lang['L_SQL_UPLOADEDFILE'] = 'File caricato: ';
+$lang['L_SQL_IMPORT'] = 'Import del database `%s`';
+$lang['L_EXPORT'] = 'Esporta';
+$lang['L_IMPORT'] = 'Importa';
+$lang['L_IMPORTOPTIONS'] = 'Opzioni di importazione';
+$lang['L_CSVOPTIONS'] = 'Opzioni-CSV';
+$lang['L_IMPORTTABLE'] = 'Importa nella tabella';
+$lang['L_NEWTABLE'] = 'tabella nuova';
+$lang['L_IMPORTSOURCE'] = 'Sorgente di importazione';
+$lang['L_FROMTEXTBOX'] = 'dal campo testo';
+$lang['L_FROMFILE'] = 'dal file';
+$lang['L_EMPTYTABLEBEFORE'] = 'Svuota prima la tabella';
+$lang['L_CREATEAUTOINDEX'] = 'Creare indice automatico';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'nome del campo nella prima riga';
+$lang['L_CSV_FIELDSEPERATE'] = 'Campi separati con';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Campi inclusi in';
+$lang['L_CSV_FIELDSESCAPE'] = 'Campi sfuggiti da';
+$lang['L_CSV_EOL'] = 'Linee separate con';
+$lang['L_CSV_NULL'] = 'Cambia ZERO con';
+$lang['L_CSV_FILEOPEN'] = 'aprire file CSV';
+$lang['L_IMPORTIEREN'] = 'importare';
+$lang['L_SQL_EXPORT'] = 'Esportazione del database `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Opzioni di esportazione';
+$lang['L_EXCEL2003'] = 'Excel 2003';
+$lang['L_SHOWRESULT'] = 'Visualizzare il risultato';
+$lang['L_SENDRESULTASFILE'] = 'Inviare risultato come file';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> righe da esportare';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'La quantità dei campi della tabella non coincide con i dati da importare (%d al posto di %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d campi trovati, totale %d righe';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Errore nella creazione della tabella `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Scegli un file.';
+$lang['L_CSV_NODATA'] = 'File da importare non trovato!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'funzioni generali';
+$lang['L_SQLLIB_RESETAUTO'] = 'ripristina autoincremento';
+$lang['L_SQLLIB_BOARDS'] = 'Board';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'disattiva Board';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'attivare Board';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Non ci sono tabelle selezionate !';
+$lang['L_TOOLS'] = 'Tools';
+$lang['L_TOOLS_TOOLBOX'] = 'Scegliere database / Funzione database / Importa e Esporta ';
+$lang['L_SQL_OPENFILE'] = 'aprire file - SQL';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Caricare';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Grandezza massima del file';
+$lang['L_SQL_SEARCH'] = 'Ricerca';
+$lang['L_SQL_SEARCHWORDS'] = 'Parola(e) di ricerca';
+$lang['L_START_SQL_SEARCH'] = 'esegui ricerca';
+$lang['L_RESET_SEARCHWORDS'] = 'resetta ricerca';
+$lang['L_SEARCH_OPTIONS'] = 'Opzione di ricerca';
+$lang['L_SEARCH_RESULTS'] = 'La ricera di "<b>%s</b>" nella tabella "<b>%s</b>" ha portato al seguente risultato';
+$lang['L_SEARCH_NO_RESULTS'] = 'La ricera "<b>%s</b>" nella tabella "<b>%s</b>" non ha prodotto risultati!';
+$lang['L_NO_ENTRIES'] = 'La tabella "<b>%s</b>" è vuota.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Sfogliare: avanti=ALT+V, indietro=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'una colonna deve contenere almeno una parola di ricerca';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'un record deve contenere tutte le parole di ricerca, però possono essere in colonne diverse (Calcolo intensivo!)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'una colonna deve contenere tutte le parole di ricerca';
+$lang['L_SEARCH_IN_TABLE'] = 'cerca nelle tabelle';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Edit struttura tabelle';
+$lang['L_DEFAULT_CHARSET'] = 'Set di caretteri standard';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Chiave primaria';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Chiave unica';
+$lang['L_TITLE_INDEX'] = 'Indice';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Chiave testo pieno';
+$lang['L_TITLE_NOKEY'] = 'Nessuna chiave';
+$lang['L_TITLE_SEARCH'] = 'Cerca';
+$lang['L_TITLE_MYSQL_HELP'] = 'Documentazione MySQL';
+$lang['L_TITLE_UPLOAD'] = 'Carica dati-SQL';
+$lang['L_PRIMARYKEY_DELETED'] = 'Chiave primaria cancellata';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Chiave primaria non trovata';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Chiave primaria cambiata';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Errore nel cambiare della chiave primaria';
+$lang['L_SQL_VIEW_COMPACT'] = 'Visualizza: compatto';
+$lang['L_SQL_VIEW_STANDARD'] = 'Visualizza: normale';
+$lang['L_FIELDS_OF_TABLE'] = 'Campi della tabella';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'Grandezza';
+$lang['L_TABLE_TYPE'] = 'Tipo';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/lang_list.php b/msd/language/lang_list.php
index 7e53e096..9b9556c6 100644
--- a/msd/language/lang_list.php
+++ b/msd/language/lang_list.php
@@ -1,10 +1,11 @@
 <?php
+
 // *****************************************************************************
 // This file holds all available languages
 // *****************************************************************************
 
 // Array initialization
-$lang=Array();
+$lang = [];
 
 // *****************************************************************************
 // Add language to array. Must match directory name of the language.
@@ -12,114 +13,116 @@ GetLanguageArray();
 
 // *****************************************************************************
 // Language name in its own language.
-$lang['en']='English';
-$lang['de']='Deutsch';
-$lang['es']='Español';
-$lang['fr']='Français';
-$lang['it']='Italiano';
-$lang['nl']='Nederlands';
-$lang['sw']='Svenska';
-$lang['de_du']='Deutsch (mit Anredeform "du")';
-$lang['pt_br']='Portuguese - BR';
-$lang['tr']='Türkçe';
-$lang['da']='Dansk';
-$lang['lu']='Luxemburg';
-$lang['pl']='Polski';
-$lang['ch']='Schweizer Deutsch';
-$lang['ar']='Arabic';
-$lang['vn']='Vietnamese';
-$lang['el']='Ελληνικά';
+$lang['en'] = 'English';
+$lang['de'] = 'Deutsch';
+$lang['es'] = 'Español';
+$lang['fr'] = 'Français';
+$lang['it'] = 'Italiano';
+$lang['nl'] = 'Nederlands';
+$lang['sw'] = 'Svenska';
+$lang['de_du'] = 'Deutsch (mit Anredeform "du")';
+$lang['pt_br'] = 'Portuguese - BR';
+$lang['tr'] = 'Türkçe';
+$lang['da'] = 'Dansk';
+$lang['lu'] = 'Luxemburg';
+$lang['pl'] = 'Polski';
+$lang['ch'] = 'Schweizer Deutsch';
+$lang['ar'] = 'Arabic';
+$lang['vn'] = 'Vietnamese';
+$lang['el'] = 'Ελληνικά';
 
 // *****************************************************************************
 // Add the installation entries here, and you're done with this file. :-)
 
-$lang['L_TOOLS1']['de']='MyOOS [Dumper] deinstallieren';
-$lang['L_TOOLS2']['de']='Vorhandene Konfigurationssicherung importieren';
-$lang['L_TOOLS3']['de']='Konfigurationssicherung hochladen und importieren';
-$lang['L_TOOLS4']['de']='Konfigurationssicherung herunterladen';
+$lang['L_TOOLS1']['de'] = 'MyOOS [Dumper] deinstallieren';
+$lang['L_TOOLS2']['de'] = 'Vorhandene Konfigurationssicherung importieren';
+$lang['L_TOOLS3']['de'] = 'Konfigurationssicherung hochladen und importieren';
+$lang['L_TOOLS4']['de'] = 'Konfigurationssicherung herunterladen';
 
-$lang['L_TOOLS1']['de_du']='MyOOS [Dumper] deinstallieren';
-$lang['L_TOOLS2']['de_du']='Vorhandene Konfigurationssicherung importieren';
-$lang['L_TOOLS3']['de_du']='Konfigurationssicherung hochladen und importieren';
-$lang['L_TOOLS4']['de_du']='Konfigurationssicherung herunterladen';
+$lang['L_TOOLS1']['de_du'] = 'MyOOS [Dumper] deinstallieren';
+$lang['L_TOOLS2']['de_du'] = 'Vorhandene Konfigurationssicherung importieren';
+$lang['L_TOOLS3']['de_du'] = 'Konfigurationssicherung hochladen und importieren';
+$lang['L_TOOLS4']['de_du'] = 'Konfigurationssicherung herunterladen';
 
-$lang['L_TOOLS1']['en']='Uninstall MyOOS [Dumper]';
-$lang['L_TOOLS2']['en']='Import existing configuration backup';
-$lang['L_TOOLS3']['en']='Upload configuration backup and import';
-$lang['L_TOOLS4']['en']='Download Configuration Backup';
+$lang['L_TOOLS1']['en'] = 'Uninstall MyOOS [Dumper]';
+$lang['L_TOOLS2']['en'] = 'Import existing configuration backup';
+$lang['L_TOOLS3']['en'] = 'Upload configuration backup and import';
+$lang['L_TOOLS4']['en'] = 'Download Configuration Backup';
 
-$lang['L_TOOLS1']['es']='Desinstalar MyOOS [Dumper]';
-$lang['L_TOOLS2']['es']='Importar configuración existente';
-$lang['L_TOOLS3']['es']='Subir copia de la configuración e importar';
-$lang['L_TOOLS4']['es']='Crear y descargar una copia de la configuración';
+$lang['L_TOOLS1']['es'] = 'Desinstalar MyOOS [Dumper]';
+$lang['L_TOOLS2']['es'] = 'Importar configuración existente';
+$lang['L_TOOLS3']['es'] = 'Subir copia de la configuración e importar';
+$lang['L_TOOLS4']['es'] = 'Crear y descargar una copia de la configuración';
 
-$lang['L_TOOLS1']['fr']='Désinstaller MyOOS [Dumper]';
-$lang['L_TOOLS2']['fr']='Importation d\'une copie de sauvegarde existante';
-$lang['L_TOOLS3']['fr']='Télécharger une copie de sauvegarde sur le serveur ';
-$lang['L_TOOLS4']['fr']='Télécharger une copie de sauvegarde';
+$lang['L_TOOLS1']['fr'] = 'Désinstaller MyOOS [Dumper]';
+$lang['L_TOOLS2']['fr'] = 'Importation d\'une copie de sauvegarde existante';
+$lang['L_TOOLS3']['fr'] = 'Télécharger une copie de sauvegarde sur le serveur ';
+$lang['L_TOOLS4']['fr'] = 'Télécharger une copie de sauvegarde';
 
-$lang['L_TOOLS1']['it']='MyOOS [Dumper] disinstallare';
-$lang['L_TOOLS2']['it']='Importare l`attuale backup di configurazione';
-$lang['L_TOOLS3']['it']='Prelevare ed importare il backup di configurazione';
-$lang['L_TOOLS4']['it']='Scaricare backup di configurazione';
+$lang['L_TOOLS1']['it'] = 'MyOOS [Dumper] disinstallare';
+$lang['L_TOOLS2']['it'] = 'Importare l`attuale backup di configurazione';
+$lang['L_TOOLS3']['it'] = 'Prelevare ed importare il backup di configurazione';
+$lang['L_TOOLS4']['it'] = 'Scaricare backup di configurazione';
 
-$lang['L_TOOLS1']['nl']='MyOOS [Dumper] deinstalleren';
-$lang['L_TOOLS2']['nl']='Bestaande configuratie backup importeren';
-$lang['L_TOOLS3']['nl']='Upload configuratie backup en importeren';
-$lang['L_TOOLS4']['nl']='Download configuratie backup';
+$lang['L_TOOLS1']['nl'] = 'MyOOS [Dumper] deinstalleren';
+$lang['L_TOOLS2']['nl'] = 'Bestaande configuratie backup importeren';
+$lang['L_TOOLS3']['nl'] = 'Upload configuratie backup en importeren';
+$lang['L_TOOLS4']['nl'] = 'Download configuratie backup';
 
-$lang['L_TOOLS1']['sw']='Avinstallera MyOOS [Dumper]';
-$lang['L_TOOLS2']['sw']='Importera existerande konfigureringsbackup';
-$lang['L_TOOLS3']['sw']='Ladda upp och importera konfigureringsbackup';
-$lang['L_TOOLS4']['sw']='Ladda ner konfigureringsbackup';
+$lang['L_TOOLS1']['sw'] = 'Avinstallera MyOOS [Dumper]';
+$lang['L_TOOLS2']['sw'] = 'Importera existerande konfigureringsbackup';
+$lang['L_TOOLS3']['sw'] = 'Ladda upp och importera konfigureringsbackup';
+$lang['L_TOOLS4']['sw'] = 'Ladda ner konfigureringsbackup';
 
-$lang['L_TOOLS1']['pt_br']='Desinstalar MyOOS [Dumper]';
-$lang['L_TOOLS2']['pt_br']='Importar backup de configuração existente';
-$lang['L_TOOLS3']['pt_br']='Enviar backup da configuração e importar';
-$lang['L_TOOLS4']['pt_br']='Baixar backup da configuração';
+$lang['L_TOOLS1']['pt_br'] = 'Desinstalar MyOOS [Dumper]';
+$lang['L_TOOLS2']['pt_br'] = 'Importar backup de configuração existente';
+$lang['L_TOOLS3']['pt_br'] = 'Enviar backup da configuração e importar';
+$lang['L_TOOLS4']['pt_br'] = 'Baixar backup da configuração';
 
-$lang['L_TOOLS1']['tr']='MyOOS [Dumper]i kaldır';
-$lang['L_TOOLS2']['tr']='Ayar dosyasını içeri aktar';
-$lang['L_TOOLS3']['tr']='Ayar dosyasını yükle ve içeri aktar';
-$lang['L_TOOLS4']['tr']='Ayar dosyasını indir';
+$lang['L_TOOLS1']['tr'] = 'MyOOS [Dumper]i kaldır';
+$lang['L_TOOLS2']['tr'] = 'Ayar dosyasını içeri aktar';
+$lang['L_TOOLS3']['tr'] = 'Ayar dosyasını yükle ve içeri aktar';
+$lang['L_TOOLS4']['tr'] = 'Ayar dosyasını indir';
 
-$lang['L_TOOLS1']['da']='Afinstallér MyOOS [Dumper]';
-$lang['L_TOOLS2']['da']='Importér eksisterende konfigurationsbackup';
-$lang['L_TOOLS3']['da']='Upload og importér konfigurationsbackup';
-$lang['L_TOOLS4']['da']='Download konfigurationsbackup';
+$lang['L_TOOLS1']['da'] = 'Afinstallér MyOOS [Dumper]';
+$lang['L_TOOLS2']['da'] = 'Importér eksisterende konfigurationsbackup';
+$lang['L_TOOLS3']['da'] = 'Upload og importér konfigurationsbackup';
+$lang['L_TOOLS4']['da'] = 'Download konfigurationsbackup';
 
-$lang['L_TOOLS1']['lu']='MyOOS [Dumper] deinstallieren';
-$lang['L_TOOLS2']['lu']='Vorhandene Konfigurationssicherung importieren';
-$lang['L_TOOLS3']['lu']='Konfigurationssicherung hochladen und importieren';
-$lang['L_TOOLS4']['lu']='Konfigurationssicherung herunterladen';
+$lang['L_TOOLS1']['lu'] = 'MyOOS [Dumper] deinstallieren';
+$lang['L_TOOLS2']['lu'] = 'Vorhandene Konfigurationssicherung importieren';
+$lang['L_TOOLS3']['lu'] = 'Konfigurationssicherung hochladen und importieren';
+$lang['L_TOOLS4']['lu'] = 'Konfigurationssicherung herunterladen';
 
-$lang['L_TOOLS1']['pl']='Odinstaluj MyOOS [Dumper]';
-$lang['L_TOOLS2']['pl']='Zaimportuj istniejące ustawienia backupu';
-$lang['L_TOOLS3']['pl']='Prześil i zaimportuj ustawienia backupu';
-$lang['L_TOOLS4']['pl']='Ściągnij ustawienia backupu';
+$lang['L_TOOLS1']['pl'] = 'Odinstaluj MyOOS [Dumper]';
+$lang['L_TOOLS2']['pl'] = 'Zaimportuj istniejące ustawienia backupu';
+$lang['L_TOOLS3']['pl'] = 'Prześil i zaimportuj ustawienia backupu';
+$lang['L_TOOLS4']['pl'] = 'Ściągnij ustawienia backupu';
 
-$lang['L_TOOLS1']['ch']='MyOOS [Dumper] deinstallieren';
-$lang['L_TOOLS2']['ch']='Vorhandene Konfigurationssicherung importieren';
-$lang['L_TOOLS3']['ch']='Konfigurationssicherung hochladen und importieren';
-$lang['L_TOOLS4']['ch']='Konfigurationssicherung herunterladen';
+$lang['L_TOOLS1']['ch'] = 'MyOOS [Dumper] deinstallieren';
+$lang['L_TOOLS2']['ch'] = 'Vorhandene Konfigurationssicherung importieren';
+$lang['L_TOOLS3']['ch'] = 'Konfigurationssicherung hochladen und importieren';
+$lang['L_TOOLS4']['ch'] = 'Konfigurationssicherung herunterladen';
 
-$lang['L_TOOLS1']['ar']='Uninstall MyOOS [Dumper]';
-$lang['L_TOOLS2']['ar']='Import existing configuration backup';
-$lang['L_TOOLS3']['ar']='Upload configuration backup and import';
-$lang['L_TOOLS4']['ar']='Download Configuration Backup';
+$lang['L_TOOLS1']['ar'] = 'Uninstall MyOOS [Dumper]';
+$lang['L_TOOLS2']['ar'] = 'Import existing configuration backup';
+$lang['L_TOOLS3']['ar'] = 'Upload configuration backup and import';
+$lang['L_TOOLS4']['ar'] = 'Download Configuration Backup';
 
-$lang['L_TOOLS1']['vn']='Uninstall MyOOS [Dumper]';
-$lang['L_TOOLS2']['vn']='Import existing configuration backup';
-$lang['L_TOOLS3']['vn']='Upload configuration backup and import';
-$lang['L_TOOLS4']['vn']='Download Configuration Backup';
+$lang['L_TOOLS1']['vn'] = 'Uninstall MyOOS [Dumper]';
+$lang['L_TOOLS2']['vn'] = 'Import existing configuration backup';
+$lang['L_TOOLS3']['vn'] = 'Upload configuration backup and import';
+$lang['L_TOOLS4']['vn'] = 'Download Configuration Backup';
 
-$lang['L_TOOLS1']['el']='Απεγκατάσταση MyOOS [Dumper]';
-$lang['L_TOOLS2']['el']='Εισαγωγή υπάρχουσας αποθηκευμένης ρύθμισης';
-$lang['L_TOOLS3']['el']='Φόρτωση αποθηκευμένης ρύθμισης και εισαγωγή της';
-$lang['L_TOOLS4']['el']='Μεταφόρτωση αποθηκευμένης ρύθμισης';
+$lang['L_TOOLS1']['el'] = 'Απεγκατάσταση MyOOS [Dumper]';
+$lang['L_TOOLS2']['el'] = 'Εισαγωγή υπάρχουσας αποθηκευμένης ρύθμισης';
+$lang['L_TOOLS3']['el'] = 'Φόρτωση αποθηκευμένης ρύθμισης και εισαγωγή της';
+$lang['L_TOOLS4']['el'] = 'Μεταφόρτωση αποθηκευμένης ρύθμισης';
 
 // *****************************************************************************
 // Language defaults to english.
 
-if (!in_array($config['language'],$lang['languages'])) $config['language']='en';
-include_once('./language/'.$config['language'].'/lang.php');
+if (!in_array($config['language'], $lang['languages'])) {
+    $config['language'] = 'en';
+}
+include_once './language/'.$config['language'].'/lang.php';
diff --git a/msd/language/pt_br/help.html b/msd/language/pt_br/help.html
new file mode 100644
index 00000000..64a1411b
--- /dev/null
+++ b/msd/language/pt_br/help.html
@@ -0,0 +1,147 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/pt_br/help.php b/msd/language/pt_br/help.php
deleted file mode 100644
index e0be00d0..00000000
--- a/msd/language/pt_br/help.php
+++ /dev/null
@@ -1,156 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Sobre este Projeto </h3>
-<SPAN id=BABID_Results>A idéia para este projeto é de Daniel Schlichtholz.</SPAN>
-<p>Em 2004 ele criou um fórum chamado <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> e logo , programadores estavam escrevendo novos scripts, que complementavam os scripts de Daniel.<br>
-Depois de um período curto de tempo um pequeno script de backup tinha se tornado um projeto robusto e avançado.
-<p>Se você tiver alguma sugestão de aperfeiçoamento por favor visite o fórum do MySQLDumper: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.
-<p>Nós esperamos que você tenha bons momentos com este projeto!<br>
-<br>
-<h4>Equipe do  MySQLDumper</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-
-<h3>Ajuda do MySQLDumper</h3>
-
-<h4>Download</h4>
-O script está disponível na página principal do  MySQLDumper.<br>
-Recomendamos que você visite a página principal com frequência para obter as últimas informações, atualizações e ajuda.<br>
-O endereço é
-<a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>Requisitos de sistema obrigatórios </h4>
-O script funciona em praticamente qualquer tipo de servidor (Windows, Linux, ...) <br>
-e PHP >= Version 4.3.4 com GZip-Library, MySQL (>= 3.23), JavaScript (deve estar habilitado).
-
-<a href="install.php?language=de" target="_top">
-<h4>Instalação</h4>
-</a>
-A Instalação é muito fácil.
-Descompacte o arquivo em qualquer pasta, com acesso permitido, no servidor<br>
-(p.ex. no diretório raiz [Server rootdir/]MySQLDumper)<br>
-altere o config.php para chmod 777 <br>
-... e pronto!<br>
-você pode executar o  MySQLDumper em seu navegador digitando"http://webserver/MySQLDumper"
-para completar o setup, simplesmente siga as instruções.
-
-<br>
-<b>Nota:</b><br>
-<i>Se o seu  webserver operar com a opção safemode=ON, o MySqlDump pode não conseguir criar os diretórios.<br>
-você deverá fazê-lo, criando os diretórios você mesmo.<br>
-O MySqlDump vai parar, neste caso, e dizer a você o quê fazer.<br>
-Depois de criados os diretórios o  MySqlDump irá funcionar normalmente.</i><br>
-
-<a name="perl"></a>
-<h4>Guia para o script  Perl </h4>
-
-Muitos tem um diretório  cgi-bin , no qual scripts  Perl podem ser executados. <br>
-Normalmente isto é feito pelo navegador, i.é, http://www.domain.de/cgi-bin/ script disponível. <br>
-<br>
-
-Siga os seguintes passos, por favor.  <br>
-<br>
-
-1. Carregue no MySQLDumper a página Backup e clique em "Backup Perl"   <br>
-2. Copie o path, antes da entrada em  crondump.pl para $absolute_path_of_configdir:    <br>
-3. Abra o arquivoe "crondump.pl" em um editor <br>
-4. Cole o path copiado como absolute_path_of_configdir (sem espaços em branco) <br>
-5. Salve o crondump.pl <br>
-6. Copie o crondump.pl, como perltest.pl e simpletest.pl para o diretório cgi-bin (use o modo ASCII do seu prog. de ftp!) <br>
-7. Aplique chmod 755 nos scripts.  <br>
-7b. Se o final do cgi for pedido, mude o final de todos os 3 arquivos pl - >cgi (renomear)<br>
-8.  Carregue a página Configuração no  MySQLDumper<br>
-9. Clique em Cronscript <br>
-10. Altere a execução do path do para  /cgi-bin/<br>
-10b. Se os scripts foram renomeados para *.cgi, altere a extensão do arquivo para cgii <br>
-11. Salve a Configuração<br>
-<br>
-
-Pronto ! Os scripts estão disponíveis a partir da página "Backup" <br>
-<br>
-
-Quando você executar o Perl em qualquer lugar, somente os seguintes passos são necessários:  <br>
-<br>
-
-1. Carregue no MySQLDumper a página Backup.  <br>
-2. Copie o path, antes da entrada em  crondump.pl para $absolute_path_of_configdir:    <br>
-3. Abra o arquivo "crondump.pl" no seu editor<br>
-4. Cole o path copiado como absolute_path_of_configdir (sem espaços em branco) <br>
-5.  Salve o crondump.pl <br>
-
-6. Aplique chmod 755 nestes scripts.  <br>
-6b.Se o final do cgi for pedido, mude o final de todos os 3 arquivos pl - >;cgi (renomear)<br>
-(ver 10b+11 acima) <br>
-<br>
-
-
-Usuários do windows devem alterar a primeira linha de todos os scripts Perl, para o path do Perl.<br>
-<br>
-
-Exemplo:  <br>
-
-em lugar de:  #!/usr/bin/perl w <br>
-agora #!C:\perl\bin\perl.exe w<br>
-
-<h4>Operação</h4>
-<ul>
-
-<h6>Menu</h6>
-Na caixa de seleção acima você deve escolher o banco de dados.<br>
-Todas as ações serão para este banco de dados.
-
-<h6>Inicial</h6>
-Aqui você irá obter informação sobre o sistema, os números da versão e detalhes
-sobre as configurações do banco de dados.<br>
-Se você clicar em um banco de dados na caixa de seleção, irá ver a lista de tabelas
-com os registros de gravação, tamanho e a data da última atualização.
-<h6>Configuração</h6>
-Aqui você pode editar sua Configuração, salvá-la ou carregar as configurações
-padrão.
-<ul>
-	<li><a name="conf1"></a><strong>Bancos de Dados Configurados:</strong> lista dos bancos
-	  de dados. O bd ativo está em negrito.</li>
-	<li><a name="conf2"></a><strong>Prefixo da Tabela:</strong> você pode escolher um prefixo
-	  para cada bd separadamente. O prefixo pode operar como um filtro, o que permite que você escolha tabelas em um backup, que comecem com esse prefixo (p.ex. todas as tabelas que comecem com "phpBB_").
-	  Se você não for usar isto deixe este campo em branco.</li>
-	<li><a name="conf3"></a><strong>GZip-Compression:</strong> Aqui você pode ativar a compressão. é recomendável trabalhar com compressão por conta do tamanho dos arquivos: espaço em disco sempre é algo precioso, não é?</li>
-	<li><a name="conf19"></a><strong>Contagem de Registros para Backup:</strong> Número de registros lidos simultaneamente durante o processo de backup, antes do registro fazer nova chamada. Em servidores lentos você deve reduzir este parâmetro para prevenir timeouts.</li>
-	<li><a name="conf20"></a><strong>Contagem de Registros para restaurar:</strong>  Número de registros lidos simultaneamente durante o processo de restauração, antes do registro fazer nova chamada.Em servidores lentos você deve reduzir este parâmetro para prevenir timeouts</li>
-	<li><a name="conf4"></a><strong>diretório para arquivos de backup:</strong> escolha seu diretório para os arquivos de backup. Se você quiser criar um, o script irá criar um para você. você pode usar paths relativos ou absolutos.</li>
-	<li><a name="conf5"></a><strong>Enviar arquivo de backup como e-mail:</strong> Quando esta opção está ativa, o script irá encaminhar automaticamente o arquivo de backup como anexo do e-mail (cuidado!, você deve usar a opção de comprimir os arquivos porquê os arquivos de backup podem ficar muito grandes para serem encaminhados por eamail!</li>
-	<li><a name="conf6"></a><strong>endereço de e-mail:</strong> endereço do e-mail do destinatário </li>
-	<li><a name="conf7"></a><strong>Assunto do E-mail:</strong> Assunto do e-mail </li>
-	<li><a name="conf13"></a><strong>Transferência por FTP: </strong>Quando esta opção estiver ativa, o script irá, automaticamente, enviar o arquivo de backup via FTP.</li>
-	<li><a name="conf14"></a><strong>Servidor de FTP: </strong>endereço do servidor de FTP
-	  (p.ex. ftp.mybackups.de)</li>
-	<li><a name="conf15"></a><strong>Porta do Servidor de FTP: </strong>a Porta do Servidor de FTP (normalmente 21)</li>
-	<li><a name="conf16"></a><strong>Usuário do FTP: </strong>nome de Usuário da conta de FTP</li>
-	<li><a name="conf17"></a><strong>Senha do FTP: </strong>senha da conta de FTP</li>
-	<li><a name="conf18"></a><strong>FTP - diretório para upload: </strong>diretório/pasta para salvar os arquivos de backup (tem de ter permissão para upload!)</li>
-
-	<li><a name="conf8"></a><strong>Apagar backups automaticamente:</strong> Quando você ativar esta opção os arquivos de backup serão apagados automaticamente segundo as configurações a seguir.</li>
-	<li><a name="conf10"></a><strong>Apagar por Número de arquivos:</strong> Um valor > 0
-	  apagará todos os que excederem o valor determinado</li>
-	<li><a name="conf11"></a><strong>Idioma:</strong> escolha a linguagem para a interface.</li>
-</ul>
-
-<h6>Gerenciamento</h6>
-Todas as ações estão listadas aqui.<br>
-Você poderá ver todos os arquivos do diretório de backup .Para realizar as ações
-de "Restore" e "Backup" você deve selecionar um arquivo primeiro.
-<UL>
-	<li><strong>Restaurar:</strong> você restaura o banco de dados com os registros
-	  do arquivo de backup selecionado.</li>
-	<li><strong>Apagar:</strong> você pode apagar o arquivo de backup selecionado.</li>
-	<li><strong>Iniciar novo Dump:</strong> aqui você inicia um novo backup (dump)
-	  com seus parâmetros anteriormente configurados.</li>
-</UL>
-
-<h6>Log</h6>
-você pode ler os registros de Log e apagá-los.
-<h6>Créditos/Ajuda</h6>
-Esta página.
-</ul>
\ No newline at end of file
diff --git a/msd/language/pt_br/lang.php b/msd/language/pt_br/lang.php
index fcaf3cbd..ce7ea6b2 100644
--- a/msd/language/pt_br/lang.php
+++ b/msd/language/pt_br/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="sim";
-$lang['L_TO']="para";
-$lang['L_ACTIVATED']="ativado";
-$lang['L_NOT_ACTIVATED']="não ativado";
-$lang['L_ERROR']="Erro";
-$lang['L_OF']=" de ";
-$lang['L_ADDED']="adicionado";
-$lang['L_DB']="Banco de dados";
-$lang['L_DBS']="Bancos de dados";
-$lang['L_TABLES']="Tabelas";
-$lang['L_TABLE']="Tabela";
-$lang['L_RECORDS']="Registros";
-$lang['L_COMPRESSED']="compactado (gz)";
-$lang['L_NOTCOMPRESSED']="normal (não compactado)";
-$lang['L_GENERAL']="geral";
-$lang['L_COMMENT']="Comentário";
-$lang['L_FILESIZE']="Tamanho do arquivo";
-$lang['L_ALL']="todos";
-$lang['L_NONE']="nenhum";
-$lang['L_WITH']=" com ";
-$lang['L_DIR']="Diretório";
-$lang['L_RECHTE']="Permissões";
-$lang['L_STATUS']="Estado";
-$lang['L_FINISHED']="terminado";
-$lang['L_FILE']="Arquivo";
-$lang['L_FIELDS']="campos";
-$lang['L_NEW']="novo";
-$lang['L_CHARSET']="Conjunto de caracteres";
-$lang['L_COLLATION']="Collation";
-$lang['L_CHANGE']="alterar";
-$lang['L_IN']="em";
-$lang['L_DO']="Executar";
-$lang['L_VIEW']="exibir";
-$lang['L_EXISTING']="existente";
-$lang['L_BACK']="voltar";
-$lang['L_DB_HOST']="Host";
-$lang['L_DB_USER']="Usuáio";
-$lang['L_DB_PASS']="Senha";
-$lang['L_INFO_SCRIPTDIR']="Diretório do MySQLDumper";
-$lang['L_INFO_ACTDB']="Banco de dados atual";
-$lang['L_WRONGCONNECTIONPARS']="Incorreto ou nenhum parâmetro de conexão!";
-$lang['L_CONN_NOT_POSSIBLE']="Conexão impossível !";
-$lang['L_SERVERCAPTION']="Exibir servidor";
-$lang['L_HELP_SERVERCAPTION']="Ao usar o MySQLDumper em domínios ou servidores diferentes, pode ser útil exibir o nome do domínio/servidor no topo da tela.";
-$lang['L_ACTIVATE_MULTIDUMP']="ativar Multi-dump";
-$lang['L_SAVE']="Salvar";
-$lang['L_RESET']="Reiniciar";
-$lang['L_PRAEFIX']="Prefixo das tabelas";
-$lang['L_AUTODELETE']="Excluir backups automaticamente";
-$lang['L_MAX_BACKUP_FILES_EACH2']="Para cada banco de dados";
-$lang['L_SAVING_DB_FORM']="Banco de dados";
-$lang['L_TESTCONNECTION']="Testar conexão";
-$lang['L_BACK_TO_MINISQL']="Editar banco de dados";
-$lang['L_CREATE']="Criar";
-$lang['L_VARIABELN']="Variáveis";
-$lang['L_STATUSINFORMATIONEN']="Status da informação";
-$lang['L_VERSIONSINFORMATIONEN']="Versão da informação";
-$lang['L_MSD_INFO']="Informação do dump MyOOS [Dumper]";
-$lang['L_BACKUPFILESANZAHL']="No diretório de backup há ";
-$lang['L_LASTBACKUP']="Último backup";
-$lang['L_NOTAVAIL']="<em>não disponível</em>";
-$lang['L_VOM']="de";
-$lang['L_MYSQLVARS']="Variáveis do MySQL";
-$lang['L_MYSQLSYS']="Comandos do MySQL";
-$lang['L_STATUS']="Estado";
-$lang['L_PROZESSE']="Processos";
-$lang['L_INFO_NOVARS']="nenhuma variável disponível";
-$lang['L_INHALT']="Valor";
-$lang['L_INFO_NOSTATUS']="nenhum estado disponível";
-$lang['L_INFO_NOPROCESSES']="nenhum processo em execução";
-$lang['L_FM_FREESPACE']="Espaço livre no servidor";
-$lang['L_LOAD_DATABASE']="recarregar bancos de dados";
-$lang['L_HOME']="Início";
-$lang['L_CONFIG']="Configuração";
-$lang['L_DUMP']="Criar backup";
-$lang['L_RESTORE']="Restaurar";
-$lang['L_FILE_MANAGE']="Administração de arquivos";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Escolher banco de dados";
-$lang['L_CREDITS']="Créditos / Ajuda";
-$lang['L_MULTI_PART']="Backup multi-parte";
-$lang['L_LOGFILENOTWRITABLE']="Não pude criar o arquivo de log !";
-$lang['L_SQL_ERROR1']="Erro na consulta:";
-$lang['L_SQL_ERROR2']="MySQL diz:";
-$lang['L_UNKNOWN']="desconhecido";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="desconhecido";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Registrar todas as saídas";
-$lang['L_NO']="não";
-$lang['L_CREATE_DATABASE']="Criar novo banco de dados";
-$lang['L_EXPORTFINISHED']="Exportação finalizada.";
-$lang['L_SQL_BROWSER']="Navegador-SQL";
-$lang['L_SERVER']="Servidor";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Standard encoding of MySQL-Server";
-$lang['L_TITLE_SHOW_DATA']="Show data";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="Cancel";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Backups";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'sim';
+$lang['L_TO'] = 'para';
+$lang['L_ACTIVATED'] = 'ativado';
+$lang['L_NOT_ACTIVATED'] = 'não ativado';
+$lang['L_ERROR'] = 'Erro';
+$lang['L_OF'] = ' de ';
+$lang['L_ADDED'] = 'adicionado';
+$lang['L_DB'] = 'Banco de dados';
+$lang['L_DBS'] = 'Bancos de dados';
+$lang['L_TABLES'] = 'Tabelas';
+$lang['L_TABLE'] = 'Tabela';
+$lang['L_RECORDS'] = 'Registros';
+$lang['L_COMPRESSED'] = 'compactado (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (não compactado)';
+$lang['L_COMMENT'] = 'Comentário';
+$lang['L_FILESIZE'] = 'Tamanho do arquivo';
+$lang['L_ALL'] = 'todos';
+$lang['L_NONE'] = 'nenhum';
+$lang['L_WITH'] = ' com ';
+$lang['L_DIR'] = 'Diretório';
+$lang['L_RECHTE'] = 'Permissões';
+$lang['L_STATUS'] = 'Estado';
+$lang['L_FINISHED'] = 'terminado';
+$lang['L_FILE'] = 'Arquivo';
+$lang['L_FIELDS'] = 'campos';
+$lang['L_NEW'] = 'novo';
+$lang['L_CHARSET'] = 'Conjunto de caracteres';
+$lang['L_COLLATION'] = 'Collation';
+$lang['L_CHANGE'] = 'alterar';
+$lang['L_IN'] = 'em';
+$lang['L_DO'] = 'Executar';
+$lang['L_VIEW'] = 'exibir';
+$lang['L_EXISTING'] = 'existente';
+$lang['L_BACK'] = 'voltar';
+$lang['L_DB_HOST'] = 'Host';
+$lang['L_DB_USER'] = 'Usuáio';
+$lang['L_DB_PASS'] = 'Senha';
+$lang['L_INFO_SCRIPTDIR'] = 'Diretório do MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Banco de dados atual';
+$lang['L_WRONGCONNECTIONPARS'] = 'Incorreto ou nenhum parâmetro de conexão!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Conexão impossível !';
+$lang['L_SERVERCAPTION'] = 'Exibir servidor';
+$lang['L_HELP_SERVERCAPTION'] = 'Ao usar o MyOOS [Dumper] em domínios ou servidores diferentes, pode ser útil exibir o nome do domínio/servidor no topo da tela.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'ativar Multi-dump';
+$lang['L_SAVE'] = 'Salvar';
+$lang['L_RESET'] = 'Reiniciar';
+$lang['L_PRAEFIX'] = 'Prefixo das tabelas';
+$lang['L_AUTODELETE'] = 'Excluir backups automaticamente';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'Para cada banco de dados';
+$lang['L_SAVING_DB_FORM'] = 'Banco de dados';
+$lang['L_TESTCONNECTION'] = 'Testar conexão';
+$lang['L_BACK_TO_MINISQL'] = 'Editar banco de dados';
+$lang['L_CREATE'] = 'Criar';
+$lang['L_VARIABELN'] = 'Variáveis';
+$lang['L_STATUSINFORMATIONEN'] = 'Status da informação';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versão da informação';
+$lang['L_MOD_INFO'] = 'Informação do dump MyOOS [Dumper]';
+$lang['L_BACKUPFILESANZAHL'] = 'No diretório de backup há ';
+$lang['L_LASTBACKUP'] = 'Último backup';
+$lang['L_NOTAVAIL'] = '<em>não disponível</em>';
+$lang['L_VOM'] = 'de';
+$lang['L_MYSQLVARS'] = 'Variáveis do MySQL';
+$lang['L_MYSQLSYS'] = 'Comandos do MySQL';
+$lang['L_STATUS'] = 'Estado';
+$lang['L_PROZESSE'] = 'Processos';
+$lang['L_INFO_NOVARS'] = 'nenhuma variável disponível';
+$lang['L_INHALT'] = 'Valor';
+$lang['L_INFO_NOSTATUS'] = 'nenhum estado disponível';
+$lang['L_INFO_NOPROCESSES'] = 'nenhum processo em execução';
+$lang['L_FM_FREESPACE'] = 'Espaço livre no servidor';
+$lang['L_LOAD_DATABASE'] = 'recarregar bancos de dados';
+$lang['L_HOME'] = 'Início';
+$lang['L_CONFIG'] = 'Configuração';
+$lang['L_DUMP'] = 'Criar backup';
+$lang['L_RESTORE'] = 'Restaurar';
+$lang['L_FILE_MANAGE'] = 'Administração de arquivos';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Escolher banco de dados';
+$lang['L_CREDITS'] = 'Créditos / Ajuda';
+$lang['L_MULTI_PART'] = 'Backup multi-parte';
+$lang['L_LOGFILENOTWRITABLE'] = 'Não pude criar o arquivo de log !';
+$lang['L_SQL_ERROR1'] = 'Erro na consulta:';
+$lang['L_SQL_ERROR2'] = 'MySQL diz:';
+$lang['L_UNKNOWN'] = 'desconhecido';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'desconhecido';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Registrar todas as saídas';
+$lang['L_NO'] = 'não';
+$lang['L_CREATE_DATABASE'] = 'Criar novo banco de dados';
+$lang['L_EXPORTFINISHED'] = 'Exportação finalizada.';
+$lang['L_SQL_BROWSER'] = 'Navegador-SQL';
+$lang['L_SERVER'] = 'Servidor';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Standard encoding of MySQL-Server';
+$lang['L_TITLE_SHOW_DATA'] = 'Show data';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'Cancel';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Backups';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/pt_br/lang_config_overview.php b/msd/language/pt_br/lang_config_overview.php
index 18b56c07..669a2a63 100644
--- a/msd/language/pt_br/lang_config_overview.php
+++ b/msd/language/pt_br/lang_config_overview.php
@@ -1,111 +1,128 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Configuração";
-$lang['L_SAVE_SUCCESS']="Configuration was saved succesfully into configuration file \"%s\".";
-$lang['L_CONFIG_LOADED']="Configuration \"%s\" has been imported successfully.";
-$lang['L_SAVE_ERROR']="Erro - incapaz de salvar configuração!";
-$lang['L_CONFIG_EMAIL']="Notificação por email";
-$lang['L_CONFIG_AUTODELETE']="Autoexcluir";
-$lang['L_CONFIG_INTERFACE']="Interface";
-$lang['L_MULTI_PART_GROESSE']="tamanho máximo do arquivo";
-$lang['L_HELP_MULTIPART']="Se a opção multi-parte estiver ativada, o backup criará múltiplos arqruvos de backup, com o tamanho máximo determinado pela configuração abaixo";
-$lang['L_HELP_MULTIPARTGROESSE']="O tamanho máximo dos arquivos de backup é configurado aqui, se a opção multi-parte estiver ativada";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Excluir tabelas antes de restaurar";
-$lang['L_ALLPARS']="Todos os parâmetros";
-$lang['L_CRON_EXTENDER']="Extensão do arquivo";
-$lang['L_CRON_SAVEPATH']="Arquivo de configuração";
-$lang['L_CRON_PRINTOUT']="Imprimir a saída na tela.";
-$lang['L_CONFIG_CRONPERL']="Configurações do Crondump para o script Perl";
-$lang['L_CRON_MAILPRG']="Programa de email";
-$lang['L_OPTIMIZE']="Otimizar as tabelas antes do backup";
-$lang['L_HELP_OPTIMIZE']="Se esta opção estiver ativada, todas as tabelas serão otimizadas antes do backup";
-$lang['L_HELP_FTPTIMEOUT']="O ajuste padrão para o Timeout é de 90 segundos.";
-$lang['L_FTP_TIMEOUT']="Timeout da conexão";
-$lang['L_HELP_FTPSSL']="Escolher se a conexão será estabelecida via SSL.";
-$lang['L_CONFIG_ASKLOAD']="Você deseja sobrescrever as configurações atuais com as configurações padrão?";
-$lang['L_LOAD']="Usar config. padrão";
-$lang['L_LOAD_SUCCESS']="As configurações padrão foram carregadas.";
-$lang['L_CRON_CRONDBINDEX']="Banco de dados";
-$lang['L_WITHATTACH']=" com anexo";
-$lang['L_WITHOUTATTACH']=" sem anexo";
-$lang['L_MULTIDUMPCONF']="=Configuração do Multi-dump=";
-$lang['L_MULTIDUMPALL']="=todos os bancos de dados=";
-$lang['L_GZIP']="Compressão gzip";
-$lang['L_SEND_MAIL_FORM']="Enviar relatório por email";
-$lang['L_SEND_MAIL_DUMP']="Anexar o backup";
-$lang['L_EMAIL_ADRESS']="Endereço do email";
-$lang['L_EMAIL_SENDER']="Endereço do remetente do email";
-$lang['L_EMAIL_MAXSIZE']="Tamanho máximo do anexo";
-$lang['L_NUMBER_OF_FILES_FORM']="Excluir pelo número de arquivos";
-$lang['L_LANGUAGE']="Idioma";
-$lang['L_LIST_DB']="Bancos de dados configurados:";
-$lang['L_CONFIG_FTP']="Transferência via FTP do arquivo de backup";
-$lang['L_FTP_TRANSFER']="Transferência via FTP";
-$lang['L_FTP_SERVER']="Servidor";
-$lang['L_FTP_PORT']="Porta";
-$lang['L_FTP_USER']="Usuário";
-$lang['L_FTP_PASS']="Senha";
-$lang['L_FTP_DIR']="Diretório para upload";
-$lang['L_FTP_SSL']="Conexão segura SSL FTP";
-$lang['L_FTP_USESSL']="usar conexão SSL";
-$lang['L_SQLBOXHEIGHT']="Altura da caixa SQL";
-$lang['L_SQLLIMIT']="Quantidade de registros por página";
-$lang['L_BBPARAMS']="Configuração para códigos BB";
-$lang['L_BBTEXTCOLOR']="Cor do texto";
-$lang['L_HELP_COMMANDS']="Você pode executar um comando antes ou depois do backup.
-Este comando pode ser uma cláusula SQL ou um comando do sistema (p.e. um script)";
-$lang['L_COMMAND']="Comando";
-$lang['L_WRONG_CONNECTIONPARS']="Os parâmetros de conexão estão incorretos !";
-$lang['L_CONNECTIONPARS']="Parâmetros de conexão";
-$lang['L_EXTENDEDPARS']="Parâmetros extendidos";
-$lang['L_FADE_IN_OUT']="Exibir sim/não";
-$lang['L_DB_BACKUPPARS']="Parâmetro de backup do banco de dados";
-$lang['L_GENERAL']="Geral";
-$lang['L_MAXSIZE']="Tamanho máx.";
-$lang['L_ERRORHANDLING_RESTORE']="Controle de erro durante a restauração";
-$lang['L_EHRESTORE_CONTINUE']="continuar e registrar erros";
-$lang['L_EHRESTORE_STOP']="parar";
-$lang['L_IN_MAINFRAME']="no frame principal";
-$lang['L_IN_LEFTFRAME']="no frame da esquerda";
-$lang['L_WIDTH']="Largura";
-$lang['L_SQL_BEFEHLE']="Comandos SQL";
-$lang['L_DOWNLOAD_LANGUAGES']="baixar outros idiomas";
-$lang['L_DOWNLOAD_STYLES']="baixar outros temas";
-$lang['L_CONNECT_TO']="Conectar-se à";
-$lang['L_CHANGEDIR']="Mudando para o diretório";
-$lang['L_CHANGEDIRERROR']="Não pude mudar de diretório!";
-$lang['L_FTP_OK']="Conexão bem sucedida.";
-$lang['L_INSTALL']="Instalação";
-$lang['L_NOFTPPOSSIBLE']="Você não tem as funções de FTP !";
-$lang['L_FOUND_DB']="encontrado db";
-$lang['L_FTP_CHOOSE_MODE']="Modo de Transferência - FTP";
-$lang['L_FTP_PASSIVE']="usar modo passivo";
-$lang['L_HELP_FTP_MODE']="Escolha o modo passivo quando você encontrar problemas usando o modo ativo";
-$lang['L_DB_IN_LIST']="O banco de dados '%s' não pode ser adicionado pois ele já existe";
-$lang['L_ADD_DB_MANUALLY']="Adicionar banco de dados manualmente";
-$lang['L_DB_MANUAL_ERROR']="Desculpe, não é possível conectar com o banco de dados '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Erro de arquivo: não foi possível inserir na base de dados '%s'!";
-$lang['L_NO_DB_FOUND']="Não pude encontrar nenhuma base de dados automaticamente!
-Por favor, verifique os parâmetros de conexão e coloque o nome de seu banco de dados manualmente.";
-$lang['L_CONFIGFILES']="Configuration Files";
-$lang['L_CONFIGFILE']="Config File";
-$lang['L_MYSQL_DATA']="MySQL-Data";
-$lang['L_CONFIGURATIONS']="Configurations";
-$lang['L_ACTION']="Action";
-$lang['L_FTP_SEND_TO']="to <strong>%s</strong><br> into <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Receiver";
-$lang['L_NAME']="Name";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Really delete the configuration file %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Error: couldn't delete configuration file %s!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="The configuration file %s has successfully been deleted.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Configuration file %s has successfully been created.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Filename \"%s\" contains invalid characters.";
-$lang['L_CREATE_CONFIGFILE']="Create a new configuration file";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Couldn't load configfile \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="DBs to backup (PHP)";
-$lang['L_BACKUP_DBS_PERL']="DBs to backup (PERL)";
-$lang['L_CRON_COMMENT']="Digitar comentário";
-$lang['L_AUTODETECT']="auto detect";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Configuração';
+$lang['L_SAVE_SUCCESS'] = 'Configuration was saved succesfully into configuration file "%s".';
+$lang['L_CONFIG_LOADED'] = 'Configuration "%s" has been imported successfully.';
+$lang['L_SAVE_ERROR'] = 'Erro - incapaz de salvar configuração!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Notificação por email';
+$lang['L_CONFIG_AUTODELETE'] = 'Autoexcluir';
+$lang['L_CONFIG_INTERFACE'] = 'Interface';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'tamanho máximo do arquivo';
+$lang['L_HELP_MULTIPART'] = 'Se a opção multi-parte estiver ativada, o backup criará múltiplos arqruvos de backup, com o tamanho máximo determinado pela configuração abaixo';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'O tamanho máximo dos arquivos de backup é configurado aqui, se a opção multi-parte estiver ativada';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Excluir tabelas antes de restaurar';
+$lang['L_ALLPARS'] = 'Todos os parâmetros';
+$lang['L_CRON_EXTENDER'] = 'Extensão do arquivo';
+$lang['L_CRON_SAVEPATH'] = 'Arquivo de configuração';
+$lang['L_CRON_PRINTOUT'] = 'Imprimir a saída na tela.';
+$lang['L_CONFIG_CRONPERL'] = 'Configurações do Crondump para o script Perl';
+$lang['L_CRON_MAILPRG'] = 'Programa de email';
+$lang['L_OPTIMIZE'] = 'Otimizar as tabelas antes do backup';
+$lang['L_HELP_OPTIMIZE'] = 'Se esta opção estiver ativada, todas as tabelas serão otimizadas antes do backup';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'O ajuste padrão para o Timeout é de 90 segundos.';
+$lang['L_FTP_TIMEOUT'] = 'Timeout da conexão';
+$lang['L_HELP_FTPSSL'] = 'Escolher se a conexão será estabelecida via SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Timeout da conexão';
+$lang['L_HELP_SFTPSSL'] = 'Escolher se a conexão será estabelecida via SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'Você deseja sobrescrever as configurações atuais com as configurações padrão?';
+$lang['L_LOAD'] = 'Usar config. padrão';
+$lang['L_LOAD_SUCCESS'] = 'As configurações padrão foram carregadas.';
+$lang['L_CRON_CRONDBINDEX'] = 'Banco de dados';
+$lang['L_WITHATTACH'] = ' com anexo';
+$lang['L_WITHOUTATTACH'] = ' sem anexo';
+$lang['L_MULTIDUMPCONF'] = '=Configuração do Multi-dump=';
+$lang['L_MULTIDUMPALL'] = '=todos os bancos de dados=';
+$lang['L_GZIP'] = 'Compressão gzip';
+$lang['L_SEND_MAIL_FORM'] = 'Enviar relatório por email';
+$lang['L_SEND_MAIL_DUMP'] = 'Anexar o backup';
+$lang['L_EMAIL_ADRESS'] = 'Endereço do email';
+$lang['L_EMAIL_SENDER'] = 'Endereço do remetente do email';
+$lang['L_EMAIL_MAXSIZE'] = 'Tamanho máximo do anexo';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Excluir pelo número de arquivos';
+$lang['L_LANGUAGE'] = 'Idioma';
+$lang['L_LIST_DB'] = 'Bancos de dados configurados:';
+$lang['L_CONFIG_FTP'] = 'Transferência via FTP do arquivo de backup';
+$lang['L_FTP_TRANSFER'] = 'Transferência via FTP';
+$lang['L_FTP_SERVER'] = 'Servidor';
+$lang['L_FTP_PORT'] = 'Porta';
+$lang['L_FTP_USER'] = 'Usuário';
+$lang['L_FTP_PASS'] = 'Senha';
+$lang['L_FTP_DIR'] = 'Diretório para upload';
+$lang['L_FTP_SSL'] = 'Conexão segura SSL FTP';
+$lang['L_FTP_USESSL'] = 'usar conexão SSL';
+$lang['L_CONFIG_SFTP'] = 'Transferência via SFTP do arquivo de backup';
+$lang['L_SFTP_TRANSFER'] = 'Transferência via SFTP';
+$lang['L_SFTP_SERVER'] = 'Servidor';
+$lang['L_SFTP_PORT'] = 'Porta';
+$lang['L_SFTP_USER'] = 'Usuário';
+$lang['L_SFTP_PASS'] = 'Senha';
+$lang['L_SFTP_DIR'] = 'Diretório para upload';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Altura da caixa SQL';
+$lang['L_SQLLIMIT'] = 'Quantidade de registros por página';
+$lang['L_BBPARAMS'] = 'Configuração para códigos BB';
+$lang['L_BBTEXTCOLOR'] = 'Cor do texto';
+$lang['L_HELP_COMMANDS'] = 'Você pode executar um comando antes ou depois do backup.
+Este comando pode ser uma cláusula SQL ou um comando do sistema (p.e. um script)';
+$lang['L_COMMAND'] = 'Comando';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Os parâmetros de conexão estão incorretos !';
+$lang['L_CONNECTIONPARS'] = 'Parâmetros de conexão';
+$lang['L_EXTENDEDPARS'] = 'Parâmetros extendidos';
+$lang['L_FADE_IN_OUT'] = 'Exibir sim/não';
+$lang['L_DB_BACKUPPARS'] = 'Parâmetro de backup do banco de dados';
+$lang['L_GENERAL'] = 'Geral';
+$lang['L_MAXSIZE'] = 'Tamanho máx.';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Controle de erro durante a restauração';
+$lang['L_EHRESTORE_CONTINUE'] = 'continuar e registrar erros';
+$lang['L_EHRESTORE_STOP'] = 'parar';
+$lang['L_IN_MAINFRAME'] = 'no frame principal';
+$lang['L_IN_LEFTFRAME'] = 'no frame da esquerda';
+$lang['L_WIDTH'] = 'Largura';
+$lang['L_SQL_BEFEHLE'] = 'Comandos SQL';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'baixar outros idiomas';
+$lang['L_DOWNLOAD_STYLES'] = 'baixar outros temas';
+$lang['L_CONNECT_TO'] = 'Conectar-se à';
+$lang['L_CHANGEDIR'] = 'Mudando para o diretório';
+$lang['L_CHANGEDIRERROR'] = 'Não pude mudar de diretório!';
+$lang['L_FTP_OK'] = 'Conexão bem sucedida.';
+$lang['L_INSTALL'] = 'Instalação';
+$lang['L_NOFTPPOSSIBLE'] = 'Você não tem as funções de FTP !';
+$lang['L_FOUND_DB'] = 'encontrado db';
+$lang['L_FTP_CHOOSE_MODE'] = 'Modo de Transferência - FTP';
+$lang['L_FTP_PASSIVE'] = 'usar modo passivo';
+$lang['L_HELP_FTP_MODE'] = 'Escolha o modo passivo quando você encontrar problemas usando o modo ativo';
+$lang['L_SFTP_PASSIVE'] = 'usar modo passivo';
+$lang['L_DB_IN_LIST'] = "O banco de dados '%s' não pode ser adicionado pois ele já existe";
+$lang['L_ADD_DB_MANUALLY'] = 'Adicionar banco de dados manualmente';
+$lang['L_DB_MANUAL_ERROR'] = "Desculpe, não é possível conectar com o banco de dados '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Erro de arquivo: não foi possível inserir na base de dados '%s'!";
+$lang['L_NO_DB_FOUND'] = 'Não pude encontrar nenhuma base de dados automaticamente!
+Por favor, verifique os parâmetros de conexão e coloque o nome de seu banco de dados manualmente.';
+$lang['L_CONFIGFILES'] = 'Configuration Files';
+$lang['L_CONFIGFILE'] = 'Config File';
+$lang['L_MYSQL_DATA'] = 'MySQL-Data';
+$lang['L_CONFIGURATIONS'] = 'Configurations';
+$lang['L_ACTION'] = 'Action';
+$lang['L_FTP_SEND_TO'] = 'to <strong>%s</strong><br> into <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'to <strong>%s</strong><br> into <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Receiver';
+$lang['L_NAME'] = 'Name';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Really delete the configuration file %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = "Error: couldn't delete configuration file %s!";
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'The configuration file %s has successfully been deleted.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Configuration file %s has successfully been created.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Filename "%s" contains invalid characters.';
+$lang['L_CREATE_CONFIGFILE'] = 'Create a new configuration file';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = "Couldn't load configfile \"%s\".";
+$lang['L_BACKUP_DBS_PHP'] = 'DBs to backup (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'DBs to backup (PERL)';
+$lang['L_CRON_COMMENT'] = 'Digitar comentário';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/pt_br/lang_dump.php b/msd/language/pt_br/lang_dump.php
index 98d98263..8e59472c 100644
--- a/msd/language/pt_br/lang_dump.php
+++ b/msd/language/pt_br/lang_dump.php
@@ -1,57 +1,58 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Criar backup...";
-$lang['L_GZIP_COMPRESSION']="Compressão gzip";
-$lang['L_SAVING_TABLE']="Salvando a tabela ";
-$lang['L_OF']="of";
-$lang['L_ACTUAL_TABLE']="Tabela atual";
-$lang['L_PROGRESS_TABLE']="Progresso da tabela";
-$lang['L_PROGRESS_OVER_ALL']="Progresso do todo";
-$lang['L_ENTRY']="Entrada";
-$lang['L_DONE']="Pronto!";
-$lang['L_DUMP_SUCCESSFUL']=" foi criado com sucesso.";
-$lang['L_UPTO']="até";
-$lang['L_EMAIL_WAS_SEND']="Um email foi enviado com sucesso para ";
-$lang['L_BACK_TO_CONTROL']="Continuar";
-$lang['L_BACK_TO_OVERVIEW']="Visão geral do banco de dados";
-$lang['L_DUMP_FILENAME']="Arquivo de backup: ";
-$lang['L_WITHPRAEFIX']="com o prefixo";
-$lang['L_DUMP_NOTABLES']="Nenhuma tabela foi encontrada no banco de dados `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="O arquivo contém <b>%s</b> tabela(s) com <b>%s</b> registro(s).<br>";
-$lang['L_MAILERROR']="O envio do email falhou!";
-$lang['L_EMAILBODY_ATTACH']="O anexo contém o backup do seu banco de dados MySQL.<br>Backup do banco de dados `%s`
-<br><br>O seguinte arquivo foi criado:<br><br>%s <br><br>Atenciosamente<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Um backup Multi-parte foi criad.<br>Os arquivos não estão anexados a este email!<br>Backup do banco de dados `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'Criar backup...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'Compressão gzip';
+$lang['L_SAVING_TABLE'] = 'Salvando a tabela ';
+$lang['L_OF'] = 'of';
+$lang['L_ACTUAL_TABLE'] = 'Tabela atual';
+$lang['L_PROGRESS_TABLE'] = 'Progresso da tabela';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progresso do todo';
+$lang['L_ENTRY'] = 'Entrada';
+$lang['L_DONE'] = 'Pronto!';
+$lang['L_DUMP_SUCCESSFUL'] = ' foi criado com sucesso.';
+$lang['L_UPTO'] = 'até';
+$lang['L_EMAIL_WAS_SEND'] = 'Um email foi enviado com sucesso para ';
+$lang['L_BACK_TO_CONTROL'] = 'Continuar';
+$lang['L_BACK_TO_OVERVIEW'] = 'Visão geral do banco de dados';
+$lang['L_DUMP_FILENAME'] = 'Arquivo de backup: ';
+$lang['L_WITHPRAEFIX'] = 'com o prefixo';
+$lang['L_DUMP_NOTABLES'] = 'Nenhuma tabela foi encontrada no banco de dados `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = 'O arquivo contém <b>%s</b> tabela(s) com <b>%s</b> registro(s).<br>';
+$lang['L_MAILERROR'] = 'O envio do email falhou!';
+$lang['L_EMAILBODY_ATTACH'] = 'O anexo contém o backup do seu banco de dados MySQL.<br>Backup do banco de dados `%s`
+<br><br>O seguinte arquivo foi criado:<br><br>%s <br><br>Atenciosamente<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Um backup Multi-parte foi criad.<br>Os arquivos não estão anexados a este email!<br>Backup do banco de dados `%s`
 <br><br>Os seguintes arquivos foram criados:<br><br>%s
-<br><br>Atenciosamente<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Um backup Multi-parte foi criado.<br>Os arquivos de backup estão anexados em emails separados.<br>Backup do banco de dados `%s`
-<br><br>Os seguintes arquivos foram criados:<br><br>%s <br><br>Atenciosamente<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="`<br><br>Atenciosamente<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="O arquivo de backup excedeu o tamanho máximo de %s e não foi anexado a este email.<br>Backup do banco de dados `%s`
+<br><br>Atenciosamente<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Um backup Multi-parte foi criado.<br>Os arquivos de backup estão anexados em emails separados.<br>Backup do banco de dados `%s`
+<br><br>Os seguintes arquivos foram criados:<br><br>%s <br><br>Atenciosamente<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '`<br><br>Atenciosamente<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'O arquivo de backup excedeu o tamanho máximo de %s e não foi anexado a este email.<br>Backup do banco de dados `%s`
 <br><br>O seguinte arquivo foi criado:<br><br>%s
-<br><br>Atenciosamente<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Os arquivos não estão anexados a este email!<br>Backup do banco de dados `%s`
+<br><br>Atenciosamente<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Os arquivos não estão anexados a este email!<br>Backup do banco de dados `%s`
 <br><br>O seguinte arquivo foi criado:<br><br>%s
-<br><br>Atenciosamente<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... somente anexos.";
-$lang['L_TABLESELECTION']="Seleção de tabela";
-$lang['L_SELECTALL']="Selecionar tudo";
-$lang['L_DESELECTALL']="Desselecionar tudo";
-$lang['L_STARTDUMP']="Iniciar backup";
-$lang['L_LASTBUFROM']="última atualização de";
-$lang['L_NOT_SUPPORTED']="Este backup não suporta esta função.";
-$lang['L_MULTIDUMP']="Multidump: Backup do(s) <b>%d</b> banco(s) de dados pronto.";
-$lang['L_FILESENDFTP']="enviando o arquivo via FTP... favor ter paciente. ";
-$lang['L_FTPCONNERROR']="Conexão de FTP não estabelecida! Conexão com ";
-$lang['L_FTPCONNERROR1']=" com o usuário ";
-$lang['L_FTPCONNERROR2']=" impossível";
-$lang['L_FTPCONNERROR3']="Envio por FTP falhou! ";
-$lang['L_FTPCONNECTED1']="Conectado com ";
-$lang['L_FTPCONNECTED2']=" em ";
-$lang['L_FTPCONNECTED3']=" trasnferido com sucesso";
-$lang['L_NR_TABLES_SELECTED']="- com %s tabelas selecionadas";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tabelas foram otimizadas.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s erros ocorreram: <a href=\"log.php?r=3\">verdere</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Fatal error: the CREATE-Statement of table '%s' in database '%s' couldn't be read!";
-
-
-?>
\ No newline at end of file
+<br><br>Atenciosamente<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... somente anexos.';
+$lang['L_TABLESELECTION'] = 'Seleção de tabela';
+$lang['L_SELECTALL'] = 'Selecionar tudo';
+$lang['L_DESELECTALL'] = 'Desselecionar tudo';
+$lang['L_STARTDUMP'] = 'Iniciar backup';
+$lang['L_LASTBUFROM'] = 'última atualização de';
+$lang['L_NOT_SUPPORTED'] = 'Este backup não suporta esta função.';
+$lang['L_MULTIDUMP'] = 'Multidump: Backup do(s) <b>%d</b> banco(s) de dados pronto.';
+$lang['L_FILESENDFTP'] = 'enviando o arquivo via FTP... favor ter paciente. ';
+$lang['L_FTPCONNERROR'] = 'Conexão de FTP não estabelecida! Conexão com ';
+$lang['L_FTPCONNERROR1'] = ' com o usuário ';
+$lang['L_FTPCONNERROR2'] = ' impossível';
+$lang['L_FTPCONNERROR3'] = 'Envio por FTP falhou! ';
+$lang['L_FTPCONNECTED1'] = 'Conectado com ';
+$lang['L_FTPCONNECTED2'] = ' em ';
+$lang['L_FTPCONNECTED3'] = ' trasnferido com sucesso';
+$lang['L_FILESENDSFTP'] = 'enviando o arquivo via SFTP... favor ter paciente. ';
+$lang['L_SFTPCONNERROR'] = 'Conexão de SFTP não estabelecida! Conexão com ';
+$lang['L_NR_TABLES_SELECTED'] = '- com %s tabelas selecionadas';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tabelas foram otimizadas.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s erros ocorreram: <a href="log.php?r=3">verdere</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Fatal error: the CREATE-Statement of table '%s' in database '%s' couldn't be read!";
diff --git a/msd/language/pt_br/lang_filemanagement.php b/msd/language/pt_br/lang_filemanagement.php
index 81bd6163..0a10cc88 100644
--- a/msd/language/pt_br/lang_filemanagement.php
+++ b/msd/language/pt_br/lang_filemanagement.php
@@ -1,79 +1,79 @@
 <?php
-$lang['L_CONVERT_START']="Iniciar a conversão";
-$lang['L_CONVERT_TITLE']="Converter o dump para o formato MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Parâmetros incorretos!  A conversão não é possível.";
-$lang['L_FM_UPLOADFILEREQUEST']="favor escolher um arquivo.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Este tipo de arquivo não é suportado.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Os tipos válidos são: *.gz and *.sql-files";
-$lang['L_FM_UPLOADMOVEERROR']="Não pude mover os arqruivos selecionados para o diretório de envio.";
-$lang['L_FM_UPLOADFAILED']="O envio falhou!";
-$lang['L_FM_UPLOADFILEEXISTS']="Um arquivo com o mesmo nome já existe !";
-$lang['L_FM_NOFILE']="Você não escolheu nenhum arquivo!";
-$lang['L_FM_DELETE1']="O arquivo ";
-$lang['L_FM_DELETE2']=" foi excluido com sucesso.";
-$lang['L_FM_DELETE3']=" não pode ser excluido!";
-$lang['L_FM_CHOOSE_FILE']="Arquivo escolhido:";
-$lang['L_FM_FILESIZE']="Tamanho do arquivo";
-$lang['L_FM_FILEDATE']="Data do arquivo";
-$lang['L_FM_NOFILESFOUND']="Nenhum arquivo encontrado.";
-$lang['L_FM_TABLES']="Tabelas";
-$lang['L_FM_RECORDS']="Registros";
-$lang['L_FM_ALL_BU']="Todos os backups";
-$lang['L_FM_ANZ_BU']="Backups";
-$lang['L_FM_LAST_BU']="Último backup";
-$lang['L_FM_TOTALSIZE']="Tamanho total";
-$lang['L_FM_SELECTTABLES']="Selecionar tabelas";
-$lang['L_FM_COMMENT']="Digitar comentário";
-$lang['L_FM_RESTORE']="Restaurar";
-$lang['L_FM_ALERTRESTORE1']="Deve o banco de dados";
-$lang['L_FM_ALERTRESTORE2']="ser restaurado com os rgistros do arquivo";
-$lang['L_FM_ALERTRESTORE3']=" ?";
-$lang['L_FM_DELETE']="Excluir";
-$lang['L_FM_ASKDELETE1']="Deve o arquivo ";
-$lang['L_FM_ASKDELETE2']="realmente ser excluido?";
-$lang['L_FM_ASKDELETE3']="Você deseja que a autoexclusão seja executada com as regras configuradas agora?";
-$lang['L_FM_ASKDELETE4']="Você deseja excluir todos os arqruvos de backup?";
-$lang['L_FM_ASKDELETE5']="Você deseja excluir todos os arqruvos de backup com ";
-$lang['L_FM_ASKDELETE5_2']="_* ?";
-$lang['L_FM_DELETEAUTO']="Executar a autoexclusão manualmente";
-$lang['L_FM_DELETEALL']="Excluir todos os arqruvos de backup";
-$lang['L_FM_DELETEALLFILTER']="Excluir todos com ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Iniciar novo backup";
-$lang['L_FM_FILEUPLOAD']="Enviar arquivo";
-$lang['L_FM_DBNAME']="Nome do banco de dados";
-$lang['L_FM_FILES1']="Backups do banco de dados";
-$lang['L_FM_FILES2']="Estruturas do banco de dados";
-$lang['L_FM_AUTODEL1']="Autoexclusão: os seguintes arqruivos foram excluidos devido ao ajuste de número máximo de arquivos:";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="Configuração do script";
-$lang['L_FM_OLDBACKUP']="(desconhecido)";
-$lang['L_FM_RESTORE_HEADER']="Restaurar o banco de dados \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Executar o script Perl Cron";
-$lang['L_DOPERLTEST']="Testar módulos Perl";
-$lang['L_DOSIMPLETEST']="Testar Perl";
-$lang['L_PERLOUTPUT1']="Entrada no crondump.pl para o absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="URL para o navegador ou serviço Cron externo";
-$lang['L_PERLOUTPUT3']="Linha de comando no terminal para o Crontab";
-$lang['L_RESTORE_OF_TABLES']="Choose tables to be restored";
-$lang['L_CONVERTER']="Conversor de backup";
-$lang['L_CONVERT_FILE']="Arquivo a ser convertido";
-$lang['L_CONVERT_FILENAME']="Nome do arquivo de destino (sem extensão)";
-$lang['L_CONVERTING']="Convertendo";
-$lang['L_CONVERT_FILEREAD']="Ler arquivo '%s'";
-$lang['L_CONVERT_FINISHED']="Conversão terminada, o arquivo '%s' foi gravado com sucesso.";
-$lang['L_NO_MSD_BACKUPFILE']="Backups de outros scripts";
-$lang['L_MAX_UPLOAD_SIZE']="Tamanho máximo do aqruivo";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Se o seu arquivo de dump é maior que o limite mencionado acima, você deve enviá-lo via FTP para o diretório \"work/backup\".
-Após fazer isso você poderá escolhê-lo novamente para iniciar o processo de restauração. ";
-$lang['L_ENCODING']="encoding";
-$lang['L_FM_CHOOSE_ENCODING']="Choose encoding of backup file";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper couldn't detect the encoding of the backup file automatically.
+
+$lang['L_CONVERT_START'] = 'Iniciar a conversão';
+$lang['L_CONVERT_TITLE'] = 'Converter o dump para o formato MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Parâmetros incorretos!  A conversão não é possível.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'favor escolher um arquivo.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Este tipo de arquivo não é suportado.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Os tipos válidos são: *.gz and *.sql-files';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Não pude mover os arqruivos selecionados para o diretório de envio.';
+$lang['L_FM_UPLOADFAILED'] = 'O envio falhou!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Um arquivo com o mesmo nome já existe !';
+$lang['L_FM_NOFILE'] = 'Você não escolheu nenhum arquivo!';
+$lang['L_FM_DELETE1'] = 'O arquivo ';
+$lang['L_FM_DELETE2'] = ' foi excluido com sucesso.';
+$lang['L_FM_DELETE3'] = ' não pode ser excluido!';
+$lang['L_FM_CHOOSE_FILE'] = 'Arquivo escolhido:';
+$lang['L_FM_FILESIZE'] = 'Tamanho do arquivo';
+$lang['L_FM_FILEDATE'] = 'Data do arquivo';
+$lang['L_FM_NOFILESFOUND'] = 'Nenhum arquivo encontrado.';
+$lang['L_FM_TABLES'] = 'Tabelas';
+$lang['L_FM_RECORDS'] = 'Registros';
+$lang['L_FM_ALL_BU'] = 'Todos os backups';
+$lang['L_FM_ANZ_BU'] = 'Backups';
+$lang['L_FM_LAST_BU'] = 'Último backup';
+$lang['L_FM_TOTALSIZE'] = 'Tamanho total';
+$lang['L_FM_SELECTTABLES'] = 'Selecionar tabelas';
+$lang['L_FM_COMMENT'] = 'Digitar comentário';
+$lang['L_FM_RESTORE'] = 'Restaurar';
+$lang['L_FM_ALERTRESTORE1'] = 'Deve o banco de dados';
+$lang['L_FM_ALERTRESTORE2'] = 'ser restaurado com os rgistros do arquivo';
+$lang['L_FM_ALERTRESTORE3'] = ' ?';
+$lang['L_FM_DELETE'] = 'Excluir';
+$lang['L_FM_ASKDELETE1'] = 'Deve o arquivo ';
+$lang['L_FM_ASKDELETE2'] = 'realmente ser excluido?';
+$lang['L_FM_ASKDELETE3'] = 'Você deseja que a autoexclusão seja executada com as regras configuradas agora?';
+$lang['L_FM_ASKDELETE4'] = 'Você deseja excluir todos os arqruvos de backup?';
+$lang['L_FM_ASKDELETE5'] = 'Você deseja excluir todos os arqruvos de backup com ';
+$lang['L_FM_ASKDELETE5_2'] = '_* ?';
+$lang['L_FM_DELETEAUTO'] = 'Executar a autoexclusão manualmente';
+$lang['L_FM_DELETEALL'] = 'Excluir todos os arqruvos de backup';
+$lang['L_FM_DELETEALLFILTER'] = 'Excluir todos com ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Iniciar novo backup';
+$lang['L_FM_FILEUPLOAD'] = 'Enviar arquivo';
+$lang['L_FM_DBNAME'] = 'Nome do banco de dados';
+$lang['L_FM_FILES1'] = 'Backups do banco de dados';
+$lang['L_FM_FILES2'] = 'Estruturas do banco de dados';
+$lang['L_FM_AUTODEL1'] = 'Autoexclusão: os seguintes arqruivos foram excluidos devido ao ajuste de número máximo de arquivos:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'Configuração do script';
+$lang['L_FM_OLDBACKUP'] = '(desconhecido)';
+$lang['L_FM_RESTORE_HEADER'] = 'Restaurar o banco de dados "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Executar o script Perl Cron';
+$lang['L_DOPERLTEST'] = 'Testar módulos Perl';
+$lang['L_DOSIMPLETEST'] = 'Testar Perl';
+$lang['L_PERLOUTPUT1'] = 'Entrada no crondump.pl para o absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'URL para o navegador ou serviço Cron externo';
+$lang['L_PERLOUTPUT3'] = 'Linha de comando no terminal para o Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Choose tables to be restored';
+$lang['L_CONVERTER'] = 'Conversor de backup';
+$lang['L_CONVERT_FILE'] = 'Arquivo a ser convertido';
+$lang['L_CONVERT_FILENAME'] = 'Nome do arquivo de destino (sem extensão)';
+$lang['L_CONVERTING'] = 'Convertendo';
+$lang['L_CONVERT_FILEREAD'] = "Ler arquivo '%s'";
+$lang['L_CONVERT_FINISHED'] = "Conversão terminada, o arquivo '%s' foi gravado com sucesso.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Backups de outros scripts';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Tamanho máximo do aqruivo';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Se o seu arquivo de dump é maior que o limite mencionado acima, você deve enviá-lo via FTP para o diretório "work/backup".
+Após fazer isso você poderá escolhê-lo novamente para iniciar o processo de restauração. ';
+$lang['L_ENCODING'] = 'encoding';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Choose encoding of backup file';
+$lang['L_CHOOSE_CHARSET'] = "MyOOS [Dumper] couldn't detect the encoding of the backup file automatically.
 <br>You must choose the charset with which this backup was saved.
 <br>If you discover any problems with some characters after restoring, you can repeat the backup-progress and then choose another character set.
 <br>Good luck. ;)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/pt_br/lang_help.php b/msd/language/pt_br/lang_help.php
index b4939678..71503db1 100644
--- a/msd/language/pt_br/lang_help.php
+++ b/msd/language/pt_br/lang_help.php
@@ -1,36 +1,40 @@
 <?php
-$lang['L_HELP_DB']="Esta é a lista de todos os bancos de dados";
-$lang['L_HELP_PRAEFIX']="o prefixo é uma string no começo do nome da tabela, que funciona como um filtro.";
-$lang['L_HELP_ZIP']="Compressão com GZip - estado recomendado é 'ativado'";
-$lang['L_HELP_MEMORYLIMIT']="Quantidade máxima de memória em bytes para o script
-0 = desativado";
-$lang['L_MEMORY_LIMIT']="Limite de memória";
-$lang['L_HELP_AD1']="Se ativado os arquivos de backup serão excluidos automaticamente.";
-$lang['L_HELP_AD3']="número máximo de arquivos de backup (para autoexclusão)
-0 = desativado";
-$lang['L_HELP_LANG']="selecione seu idioma";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Para eliminar dados sem valor você pode configurar para limpar seu banco de dados antes de restaurar";
-$lang['L_HELP_CRONEXTENDER']="Extensão dos scripts Perl, o padrão é '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="Nome do arquivo de configuração para o script Perl";
-$lang['L_HELP_CRONPRINTOUT']="Se a saída estiver desativada ela não irá aparecer na tela.
-Isto é independente de fazer impressão a partir do arquivo de log.";
-$lang['L_HELP_CRONSAMEDB']="Usar o mesmo bd no trabalho Cron como está configurado o banco de dados?";
-$lang['L_HELP_CRONDBINDEX']="escolha o banco de dados para o Cron";
-$lang['L_HELP_FTPTRANSFER']="se ativado o arquivo será encaminhado via FTP.";
-$lang['L_HELP_FTPSERVER']="Endereço do servidor de FTP";
-$lang['L_HELP_FTPPORT']="Porta do servidor de FTP, padrão: 21";
-$lang['L_HELP_FTPUSER']="digite o nome do usuário para o FTP";
-$lang['L_HELP_FTPPASS']="digite a senha para o FTP";
-$lang['L_HELP_FTPDIR']="onde está o diretório para upload? Digite o caminho!";
-$lang['L_HELP_SPEED']="Velocidade mínima e máxima. O padrão é: 50 à 5000";
-$lang['L_SPEED']="Controle de velocidade";
-$lang['L_HELP_CRONEXECPATH']="Lugar dos scripts Perl.
+
+$lang['L_HELP_DB'] = 'Esta é a lista de todos os bancos de dados';
+$lang['L_HELP_PRAEFIX'] = 'o prefixo é uma string no começo do nome da tabela, que funciona como um filtro.';
+$lang['L_HELP_ZIP'] = "Compressão com GZip - estado recomendado é 'ativado'";
+$lang['L_HELP_MEMORYLIMIT'] = 'Quantidade máxima de memória em bytes para o script
+0 = desativado';
+$lang['L_MEMORY_LIMIT'] = 'Limite de memória';
+$lang['L_HELP_AD1'] = 'Se ativado os arquivos de backup serão excluidos automaticamente.';
+$lang['L_HELP_AD3'] = 'número máximo de arquivos de backup (para autoexclusão)
+0 = desativado';
+$lang['L_HELP_LANG'] = 'selecione seu idioma';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Para eliminar dados sem valor você pode configurar para limpar seu banco de dados antes de restaurar';
+$lang['L_HELP_CRONEXTENDER'] = "Extensão dos scripts Perl, o padrão é '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'Nome do arquivo de configuração para o script Perl';
+$lang['L_HELP_CRONPRINTOUT'] = 'Se a saída estiver desativada ela não irá aparecer na tela.
+Isto é independente de fazer impressão a partir do arquivo de log.';
+$lang['L_HELP_CRONSAMEDB'] = 'Usar o mesmo bd no trabalho Cron como está configurado o banco de dados?';
+$lang['L_HELP_CRONDBINDEX'] = 'escolha o banco de dados para o Cron';
+$lang['L_HELP_FTPTRANSFER'] = 'se ativado o arquivo será encaminhado via FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Endereço do servidor de FTP';
+$lang['L_HELP_FTPPORT'] = 'Porta do servidor de FTP, padrão: 21';
+$lang['L_HELP_FTPUSER'] = 'digite o nome do usuário para o FTP';
+$lang['L_HELP_FTPPASS'] = 'digite a senha para o FTP';
+$lang['L_HELP_FTPDIR'] = 'onde está o diretório para upload? Digite o caminho!';
+$lang['L_HELP_SFTPTRANSFER'] = 'se ativado o arquivo será encaminhado via SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Endereço do servidor de SFTP';
+$lang['L_HELP_SFTPPORT'] = 'Porta do servidor de SFTP, padrão: 22';
+$lang['L_HELP_SFTPUSER'] = 'digite o nome do usuário para o SFTP';
+$lang['L_HELP_SFTPPASS'] = 'digite a senha para o SFTP';
+$lang['L_HELP_SFTPDIR'] = 'onde está o diretório para upload? Digite o caminho!';
+$lang['L_HELP_SPEED'] = 'Velocidade mínima e máxima. O padrão é: 50 à 5000';
+$lang['L_SPEED'] = 'Controle de velocidade';
+$lang['L_HELP_CRONEXECPATH'] = 'Lugar dos scripts Perl.
 O ponto de partida é o endereço HTTP (como um endereço no navegador)
-Permitidas entradas absolutas ou relativas.";
-$lang['L_CRON_EXECPATH']="Caminho dos scripts Perl";
-$lang['L_HELP_CRONCOMPLETELOG']="Quando ativo o resultado completo será escrito em um arquivo_logcompleto.
-Isto é independente de imprimir o texto";
-$lang['L_HELP_FTP_MODE']="Quando você observar problemas usando a tranferência em FTP, ative o modo passivo.";
-
-
-?>
\ No newline at end of file
+Permitidas entradas absolutas ou relativas.';
+$lang['L_CRON_EXECPATH'] = 'Caminho dos scripts Perl';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Quando ativo o resultado completo será escrito em um arquivo_logcompleto.
+Isto é independente de imprimir o texto';
+$lang['L_HELP_FTP_MODE'] = 'Quando você observar problemas usando a tranferência em FTP, ative o modo passivo.';
diff --git a/msd/language/pt_br/lang_install.php b/msd/language/pt_br/lang_install.php
index f36cce72..bb9cd311 100644
--- a/msd/language/pt_br/lang_install.php
+++ b/msd/language/pt_br/lang_install.php
@@ -1,89 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Instalação completada  --> <a href=\"index.php\">iniciar o MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Voltar ao menu principal";
-$lang['L_INSTALLMENU']="Menu principal";
-$lang['L_STEP']="Passo";
-$lang['L_INSTALL']="Instalação";
-$lang['L_UNINSTALL']="Desinstalar";
-$lang['L_TOOLS']="Ferramentas";
-$lang['L_EDITCONF']="Editar configuração";
-$lang['L_OSWEITER']="Continuar sem salvar";
-$lang['L_ERRORMAN']="<strong>Erro durante a gravação da configuração!</strong><br>Favor editar o Arquivo ";
-$lang['L_MANUELL']="manualmente";
-$lang['L_CREATEDIRS']="Criar diretórios";
-$lang['L_INSTALL_CONTINUE']="Continuar com a  instalação";
-$lang['L_CONNECTTOMYSQL']="Conectar ao MySQL ";
-$lang['L_DBPARAMETER']="Parâmetros do banco de dados";
-$lang['L_CONFIGNOTWRITABLE']="Eu não consigo escrever no arquivo \"config.php\".
-Favor usar seu programa de FTP e alterar as permissões deste arquivo para 0777.";
-$lang['L_DBCONNECTION']="Conexão do banco de dados";
-$lang['L_CONNECTIONERROR']="Erro: incapaz de conectar.";
-$lang['L_CONNECTION_OK']="A conexão ao banco de dados foi estabelecida.";
-$lang['L_SAVEANDCONTINUE']="Salvar e continuar a instalação";
-$lang['L_CONFBASIC']="Parâmetros básicos";
-$lang['L_INSTALL_STEP2FINISHED']="Os parâmetros do banco de dados foram salvos.";
-$lang['L_INSTALL_STEP2_1']="Continuar a instalação com as opções padrão";
-$lang['L_LASTSTEP']="Instalação terminada";
-$lang['L_FTPMODE']="Criar os diretórios necessários em modo seguro";
-$lang['L_IDOMANUAL']="Eu mesmo criarei os diretórios";
-$lang['L_DOFROM']="iniciando com";
-$lang['L_FTPMODE2']="Criar os diretórios pelo FTP:";
-$lang['L_CONNECT']="conectar";
-$lang['L_DIRS_CREATED']="Os diretórios foram criados e as permissões corretamente atribuídas.";
-$lang['L_CONNECT_TO']="conectar a";
-$lang['L_CHANGEDIR']="mudar para o diretório";
-$lang['L_CHANGEDIRERROR']="a mudança para o diretório não foi possível";
-$lang['L_FTP_OK']="os parâmetros de FTP estão ok";
-$lang['L_CREATEDIRS2']="Criar diretórios";
-$lang['L_FTP_NOTCONNECTED']="A conexão de FTP não foi estabelecida!";
-$lang['L_CONNWITH']="Conexão com";
-$lang['L_ASUSER']="como usuário";
-$lang['L_NOTPOSSIBLE']="impossível";
-$lang['L_DIRCR1']="criar workdir";
-$lang['L_DIRCR2']="criar backupdir";
-$lang['L_DIRCR4']="criar logdir";
-$lang['L_DIRCR5']="criar configurationdir";
-$lang['L_INDIR']="agora no diretório";
-$lang['L_CHECK_DIRS']="Verificar meus diretórios";
-$lang['L_DISABLEDFUNCTIONS']="Funções desativadas";
-$lang['L_NOFTPPOSSIBLE']="Você não tem as funções de FTP !";
-$lang['L_NOGZPOSSIBLE']="Você não tem as funções de compressão !";
-$lang['L_UI1']="Todos os diretórios que podem conter backups serão excluidos.";
-$lang['L_UI2']="Você tem certeza de que quer isso?";
-$lang['L_UI3']="não, cancelar imediatamente";
-$lang['L_UI4']="sim, favor continuar";
-$lang['L_UI5']="excluir diretórios de serviço";
-$lang['L_UI6']="todos foram excluidos com sucesso.";
-$lang['L_UI7']="Fvor excluir o diretório de script";
-$lang['L_UI8']="one level up";
-$lang['L_UI9']="Um erro ocorreu, impossível excluir</p>Erro com o diretório ";
-$lang['L_IMPORT']="Importar configuração";
-$lang['L_IMPORT3']="A configuração foi carregada ...";
-$lang['L_IMPORT4']="A configuração foi salva.";
-$lang['L_IMPORT5']="Iniciar o MySQLDumper";
-$lang['L_IMPORT6']="Menu de instalação";
-$lang['L_IMPORT7']="Enviar configuração";
-$lang['L_IMPORT8']="voltar ao envio";
-$lang['L_IMPORT9']="Este não é um backup de configuração !";
-$lang['L_IMPORT10']="A configuração foi enviada com sucesso ...";
-$lang['L_IMPORT11']="<strong>Erro: </strong>Houveram problemas ao escrever os comandos sql";
-$lang['L_IMPORT12']="<strong>Erro: </strong>Houveram problemas ao escrever o config.php";
-$lang['L_INSTALL_HELP_PORT']="(em branco = Porta padrão)";
-$lang['L_INSTALL_HELP_SOCKET']="(em branco = Socket padrão)";
-$lang['L_TRYAGAIN']="Tentar novamente";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Porta";
-$lang['L_FOUND_DB']="bd localizado";
-$lang['L_FM_FILEUPLOAD']="Enviar arquivo";
-$lang['L_PASS']="Senha";
-$lang['L_NO_DB_FOUND_INFO']="A conexão com o banco de dados foi estabelecida com sucesso.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>Instalação completada  --> <a href="index.php">iniciar o MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Voltar ao menu principal';
+$lang['L_INSTALLMENU'] = 'Menu principal';
+$lang['L_STEP'] = 'Passo';
+$lang['L_INSTALL'] = 'Instalação';
+$lang['L_UNINSTALL'] = 'Desinstalar';
+$lang['L_TOOLS'] = 'Ferramentas';
+$lang['L_EDITCONF'] = 'Editar configuração';
+$lang['L_OSWEITER'] = 'Continuar sem salvar';
+$lang['L_ERRORMAN'] = '<strong>Erro durante a gravação da configuração!</strong><br>Favor editar o Arquivo ';
+$lang['L_MANUELL'] = 'manualmente';
+$lang['L_CREATEDIRS'] = 'Criar diretórios';
+$lang['L_INSTALL_CONTINUE'] = 'Continuar com a  instalação';
+$lang['L_CONNECTTOMYSQL'] = 'Conectar ao MySQL ';
+$lang['L_DBPARAMETER'] = 'Parâmetros do banco de dados';
+$lang['L_CONFIGNOTWRITABLE'] = 'Eu não consigo escrever no arquivo "config.php".
+Favor usar seu programa de FTP e alterar as permissões deste arquivo para 0777.';
+$lang['L_DBCONNECTION'] = 'Conexão do banco de dados';
+$lang['L_CONNECTIONERROR'] = 'Erro: incapaz de conectar.';
+$lang['L_CONNECTION_OK'] = 'A conexão ao banco de dados foi estabelecida.';
+$lang['L_SAVEANDCONTINUE'] = 'Salvar e continuar a instalação';
+$lang['L_CONFBASIC'] = 'Parâmetros básicos';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Os parâmetros do banco de dados foram salvos.';
+$lang['L_INSTALL_STEP2_1'] = 'Continuar a instalação com as opções padrão';
+$lang['L_LASTSTEP'] = 'Instalação terminada';
+$lang['L_FTPMODE'] = 'Criar os diretórios necessários em modo seguro';
+$lang['L_IDOMANUAL'] = 'Eu mesmo criarei os diretórios';
+$lang['L_DOFROM'] = 'iniciando com';
+$lang['L_FTPMODE2'] = 'Criar os diretórios pelo FTP:';
+$lang['L_CONNECT'] = 'conectar';
+$lang['L_DIRS_CREATED'] = 'Os diretórios foram criados e as permissões corretamente atribuídas.';
+$lang['L_CONNECT_TO'] = 'conectar a';
+$lang['L_CHANGEDIR'] = 'mudar para o diretório';
+$lang['L_CHANGEDIRERROR'] = 'a mudança para o diretório não foi possível';
+$lang['L_FTP_OK'] = 'os parâmetros de FTP estão ok';
+$lang['L_CREATEDIRS2'] = 'Criar diretórios';
+$lang['L_FTP_NOTCONNECTED'] = 'A conexão de FTP não foi estabelecida!';
+$lang['L_CONNWITH'] = 'Conexão com';
+$lang['L_ASUSER'] = 'como usuário';
+$lang['L_NOTPOSSIBLE'] = 'impossível';
+$lang['L_DIRCR1'] = 'criar workdir';
+$lang['L_DIRCR2'] = 'criar backupdir';
+$lang['L_DIRCR4'] = 'criar logdir';
+$lang['L_DIRCR5'] = 'criar configurationdir';
+$lang['L_INDIR'] = 'agora no diretório';
+$lang['L_CHECK_DIRS'] = 'Verificar meus diretórios';
+$lang['L_DISABLEDFUNCTIONS'] = 'Funções desativadas';
+$lang['L_NOFTPPOSSIBLE'] = 'Você não tem as funções de FTP !';
+$lang['L_NOGZPOSSIBLE'] = 'Você não tem as funções de compressão !';
+$lang['L_UI1'] = 'Todos os diretórios que podem conter backups serão excluidos.';
+$lang['L_UI2'] = 'Você tem certeza de que quer isso?';
+$lang['L_UI3'] = 'não, cancelar imediatamente';
+$lang['L_UI4'] = 'sim, favor continuar';
+$lang['L_UI5'] = 'excluir diretórios de serviço';
+$lang['L_UI6'] = 'todos foram excluidos com sucesso.';
+$lang['L_UI7'] = 'Fvor excluir o diretório de script';
+$lang['L_UI8'] = 'one level up';
+$lang['L_UI9'] = 'Um erro ocorreu, impossível excluir</p>Erro com o diretório ';
+$lang['L_IMPORT'] = 'Importar configuração';
+$lang['L_IMPORT3'] = 'A configuração foi carregada ...';
+$lang['L_IMPORT4'] = 'A configuração foi salva.';
+$lang['L_IMPORT5'] = 'Iniciar o MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Menu de instalação';
+$lang['L_IMPORT7'] = 'Enviar configuração';
+$lang['L_IMPORT8'] = 'voltar ao envio';
+$lang['L_IMPORT9'] = 'Este não é um backup de configuração !';
+$lang['L_IMPORT10'] = 'A configuração foi enviada com sucesso ...';
+$lang['L_IMPORT11'] = '<strong>Erro: </strong>Houveram problemas ao escrever os comandos sql';
+$lang['L_IMPORT12'] = '<strong>Erro: </strong>Houveram problemas ao escrever o config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(em branco = Porta padrão)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(em branco = Socket padrão)';
+$lang['L_TRYAGAIN'] = 'Tentar novamente';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Porta';
+$lang['L_FOUND_DB'] = 'bd localizado';
+$lang['L_FM_FILEUPLOAD'] = 'Enviar arquivo';
+$lang['L_PASS'] = 'Senha';
+$lang['L_NO_DB_FOUND_INFO'] = 'A conexão com o banco de dados foi estabelecida com sucesso.<br>
 Seus dados de usuário são válidos e foram aceitos pelo Servidor MySQL.<br>
-Mas o MySQLDumper não foi capaz de encontrar nenhuma base de dados.<br>
+Mas o MyOOS [Dumper] não foi capaz de encontrar nenhuma base de dados.<br>
 A detecção automática via script é bloqueada em alguns servidores.<br>
 Você deve colocar seus dados do banco de dados manualmente depois de terminada a instalação.
-Clique em \"configurações\" \"Parâmetros de Conexão - exibir\" e digite ali o nome do banco de dados.";
-$lang['L_SAFEMODEDESC']="Because PHP is running in safe_mode you need to create the following directories manually using your FTP-Programm:";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+Clique em "configurações" "Parâmetros de Conexão - exibir" e digite ali o nome do banco de dados.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/pt_br/lang_log.php b/msd/language/pt_br/lang_log.php
index 8b94782d..b103cb4f 100644
--- a/msd/language/pt_br/lang_log.php
+++ b/msd/language/pt_br/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="excluir log";
-$lang['L_LOGFILEFORMAT']="Formato do arquivo de log";
-$lang['L_LOGFILENOTWRITABLE']="Não pude escrever no arquiuvo de log !";
-$lang['L_NOREVERSE']="Entradas mais antigas primeiro";
-$lang['L_REVERSE']="Últimas entradas primeiro";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'excluir log';
+$lang['L_LOGFILEFORMAT'] = 'Formato do arquivo de log';
+$lang['L_LOGFILENOTWRITABLE'] = 'Não pude escrever no arquiuvo de log !';
+$lang['L_NOREVERSE'] = 'Entradas mais antigas primeiro';
+$lang['L_REVERSE'] = 'Últimas entradas primeiro';
diff --git a/msd/language/pt_br/lang_main.php b/msd/language/pt_br/lang_main.php
index a165e5c4..db804b0b 100644
--- a/msd/language/pt_br/lang_main.php
+++ b/msd/language/pt_br/lang_main.php
@@ -1,78 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Você não tem alçada para funções de FTP !";
-$lang['L_INFO_LOCATION']="Sua localização é ";
-$lang['L_INFO_DATABASES']="Os seguintes bancos de dados estão no seu servidor:";
-$lang['L_INFO_NODB']="O banco de dados não existe.";
-$lang['L_INFO_DBDETAIL']="informação detalhada do banco de dados ";
-$lang['L_INFO_DBEMPTY']="O banco de dados está vazio !";
-$lang['L_INFO_RECORDS']="Registros";
-$lang['L_INFO_SIZE']="tamanho";
-$lang['L_INFO_LASTUPDATE']="Última atualização";
-$lang['L_INFO_SUM']="total";
-$lang['L_INFO_OPTIMIZED']="otimizada";
-$lang['L_OPTIMIZE_DATABASES']="Otimizar tabelas";
-$lang['L_CHECK_TABLES']="Verificar tabelas";
-$lang['L_CLEAR_DATABASE']="Limpar banco de dados";
-$lang['L_DELETE_DATABASE']="Excluir banco de dados";
-$lang['L_INFO_CLEARED']="foi limpa";
-$lang['L_INFO_DELETED']="foi excluida";
-$lang['L_INFO_EMPTYDB1']="Deve o banco de dados";
-$lang['L_INFO_EMPTYDB2']=" ser truncado? (Atenção: Todos os dados serão perdidos para sempre!)";
-$lang['L_INFO_KILLDB']=" ser excluído? (Atenção: Todos os dados serão perdidos para sempre!)";
-$lang['L_PROCESSKILL1']="O script tenta abortar o processo ";
-$lang['L_PROCESSKILL2']="para abortar.";
-$lang['L_PROCESSKILL3']="O script tenta desde  ";
-$lang['L_PROCESSKILL4']=" sec. abortar o processo ";
-$lang['L_HTACC_CREATE']="Criar proteção do diretório";
-$lang['L_ENCRYPTION_TYPE']="Tipo de encriptação";
-$lang['L_HTACC_CRYPT']="Crypt (Linux e Sistemas Unix)";
-$lang['L_HTACC_MD5']="MD5 (Linux e Sistemas Unix)";
-$lang['L_HTACC_NO_ENCRYPTION']="texto plano, sem encriptação (Windows)";
-$lang['L_HTACCESS8']="Já existe uma proteção do diretório. Se você criar novas, as antigas serão sobrescritas !";
-$lang['L_HTACC_NO_USERNAME']="Você tem que digitar um nome!";
-$lang['L_PASSWORDS_UNEQUAL']="As senhas não são idênticas ou são nulas !";
-$lang['L_HTACC_CONFIRM_DELETE']="Deve a proteção do diretório ser gravada agora ?";
-$lang['L_HTACC_CREATED']="A proteção do diretório foi criada.";
-$lang['L_HTACC_CONTENT']="Conteúdo do arquivo";
-$lang['L_HTACC_CREATE_ERROR']="Houve um erro durante a criação da proteção do diretório !<br>Favor criar os 2 arquivos manualmente com o seguinte conteúdo";
-$lang['L_HTACC_PROPOSED']="Urgentemente recomendado";
-$lang['L_HTACC_EDIT']="Editar o .htaccess";
-$lang['L_HTACCESS18']="Criar o .htaccess em ";
-$lang['L_HTACCESS19']="Recarregar ";
-$lang['L_HTACCESS20']="Executar script";
-$lang['L_HTACCESS21']="Adicionar handler";
-$lang['L_HTACCESS22']="Tornar executável";
-$lang['L_HTACCESS23']="Listar Diretórios";
-$lang['L_HTACCESS24']="Documento de Erro";
-$lang['L_HTACCESS25']="Ativar rewrite";
-$lang['L_HTACCESS26']="Negar / Permitir";
-$lang['L_HTACCESS27']="Redirecionar";
-$lang['L_HTACCESS28']="Error Log";
-$lang['L_HTACCESS29']="Mais exemplos e documentação";
-$lang['L_HTACCESS30']="Provedor";
-$lang['L_HTACCESS31']="General";
-$lang['L_HTACCESS32']="Atenção! As diretivas do .htaccess afetam o comportamento do navegador.<br>Com conteúdo incorreto, as páginas podem ficar inacessíveis.";
-$lang['L_PHPBUG']="Bug em zlib ! Não foi possível comprimir!";
-$lang['L_DISABLEDFUNCTIONS']="Desativar Funções";
-$lang['L_NOGZPOSSIBLE']="Como Zlib não está instalado, você não poderá usar as funções do GZip!";
-$lang['L_DELETE_HTACCESS']="Remover proteção de diretório (apagar .htaccess)";
-$lang['L_WRONG_RIGHTS']="O arquivo ou o diretório '%s' não tem permissão de escrita para mim.<br>
+
+$lang['L_NOFTPPOSSIBLE'] = 'Você não tem alçada para funções de FTP !';
+$lang['L_INFO_LOCATION'] = 'Sua localização é ';
+$lang['L_INFO_DATABASES'] = 'Os seguintes bancos de dados estão no seu servidor:';
+$lang['L_INFO_NODB'] = 'O banco de dados não existe.';
+$lang['L_INFO_DBDETAIL'] = 'informação detalhada do banco de dados ';
+$lang['L_INFO_DBEMPTY'] = 'O banco de dados está vazio !';
+$lang['L_INFO_RECORDS'] = 'Registros';
+$lang['L_INFO_SIZE'] = 'tamanho';
+$lang['L_INFO_LASTUPDATE'] = 'Última atualização';
+$lang['L_INFO_SUM'] = 'total';
+$lang['L_INFO_OPTIMIZED'] = 'otimizada';
+$lang['L_OPTIMIZE_DATABASES'] = 'Otimizar tabelas';
+$lang['L_CHECK_TABLES'] = 'Verificar tabelas';
+$lang['L_CLEAR_DATABASE'] = 'Limpar banco de dados';
+$lang['L_DELETE_DATABASE'] = 'Excluir banco de dados';
+$lang['L_INFO_CLEARED'] = 'foi limpa';
+$lang['L_INFO_DELETED'] = 'foi excluida';
+$lang['L_INFO_EMPTYDB1'] = 'Deve o banco de dados';
+$lang['L_INFO_EMPTYDB2'] = ' ser truncado? (Atenção: Todos os dados serão perdidos para sempre!)';
+$lang['L_INFO_KILLDB'] = ' ser excluído? (Atenção: Todos os dados serão perdidos para sempre!)';
+$lang['L_PROCESSKILL1'] = 'O script tenta abortar o processo ';
+$lang['L_PROCESSKILL2'] = 'para abortar.';
+$lang['L_PROCESSKILL3'] = 'O script tenta desde  ';
+$lang['L_PROCESSKILL4'] = ' sec. abortar o processo ';
+$lang['L_HTACC_CREATE'] = 'Criar proteção do diretório';
+$lang['L_ENCRYPTION_TYPE'] = 'Tipo de encriptação';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Já existe uma proteção do diretório. Se você criar novas, as antigas serão sobrescritas !';
+$lang['L_HTACC_NO_USERNAME'] = 'Você tem que digitar um nome!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'As senhas não são idênticas ou são nulas !';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Deve a proteção do diretório ser gravada agora ?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'A proteção do diretório foi criada.';
+$lang['L_HTACC_CONTENT'] = 'Conteúdo do arquivo';
+$lang['L_HTACC_CREATE_ERROR'] = 'Houve um erro durante a criação da proteção do diretório !<br>Favor criar os 2 arquivos manualmente com o seguinte conteúdo';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'Editar o .htaccess';
+$lang['L_HTACCESS18'] = 'Criar o .htaccess em ';
+$lang['L_HTACCESS19'] = 'Recarregar ';
+$lang['L_HTACCESS20'] = 'Executar script';
+$lang['L_HTACCESS21'] = 'Adicionar handler';
+$lang['L_HTACCESS22'] = 'Tornar executável';
+$lang['L_HTACCESS23'] = 'Listar Diretórios';
+$lang['L_HTACCESS24'] = 'Documento de Erro';
+$lang['L_HTACCESS25'] = 'Ativar rewrite';
+$lang['L_HTACCESS26'] = 'Negar / Permitir';
+$lang['L_HTACCESS27'] = 'Redirecionar';
+$lang['L_HTACCESS28'] = 'Error Log';
+$lang['L_HTACCESS29'] = 'Mais exemplos e documentação';
+$lang['L_HTACCESS30'] = 'Provedor';
+$lang['L_HTACCESS31'] = 'General';
+$lang['L_HTACCESS32'] = 'Atenção! As diretivas do .htaccess afetam o comportamento do navegador.<br>Com conteúdo incorreto, as páginas podem ficar inacessíveis.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Desativar Funções';
+$lang['L_NOGZPOSSIBLE'] = 'Como Zlib não está instalado, você não poderá usar as funções do GZip!';
+$lang['L_DELETE_HTACCESS'] = 'Remover proteção de diretório (apagar .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "O arquivo ou o diretório '%s' não tem permissão de escrita para mim.<br>
 As permissões (chmod) não estão configuradas apropriadamente ou não há privilégios suficientes para este usuário.<br>
 Por favor configure corretamente as permissões usando o programa de FTP.<br>
 O arquivo ou diretório necessitam de configuração para %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Não foi possível criar o diretório '%s'. 
+$lang['L_CANT_CREATE_DIR'] = "Não foi possível criar o diretório '%s'. 
 Por favor utilize seu programa de FTP.";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="não pude encontrar o arquivo";
-
-
-?>
\ No newline at end of file
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'não pude encontrar o arquivo';
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/pt_br/lang_restore.php b/msd/language/pt_br/lang_restore.php
index 3d30a59a..08800c88 100644
--- a/msd/language/pt_br/lang_restore.php
+++ b/msd/language/pt_br/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Até agora <b>%d</b> tabelas foram criadas.";
-$lang['L_FILE_MISSING']="não pude encontrar o arquivo";
-$lang['L_RESTORE_DB']="banco de dados '<b>%s</b>' em '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> tabelas driadas.";
-$lang['L_RESTORE_RUN1']="<br>Up to now  <b>%s</b> of <b>%s</b> registros foram adicionados com sucesso.";
-$lang['L_RESTORE_RUN2']="<br>Agora a tabela '<b>%s</b>' está sendo restaurada.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> registros inseridos.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Até agora <b>%d</b> de <b>%d</b> tabelas foram criadas.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Parabéns.</b><br><br>A restauração do banco de dados está pronta.<br>todos os dados do arquivo de backup foram restaurados.<br><br>Está tudo pronto. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Error:<br>Seleção do banco de dados <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> falhou!";
-$lang['L_FILE_OPEN_ERROR']="Erro: não pude abrir o arquivo.";
-$lang['L_PROGRESS_OVER_ALL']="Progresso do todo";
-$lang['L_BACK_TO_OVERVIEW']="Visão geral do banco de dados";
-$lang['L_RESTORE_RUN0']="<br>até agora <b>%s</b> registros foram adicionados com sucesso.";
-$lang['L_UNKNOWN_SQLCOMMAND']="comando SQL desconhecido";
-$lang['L_NOTICES']="Notices";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Até agora <b>%d</b> tabelas foram criadas.';
+$lang['L_FILE_MISSING'] = 'não pude encontrar o arquivo';
+$lang['L_RESTORE_DB'] = "banco de dados '<b>%s</b>' em '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> tabelas driadas.';
+$lang['L_RESTORE_RUN1'] = '<br>Up to now  <b>%s</b> of <b>%s</b> registros foram adicionados com sucesso.';
+$lang['L_RESTORE_RUN2'] = "<br>Agora a tabela '<b>%s</b>' está sendo restaurada.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> registros inseridos.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Até agora <b>%d</b> de <b>%d</b> tabelas foram criadas.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Parabéns.</b><br><br>A restauração do banco de dados está pronta.<br>todos os dados do arquivo de backup foram restaurados.<br><br>Está tudo pronto. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>Error:<br>Seleção do banco de dados <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> falhou!';
+$lang['L_FILE_OPEN_ERROR'] = 'Erro: não pude abrir o arquivo.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Progresso do todo';
+$lang['L_BACK_TO_OVERVIEW'] = 'Visão geral do banco de dados';
+$lang['L_RESTORE_RUN0'] = '<br>até agora <b>%s</b> registros foram adicionados com sucesso.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'comando SQL desconhecido';
+$lang['L_NOTICES'] = 'Notices';
diff --git a/msd/language/pt_br/lang_sql.php b/msd/language/pt_br/lang_sql.php
index 4c4b6eca..f902886e 100644
--- a/msd/language/pt_br/lang_sql.php
+++ b/msd/language/pt_br/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Comando";
-$lang['L_IMPORT_NOTABLE']="Nenhuma tabela foi selecionada para importação!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="A execução do comandos SQL pode manipular os dados. CUIDADO! Os autores não aceitam qualquer responsabilidade por danos ou perda de dados.";
-$lang['L_SQL_EXEC']="Executar comando SQL";
-$lang['L_SQL_DATAVIEW']="Exibir dados";
-$lang['L_SQL_TABLEVIEW']="Exibir tabelas";
-$lang['L_SQL_VONINS']="do total";
-$lang['L_SQL_NODATA']="nenhum registro";
-$lang['L_SQL_RECORDUPDATED']="O registro foi atualizado";
-$lang['L_SQL_RECORDINSERTED']="O registro foi adicionado";
-$lang['L_SQL_BACKDBOVERVIEW']="Voltar para Visão geral";
-$lang['L_SQL_RECORDDELETED']="O registro foi excluido";
-$lang['L_ASKTABLEEMPTY']="Deve a tabela `%s` ser esvaziada?";
-$lang['L_SQL_RECORDEDIT']="editar registro";
-$lang['L_SQL_RECORDNEW']="novo registro";
-$lang['L_ASKDELETERECORD']="Você tem certeza em apagar este registro?";
-$lang['L_ASKDELETETABLE']="Deve a tabela `%s` ser excluida?";
-$lang['L_SQL_BEFEHLE']="Comandos SQL";
-$lang['L_SQL_BEFEHLNEU']="Novo comando";
-$lang['L_SQL_BEFEHLSAVED1']="Comando SQL";
-$lang['L_SQL_BEFEHLSAVED2']="foi adicionada";
-$lang['L_SQL_BEFEHLSAVED3']="foi salva";
-$lang['L_SQL_BEFEHLSAVED4']="foi movida acima";
-$lang['L_SQL_BEFEHLSAVED5']="foi excluida";
-$lang['L_SQL_QUERYENTRY']="A consulta contém";
-$lang['L_SQL_COLUMNS']="Colunas";
-$lang['L_ASKDBDELETE']="Você quer excluir o banco de dados `%s` com seu conteúdo?";
-$lang['L_ASKDBEMPTY']="Você quer esvaziar o banco de dados `%s` ?";
-$lang['L_ASKDBCOPY']="Você quer copiar o banco de dados `%s` para o banco de dados `%s`?";
-$lang['L_SQL_TABLENEW']="Editar tabelas";
-$lang['L_SQL_OUTPUT']="Saída SQL";
-$lang['L_DO_NOW']="executar agora";
-$lang['L_SQL_NAMEDEST_MISSING']="O nome da destinação está faltando !";
-$lang['L_ASKDELETEFIELD']="Você quer excluir o campo?";
-$lang['L_SQL_COMMANDS_IN']=" linhas em ";
-$lang['L_SQL_COMMANDS_IN2']="  sec. parsed.";
-$lang['L_SQL_OUT1']="Executado ";
-$lang['L_SQL_OUT2']="Comandos";
-$lang['L_SQL_OUT3']="Haviam ";
-$lang['L_SQL_OUT4']="Comentários";
-$lang['L_SQL_OUT5']="Devido à saída conter mais de 5000 linhas ela não será exibida.";
-$lang['L_SQL_SELECDB']="Selecionar banco de dados";
-$lang['L_SQL_TABLESOFDB']="Tabelas do banco de dados";
-$lang['L_SQL_EDIT']="editar";
-$lang['L_SQL_NOFIELDDELETE']="A exclusão não é possível porque as tabelas devem ter pelo menos um campo.";
-$lang['L_SQL_FIELDDELETE1']="O campo";
-$lang['L_SQL_DELETED']="foi excluido";
-$lang['L_SQL_CHANGED']="foi modificado.";
-$lang['L_SQL_CREATED']="foi criado.";
-$lang['L_SQL_NODEST_COPY']="Nenhuma cópia sem destinação !";
-$lang['L_SQL_DESTTABLE_EXISTS']="tabelas de destinação existem !";
-$lang['L_SQL_SCOPY']="A estrutura da tabela `%s` foi copiada para a tabela `%s`.";
-$lang['L_SQL_TCOPY']="A tabela `%s` foi copiada com os dados da tabela `%s`.";
-$lang['L_SQL_TABLENONAME']="A tabela requer um nome!";
-$lang['L_SQL_TBLNAMEEMPTY']="O nome da tabela não pode ser nulo!";
-$lang['L_SQL_COLLATENOTMATCH']="O conjunto de caracteres e intercalação não combinam juntos!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Erro: Nenhum nome de campo válido";
-$lang['L_SQL_CREATETABLE']="crair tabela";
-$lang['L_SQL_COPYTABLE']="copiar tabela";
-$lang['L_SQL_STRUCTUREONLY']="Somente a estrutura";
-$lang['L_SQL_STRUCTUREDATA']="Estrutura e dados";
-$lang['L_SQL_NOTABLESINDB']="Nenhuma tabela encontrada no banco de dados";
-$lang['L_SQL_SELECTTABLE']="selecionar tabela";
-$lang['L_SQL_SHOWDATATABLE']="Exibir dados da tabela";
-$lang['L_SQL_TBLPROPSOF']="Propriedades da tabela";
-$lang['L_SQL_EDITFIELD']="Editar campo";
-$lang['L_SQL_NEWFIELD']="Novo campo";
-$lang['L_SQL_INDEXES']="Índices";
-$lang['L_SQL_ATPOSITION']="inserir na posição";
-$lang['L_SQL_FIRST']="primeiro";
-$lang['L_SQL_AFTER']="após";
-$lang['L_SQL_CHANGEFIELD']="modificar campo";
-$lang['L_SQL_INSERTFIELD']="inserir campo";
-$lang['L_SQL_INSERTNEWFIELD']="inserir novo campo";
-$lang['L_SQL_TABLEINDEXES']="Índices da tabela";
-$lang['L_SQL_ALLOWDUPS']="Duplicidade permitida";
-$lang['L_SQL_CARDINALITY']="Cardinalmente";
-$lang['L_SQL_TABLENOINDEXES']="Nenhum índices na tabela";
-$lang['L_SQL_CREATEINDEX']="criar novo índice";
-$lang['L_SQL_WASEMPTIED']="foi esvaziada";
-$lang['L_SQL_RENAMEDTO']="foi renomeado para";
-$lang['L_SQL_DBCOPY']="O conteúdo do banco de dados `%s` foi copiado no banco de dados `%s`.";
-$lang['L_SQL_DBSCOPY']="A estrutura do banco de dados `%s` foi copiada no banco de dados `%s`.";
-$lang['L_SQL_WASCREATED']="foi criada";
-$lang['L_SQL_RENAMEDB']="Renomear banco de dados";
-$lang['L_SQL_ACTIONS']="Ações";
-$lang['L_SQL_CHOOSEACTION']="Escolher ação";
-$lang['L_SQL_DELETEDB']="Excluir banco de dados";
-$lang['L_SQL_EMPTYDB']="Esvaziar banco de dados";
-$lang['L_SQL_COPYDATADB']="Copiar todo o banco de dados para";
-$lang['L_SQL_COPYSDB']="Copiar a estrutura do banco de dados";
-$lang['L_SQL_IMEXPORT']="Importar-Exportar";
-$lang['L_INFO_RECORDS']="registros";
-$lang['L_NAME']="Name";
-$lang['L_ASKTABLEEMPTYKEYS']="Deve a tabela `%s` ser esvaziada e os índices reiniciados?";
-$lang['L_EDIT']="editar";
-$lang['L_DELETE']="excluir";
-$lang['L_EMPTY']="esvaziar";
-$lang['L_EMPTYKEYS']="esvaziar e reiniciar os índices";
-$lang['L_SQL_TABLEEMPTIED']="A tabela `%s` foi excluida.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="A tabela `%s` foi excluida e os índices reiniciados.";
-$lang['L_SQL_LIBRARY']="Biblioteca SQL";
-$lang['L_SQL_ATTRIBUTES']="Atributos";
-$lang['L_SQL_UPLOADEDFILE']="arquivo carregado: ";
-$lang['L_SQL_IMPORT']="Importar no banco de dados `%s`";
-$lang['L_EXPORT']="Exportar";
-$lang['L_IMPORT']="Importar";
-$lang['L_IMPORTOPTIONS']="Opções de importação";
-$lang['L_CSVOPTIONS']="Opções de CSV";
-$lang['L_IMPORTTABLE']="Importar para a tabela";
-$lang['L_NEWTABLE']="nova tabela";
-$lang['L_IMPORTSOURCE']="Fonte da importação";
-$lang['L_FROMTEXTBOX']="da caixa de texto";
-$lang['L_FROMFILE']="do arquivo";
-$lang['L_EMPTYTABLEBEFORE']="Esvaziar a tabela antes";
-$lang['L_CREATEAUTOINDEX']="Criar um Auto-índice";
-$lang['L_CSV_NAMEFIRSTLINE']="Nome dos campos na primeira linha";
-$lang['L_CSV_FIELDSEPERATE']="Campos separados por";
-$lang['L_CSV_FIELDSENCLOSED']="Campos fechados por";
-$lang['L_CSV_FIELDSESCAPE']="Campos escapados com";
-$lang['L_CSV_EOL']="Separar linhas com";
-$lang['L_CSV_NULL']="Substituir NULL com";
-$lang['L_CSV_FILEOPEN']="Abrir arquivo CSV";
-$lang['L_IMPORTIEREN']="Importar";
-$lang['L_SQL_EXPORT']="Exportar from banco de dados `%s`";
-$lang['L_EXPORTOPTIONS']="Opções de exportação";
-$lang['L_EXCEL2003']="Excel de 2003";
-$lang['L_SHOWRESULT']="exibir resultado";
-$lang['L_SENDRESULTASFILE']="enviar resultado como arquivo";
-$lang['L_EXPORTLINES']="<strong>%s</strong> linhas exportadas";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="A contagem de campos não confere com a dos dados a importar (%d ao invés de %d).";
-$lang['L_CSV_FIELDSLINES']="%d campos reconhecidos, totalizando %d linhas";
-$lang['L_CSV_ERRORCREATETABLE']="Erro durante a criação da tabela `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="favor escolher um arquivo.";
-$lang['L_CSV_NODATA']="Nenhum dado encontrado para importação!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="funções gerais";
-$lang['L_SQLLIB_RESETAUTO']="reiniciar o auto-incremento";
-$lang['L_SQLLIB_BOARDS']="Quadros";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="desativar quadro";
-$lang['L_SQLLIB_ACTIVATEBOARD']="ativar quadro";
-$lang['L_SQL_NOTABLESSELECTED']="Nenhuma tabela selecionada !";
-$lang['L_TOOLS']="Ferramentas";
-$lang['L_TOOLS_TOOLBOX']="Selecionar banco de dados / Funções de banco de dados / Importar - Exportar ";
-$lang['L_SQL_OPENFILE']="Abrir arquivo SQL";
-$lang['L_SQL_OPENFILE_BUTTON']="Upload";
-$lang['L_MAX_UPLOAD_SIZE']="Tamanho máximo de arquivo";
-$lang['L_SQL_SEARCH']="Pesquisar";
-$lang['L_SQL_SEARCHWORDS']="Pesquisar palavra(s)";
-$lang['L_START_SQL_SEARCH']="iniciar pesquisa";
-$lang['L_RESET_SEARCHWORDS']="reiniciar pesquisa de palavras";
-$lang['L_SEARCH_OPTIONS']="Opções de pesquisa";
-$lang['L_SEARCH_RESULTS']="A pesquisa por \"<b>%s</b>\" na tabela \"<b>%s</b>\" levou aos seguintes resultados";
-$lang['L_SEARCH_NO_RESULTS']="A pesquisa por \"<b>%s</b>\" na tabela \"<b>%s</b>\" não trouxe nenhum resultado!";
-$lang['L_NO_ENTRIES']="A tabela \"<b>%s</b>\" está vazia e não contêm nenhuma entrada.";
-$lang['L_SEARCH_ACCESS_KEYS']="Navegação: para frente=ALT+V, para trás=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="a coluna deve conter uma das palavras a pesquisar (OU-pesquisar)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="a linha deve conter todas as palavras a pesquisar, mas elas podem estar em qualquer coluna (pode levar algum tempo)";
-$lang['L_SEARCH_OPTIONS_AND']="a coluna deve conter todas as palavras a pesquisar (E-pesquisar)";
-$lang['L_SEARCH_IN_TABLE']="Pesquisar na tabela";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Edit table structure";
-$lang['L_DEFAULT_CHARSET']="Default character set";
-$lang['L_TITLE_KEY_PRIMARY']="Primary key";
-$lang['L_TITLE_KEY_UNIQUE']="Unique key";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Fulltext key";
-$lang['L_TITLE_NOKEY']="No key";
-$lang['L_TITLE_SEARCH']="Search";
-$lang['L_TITLE_MYSQL_HELP']="MySQl Documentation";
-$lang['L_TITLE_UPLOAD']="Upload SQL file";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="tamanho";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Comando';
+$lang['L_IMPORT_NOTABLE'] = 'Nenhuma tabela foi selecionada para importação!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'A execução do comandos SQL pode manipular os dados. CUIDADO! Os autores não aceitam qualquer responsabilidade por danos ou perda de dados.';
+$lang['L_SQL_EXEC'] = 'Executar comando SQL';
+$lang['L_SQL_DATAVIEW'] = 'Exibir dados';
+$lang['L_SQL_TABLEVIEW'] = 'Exibir tabelas';
+$lang['L_SQL_VONINS'] = 'do total';
+$lang['L_SQL_NODATA'] = 'nenhum registro';
+$lang['L_SQL_RECORDUPDATED'] = 'O registro foi atualizado';
+$lang['L_SQL_RECORDINSERTED'] = 'O registro foi adicionado';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'Voltar para Visão geral';
+$lang['L_SQL_RECORDDELETED'] = 'O registro foi excluido';
+$lang['L_ASKTABLEEMPTY'] = 'Deve a tabela `%s` ser esvaziada?';
+$lang['L_SQL_RECORDEDIT'] = 'editar registro';
+$lang['L_SQL_RECORDNEW'] = 'novo registro';
+$lang['L_ASKDELETERECORD'] = 'Você tem certeza em apagar este registro?';
+$lang['L_ASKDELETETABLE'] = 'Deve a tabela `%s` ser excluida?';
+$lang['L_SQL_BEFEHLE'] = 'Comandos SQL';
+$lang['L_SQL_BEFEHLNEU'] = 'Novo comando';
+$lang['L_SQL_BEFEHLSAVED1'] = 'Comando SQL';
+$lang['L_SQL_BEFEHLSAVED2'] = 'foi adicionada';
+$lang['L_SQL_BEFEHLSAVED3'] = 'foi salva';
+$lang['L_SQL_BEFEHLSAVED4'] = 'foi movida acima';
+$lang['L_SQL_BEFEHLSAVED5'] = 'foi excluida';
+$lang['L_SQL_QUERYENTRY'] = 'A consulta contém';
+$lang['L_SQL_COLUMNS'] = 'Colunas';
+$lang['L_ASKDBDELETE'] = 'Você quer excluir o banco de dados `%s` com seu conteúdo?';
+$lang['L_ASKDBEMPTY'] = 'Você quer esvaziar o banco de dados `%s` ?';
+$lang['L_ASKDBCOPY'] = 'Você quer copiar o banco de dados `%s` para o banco de dados `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Editar tabelas';
+$lang['L_SQL_OUTPUT'] = 'Saída SQL';
+$lang['L_DO_NOW'] = 'executar agora';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'O nome da destinação está faltando !';
+$lang['L_ASKDELETEFIELD'] = 'Você quer excluir o campo?';
+$lang['L_SQL_COMMANDS_IN'] = ' linhas em ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sec. parsed.';
+$lang['L_SQL_OUT1'] = 'Executado ';
+$lang['L_SQL_OUT2'] = 'Comandos';
+$lang['L_SQL_OUT3'] = 'Haviam ';
+$lang['L_SQL_OUT4'] = 'Comentários';
+$lang['L_SQL_OUT5'] = 'Devido à saída conter mais de 5000 linhas ela não será exibida.';
+$lang['L_SQL_SELECDB'] = 'Selecionar banco de dados';
+$lang['L_SQL_TABLESOFDB'] = 'Tabelas do banco de dados';
+$lang['L_SQL_EDIT'] = 'editar';
+$lang['L_SQL_NOFIELDDELETE'] = 'A exclusão não é possível porque as tabelas devem ter pelo menos um campo.';
+$lang['L_SQL_FIELDDELETE1'] = 'O campo';
+$lang['L_SQL_DELETED'] = 'foi excluido';
+$lang['L_SQL_CHANGED'] = 'foi modificado.';
+$lang['L_SQL_CREATED'] = 'foi criado.';
+$lang['L_SQL_NODEST_COPY'] = 'Nenhuma cópia sem destinação !';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'tabelas de destinação existem !';
+$lang['L_SQL_SCOPY'] = 'A estrutura da tabela `%s` foi copiada para a tabela `%s`.';
+$lang['L_SQL_TCOPY'] = 'A tabela `%s` foi copiada com os dados da tabela `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'A tabela requer um nome!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'O nome da tabela não pode ser nulo!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'O conjunto de caracteres e intercalação não combinam juntos!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Erro: Nenhum nome de campo válido';
+$lang['L_SQL_CREATETABLE'] = 'crair tabela';
+$lang['L_SQL_COPYTABLE'] = 'copiar tabela';
+$lang['L_SQL_STRUCTUREONLY'] = 'Somente a estrutura';
+$lang['L_SQL_STRUCTUREDATA'] = 'Estrutura e dados';
+$lang['L_SQL_NOTABLESINDB'] = 'Nenhuma tabela encontrada no banco de dados';
+$lang['L_SQL_SELECTTABLE'] = 'selecionar tabela';
+$lang['L_SQL_SHOWDATATABLE'] = 'Exibir dados da tabela';
+$lang['L_SQL_TBLPROPSOF'] = 'Propriedades da tabela';
+$lang['L_SQL_EDITFIELD'] = 'Editar campo';
+$lang['L_SQL_NEWFIELD'] = 'Novo campo';
+$lang['L_SQL_INDEXES'] = 'Índices';
+$lang['L_SQL_ATPOSITION'] = 'inserir na posição';
+$lang['L_SQL_FIRST'] = 'primeiro';
+$lang['L_SQL_AFTER'] = 'após';
+$lang['L_SQL_CHANGEFIELD'] = 'modificar campo';
+$lang['L_SQL_INSERTFIELD'] = 'inserir campo';
+$lang['L_SQL_INSERTNEWFIELD'] = 'inserir novo campo';
+$lang['L_SQL_TABLEINDEXES'] = 'Índices da tabela';
+$lang['L_SQL_ALLOWDUPS'] = 'Duplicidade permitida';
+$lang['L_SQL_CARDINALITY'] = 'Cardinalmente';
+$lang['L_SQL_TABLENOINDEXES'] = 'Nenhum índices na tabela';
+$lang['L_SQL_CREATEINDEX'] = 'criar novo índice';
+$lang['L_SQL_WASEMPTIED'] = 'foi esvaziada';
+$lang['L_SQL_RENAMEDTO'] = 'foi renomeado para';
+$lang['L_SQL_DBCOPY'] = 'O conteúdo do banco de dados `%s` foi copiado no banco de dados `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'A estrutura do banco de dados `%s` foi copiada no banco de dados `%s`.';
+$lang['L_SQL_WASCREATED'] = 'foi criada';
+$lang['L_SQL_RENAMEDB'] = 'Renomear banco de dados';
+$lang['L_SQL_ACTIONS'] = 'Ações';
+$lang['L_SQL_CHOOSEACTION'] = 'Escolher ação';
+$lang['L_SQL_DELETEDB'] = 'Excluir banco de dados';
+$lang['L_SQL_EMPTYDB'] = 'Esvaziar banco de dados';
+$lang['L_SQL_COPYDATADB'] = 'Copiar todo o banco de dados para';
+$lang['L_SQL_COPYSDB'] = 'Copiar a estrutura do banco de dados';
+$lang['L_SQL_IMEXPORT'] = 'Importar-Exportar';
+$lang['L_INFO_RECORDS'] = 'registros';
+$lang['L_NAME'] = 'Name';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Deve a tabela `%s` ser esvaziada e os índices reiniciados?';
+$lang['L_EDIT'] = 'editar';
+$lang['L_DELETE'] = 'excluir';
+$lang['L_EMPTY'] = 'esvaziar';
+$lang['L_EMPTYKEYS'] = 'esvaziar e reiniciar os índices';
+$lang['L_SQL_TABLEEMPTIED'] = 'A tabela `%s` foi excluida.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'A tabela `%s` foi excluida e os índices reiniciados.';
+$lang['L_SQL_LIBRARY'] = 'Biblioteca SQL';
+$lang['L_SQL_ATTRIBUTES'] = 'Atributos';
+$lang['L_SQL_UPLOADEDFILE'] = 'arquivo carregado: ';
+$lang['L_SQL_IMPORT'] = 'Importar no banco de dados `%s`';
+$lang['L_EXPORT'] = 'Exportar';
+$lang['L_IMPORT'] = 'Importar';
+$lang['L_IMPORTOPTIONS'] = 'Opções de importação';
+$lang['L_CSVOPTIONS'] = 'Opções de CSV';
+$lang['L_IMPORTTABLE'] = 'Importar para a tabela';
+$lang['L_NEWTABLE'] = 'nova tabela';
+$lang['L_IMPORTSOURCE'] = 'Fonte da importação';
+$lang['L_FROMTEXTBOX'] = 'da caixa de texto';
+$lang['L_FROMFILE'] = 'do arquivo';
+$lang['L_EMPTYTABLEBEFORE'] = 'Esvaziar a tabela antes';
+$lang['L_CREATEAUTOINDEX'] = 'Criar um Auto-índice';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Nome dos campos na primeira linha';
+$lang['L_CSV_FIELDSEPERATE'] = 'Campos separados por';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Campos fechados por';
+$lang['L_CSV_FIELDSESCAPE'] = 'Campos escapados com';
+$lang['L_CSV_EOL'] = 'Separar linhas com';
+$lang['L_CSV_NULL'] = 'Substituir NULL com';
+$lang['L_CSV_FILEOPEN'] = 'Abrir arquivo CSV';
+$lang['L_IMPORTIEREN'] = 'Importar';
+$lang['L_SQL_EXPORT'] = 'Exportar from banco de dados `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Opções de exportação';
+$lang['L_EXCEL2003'] = 'Excel de 2003';
+$lang['L_SHOWRESULT'] = 'exibir resultado';
+$lang['L_SENDRESULTASFILE'] = 'enviar resultado como arquivo';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> linhas exportadas';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'A contagem de campos não confere com a dos dados a importar (%d ao invés de %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d campos reconhecidos, totalizando %d linhas';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Erro durante a criação da tabela `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'favor escolher um arquivo.';
+$lang['L_CSV_NODATA'] = 'Nenhum dado encontrado para importação!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'funções gerais';
+$lang['L_SQLLIB_RESETAUTO'] = 'reiniciar o auto-incremento';
+$lang['L_SQLLIB_BOARDS'] = 'Quadros';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'desativar quadro';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'ativar quadro';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Nenhuma tabela selecionada !';
+$lang['L_TOOLS'] = 'Ferramentas';
+$lang['L_TOOLS_TOOLBOX'] = 'Selecionar banco de dados / Funções de banco de dados / Importar - Exportar ';
+$lang['L_SQL_OPENFILE'] = 'Abrir arquivo SQL';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Upload';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Tamanho máximo de arquivo';
+$lang['L_SQL_SEARCH'] = 'Pesquisar';
+$lang['L_SQL_SEARCHWORDS'] = 'Pesquisar palavra(s)';
+$lang['L_START_SQL_SEARCH'] = 'iniciar pesquisa';
+$lang['L_RESET_SEARCHWORDS'] = 'reiniciar pesquisa de palavras';
+$lang['L_SEARCH_OPTIONS'] = 'Opções de pesquisa';
+$lang['L_SEARCH_RESULTS'] = 'A pesquisa por "<b>%s</b>" na tabela "<b>%s</b>" levou aos seguintes resultados';
+$lang['L_SEARCH_NO_RESULTS'] = 'A pesquisa por "<b>%s</b>" na tabela "<b>%s</b>" não trouxe nenhum resultado!';
+$lang['L_NO_ENTRIES'] = 'A tabela "<b>%s</b>" está vazia e não contêm nenhuma entrada.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Navegação: para frente=ALT+V, para trás=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'a coluna deve conter uma das palavras a pesquisar (OU-pesquisar)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'a linha deve conter todas as palavras a pesquisar, mas elas podem estar em qualquer coluna (pode levar algum tempo)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'a coluna deve conter todas as palavras a pesquisar (E-pesquisar)';
+$lang['L_SEARCH_IN_TABLE'] = 'Pesquisar na tabela';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Edit table structure';
+$lang['L_DEFAULT_CHARSET'] = 'Default character set';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primary key';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Unique key';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Fulltext key';
+$lang['L_TITLE_NOKEY'] = 'No key';
+$lang['L_TITLE_SEARCH'] = 'Search';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQl Documentation';
+$lang['L_TITLE_UPLOAD'] = 'Upload SQL file';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'tamanho';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/sw/help.html b/msd/language/sw/help.html
new file mode 100644
index 00000000..4fbd2929
--- /dev/null
+++ b/msd/language/sw/help.html
@@ -0,0 +1,146 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/sw/help.php b/msd/language/sw/help.php
deleted file mode 100644
index df501cd1..00000000
--- a/msd/language/sw/help.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Om detta projekt</h3>
-Daniel Schlichtholz hade iden för detta projekt.<p>2004 startade han forumet <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> och väldigt snabbt infann sig ett antal hobby-programmerare som skrev nya skripter och anpassade de skripter som Daniel hade skrivit.<br>På kortaste tid uppstod ett omfångsrikt projekt.<p>Välkommen att yttra dina förbättringsförslag i MySQLDumper-forumet <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>Vi önskar mycket nytta och nöje med detta projekt.<br><p><h4>MySQLDumper-teamet</h4>
-
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
-
-<h3>MySQLDumper hjälp</h3>
-
-<h4>Download</h4>
-Detta skript kan laddas hem från MySQLDumper-projektets hemsida.<br>
-Vi rekommenderar att du besöker sajten regelbundet för hjälp och uppdateringar.<br>
-Adressen lyder: <a href="http://www.mysqldumper.de" target="_blank">
-http://www.mysqldumper.de</a>
-
-<h4>Systemförutsättningar</h4>
-Skriptet fungerar på alla servrar (Windows, Linux, ...) <br>
-med PHP >= version 4.3.4 med stöd för GZip, MySQL (från version 3.23), JavaScript (måste aktiveras).
-
-<a href="install.php?language=de" target="_top"><h4>Installation</h4></a>
-Installationen är mycket enkel.
-Packa upp arkivet till en valfri mapp.<br>
-Ladda upp alla filerna till din webbserver (t.ex. till serverns högsta nivå [server mapp/]MySQLDumper)<br>
-... färdigt!<br>
-Du kan nu starta MySQLDumper i webbläsaren med "http://mein-webserver/MySQLDumper"<br>
-för att avsluta installationen. Följ helt enkelt instruktionerna.<br>
-<br><b>Hänvisning:</b><br><i>Om servern är inställd på PHP-Safemode så får skriptet ej skapa mappar på servern.<br>
-Detta måste du då göra manuellt eftersom MySqlDump sparar data i mappar.<br> 
-Skriptet stoppas och motsvarande anvisning visas!<br>
-Efter det att du har skapat mapparna (se anvisningen) kan du fortsätta helt normalt och utan inskränkningar.</i>
-
-<a name="perl"></a><h4>Instruktion till perlskriptet</h4>
-De flesta har en cgi-bin mapp i vilken CGI-skript kan utföras.<br>
-Denna mapp kan nås med webbläsaren via http://www.domain.se/cgi-bin/ . <br>
-<br>
-Om detta är fallet så bör följande steg genomföras:<br><br>
-
-1. Starta sidan Backup i MySQLDumper and click "Backup Perl". <br>
-2. Kopiera sökvägen som visas efter crondump.pl för $absolute_path_of_configdir: . <br>
-3. Öppna filen "crondump.pl" i Anteckningar.<br>
-4. Kopiera in skriptsökvägen vid absolute_path_of_configdir (utan mellanslag).<br>
-5. Spara crondump.pl .<br>
-6. Kopiera över crondump.pl samt perltest.pl och simpletest.pl till cgi-bin-mappen (använd ASCII-läge i FTP-programmet).<br>
-7. Ställ in rättigheten 755 (CHMOD). <br>
-7b. Om filändelsen cgi önskas ändrar du ändelsen pl -> cgi hos alla tre filerna. <br>
-8. Starta konfigureringen i MySQLDumper.<br>
-9. Välj sidan Cronscript. <br>
-10. Ändra Perl-skriptsökvägen till /cgi-bin/ .<br>
-10b. Om skripterna har ändelsen .pl ändrar du dem till .cgi .<br>
-11. Spara konfigureringen. <br><br>
-
-Färdigt! Skripterna kan nu startas från sidan Backupertig.<br><br>
-
-Om du kan utföra Perl-skript i alla mappar så räcker följande ändringar:<br><br>
-
-1. Starta sidan Backup i MySQLDumper. <br>
-2. Kopiera sökvägen som visas efter crondump.pl för $absolute_path_of_configdir: . <br>
-3. Öppna filen "crondump.pl" i Anteckningar. <br>
-4. Kopiera in skriptsökvägen vid absolute_path_of_configdir (utan mellanslag). <br>
-5. Spara crondump.pl .<br>
-6. Ställ in rättigheten 755 (CHMOD). <br>
-6b. Om filändelsen cgi önskas ändrar du ändelsen pl -> cgi hos alla tre filerna. <br>
-(ev. stegen 10b + 11 längre upp)<br>
-<br>
-
-Windows-användare måste ändra den första raden i alla skripter, där står sökvägen för Perl. Exempel: <br>
-hitta: #!/usr/bin/perl -w <br>
-ändra till: #!C:\perl\bin\perl.exe -w <br>
-
-<h4>Användning</h4><ul>
-
-<h6>Meny</h6>
-I ovan nämnda lista ställer du in databasen.<br>
-Alla aktioner är beroende av inställningarna som görs här.
-
-<h6>Startsidan</h6>
-Här visas diverse information om ditt system, de olika installerade versionerna och detaljer om de konfigurerade datbaserna.<br>
-Om du klickar på databasens namn så visas lista över tabellerna med antalet poster, storleken och datumet för senaste aktualisering.
-
-<h6>Konfigurering</h6>
-Här kan du redigera, spara eller återställa din konfigurering.
-<ul><br>
-	<li><a name="conf1"></a><strong>Konfigurerade databaser:</strong> en lista över konfigurerade databaser. Den aktiva databasen visas med <b>fet</b> text. </li>
-	<li><a name="conf2"></a><strong>Tabell-prefix:</strong> här kan du ange ett prefix (för varje databas). Detta är ett filter som filtrar ut tabeller som börjar med detta prefix (t.ex. alla tabeller som börjar med "phpBB_") när en dump görs. Lämna fältet tomt om alla tabeller skall sparas.</li>
-	<li><a name="conf3"></a><strong>GZip-komprimering:</strong> här kan du aktivera komprimeringen. Vi rekommenderar att komprimering aktiveras eftersom filerna blir mycket mindre och platsen på hårddisken är dyr.</li>
-	<li><a name="conf5"></a><strong>Email med dump-filen:</strong> om denna option aktiveras så sänds den färdiga dumpen som email-attachment (VARNING: aktivera ovillkorligen kompression, annars kan attachmentet blir för stort och kan eventuellt ej skickas!).</li>
-	<li><a name="conf6"></a><strong>Email-adress:</strong> mottagaradressen för dessa email.</li>
-	<li><a name="conf7"></a><strong>Emailets avsändare:</strong> denna adress används som avsändaradress.</li>
-	<li><a name="conf13"></a><strong>FTP-överföring:</strong> om denna option aktiveras så överförs den färdiga dumpen via FTP.</li>
-	<li><a name="conf14"></a><strong>FTP-server:</strong> FTP-serverns adress (t.ex. ftp.mindomain.se).</li>
-	<li><a name="conf15"></a><strong>FTP-serverns port:</strong> FTP-serverns port (normalt sett 21).</li>
-	<li><a name="conf16"></a><strong>FTP-användare:</strong> användarnamnet för FTP-kontot.</li>
-	<li><a name="conf17"></a><strong>FTP-lösenord:</strong> lösenordet för FTP-kontot.</li>
-	<li><a name="conf18"></a><strong>FTP upload-mapp:</strong> mappen i vilken backup-filen skall sparas (servern måste tillåtas skriva till denna mapp!).</li>
-	<li><a name="conf8"></a><strong>Automatisk radering av backup:</strong> om denna option aktiveras så raderas äldre backup-filer automatiskt enligt följande regler.</li>
-	<li><a name="conf10"></a><strong>Antal backup-filer:</strong> ett värde > 0 raderar alla filer utöver antalet i detta värde.</li>
-	<li><a name="conf11"></a><strong>Spåk:</strong> här ställer du in språket för gränssnittet.</li>
-</ul>
-
-<h6>Förvaltning</h6>
-Här utförs de egentliga aktionerna.<br>
-Alla filerna i backup-mappen visas.
-Du måste välja/markera en fil för att kunna utföra aktionerna "Återställ" och "Radera".
-<UL>
-	<li><strong>Återställ:</strong> med denna funktion aktualiseras databasen med vald backup-fil.</li>
-	<li><strong>Radera:</strong> med denna funktion kan du radera vald backup-fil.</li>
-	<li><strong>Starta ny backup:</strong> med denna funktion startar du en ny backup (dump) i enlighet med de parametrar som ställts in i konfigureringen.</li>
-</UL>
-
-<h6>Logg</h6>
-Här kan du se och radera posterna i loggen.
-<h6>Credits / Hjälp</h6>
-denna sida.
-</ul>
\ No newline at end of file
diff --git a/msd/language/sw/lang.php b/msd/language/sw/lang.php
index 21c472ea..72d28ca4 100644
--- a/msd/language/sw/lang.php
+++ b/msd/language/sw/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="ja";
-$lang['L_TO']="till";
-$lang['L_ACTIVATED']="aktiverat";
-$lang['L_NOT_ACTIVATED']="ej aktiverat";
-$lang['L_ERROR']="Fel";
-$lang['L_OF']=" av ";
-$lang['L_ADDED']="adderat";
-$lang['L_DB']="Databas";
-$lang['L_DBS']="Databaser";
-$lang['L_TABLES']="Tabeller";
-$lang['L_TABLE']="Tabell";
-$lang['L_RECORDS']="Dataposter";
-$lang['L_COMPRESSED']="komprimerat (gz)";
-$lang['L_NOTCOMPRESSED']="normalt (okomprimerat)";
-$lang['L_GENERAL']="allmänt";
-$lang['L_COMMENT']="Kommentar";
-$lang['L_FILESIZE']="Filstorlek";
-$lang['L_ALL']="alla";
-$lang['L_NONE']="inga";
-$lang['L_WITH']=" med ";
-$lang['L_DIR']="Mapp";
-$lang['L_RECHTE']="Rättigheter";
-$lang['L_STATUS']="Status";
-$lang['L_FINISHED']="färdig";
-$lang['L_FILE']="Fil";
-$lang['L_FIELDS']="Fält";
-$lang['L_NEW']="ny";
-$lang['L_CHARSET']="Teckensats";
-$lang['L_COLLATION']="Sortering";
-$lang['L_CHANGE']="redigera";
-$lang['L_IN']="i";
-$lang['L_DO']="utför";
-$lang['L_VIEW']="visa";
-$lang['L_EXISTING']="existerar";
-$lang['L_BACK']="tillbaka";
-$lang['L_DB_HOST']="Databas-hostnamn";
-$lang['L_DB_USER']="Databas-användare";
-$lang['L_DB_PASS']="Databas-lösenord";
-$lang['L_INFO_SCRIPTDIR']="Mapp för MySQLDumper";
-$lang['L_INFO_ACTDB']="Aktuell databas";
-$lang['L_WRONGCONNECTIONPARS']="Fel eller inga förbindelse-parametrar!";
-$lang['L_CONN_NOT_POSSIBLE']="Förbindelse kunde ej upprättas!";
-$lang['L_SERVERCAPTION']="Visning av server";
-$lang['L_HELP_SERVERCAPTION']="Om olika system används kan det vara till hjälp om server-adressen kännetecknas med olika färger";
-$lang['L_ACTIVATE_MULTIDUMP']="aktivera MultiDump";
-$lang['L_SAVE']="Spara";
-$lang['L_RESET']="Återställa";
-$lang['L_PRAEFIX']="Tabell-prefix";
-$lang['L_AUTODELETE']="Automatisk radering av backup-filer";
-$lang['L_MAX_BACKUP_FILES_EACH2']="för varje databas";
-$lang['L_SAVING_DB_FORM']="Databas";
-$lang['L_TESTCONNECTION']="Testa förbindelsen";
-$lang['L_BACK_TO_MINISQL']="Redigera databas";
-$lang['L_CREATE']="skapa";
-$lang['L_VARIABELN']="Variabler";
-$lang['L_STATUSINFORMATIONEN']="Statusinformationer";
-$lang['L_VERSIONSINFORMATIONEN']="Versionsinformationer";
-$lang['L_MSD_INFO']="MyOOS [Dumper] informationer";
-$lang['L_BACKUPFILESANZAHL']="I backup-mappen finns";
-$lang['L_LASTBACKUP']="Senaste backup";
-$lang['L_NOTAVAIL']="<em>existerar ej</em>";
-$lang['L_VOM']="den";
-$lang['L_MYSQLVARS']="MySQL-variabler";
-$lang['L_MYSQLSYS']="MySQL-kommandon";
-$lang['L_STATUS']="Status";
-$lang['L_PROZESSE']="Processer";
-$lang['L_INFO_NOVARS']="inga variabler";
-$lang['L_INHALT']="Innehåll";
-$lang['L_INFO_NOSTATUS']="ingen status";
-$lang['L_INFO_NOPROCESSES']="inga aktuella processer";
-$lang['L_FM_FREESPACE']="Ledigt utrymme på servern";
-$lang['L_LOAD_DATABASE']="Ladda om databaserna";
-$lang['L_HOME']="Hem";
-$lang['L_CONFIG']="Konfigurering";
-$lang['L_DUMP']="Backup";
-$lang['L_RESTORE']="Återställning";
-$lang['L_FILE_MANAGE']="Administrering";
-$lang['L_LOG']="Logg";
-$lang['L_CHOOSE_DB']="Välj databas";
-$lang['L_CREDITS']="Credits / Hjälp";
-$lang['L_MULTI_PART']="Backup uppdelad i flera filer";
-$lang['L_LOGFILENOTWRITABLE']="Loggfil kan ej skrivas!";
-$lang['L_SQL_ERROR1']="Fel i förfrågningen:";
-$lang['L_SQL_ERROR2']="MySQL svarar:";
-$lang['L_UNKNOWN']="okänd";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="okänt";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Logga hela utmatningen";
-$lang['L_NO']="nej";
-$lang['L_CREATE_DATABASE']="skapa ny databas";
-$lang['L_EXPORTFINISHED']="Exporten avslutad.";
-$lang['L_SQL_BROWSER']="SQL-läsare";
-$lang['L_SERVER']="Server";
-$lang['L_MYSQL_CONNECTION_ENCODING']="MySQL-serverns standardkodering";
-$lang['L_TITLE_SHOW_DATA']="Visa data";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Vill du verkligen radera primärnyckeln?";
-$lang['L_SETPRIMARYKEYSFOR']="Sätt nya primärnycklar för tabellen";
-$lang['L_PRIMARYKEY_FIELD']="Nyckelfält";
-$lang['L_PRIMARYKEYS_SAVE']="Spara primärnycklar";
-$lang['L_CANCEL']="Avbryt";
-$lang['L_VISIT_HOMEPAGE']="Besök hemsidan";
-$lang['L_SECONDS']="sekunder";
-$lang['L_BACKUPS']="backup(er)";
-$lang['L_MINUTES']="minuter";
-$lang['L_PAGE_REFRESHS']="sidvisningar";
-$lang['L_MINUTE']="minut";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'ja';
+$lang['L_TO'] = 'till';
+$lang['L_ACTIVATED'] = 'aktiverat';
+$lang['L_NOT_ACTIVATED'] = 'ej aktiverat';
+$lang['L_ERROR'] = 'Fel';
+$lang['L_OF'] = ' av ';
+$lang['L_ADDED'] = 'adderat';
+$lang['L_DB'] = 'Databas';
+$lang['L_DBS'] = 'Databaser';
+$lang['L_TABLES'] = 'Tabeller';
+$lang['L_TABLE'] = 'Tabell';
+$lang['L_RECORDS'] = 'Dataposter';
+$lang['L_COMPRESSED'] = 'komprimerat (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normalt (okomprimerat)';
+$lang['L_COMMENT'] = 'Kommentar';
+$lang['L_FILESIZE'] = 'Filstorlek';
+$lang['L_ALL'] = 'alla';
+$lang['L_NONE'] = 'inga';
+$lang['L_WITH'] = ' med ';
+$lang['L_DIR'] = 'Mapp';
+$lang['L_RECHTE'] = 'Rättigheter';
+$lang['L_STATUS'] = 'Status';
+$lang['L_FINISHED'] = 'färdig';
+$lang['L_FILE'] = 'Fil';
+$lang['L_FIELDS'] = 'Fält';
+$lang['L_NEW'] = 'ny';
+$lang['L_CHARSET'] = 'Teckensats';
+$lang['L_COLLATION'] = 'Sortering';
+$lang['L_CHANGE'] = 'redigera';
+$lang['L_IN'] = 'i';
+$lang['L_DO'] = 'utför';
+$lang['L_VIEW'] = 'visa';
+$lang['L_EXISTING'] = 'existerar';
+$lang['L_BACK'] = 'tillbaka';
+$lang['L_DB_HOST'] = 'Databas-hostnamn';
+$lang['L_DB_USER'] = 'Databas-användare';
+$lang['L_DB_PASS'] = 'Databas-lösenord';
+$lang['L_INFO_SCRIPTDIR'] = 'Mapp för MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Aktuell databas';
+$lang['L_WRONGCONNECTIONPARS'] = 'Fel eller inga förbindelse-parametrar!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Förbindelse kunde ej upprättas!';
+$lang['L_SERVERCAPTION'] = 'Visning av server';
+$lang['L_HELP_SERVERCAPTION'] = 'Om olika system används kan det vara till hjälp om server-adressen kännetecknas med olika färger';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'aktivera MultiDump';
+$lang['L_SAVE'] = 'Spara';
+$lang['L_RESET'] = 'Återställa';
+$lang['L_PRAEFIX'] = 'Tabell-prefix';
+$lang['L_AUTODELETE'] = 'Automatisk radering av backup-filer';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'för varje databas';
+$lang['L_SAVING_DB_FORM'] = 'Databas';
+$lang['L_TESTCONNECTION'] = 'Testa förbindelsen';
+$lang['L_BACK_TO_MINISQL'] = 'Redigera databas';
+$lang['L_CREATE'] = 'skapa';
+$lang['L_VARIABELN'] = 'Variabler';
+$lang['L_STATUSINFORMATIONEN'] = 'Statusinformationer';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Versionsinformationer';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] informationer';
+$lang['L_BACKUPFILESANZAHL'] = 'I backup-mappen finns';
+$lang['L_LASTBACKUP'] = 'Senaste backup';
+$lang['L_NOTAVAIL'] = '<em>existerar ej</em>';
+$lang['L_VOM'] = 'den';
+$lang['L_MYSQLVARS'] = 'MySQL-variabler';
+$lang['L_MYSQLSYS'] = 'MySQL-kommandon';
+$lang['L_STATUS'] = 'Status';
+$lang['L_PROZESSE'] = 'Processer';
+$lang['L_INFO_NOVARS'] = 'inga variabler';
+$lang['L_INHALT'] = 'Innehåll';
+$lang['L_INFO_NOSTATUS'] = 'ingen status';
+$lang['L_INFO_NOPROCESSES'] = 'inga aktuella processer';
+$lang['L_FM_FREESPACE'] = 'Ledigt utrymme på servern';
+$lang['L_LOAD_DATABASE'] = 'Ladda om databaserna';
+$lang['L_HOME'] = 'Hem';
+$lang['L_CONFIG'] = 'Konfigurering';
+$lang['L_DUMP'] = 'Backup';
+$lang['L_RESTORE'] = 'Återställning';
+$lang['L_FILE_MANAGE'] = 'Administrering';
+$lang['L_LOG'] = 'Logg';
+$lang['L_CHOOSE_DB'] = 'Välj databas';
+$lang['L_CREDITS'] = 'Credits / Hjälp';
+$lang['L_MULTI_PART'] = 'Backup uppdelad i flera filer';
+$lang['L_LOGFILENOTWRITABLE'] = 'Loggfil kan ej skrivas!';
+$lang['L_SQL_ERROR1'] = 'Fel i förfrågningen:';
+$lang['L_SQL_ERROR2'] = 'MySQL svarar:';
+$lang['L_UNKNOWN'] = 'okänd';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'okänt';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Logga hela utmatningen';
+$lang['L_NO'] = 'nej';
+$lang['L_CREATE_DATABASE'] = 'skapa ny databas';
+$lang['L_EXPORTFINISHED'] = 'Exporten avslutad.';
+$lang['L_SQL_BROWSER'] = 'SQL-läsare';
+$lang['L_SERVER'] = 'Server';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'MySQL-serverns standardkodering';
+$lang['L_TITLE_SHOW_DATA'] = 'Visa data';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Vill du verkligen radera primärnyckeln?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Sätt nya primärnycklar för tabellen';
+$lang['L_PRIMARYKEY_FIELD'] = 'Nyckelfält';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Spara primärnycklar';
+$lang['L_CANCEL'] = 'Avbryt';
+$lang['L_VISIT_HOMEPAGE'] = 'Besök hemsidan';
+$lang['L_SECONDS'] = 'sekunder';
+$lang['L_BACKUPS'] = 'backup(er)';
+$lang['L_MINUTES'] = 'minuter';
+$lang['L_PAGE_REFRESHS'] = 'sidvisningar';
+$lang['L_MINUTE'] = 'minut';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/sw/lang_config_overview.php b/msd/language/sw/lang_config_overview.php
index 732cdc3b..92709d2a 100644
--- a/msd/language/sw/lang_config_overview.php
+++ b/msd/language/sw/lang_config_overview.php
@@ -1,109 +1,126 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Konfigurering";
-$lang['L_SAVE_SUCCESS']="Inställningarna har sparats i konfigureringsfilen \"%s\".";
-$lang['L_CONFIG_LOADED']="Konfigureringen \"%s\" har laddats.";
-$lang['L_SAVE_ERROR']="Inställningarna kunde ej sparas!";
-$lang['L_CONFIG_EMAIL']="Epostmeddelande";
-$lang['L_CONFIG_AUTODELETE']="Automatisk radering";
-$lang['L_CONFIG_INTERFACE']="Gränssnitt";
-$lang['L_MULTI_PART_GROESSE']="Maximal filstorlek";
-$lang['L_HELP_MULTIPART']="Med aktiverad multipart skapas flera backupfiler. Dessa filers storlek riktar sig efter inställningen nedan.";
-$lang['L_HELP_MULTIPARTGROESSE']="Backupfilernas storlek om multipart är aktiverat";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Radera databasen före återställningen";
-$lang['L_ALLPARS']="alla parametrar";
-$lang['L_CRON_EXTENDER']="Skriptets filändelse";
-$lang['L_CRON_SAVEPATH']="Konfigureringsfil";
-$lang['L_CRON_PRINTOUT']="Textutmatning";
-$lang['L_CONFIG_CRONPERL']="Crondump-inställningar för Perl-skriptet";
-$lang['L_CRON_MAILPRG']="Epostprogram";
-$lang['L_OPTIMIZE']="Optimera tabellerna före backup";
-$lang['L_HELP_OPTIMIZE']="Aktivera denna option om alla tabeller skall optimeras före varje backup.";
-$lang['L_HELP_FTPTIMEOUT']="Den tid som leder till timeout om ingen överföring sker, standard 90 sekunder.";
-$lang['L_FTP_TIMEOUT']="Förbindelse-timeout";
-$lang['L_HELP_FTPSSL']="Anger om en säker SSL-förbindelse ska användas vid överföringen.";
-$lang['L_CONFIG_ASKLOAD']="Skall inställningarna verkligen skrivas över med grundinställningarna?";
-$lang['L_LOAD']="Grundinställningar";
-$lang['L_LOAD_SUCCESS']="Startinställningarna har laddats.";
-$lang['L_CRON_CRONDBINDEX']="Databas";
-$lang['L_WITHATTACH']="med bilaga";
-$lang['L_WITHOUTATTACH']="utan bilaga";
-$lang['L_MULTIDUMPCONF']="=Multidump inställningar=";
-$lang['L_MULTIDUMPALL']="=alla databaser=";
-$lang['L_GZIP']="GZIP-komprimering";
-$lang['L_SEND_MAIL_FORM']="Skicka epost";
-$lang['L_SEND_MAIL_DUMP']="Bifoga backup";
-$lang['L_EMAIL_ADRESS']="Epostadress";
-$lang['L_EMAIL_SENDER']="Meddelandets avsändare";
-$lang['L_EMAIL_MAXSIZE']="Bilagans maximala storlek";
-$lang['L_NUMBER_OF_FILES_FORM']="Antal backup-filer per databas";
-$lang['L_LANGUAGE']="Språk";
-$lang['L_LIST_DB']="Konfigurerade databaser:";
-$lang['L_CONFIG_FTP']="FTP-överföring av backup-filen";
-$lang['L_FTP_TRANSFER']="FTP-överföring";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="Användare";
-$lang['L_FTP_PASS']="Lösenord";
-$lang['L_FTP_DIR']="Uppladdningsmapp";
-$lang['L_FTP_SSL']="Säker SSL-FTP-förbindelse";
-$lang['L_FTP_USESSL']="använd SSL-förbindelse";
-$lang['L_SQLBOXHEIGHT']="SQL-fältets höjd";
-$lang['L_SQLLIMIT']="Antal datasatser per sida";
-$lang['L_BBPARAMS']="Inställningar för BBcode";
-$lang['L_BBTEXTCOLOR']="Textfärg";
-$lang['L_HELP_COMMANDS']="Före och efter en backup kan ett kommando utföras automatiskt. Det kan vara ett SQL-kommando eller ett system-kommando (t.ex. ett skript).";
-$lang['L_COMMAND']="Kommando";
-$lang['L_WRONG_CONNECTIONPARS']="Fel förbindelseparametrar!";
-$lang['L_CONNECTIONPARS']="Förbindelse-parametrar";
-$lang['L_EXTENDEDPARS']="Ytterligare parametrar";
-$lang['L_FADE_IN_OUT']="visa/dölj";
-$lang['L_DB_BACKUPPARS']="Backup-inställningar för databas";
-$lang['L_GENERAL']="Allmänt";
-$lang['L_MAXSIZE']="max. storlek";
-$lang['L_ERRORHANDLING_RESTORE']="Felhantering under återställning";
-$lang['L_EHRESTORE_CONTINUE']="fortsätt och protokollera fel";
-$lang['L_EHRESTORE_STOP']="stoppa";
-$lang['L_IN_MAINFRAME']="i huvudframen";
-$lang['L_IN_LEFTFRAME']="i vänster frame";
-$lang['L_WIDTH']="Bredd";
-$lang['L_SQL_BEFEHLE']="SQL-kommandon";
-$lang['L_DOWNLOAD_LANGUAGES']="ladda hem andra språk";
-$lang['L_DOWNLOAD_STYLES']="ladda hem andra teman";
-$lang['L_CONNECT_TO']="Förbinder med";
-$lang['L_CHANGEDIR']="Hoppa till mapp";
-$lang['L_CHANGEDIRERROR']="Kunde ej hoppa till mapp!";
-$lang['L_FTP_OK']="Förbindelsen kunde skapas.";
-$lang['L_INSTALL']="Installation";
-$lang['L_NOFTPPOSSIBLE']="Du har inga FTP-funktioner!";
-$lang['L_FOUND_DB']="hittad databas:";
-$lang['L_FTP_CHOOSE_MODE']="FTP-överföringsläge";
-$lang['L_FTP_PASSIVE']="använd passivt läge";
-$lang['L_HELP_FTP_MODE']="Anger FTP-överföringsläget. Om problem uppträder i aktivt läge bör du istället ställa in passivt läge.";
-$lang['L_DB_IN_LIST']="Databasen '%s' kunde ej läggas till eftersom den redan existerar.";
-$lang['L_ADD_DB_MANUALLY']="Lägg till databas manuellt";
-$lang['L_DB_MANUAL_ERROR']="Kunde tyvärr ej ansluta till databasen '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Filfel: kunde ej lägga till databasen '%s'!";
-$lang['L_NO_DB_FOUND']="Inga databaser hittades. Gå till förbindelseparametrarna och ange databasens namn.";
-$lang['L_CONFIGFILES']="Konfigureringsfiler";
-$lang['L_CONFIGFILE']="Konfigureringsfil";
-$lang['L_MYSQL_DATA']="MySQL-data";
-$lang['L_CONFIGURATIONS']="Inställningar";
-$lang['L_ACTION']="Aktion";
-$lang['L_FTP_SEND_TO']="till <strong>%s</strong><br>i <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-mottagare";
-$lang['L_NAME']="Namn";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Ska konfigureringsfilen %s verkligen raderas?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Fel: konfigureringsfilen %s kunde ej raderas!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Konfigureringsfilen %s har raderats.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="Konfigureringsfilen %s har skapats.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Filnamnet \"%s\" innehåller ogiltiga tecken.";
-$lang['L_CREATE_CONFIGFILE']="Skapa en ny konfigureringsfil";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Konfigureringsfilen \"%s\" kunde ej laddas.";
-$lang['L_BACKUP_DBS_PHP']="backup av databaser (PHP)";
-$lang['L_BACKUP_DBS_PERL']="backup av databaser (PERL)";
-$lang['L_CRON_COMMENT']="Mata in kommentar";
-$lang['L_AUTODETECT']="identifiera automatiskt";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Konfigurering';
+$lang['L_SAVE_SUCCESS'] = 'Inställningarna har sparats i konfigureringsfilen "%s".';
+$lang['L_CONFIG_LOADED'] = 'Konfigureringen "%s" har laddats.';
+$lang['L_SAVE_ERROR'] = 'Inställningarna kunde ej sparas!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Epostmeddelande';
+$lang['L_CONFIG_AUTODELETE'] = 'Automatisk radering';
+$lang['L_CONFIG_INTERFACE'] = 'Gränssnitt';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'Maximal filstorlek';
+$lang['L_HELP_MULTIPART'] = 'Med aktiverad multipart skapas flera backupfiler. Dessa filers storlek riktar sig efter inställningen nedan.';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Backupfilernas storlek om multipart är aktiverat';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Radera databasen före återställningen';
+$lang['L_ALLPARS'] = 'alla parametrar';
+$lang['L_CRON_EXTENDER'] = 'Skriptets filändelse';
+$lang['L_CRON_SAVEPATH'] = 'Konfigureringsfil';
+$lang['L_CRON_PRINTOUT'] = 'Textutmatning';
+$lang['L_CONFIG_CRONPERL'] = 'Crondump-inställningar för Perl-skriptet';
+$lang['L_CRON_MAILPRG'] = 'Epostprogram';
+$lang['L_OPTIMIZE'] = 'Optimera tabellerna före backup';
+$lang['L_HELP_OPTIMIZE'] = 'Aktivera denna option om alla tabeller skall optimeras före varje backup.';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'Den tid som leder till timeout om ingen överföring sker, standard 90 sekunder.';
+$lang['L_FTP_TIMEOUT'] = 'Förbindelse-timeout';
+$lang['L_HELP_FTPSSL'] = 'Anger om en säker SSL-förbindelse ska användas vid överföringen.';
+$lang['L_SFTP_TIMEOUT'] = 'Förbindelse-timeout';
+$lang['L_HELP_SFTPSSL'] = 'Anger om en säker SSL-förbindelse ska användas vid överföringen.';
+$lang['L_CONFIG_ASKLOAD'] = 'Skall inställningarna verkligen skrivas över med grundinställningarna?';
+$lang['L_LOAD'] = 'Grundinställningar';
+$lang['L_LOAD_SUCCESS'] = 'Startinställningarna har laddats.';
+$lang['L_CRON_CRONDBINDEX'] = 'Databas';
+$lang['L_WITHATTACH'] = 'med bilaga';
+$lang['L_WITHOUTATTACH'] = 'utan bilaga';
+$lang['L_MULTIDUMPCONF'] = '=Multidump inställningar=';
+$lang['L_MULTIDUMPALL'] = '=alla databaser=';
+$lang['L_GZIP'] = 'GZIP-komprimering';
+$lang['L_SEND_MAIL_FORM'] = 'Skicka epost';
+$lang['L_SEND_MAIL_DUMP'] = 'Bifoga backup';
+$lang['L_EMAIL_ADRESS'] = 'Epostadress';
+$lang['L_EMAIL_SENDER'] = 'Meddelandets avsändare';
+$lang['L_EMAIL_MAXSIZE'] = 'Bilagans maximala storlek';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Antal backup-filer per databas';
+$lang['L_LANGUAGE'] = 'Språk';
+$lang['L_LIST_DB'] = 'Konfigurerade databaser:';
+$lang['L_CONFIG_FTP'] = 'FTP-överföring av backup-filen';
+$lang['L_FTP_TRANSFER'] = 'FTP-överföring';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'Användare';
+$lang['L_FTP_PASS'] = 'Lösenord';
+$lang['L_FTP_DIR'] = 'Uppladdningsmapp';
+$lang['L_FTP_SSL'] = 'Säker SSL-FTP-förbindelse';
+$lang['L_FTP_USESSL'] = 'använd SSL-förbindelse';
+$lang['L_CONFIG_SFTP'] = 'SFTP-överföring av backup-filen';
+$lang['L_SFTP_TRANSFER'] = 'SFTP-överföring';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'Användare';
+$lang['L_SFTP_PASS'] = 'Lösenord';
+$lang['L_SFTP_DIR'] = 'Uppladdningsmapp';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'SQL-fältets höjd';
+$lang['L_SQLLIMIT'] = 'Antal datasatser per sida';
+$lang['L_BBPARAMS'] = 'Inställningar för BBcode';
+$lang['L_BBTEXTCOLOR'] = 'Textfärg';
+$lang['L_HELP_COMMANDS'] = 'Före och efter en backup kan ett kommando utföras automatiskt. Det kan vara ett SQL-kommando eller ett system-kommando (t.ex. ett skript).';
+$lang['L_COMMAND'] = 'Kommando';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Fel förbindelseparametrar!';
+$lang['L_CONNECTIONPARS'] = 'Förbindelse-parametrar';
+$lang['L_EXTENDEDPARS'] = 'Ytterligare parametrar';
+$lang['L_FADE_IN_OUT'] = 'visa/dölj';
+$lang['L_DB_BACKUPPARS'] = 'Backup-inställningar för databas';
+$lang['L_GENERAL'] = 'Allmänt';
+$lang['L_MAXSIZE'] = 'max. storlek';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Felhantering under återställning';
+$lang['L_EHRESTORE_CONTINUE'] = 'fortsätt och protokollera fel';
+$lang['L_EHRESTORE_STOP'] = 'stoppa';
+$lang['L_IN_MAINFRAME'] = 'i huvudframen';
+$lang['L_IN_LEFTFRAME'] = 'i vänster frame';
+$lang['L_WIDTH'] = 'Bredd';
+$lang['L_SQL_BEFEHLE'] = 'SQL-kommandon';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'ladda hem andra språk';
+$lang['L_DOWNLOAD_STYLES'] = 'ladda hem andra teman';
+$lang['L_CONNECT_TO'] = 'Förbinder med';
+$lang['L_CHANGEDIR'] = 'Hoppa till mapp';
+$lang['L_CHANGEDIRERROR'] = 'Kunde ej hoppa till mapp!';
+$lang['L_FTP_OK'] = 'Förbindelsen kunde skapas.';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_NOFTPPOSSIBLE'] = 'Du har inga FTP-funktioner!';
+$lang['L_FOUND_DB'] = 'hittad databas:';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP-överföringsläge';
+$lang['L_FTP_PASSIVE'] = 'använd passivt läge';
+$lang['L_HELP_FTP_MODE'] = 'Anger FTP-överföringsläget. Om problem uppträder i aktivt läge bör du istället ställa in passivt läge.';
+$lang['L_SFTP_PASSIVE'] = 'använd passivt läge';
+$lang['L_DB_IN_LIST'] = "Databasen '%s' kunde ej läggas till eftersom den redan existerar.";
+$lang['L_ADD_DB_MANUALLY'] = 'Lägg till databas manuellt';
+$lang['L_DB_MANUAL_ERROR'] = "Kunde tyvärr ej ansluta till databasen '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Filfel: kunde ej lägga till databasen '%s'!";
+$lang['L_NO_DB_FOUND'] = 'Inga databaser hittades. Gå till förbindelseparametrarna och ange databasens namn.';
+$lang['L_CONFIGFILES'] = 'Konfigureringsfiler';
+$lang['L_CONFIGFILE'] = 'Konfigureringsfil';
+$lang['L_MYSQL_DATA'] = 'MySQL-data';
+$lang['L_CONFIGURATIONS'] = 'Inställningar';
+$lang['L_ACTION'] = 'Aktion';
+$lang['L_FTP_SEND_TO'] = 'till <strong>%s</strong><br>i <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'till <strong>%s</strong><br>i <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-mottagare';
+$lang['L_NAME'] = 'Namn';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Ska konfigureringsfilen %s verkligen raderas?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Fel: konfigureringsfilen %s kunde ej raderas!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Konfigureringsfilen %s har raderats.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'Konfigureringsfilen %s har skapats.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Filnamnet "%s" innehåller ogiltiga tecken.';
+$lang['L_CREATE_CONFIGFILE'] = 'Skapa en ny konfigureringsfil';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Konfigureringsfilen "%s" kunde ej laddas.';
+$lang['L_BACKUP_DBS_PHP'] = 'backup av databaser (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'backup av databaser (PERL)';
+$lang['L_CRON_COMMENT'] = 'Mata in kommentar';
+$lang['L_AUTODETECT'] = 'identifiera automatiskt';
diff --git a/msd/language/sw/lang_dump.php b/msd/language/sw/lang_dump.php
index 11fb2604..cba773bf 100644
--- a/msd/language/sw/lang_dump.php
+++ b/msd/language/sw/lang_dump.php
@@ -1,52 +1,53 @@
 <?php
-$lang['L_DUMP_HEADLINE']="skapa backup ...";
-$lang['L_GZIP_COMPRESSION']="GZIP-komprimering";
-$lang['L_SAVING_TABLE']="Sparar tabellen";
-$lang['L_OF']="av";
-$lang['L_ACTUAL_TABLE']="Aktuell tabell";
-$lang['L_PROGRESS_TABLE']="Genomfört av tabell";
-$lang['L_PROGRESS_OVER_ALL']="Genomfört totalt";
-$lang['L_ENTRY']="Post";
-$lang['L_DONE']="Färdig!";
-$lang['L_DUMP_SUCCESSFUL']=" har skapats.";
-$lang['L_UPTO']="upp till";
-$lang['L_EMAIL_WAS_SEND']="Epostmeddelandet har skickats till";
-$lang['L_BACK_TO_CONTROL']="fortsätt";
-$lang['L_BACK_TO_OVERVIEW']="Databasöversikt";
-$lang['L_DUMP_FILENAME']="Backup-fil: ";
-$lang['L_WITHPRAEFIX']="med prefix";
-$lang['L_DUMP_NOTABLES']="Inga tabeller hittades i databasen `<b>%s</b>`.";
-$lang['L_DUMP_ENDERGEBNIS']="<b>%s</b> tabeller med totalt <b>%s</b> dataposter har säkrats.<br>";
-$lang['L_MAILERROR']="Tyvärr uppträdde ett fel när epostmeddelandet skickades!";
-$lang['L_EMAILBODY_ATTACH']="Här kommer backupen av din MySQLdatabas.<br>Backup av databasen `%s`
-<br><br>Följande fil har skapats:<br><br>%s <br><br>Med vänliga hälsningar<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="En multipart-backup har skapats.<br>Backuperna levereras EJ som bilaga i mail!<br>Backup av databasen `%s`
-<br><br>Följande filer har skapats:<br><br>%s<br><br><br>Med vänliga hälsningar<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="En multipart-backup har skapats.<br>Backupen levereras i separata mail!<br>Backup av databasen `%s`
-<br><br>Följande filer har skapats:<br><br>%s<br><br><br>Med vänliga hälsningar<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Med vänliga hälsningar<br><br>MySQLDumper<br>";
-$lang['L_EMAILBODY_TOOBIG']="Backupen överskrider den maximala storleken på %s och har därför ej bifogats.<br>Backup av databasen `%s` <br><br>Följande fil har skapats:<br><br>%s <br><br>Vänliga hälsningar<br>Din MySQLDumper<br>";
-$lang['L_EMAILBODY_NOATTACH']="Backuperna levereras EJ som bilaga i mail!<br>Backup av databasen `%s` <br><br>Följande filer har skapats:<br><br>%s<br><br><br>Med vänliga hälsningar<br><br>MySQLDumper<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']="... endast bilagan";
-$lang['L_TABLESELECTION']="Välj tabeller";
-$lang['L_SELECTALL']="markera alla";
-$lang['L_DESELECTALL']="Avmarkera alla";
-$lang['L_STARTDUMP']="Starta backup";
-$lang['L_LASTBUFROM']="senaste uppdatering den";
-$lang['L_NOT_SUPPORTED']="Denna backup har inget stöd för den funktionen.";
-$lang['L_MULTIDUMP']="Multidump: <b>%d</b> databaser har säkrats.";
-$lang['L_FILESENDFTP']="skickar filen via FTP ... var god vänta.";
-$lang['L_FTPCONNERROR']="FTP-förbindelsen kunde ej upprättas! Förbindelse med ";
-$lang['L_FTPCONNERROR1']="som användare";
-$lang['L_FTPCONNERROR2']="ej möjligt";
-$lang['L_FTPCONNERROR3']="FTP-överföringen var korrupt!";
-$lang['L_FTPCONNECTED1']="Ansluten till";
-$lang['L_FTPCONNECTED2']="hos";
-$lang['L_FTPCONNECTED3']="överförd";
-$lang['L_NR_TABLES_SELECTED']="- med %s valda tabeller";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s tabeller har optimerats.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s fel har uppträtt: <a href=\"log.php?r=3\">visa</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Kritiskt fel: CREATE-kommandot i tabellen '%s' i databasen '%s' kunde ej läsas!";
 
-
-?>
\ No newline at end of file
+$lang['L_DUMP_HEADLINE'] = 'skapa backup ...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'GZIP-komprimering';
+$lang['L_SAVING_TABLE'] = 'Sparar tabellen';
+$lang['L_OF'] = 'av';
+$lang['L_ACTUAL_TABLE'] = 'Aktuell tabell';
+$lang['L_PROGRESS_TABLE'] = 'Genomfört av tabell';
+$lang['L_PROGRESS_OVER_ALL'] = 'Genomfört totalt';
+$lang['L_ENTRY'] = 'Post';
+$lang['L_DONE'] = 'Färdig!';
+$lang['L_DUMP_SUCCESSFUL'] = ' har skapats.';
+$lang['L_UPTO'] = 'upp till';
+$lang['L_EMAIL_WAS_SEND'] = 'Epostmeddelandet har skickats till';
+$lang['L_BACK_TO_CONTROL'] = 'fortsätt';
+$lang['L_BACK_TO_OVERVIEW'] = 'Databasöversikt';
+$lang['L_DUMP_FILENAME'] = 'Backup-fil: ';
+$lang['L_WITHPRAEFIX'] = 'med prefix';
+$lang['L_DUMP_NOTABLES'] = 'Inga tabeller hittades i databasen `<b>%s</b>`.';
+$lang['L_DUMP_ENDERGEBNIS'] = '<b>%s</b> tabeller med totalt <b>%s</b> dataposter har säkrats.<br>';
+$lang['L_MAILERROR'] = 'Tyvärr uppträdde ett fel när epostmeddelandet skickades!';
+$lang['L_EMAILBODY_ATTACH'] = 'Här kommer backupen av din MySQLdatabas.<br>Backup av databasen `%s`
+<br><br>Följande fil har skapats:<br><br>%s <br><br>Med vänliga hälsningar<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'En multipart-backup har skapats.<br>Backuperna levereras EJ som bilaga i mail!<br>Backup av databasen `%s`
+<br><br>Följande filer har skapats:<br><br>%s<br><br><br>Med vänliga hälsningar<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'En multipart-backup har skapats.<br>Backupen levereras i separata mail!<br>Backup av databasen `%s`
+<br><br>Följande filer har skapats:<br><br>%s<br><br><br>Med vänliga hälsningar<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Med vänliga hälsningar<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Backupen överskrider den maximala storleken på %s och har därför ej bifogats.<br>Backup av databasen `%s` <br><br>Följande fil har skapats:<br><br>%s <br><br>Vänliga hälsningar<br>Din MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Backuperna levereras EJ som bilaga i mail!<br>Backup av databasen `%s` <br><br>Följande filer har skapats:<br><br>%s<br><br><br>Med vänliga hälsningar<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = '... endast bilagan';
+$lang['L_TABLESELECTION'] = 'Välj tabeller';
+$lang['L_SELECTALL'] = 'markera alla';
+$lang['L_DESELECTALL'] = 'Avmarkera alla';
+$lang['L_STARTDUMP'] = 'Starta backup';
+$lang['L_LASTBUFROM'] = 'senaste uppdatering den';
+$lang['L_NOT_SUPPORTED'] = 'Denna backup har inget stöd för den funktionen.';
+$lang['L_MULTIDUMP'] = 'Multidump: <b>%d</b> databaser har säkrats.';
+$lang['L_FILESENDFTP'] = 'skickar filen via FTP ... var god vänta.';
+$lang['L_FTPCONNERROR'] = 'FTP-förbindelsen kunde ej upprättas! Förbindelse med ';
+$lang['L_FTPCONNERROR1'] = 'som användare';
+$lang['L_FTPCONNERROR2'] = 'ej möjligt';
+$lang['L_FTPCONNERROR3'] = 'FTP-överföringen var korrupt!';
+$lang['L_FTPCONNECTED1'] = 'Ansluten till';
+$lang['L_FTPCONNECTED2'] = 'hos';
+$lang['L_FTPCONNECTED3'] = 'överförd';
+$lang['L_FILESENDSFTP'] = 'skickar filen via SFTP ... var god vänta.';
+$lang['L_SFTPCONNERROR'] = 'SFTP-förbindelsen kunde ej upprättas! Förbindelse med ';
+$lang['L_NR_TABLES_SELECTED'] = '- med %s valda tabeller';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s tabeller har optimerats.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s fel har uppträtt: <a href="log.php?r=3">visa</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Kritiskt fel: CREATE-kommandot i tabellen '%s' i databasen '%s' kunde ej läsas!";
diff --git a/msd/language/sw/lang_filemanagement.php b/msd/language/sw/lang_filemanagement.php
index 128bce03..1a6301a1 100644
--- a/msd/language/sw/lang_filemanagement.php
+++ b/msd/language/sw/lang_filemanagement.php
@@ -1,75 +1,75 @@
 <?php
-$lang['L_CONVERT_START']="Starta konvertering";
-$lang['L_CONVERT_TITLE']="Konvertera dump till MSD-formatet";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Fel parametrar! Konverteringen kan ej genomföras.";
-$lang['L_FM_UPLOADFILEREQUEST']="Ange en fil.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Denna filtyp är ej tillåten.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Tillåtna filtyper: *.gz och *.sql";
-$lang['L_FM_UPLOADMOVEERROR']="Den uppladdade filen kunde ej flyttas till rätt mapp.";
-$lang['L_FM_UPLOADFAILED']="Uppladdningen har tyvärr misslyckats!";
-$lang['L_FM_UPLOADFILEEXISTS']="Det existerar redan en fil med samma namn!";
-$lang['L_FM_NOFILE']="Du har ej valt någon fil!";
-$lang['L_FM_DELETE1']="Filen";
-$lang['L_FM_DELETE2']="har raderats.";
-$lang['L_FM_DELETE3']="kunde ej raderas!";
-$lang['L_FM_CHOOSE_FILE']="Vald fil:";
-$lang['L_FM_FILESIZE']="Filstorlek";
-$lang['L_FM_FILEDATE']="Datum";
-$lang['L_FM_NOFILESFOUND']="Ingen fil hittades.";
-$lang['L_FM_TABLES']="Tabeller";
-$lang['L_FM_RECORDS']="Poster";
-$lang['L_FM_ALL_BU']="alla backuper";
-$lang['L_FM_ANZ_BU']="Antal backuper";
-$lang['L_FM_LAST_BU']="Senaste backup";
-$lang['L_FM_TOTALSIZE']="Total storlek";
-$lang['L_FM_SELECTTABLES']="Val av bestämda tabeller";
-$lang['L_FM_COMMENT']="Mata in en kommentar";
-$lang['L_FM_RESTORE']="Återställning";
-$lang['L_FM_ALERTRESTORE1']="Ska databasen";
-$lang['L_FM_ALERTRESTORE2']="återställas med innehållet i filen";
-$lang['L_FM_ALERTRESTORE3']="?";
-$lang['L_FM_DELETE']="Radera valda filer";
-$lang['L_FM_ASKDELETE1']="Vill du verkligen radera filen (filerna)";
-$lang['L_FM_ASKDELETE2']="?";
-$lang['L_FM_ASKDELETE3']="Vill du utföra den automatiska raderingen enligt de inställda reglerna nu?";
-$lang['L_FM_ASKDELETE4']="Vill du radera alla backupfiler nu?";
-$lang['L_FM_ASKDELETE5']="Vill du radera alla backupfiler med";
-$lang['L_FM_ASKDELETE5_2']="_* nu?";
-$lang['L_FM_DELETEAUTO']="Genomför automatisk radering manuellt";
-$lang['L_FM_DELETEALL']="Radera alla backupfiler";
-$lang['L_FM_DELETEALLFILTER']="Radera alla med ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Starta ny backup";
-$lang['L_FM_FILEUPLOAD']="Ladda upp fil";
-$lang['L_FM_DBNAME']="Databasens namn";
-$lang['L_FM_FILES1']="Databas-backuper";
-$lang['L_FM_FILES2']="Databas-strukturer";
-$lang['L_FM_AUTODEL1']="Automatisk radering: följande filer raderades på grund av maximalt antal filer:";
-$lang['L_DELETE_FILE_SUCCESS']="Filen \"%s\" har raderats.";
-$lang['L_FM_DUMPSETTINGS']="Backup-inställningar";
-$lang['L_FM_OLDBACKUP']="(okänd)";
-$lang['L_FM_RESTORE_HEADER']="Återställning av databasen \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Filen \"%s\" kunde ej raderas!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Utför Perl-cronscript";
-$lang['L_DOPERLTEST']="Testa Perl-modulerna";
-$lang['L_DOSIMPLETEST']="Testa Perl";
-$lang['L_PERLOUTPUT1']="Angivelse i crondump.pl för absolute_path_of_configd";
-$lang['L_PERLOUTPUT2']="Browseradress eller adress för extern crontab";
-$lang['L_PERLOUTPUT3']="Shelladress eller adress för crontab";
-$lang['L_RESTORE_OF_TABLES']="Återställning av bestämda tabeller";
-$lang['L_CONVERTER']="Backup-konverterare";
-$lang['L_CONVERT_FILE']="fil som skall konverteras";
-$lang['L_CONVERT_FILENAME']="Målfilens namn (utan filändelse)";
-$lang['L_CONVERTING']="Konvertering";
-$lang['L_CONVERT_FILEREAD']="Filen '%s' läses in";
-$lang['L_CONVERT_FINISHED']="Konverteringen avslutad, '%s' har skapats.";
-$lang['L_NO_MSD_BACKUPFILE']="Filer skapade med andra program";
-$lang['L_MAX_UPLOAD_SIZE']="Maximal filstorlek";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Om din backup-fil är större än det angivna värdet så måste du ladda upp den till mappen \"work/backup\" via FTP. Därefter visas filen här i översikten och kan väljas för återställning.";
-$lang['L_ENCODING']="Kodering";
-$lang['L_FM_CHOOSE_ENCODING']="Välj backupfilens kodering";
-$lang['L_CHOOSE_CHARSET']="Tyvärr kunde ej fastställas automatiskt med vilken teckensats denna backupfil har skapats.<br>Du måste ange koderingen manuellt.<br>Därefter ställer MySQLDumper in förbindelseparametrarna till MySQL-servern till den valda teckensatsen och startar återställningen.<br>Om datan återges med fel specialtecken efter återställningen så bör du upprepa återställningen med en annan inställning för teckensatsen.<br>Lycka till.";
-$lang['L_DOWNLOAD_FILE']="Ladda hem filen";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+
+$lang['L_CONVERT_START'] = 'Starta konvertering';
+$lang['L_CONVERT_TITLE'] = 'Konvertera dump till MOD-formatet';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Fel parametrar! Konverteringen kan ej genomföras.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Ange en fil.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Denna filtyp är ej tillåten.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Tillåtna filtyper: *.gz och *.sql';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Den uppladdade filen kunde ej flyttas till rätt mapp.';
+$lang['L_FM_UPLOADFAILED'] = 'Uppladdningen har tyvärr misslyckats!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Det existerar redan en fil med samma namn!';
+$lang['L_FM_NOFILE'] = 'Du har ej valt någon fil!';
+$lang['L_FM_DELETE1'] = 'Filen';
+$lang['L_FM_DELETE2'] = 'har raderats.';
+$lang['L_FM_DELETE3'] = 'kunde ej raderas!';
+$lang['L_FM_CHOOSE_FILE'] = 'Vald fil:';
+$lang['L_FM_FILESIZE'] = 'Filstorlek';
+$lang['L_FM_FILEDATE'] = 'Datum';
+$lang['L_FM_NOFILESFOUND'] = 'Ingen fil hittades.';
+$lang['L_FM_TABLES'] = 'Tabeller';
+$lang['L_FM_RECORDS'] = 'Poster';
+$lang['L_FM_ALL_BU'] = 'alla backuper';
+$lang['L_FM_ANZ_BU'] = 'Antal backuper';
+$lang['L_FM_LAST_BU'] = 'Senaste backup';
+$lang['L_FM_TOTALSIZE'] = 'Total storlek';
+$lang['L_FM_SELECTTABLES'] = 'Val av bestämda tabeller';
+$lang['L_FM_COMMENT'] = 'Mata in en kommentar';
+$lang['L_FM_RESTORE'] = 'Återställning';
+$lang['L_FM_ALERTRESTORE1'] = 'Ska databasen';
+$lang['L_FM_ALERTRESTORE2'] = 'återställas med innehållet i filen';
+$lang['L_FM_ALERTRESTORE3'] = '?';
+$lang['L_FM_DELETE'] = 'Radera valda filer';
+$lang['L_FM_ASKDELETE1'] = 'Vill du verkligen radera filen (filerna)';
+$lang['L_FM_ASKDELETE2'] = '?';
+$lang['L_FM_ASKDELETE3'] = 'Vill du utföra den automatiska raderingen enligt de inställda reglerna nu?';
+$lang['L_FM_ASKDELETE4'] = 'Vill du radera alla backupfiler nu?';
+$lang['L_FM_ASKDELETE5'] = 'Vill du radera alla backupfiler med';
+$lang['L_FM_ASKDELETE5_2'] = '_* nu?';
+$lang['L_FM_DELETEAUTO'] = 'Genomför automatisk radering manuellt';
+$lang['L_FM_DELETEALL'] = 'Radera alla backupfiler';
+$lang['L_FM_DELETEALLFILTER'] = 'Radera alla med ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Starta ny backup';
+$lang['L_FM_FILEUPLOAD'] = 'Ladda upp fil';
+$lang['L_FM_DBNAME'] = 'Databasens namn';
+$lang['L_FM_FILES1'] = 'Databas-backuper';
+$lang['L_FM_FILES2'] = 'Databas-strukturer';
+$lang['L_FM_AUTODEL1'] = 'Automatisk radering: följande filer raderades på grund av maximalt antal filer:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'Filen "%s" har raderats.';
+$lang['L_FM_DUMPSETTINGS'] = 'Backup-inställningar';
+$lang['L_FM_OLDBACKUP'] = '(okänd)';
+$lang['L_FM_RESTORE_HEADER'] = 'Återställning av databasen "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Filen "%s" kunde ej raderas!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Utför Perl-cronscript';
+$lang['L_DOPERLTEST'] = 'Testa Perl-modulerna';
+$lang['L_DOSIMPLETEST'] = 'Testa Perl';
+$lang['L_PERLOUTPUT1'] = 'Angivelse i crondump.pl för absolute_path_of_configd';
+$lang['L_PERLOUTPUT2'] = 'Browseradress eller adress för extern crontab';
+$lang['L_PERLOUTPUT3'] = 'Shelladress eller adress för crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Återställning av bestämda tabeller';
+$lang['L_CONVERTER'] = 'Backup-konverterare';
+$lang['L_CONVERT_FILE'] = 'fil som skall konverteras';
+$lang['L_CONVERT_FILENAME'] = 'Målfilens namn (utan filändelse)';
+$lang['L_CONVERTING'] = 'Konvertering';
+$lang['L_CONVERT_FILEREAD'] = "Filen '%s' läses in";
+$lang['L_CONVERT_FINISHED'] = "Konverteringen avslutad, '%s' har skapats.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Filer skapade med andra program';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximal filstorlek';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Om din backup-fil är större än det angivna värdet så måste du ladda upp den till mappen "work/backup" via FTP. Därefter visas filen här i översikten och kan väljas för återställning.';
+$lang['L_ENCODING'] = 'Kodering';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Välj backupfilens kodering';
+$lang['L_CHOOSE_CHARSET'] = 'Tyvärr kunde ej fastställas automatiskt med vilken teckensats denna backupfil har skapats.<br>Du måste ange koderingen manuellt.<br>Därefter ställer MyOOS [Dumper] in förbindelseparametrarna till MySQL-servern till den valda teckensatsen och startar återställningen.<br>Om datan återges med fel specialtecken efter återställningen så bör du upprepa återställningen med en annan inställning för teckensatsen.<br>Lycka till.';
+$lang['L_DOWNLOAD_FILE'] = 'Ladda hem filen';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/sw/lang_help.php b/msd/language/sw/lang_help.php
index f032958e..51c99437 100644
--- a/msd/language/sw/lang_help.php
+++ b/msd/language/sw/lang_help.php
@@ -1,33 +1,37 @@
 <?php
-$lang['L_HELP_DB']="Detta är listan över existerande databaser.";
-$lang['L_HELP_PRAEFIX']="Prefixet är en teckenkedja i början av tabeller som används som filter.";
-$lang['L_HELP_ZIP']="Komprimering med GZIP - rekommendering: 'aktiverat'.";
-$lang['L_HELP_MEMORYLIMIT']="Den maximala storleken i bytes som skriptet får i minnet. 0 = deaktiverat.";
-$lang['L_MEMORY_LIMIT']="Minnesgräns";
-$lang['L_HELP_AD1']="Aktivera för att automatiskt radera backupfiler.";
-$lang['L_HELP_AD3']="Det maximala antalet filer som får finnas i backupmappen (för automatisk radering), 0 = deaktiverat.";
-$lang['L_HELP_LANG']="Ställer in önskat språk.";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="För att eliminera överflödig data kan man ange att databasen ska tömmas helt före återställning.";
-$lang['L_HELP_CRONEXTENDER']="Perl-skriptets filändelse, standard är '.pl'.";
-$lang['L_HELP_CRONSAVEPATH']="Konfigureringsfilens namn för Perl-skriptet.";
-$lang['L_HELP_CRONPRINTOUT']="Om textutmatningen är deaktiverad så matas ingen text ut på bildskärmen.
-Denna funktion är oberoende av loggutmatningen.";
-$lang['L_HELP_CRONSAMEDB']="Ska samma databas som i inställningarna användas för Crontab?";
-$lang['L_HELP_CRONDBINDEX']="Välj databas för crontaben.";
-$lang['L_HELP_FTPTRANSFER']="Aktiveras för överföring av filen via FTP efter backup.";
-$lang['L_HELP_FTPSERVER']="FTP-serverns adress.";
-$lang['L_HELP_FTPPORT']="FTP-serverns port, standard: 21.";
-$lang['L_HELP_FTPUSER']="Ange FTP-förbindelsens användarnamn.";
-$lang['L_HELP_FTPPASS']="Ange FTP-förbindelsens lösenord.";
-$lang['L_HELP_FTPDIR']="Vart ska filen skickas?";
-$lang['L_HELP_SPEED']="Minimal och maximal hastighet. Standard är 50 till 5000 (för hög hastighet kan leda till timeouts!).";
-$lang['L_SPEED']="Hastighetskontroll";
-$lang['L_HELP_CRONEXECPATH']="Positionen för Perl-skripten.
+
+$lang['L_HELP_DB'] = 'Detta är listan över existerande databaser.';
+$lang['L_HELP_PRAEFIX'] = 'Prefixet är en teckenkedja i början av tabeller som används som filter.';
+$lang['L_HELP_ZIP'] = "Komprimering med GZIP - rekommendering: 'aktiverat'.";
+$lang['L_HELP_MEMORYLIMIT'] = 'Den maximala storleken i bytes som skriptet får i minnet. 0 = deaktiverat.';
+$lang['L_MEMORY_LIMIT'] = 'Minnesgräns';
+$lang['L_HELP_AD1'] = 'Aktivera för att automatiskt radera backupfiler.';
+$lang['L_HELP_AD3'] = 'Det maximala antalet filer som får finnas i backupmappen (för automatisk radering), 0 = deaktiverat.';
+$lang['L_HELP_LANG'] = 'Ställer in önskat språk.';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'För att eliminera överflödig data kan man ange att databasen ska tömmas helt före återställning.';
+$lang['L_HELP_CRONEXTENDER'] = "Perl-skriptets filändelse, standard är '.pl'.";
+$lang['L_HELP_CRONSAVEPATH'] = 'Konfigureringsfilens namn för Perl-skriptet.';
+$lang['L_HELP_CRONPRINTOUT'] = 'Om textutmatningen är deaktiverad så matas ingen text ut på bildskärmen.
+Denna funktion är oberoende av loggutmatningen.';
+$lang['L_HELP_CRONSAMEDB'] = 'Ska samma databas som i inställningarna användas för Crontab?';
+$lang['L_HELP_CRONDBINDEX'] = 'Välj databas för crontaben.';
+$lang['L_HELP_FTPTRANSFER'] = 'Aktiveras för överföring av filen via FTP efter backup.';
+$lang['L_HELP_FTPSERVER'] = 'FTP-serverns adress.';
+$lang['L_HELP_FTPPORT'] = 'FTP-serverns port, standard: 21.';
+$lang['L_HELP_FTPUSER'] = 'Ange FTP-förbindelsens användarnamn.';
+$lang['L_HELP_FTPPASS'] = 'Ange FTP-förbindelsens lösenord.';
+$lang['L_HELP_FTPDIR'] = 'Vart ska filen skickas?';
+$lang['L_HELP_SFTPTRANSFER'] = 'Aktiveras för överföring av filen via SFTP efter backup.';
+$lang['L_HELP_SFTPSERVER'] = 'SFTP-serverns adress.';
+$lang['L_HELP_SFTPPORT'] = 'SFTP-serverns port, standard: 22.';
+$lang['L_HELP_SFTPUSER'] = 'Ange SFTP-förbindelsens användarnamn.';
+$lang['L_HELP_SFTPPASS'] = 'Ange SFTP-förbindelsens lösenord.';
+$lang['L_HELP_SFTPDIR'] = 'Vart ska filen skickas?';
+$lang['L_HELP_SPEED'] = 'Minimal och maximal hastighet. Standard är 50 till 5000 (för hög hastighet kan leda till timeouts!).';
+$lang['L_SPEED'] = 'Hastighetskontroll';
+$lang['L_HELP_CRONEXECPATH'] = 'Positionen för Perl-skripten.
 Utgångspunkt är HTTP-adressen (alltså i webbläsaren).
-Både absoluta och relativa sökvägar är tillåtna.";
-$lang['L_CRON_EXECPATH']="Perl-skriptens sökväg";
-$lang['L_HELP_CRONCOMPLETELOG']="Om denna funktion är aktiverad så skrivs den kompletta informationen till complete_log. Denna funktion är oberoende av textutmatningen.";
-$lang['L_HELP_FTP_MODE']="Prova passivt FTP-läge om FTP-överföringen ej fungerar felfritt.";
-
-
-?>
\ No newline at end of file
+Både absoluta och relativa sökvägar är tillåtna.';
+$lang['L_CRON_EXECPATH'] = 'Perl-skriptens sökväg';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Om denna funktion är aktiverad så skrivs den kompletta informationen till complete_log. Denna funktion är oberoende av textutmatningen.';
+$lang['L_HELP_FTP_MODE'] = 'Prova passivt FTP-läge om FTP-överföringen ej fungerar felfritt.';
diff --git a/msd/language/sw/lang_install.php b/msd/language/sw/lang_install.php
index 554d5278..b7d76ca4 100644
--- a/msd/language/sw/lang_install.php
+++ b/msd/language/sw/lang_install.php
@@ -1,83 +1,79 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>installationen har avslutats --> <a href=\"index.php\">starta MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="till huvudmenyn";
-$lang['L_INSTALLMENU']="Huvudmeny";
-$lang['L_STEP']="Steg";
-$lang['L_INSTALL']="Installation";
-$lang['L_UNINSTALL']="Avinstallering";
-$lang['L_TOOLS']="Verktyg";
-$lang['L_EDITCONF']="Redigera konfigureringen";
-$lang['L_OSWEITER']="vidare utan att spara";
-$lang['L_ERRORMAN']="<strong>Ett fel uppträdde när konfigureringen skrevs!</strong><br>Redigera filen ";
-$lang['L_MANUELL']="manuellt";
-$lang['L_CREATEDIRS']="skapar mappar";
-$lang['L_INSTALL_CONTINUE']="fortsätt installationen";
-$lang['L_CONNECTTOMYSQL']=" förbind med mysql ";
-$lang['L_DBPARAMETER']="Databas-parametrar";
-$lang['L_CONFIGNOTWRITABLE']="Kan ej skriva i filen \"config.php\". Ställ in motsvarande behörighet med ditt FTP-program, t.ex. CHMOD 777.";
-$lang['L_DBCONNECTION']="Databas-förbindelse";
-$lang['L_CONNECTIONERROR']="Fel: förbindelse kunde ej upprättas.";
-$lang['L_CONNECTION_OK']="Databas-förbindelse har upprättats.";
-$lang['L_SAVEANDCONTINUE']="spara och fortsätt installationen";
-$lang['L_CONFBASIC']="Grundinställningar";
-$lang['L_INSTALL_STEP2FINISHED']="Inställningarna har sparats.";
-$lang['L_INSTALL_STEP2_1']="Fortsätt installationen med standardkonfigureringen";
-$lang['L_LASTSTEP']="Avsluta installationen";
-$lang['L_FTPMODE']="Skapa mappar via FTP (safe_mode)";
-$lang['L_IDOMANUAL']="Jag skapar mapparna manuellt";
-$lang['L_DOFROM']="utgående ifrån";
-$lang['L_FTPMODE2']="Skapa mapparna via FTP:";
-$lang['L_CONNECT']="förbind";
-$lang['L_DIRS_CREATED']="Alla mappar har skapats.";
-$lang['L_CONNECT_TO']="förbind med";
-$lang['L_CHANGEDIR']="Hoppa till mapp";
-$lang['L_CHANGEDIRERROR']="Hopp till mapp ej möjligt";
-$lang['L_FTP_OK']="FTP-parametrara är ok.";
-$lang['L_CREATEDIRS2']="Skapa mappar";
-$lang['L_FTP_NOTCONNECTED']="FTP-förbindelsen kunde ej skapas!";
-$lang['L_CONNWITH']="Förbindelse med";
-$lang['L_ASUSER']="som användare";
-$lang['L_NOTPOSSIBLE']="ej möjligt";
-$lang['L_DIRCR1']="skapar arbetsmapp";
-$lang['L_DIRCR2']="skapar backupmapp";
-$lang['L_DIRCR4']="skapar loggmapp";
-$lang['L_DIRCR5']="skapar konfigureringsmapp";
-$lang['L_INDIR']="nu i mappen";
-$lang['L_CHECK_DIRS']="kontrollera mina mappar";
-$lang['L_DISABLEDFUNCTIONS']="Deaktiverade funktioner";
-$lang['L_NOFTPPOSSIBLE']="Det står inga FTP-funktioner till förfogande!";
-$lang['L_NOGZPOSSIBLE']="Det står inga komprimeringsfunktioner till förfogande!";
-$lang['L_UI1']="Alla arbetsmappar inkl. eventuella backuper som finns i mapparna raderas!";
-$lang['L_UI2']="Är du säker på att du vill det?";
-$lang['L_UI3']="nej, avbryt genast";
-$lang['L_UI4']="ja, fortsätt";
-$lang['L_UI5']="radera arbetsmapp";
-$lang['L_UI6']="allt har raderats";
-$lang['L_UI7']="Radera skriptmappen";
-$lang['L_UI8']="en nivå upp";
-$lang['L_UI9']="Ett fel har uppträtt, radering var ej möjlig.</p>Felet uppträdde för mapp";
-$lang['L_IMPORT']="Importera konfigureringen";
-$lang['L_IMPORT3']="Konfigureringen har laddats ...";
-$lang['L_IMPORT4']="Konfigureringen har sparats.";
-$lang['L_IMPORT5']="Starta MySQLDumper";
-$lang['L_IMPORT6']="Installationsmenyn";
-$lang['L_IMPORT7']="Konfiguration uploaden";
-$lang['L_IMPORT8']="tillbaka till uppladdningen";
-$lang['L_IMPORT9']="Detta är ingen konfigureringsbackup!";
-$lang['L_IMPORT10']="Konfigureringen har laddats upp ...";
-$lang['L_IMPORT11']="<strong>Fel: </strong>ett problem uppträdde när sql_statements skrevs.";
-$lang['L_IMPORT12']="<strong>Fel: </strong>ett problem uppstod när config.php skrevs.";
-$lang['L_INSTALL_HELP_PORT']="(tom = standardport)";
-$lang['L_INSTALL_HELP_SOCKET']="(tom = standardsocket)";
-$lang['L_TRYAGAIN']="försök igen";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="hittad databas:";
-$lang['L_FM_FILEUPLOAD']="Ladda upp fil";
-$lang['L_PASS']="Lösenord";
-$lang['L_NO_DB_FOUND_INFO']="Förbindelsen till databasen kunde upprättas.<br>Dina inloggningsinformationer är giltiga har accepterats av MySQL-servern.<br>Tyvärr kunde MySQLDumper inte hitta några databaser.<br>Automatisk detektering spärras av vissa webbhotell.<br>Du måste ange databasen efter installationen, menypunkt \"Konfigurering\" \"Visa förbindelseparametrar\".<br>Genomför detta steg omedelbart efter installationen.";
-$lang['L_SAFEMODEDESC']="Eftersom PHP utförs med optionen \"safe_mode=on\" på denna server måste följande mappar skapas manuellt med ett FTP-program:";
-$lang['L_ENTER_DB_INFO']="Klicka först på knappen \"förbind med mysql\". Endast om denna förbindelse ej fungerar behöver du mata in data här.";
 
-
-?>
\ No newline at end of file
+$lang['L_INSTALLFINISHED'] = '<br>installationen har avslutats --> <a href="index.php">starta MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'till huvudmenyn';
+$lang['L_INSTALLMENU'] = 'Huvudmeny';
+$lang['L_STEP'] = 'Steg';
+$lang['L_INSTALL'] = 'Installation';
+$lang['L_UNINSTALL'] = 'Avinstallering';
+$lang['L_TOOLS'] = 'Verktyg';
+$lang['L_EDITCONF'] = 'Redigera konfigureringen';
+$lang['L_OSWEITER'] = 'vidare utan att spara';
+$lang['L_ERRORMAN'] = '<strong>Ett fel uppträdde när konfigureringen skrevs!</strong><br>Redigera filen ';
+$lang['L_MANUELL'] = 'manuellt';
+$lang['L_CREATEDIRS'] = 'skapar mappar';
+$lang['L_INSTALL_CONTINUE'] = 'fortsätt installationen';
+$lang['L_CONNECTTOMYSQL'] = ' förbind med mysql ';
+$lang['L_DBPARAMETER'] = 'Databas-parametrar';
+$lang['L_CONFIGNOTWRITABLE'] = 'Kan ej skriva i filen "config.php". Ställ in motsvarande behörighet med ditt FTP-program, t.ex. CHMOD 777.';
+$lang['L_DBCONNECTION'] = 'Databas-förbindelse';
+$lang['L_CONNECTIONERROR'] = 'Fel: förbindelse kunde ej upprättas.';
+$lang['L_CONNECTION_OK'] = 'Databas-förbindelse har upprättats.';
+$lang['L_SAVEANDCONTINUE'] = 'spara och fortsätt installationen';
+$lang['L_CONFBASIC'] = 'Grundinställningar';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Inställningarna har sparats.';
+$lang['L_INSTALL_STEP2_1'] = 'Fortsätt installationen med standardkonfigureringen';
+$lang['L_LASTSTEP'] = 'Avsluta installationen';
+$lang['L_IDOMANUAL'] = 'Jag skapar mapparna manuellt';
+$lang['L_DOFROM'] = 'utgående ifrån';
+$lang['L_FTPMODE2'] = 'Skapa mapparna via FTP:';
+$lang['L_CONNECT'] = 'förbind';
+$lang['L_DIRS_CREATED'] = 'Alla mappar har skapats.';
+$lang['L_CONNECT_TO'] = 'förbind med';
+$lang['L_CHANGEDIR'] = 'Hoppa till mapp';
+$lang['L_CHANGEDIRERROR'] = 'Hopp till mapp ej möjligt';
+$lang['L_FTP_OK'] = 'FTP-parametrara är ok.';
+$lang['L_CREATEDIRS2'] = 'Skapa mappar';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP-förbindelsen kunde ej skapas!';
+$lang['L_CONNWITH'] = 'Förbindelse med';
+$lang['L_ASUSER'] = 'som användare';
+$lang['L_NOTPOSSIBLE'] = 'ej möjligt';
+$lang['L_DIRCR1'] = 'skapar arbetsmapp';
+$lang['L_DIRCR2'] = 'skapar backupmapp';
+$lang['L_DIRCR4'] = 'skapar loggmapp';
+$lang['L_DIRCR5'] = 'skapar konfigureringsmapp';
+$lang['L_INDIR'] = 'nu i mappen';
+$lang['L_CHECK_DIRS'] = 'kontrollera mina mappar';
+$lang['L_DISABLEDFUNCTIONS'] = 'Deaktiverade funktioner';
+$lang['L_NOFTPPOSSIBLE'] = 'Det står inga FTP-funktioner till förfogande!';
+$lang['L_NOGZPOSSIBLE'] = 'Det står inga komprimeringsfunktioner till förfogande!';
+$lang['L_UI1'] = 'Alla arbetsmappar inkl. eventuella backuper som finns i mapparna raderas!';
+$lang['L_UI2'] = 'Är du säker på att du vill det?';
+$lang['L_UI3'] = 'nej, avbryt genast';
+$lang['L_UI4'] = 'ja, fortsätt';
+$lang['L_UI5'] = 'radera arbetsmapp';
+$lang['L_UI6'] = 'allt har raderats';
+$lang['L_UI7'] = 'Radera skriptmappen';
+$lang['L_UI8'] = 'en nivå upp';
+$lang['L_UI9'] = 'Ett fel har uppträtt, radering var ej möjlig.</p>Felet uppträdde för mapp';
+$lang['L_IMPORT'] = 'Importera konfigureringen';
+$lang['L_IMPORT3'] = 'Konfigureringen har laddats ...';
+$lang['L_IMPORT4'] = 'Konfigureringen har sparats.';
+$lang['L_IMPORT5'] = 'Starta MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Installationsmenyn';
+$lang['L_IMPORT7'] = 'Konfiguration uploaden';
+$lang['L_IMPORT8'] = 'tillbaka till uppladdningen';
+$lang['L_IMPORT9'] = 'Detta är ingen konfigureringsbackup!';
+$lang['L_IMPORT10'] = 'Konfigureringen har laddats upp ...';
+$lang['L_IMPORT11'] = '<strong>Fel: </strong>ett problem uppträdde när sql_statements skrevs.';
+$lang['L_IMPORT12'] = '<strong>Fel: </strong>ett problem uppstod när config.php skrevs.';
+$lang['L_INSTALL_HELP_PORT'] = '(tom = standardport)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(tom = standardsocket)';
+$lang['L_TRYAGAIN'] = 'försök igen';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'hittad databas:';
+$lang['L_FM_FILEUPLOAD'] = 'Ladda upp fil';
+$lang['L_PASS'] = 'Lösenord';
+$lang['L_NO_DB_FOUND_INFO'] = 'Förbindelsen till databasen kunde upprättas.<br>Dina inloggningsinformationer är giltiga har accepterats av MySQL-servern.<br>Tyvärr kunde MyOOS [Dumper] inte hitta några databaser.<br>Automatisk detektering spärras av vissa webbhotell.<br>Du måste ange databasen efter installationen, menypunkt "Konfigurering" "Visa förbindelseparametrar".<br>Genomför detta steg omedelbart efter installationen.';
+$lang['L_ENTER_DB_INFO'] = 'Klicka först på knappen "förbind med mysql". Endast om denna förbindelse ej fungerar behöver du mata in data här.';
diff --git a/msd/language/sw/lang_log.php b/msd/language/sw/lang_log.php
index 4fb656b3..ae1a88de 100644
--- a/msd/language/sw/lang_log.php
+++ b/msd/language/sw/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Radera loggen";
-$lang['L_LOGFILEFORMAT']="Loggfilformat";
-$lang['L_LOGFILENOTWRITABLE']="Loggfilen kan ej skrivas!";
-$lang['L_NOREVERSE']="Äldsta posten först";
-$lang['L_REVERSE']="Nyaste posten först";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Radera loggen';
+$lang['L_LOGFILEFORMAT'] = 'Loggfilformat';
+$lang['L_LOGFILENOTWRITABLE'] = 'Loggfilen kan ej skrivas!';
+$lang['L_NOREVERSE'] = 'Äldsta posten först';
+$lang['L_REVERSE'] = 'Nyaste posten först';
diff --git a/msd/language/sw/lang_main.php b/msd/language/sw/lang_main.php
index 505f17f7..9afda153 100644
--- a/msd/language/sw/lang_main.php
+++ b/msd/language/sw/lang_main.php
@@ -1,74 +1,85 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Det står inga FTP-funktioner till förfogande!";
-$lang['L_INFO_LOCATION']="Du befinner dig på";
-$lang['L_INFO_DATABASES']="Följande databas(er) finns på MySQL-servern:";
-$lang['L_INFO_NODB']="Databasen existerar ej";
-$lang['L_INFO_DBDETAIL']="Dataljerad information om databasen";
-$lang['L_INFO_DBEMPTY']="Databasen är tom!";
-$lang['L_INFO_RECORDS']="Dataposter";
-$lang['L_INFO_SIZE']="Storlek";
-$lang['L_INFO_LASTUPDATE']="senaste uppdatering";
-$lang['L_INFO_SUM']="totalt";
-$lang['L_INFO_OPTIMIZED']="optimerat";
-$lang['L_OPTIMIZE_DATABASES']="Optimera tabellerna";
-$lang['L_CHECK_TABLES']="Kontrollera tabeller";
-$lang['L_CLEAR_DATABASE']="Töm databasen";
-$lang['L_DELETE_DATABASE']="Radera databas";
-$lang['L_INFO_CLEARED']="har tömts";
-$lang['L_INFO_DELETED']="har raderats";
-$lang['L_INFO_EMPTYDB1']="Ska databasen";
-$lang['L_INFO_EMPTYDB2']=" verkligen tömmas? (OBS: all data går förlorad och kan ej återställas - gör backup först)";
-$lang['L_INFO_KILLDB']=" verkligen raderas? (OBS: all data går förlorad och kan ej återställas - gör backup först)";
-$lang['L_PROCESSKILL1']="Försöker avsluta process";
-$lang['L_PROCESSKILL2']=".";
-$lang['L_PROCESSKILL3']="Sedan";
-$lang['L_PROCESSKILL4']="sekund(er) försöks avsluta process";
-$lang['L_HTACC_CREATE']="Skapa mappskydd";
-$lang['L_ENCRYPTION_TYPE']="Krypteringssätt";
-$lang['L_HTACC_CRYPT']="Crypt (Linux och Unix-system)";
-$lang['L_HTACC_MD5']="MD5 (Linux och Unix-system)";
-$lang['L_HTACC_NO_ENCRYPTION']="ingen kryptering (Windows)";
-$lang['L_HTACCESS8']="Mappskydd existerar redan. Det gamla skrivs över om du skapar ett nytt!";
-$lang['L_HTACC_NO_USERNAME']="Du måste mata in ett namn!";
-$lang['L_PASSWORDS_UNEQUAL']="Lösenorden är ej identiska eller tomma!";
-$lang['L_HTACC_CONFIRM_DELETE']="Ska mappskyddet skapas nu?";
-$lang['L_HTACC_CREATED']="Mappskyddet har skapats.";
-$lang['L_HTACC_CONTENT']="Filens innehåll";
-$lang['L_HTACC_CREATE_ERROR']="Ett fel uppträdde när mappskyddet skulle skapas!<br>Skapa filerna manuellt med följande innehåll";
-$lang['L_HTACC_PROPOSED']="Rekommenderas starkt";
-$lang['L_HTACC_EDIT']="Editera .htaccess-skyddet";
-$lang['L_HTACCESS18']="Skapa .htaccess i";
-$lang['L_HTACCESS19']="Ladda om";
-$lang['L_HTACCESS20']="Utför skriptet";
-$lang['L_HTACCESS21']="Lägg till handler";
-$lang['L_HTACCESS22']="Gör utförbart";
-$lang['L_HTACCESS23']="Mapp-listning";
-$lang['L_HTACCESS24']="Fel-dokument";
-$lang['L_HTACCESS25']="Aktivera rewrite";
-$lang['L_HTACCESS26']="Deny / Allow";
-$lang['L_HTACCESS27']="Redirect";
-$lang['L_HTACCESS28']="Fel-logg";
-$lang['L_HTACCESS29']="ytterligare exempel och dokumentation";
-$lang['L_HTACCESS30']="Provider";
-$lang['L_HTACCESS31']="allmänt";
-$lang['L_HTACCESS32']="OBS! .htaccess har direkt inverkan på servern.<br>Om .htaccess ställs in på fel sätt kan sidan ej nås.";
-$lang['L_PHPBUG']="Bugg i zlib! Komprimering kan ej utföras!";
-$lang['L_DISABLEDFUNCTIONS']="Deaktiverade funktioner";
-$lang['L_NOGZPOSSIBLE']="Det står inga GZIP-funktioner till förfogande eftersom zlib ej har installerats!";
-$lang['L_DELETE_HTACCESS']="Avlägsna mappskyddet (radera .htaccess-filen)";
-$lang['L_WRONG_RIGHTS']="Filen eller mappen '%s' kan ej skrivas till.<br>Antingen har den fel ägare (Owner) eller fel behörigheter (Chmod).<br>Ställ in rätt attribut med ett FTP-program. <br>Filen eller mappen måste ha %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Mappen '%s' kunde ej skapas. Skapa den med ditt FTP-program.";
-$lang['L_TABLE_TYPE']="Typ";
-$lang['L_CHECK']="kontrollera";
-$lang['L_HTACC_SHA1']="SHA1 (alla system)";
-$lang['L_OS']="Operativsystem";
-$lang['L_MSD_VERSION']="MySQLDumper-version";
-$lang['L_MYSQL_VERSION']="MySQL-version";
-$lang['L_PHP_VERSION']="PHP-version";
-$lang['L_MAX_EXECUTION_TIME']="Maximal exekveringstid";
-$lang['L_PHP_EXTENSIONS']="PHP-extensioner";
-$lang['L_MEMORY']="Minne";
-$lang['L_FILE_MISSING']="kunde ej hitta filen";
 
-
-?>
\ No newline at end of file
+$lang['L_NOFTPPOSSIBLE'] = 'Det står inga FTP-funktioner till förfogande!';
+$lang['L_INFO_LOCATION'] = 'Du befinner dig på';
+$lang['L_INFO_DATABASES'] = 'Följande databas(er) finns på MySQL-servern:';
+$lang['L_INFO_NODB'] = 'Databasen existerar ej';
+$lang['L_INFO_DBDETAIL'] = 'Dataljerad information om databasen';
+$lang['L_INFO_DBEMPTY'] = 'Databasen är tom!';
+$lang['L_INFO_RECORDS'] = 'Dataposter';
+$lang['L_INFO_SIZE'] = 'Storlek';
+$lang['L_INFO_LASTUPDATE'] = 'senaste uppdatering';
+$lang['L_INFO_SUM'] = 'totalt';
+$lang['L_INFO_OPTIMIZED'] = 'optimerat';
+$lang['L_OPTIMIZE_DATABASES'] = 'Optimera tabellerna';
+$lang['L_CHECK_TABLES'] = 'Kontrollera tabeller';
+$lang['L_CLEAR_DATABASE'] = 'Töm databasen';
+$lang['L_DELETE_DATABASE'] = 'Radera databas';
+$lang['L_INFO_CLEARED'] = 'har tömts';
+$lang['L_INFO_DELETED'] = 'har raderats';
+$lang['L_INFO_EMPTYDB1'] = 'Ska databasen';
+$lang['L_INFO_EMPTYDB2'] = ' verkligen tömmas? (OBS: all data går förlorad och kan ej återställas - gör backup först)';
+$lang['L_INFO_KILLDB'] = ' verkligen raderas? (OBS: all data går förlorad och kan ej återställas - gör backup först)';
+$lang['L_PROCESSKILL1'] = 'Försöker avsluta process';
+$lang['L_PROCESSKILL2'] = '.';
+$lang['L_PROCESSKILL3'] = 'Sedan';
+$lang['L_PROCESSKILL4'] = 'sekund(er) försöks avsluta process';
+$lang['L_HTACC_CREATE'] = 'Skapa mappskydd';
+$lang['L_ENCRYPTION_TYPE'] = 'Krypteringssätt';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Mappskydd existerar redan. Det gamla skrivs över om du skapar ett nytt!';
+$lang['L_HTACC_NO_USERNAME'] = 'Du måste mata in ett namn!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Lösenorden är ej identiska eller tomma!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Ska mappskyddet skapas nu?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'Mappskyddet har skapats.';
+$lang['L_HTACC_CONTENT'] = 'Filens innehåll';
+$lang['L_HTACC_CREATE_ERROR'] = 'Ett fel uppträdde när mappskyddet skulle skapas!<br>Skapa filerna manuellt med följande innehåll';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'Editera .htaccess-skyddet';
+$lang['L_HTACCESS18'] = 'Skapa .htaccess i';
+$lang['L_HTACCESS19'] = 'Ladda om';
+$lang['L_HTACCESS20'] = 'Utför skriptet';
+$lang['L_HTACCESS21'] = 'Lägg till handler';
+$lang['L_HTACCESS22'] = 'Gör utförbart';
+$lang['L_HTACCESS23'] = 'Mapp-listning';
+$lang['L_HTACCESS24'] = 'Fel-dokument';
+$lang['L_HTACCESS25'] = 'Aktivera rewrite';
+$lang['L_HTACCESS26'] = 'Deny / Allow';
+$lang['L_HTACCESS27'] = 'Redirect';
+$lang['L_HTACCESS28'] = 'Fel-logg';
+$lang['L_HTACCESS29'] = 'ytterligare exempel och dokumentation';
+$lang['L_HTACCESS30'] = 'Provider';
+$lang['L_HTACCESS31'] = 'allmänt';
+$lang['L_HTACCESS32'] = 'OBS! .htaccess har direkt inverkan på servern.<br>Om .htaccess ställs in på fel sätt kan sidan ej nås.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Deaktiverade funktioner';
+$lang['L_NOGZPOSSIBLE'] = 'Det står inga GZIP-funktioner till förfogande eftersom zlib ej har installerats!';
+$lang['L_DELETE_HTACCESS'] = 'Avlägsna mappskyddet (radera .htaccess-filen)';
+$lang['L_WRONG_RIGHTS'] = "Filen eller mappen '%s' kan ej skrivas till.<br>Antingen har den fel ägare (Owner) eller fel behörigheter (Chmod).<br>Ställ in rätt attribut med ett FTP-program. <br>Filen eller mappen måste ha %s.<br>";
+$lang['L_CANT_CREATE_DIR'] = "Mappen '%s' kunde ej skapas. Skapa den med ditt FTP-program.";
+$lang['L_TABLE_TYPE'] = 'Typ';
+$lang['L_CHECK'] = 'kontrollera';
+$lang['L_OS'] = 'Operativsystem';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper]-version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_MYSQL_VERSION'] = 'MySQL-version';
+$lang['L_PHP_VERSION'] = 'PHP-version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Maximal exekveringstid';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-extensioner';
+$lang['L_MEMORY'] = 'Minne';
+$lang['L_FILE_MISSING'] = 'kunde ej hitta filen';
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/sw/lang_restore.php b/msd/language/sw/lang_restore.php
index 7e82e22a..dc2f99da 100644
--- a/msd/language/sw/lang_restore.php
+++ b/msd/language/sw/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Hittills har <b>%d</b> av <b>%d</b> tabeller skapats.";
-$lang['L_FILE_MISSING']="kunde ej hitta filen";
-$lang['L_RESTORE_DB']="Databas '<b>%s</b>' på server '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> tabeller har skapats.";
-$lang['L_RESTORE_RUN1']="<br>Hittills har <b>%s</b> av <b>%s</b> dataposter överförts.";
-$lang['L_RESTORE_RUN2']="<br>För närvarande analyseras datan i tabell '<b>%s</b>'.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> dataposter har överförts.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Hittills har <b>%d</b> av <b>%d</b> tabeller skapats.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Grattis!</b><br><br>Databasen har återställts komplett.<br>All data ur backupfilen har överförts till databasen.<br><br>Allt är färdigt. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Fel:<br> val av databasen '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' misslyckades!";
-$lang['L_FILE_OPEN_ERROR']="Fel: filen kunde ej öppnas.";
-$lang['L_PROGRESS_OVER_ALL']="Framsteg totalt";
-$lang['L_BACK_TO_OVERVIEW']="Databasöversikt";
-$lang['L_RESTORE_RUN0']="<br>Hittills har <b>%s</b> dataposter överförts.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Okänt SQL-kommando:";
-$lang['L_NOTICES']="Hänvisningar";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Hittills har <b>%d</b> av <b>%d</b> tabeller skapats.';
+$lang['L_FILE_MISSING'] = 'kunde ej hitta filen';
+$lang['L_RESTORE_DB'] = "Databas '<b>%s</b>' på server '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> tabeller har skapats.';
+$lang['L_RESTORE_RUN1'] = '<br>Hittills har <b>%s</b> av <b>%s</b> dataposter överförts.';
+$lang['L_RESTORE_RUN2'] = "<br>För närvarande analyseras datan i tabell '<b>%s</b>'.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> dataposter har överförts.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Hittills har <b>%d</b> av <b>%d</b> tabeller skapats.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Grattis!</b><br><br>Databasen har återställts komplett.<br>All data ur backupfilen har överförts till databasen.<br><br>Allt är färdigt. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Fel:<br> val av databasen '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' misslyckades!";
+$lang['L_FILE_OPEN_ERROR'] = 'Fel: filen kunde ej öppnas.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Framsteg totalt';
+$lang['L_BACK_TO_OVERVIEW'] = 'Databasöversikt';
+$lang['L_RESTORE_RUN0'] = '<br>Hittills har <b>%s</b> dataposter överförts.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Okänt SQL-kommando:';
+$lang['L_NOTICES'] = 'Hänvisningar';
diff --git a/msd/language/sw/lang_sql.php b/msd/language/sw/lang_sql.php
index 5ad88cf9..813dba9a 100644
--- a/msd/language/sw/lang_sql.php
+++ b/msd/language/sw/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Kommando";
-$lang['L_IMPORT_NOTABLE']="Ingen tabell har valts för importen!";
-$lang['L_PASSWORD_STRENGTH']="Lösenordets säkerhet";
-$lang['L_SQL_WARNING']="Utförs SQL-kommandon kan detta förändra data! Autorn ansvarar ej för förlust av data.";
-$lang['L_SQL_EXEC']="Utför SQL-kommandot";
-$lang['L_SQL_DATAVIEW']="Datavy";
-$lang['L_SQL_TABLEVIEW']="Tabellvy";
-$lang['L_SQL_VONINS']="av totalt";
-$lang['L_SQL_NODATA']="inga dataposter";
-$lang['L_SQL_RECORDUPDATED']="Dataposten har ändrats";
-$lang['L_SQL_RECORDINSERTED']="Dataposten har sparats";
-$lang['L_SQL_BACKDBOVERVIEW']="tillbaka till databas-översikten";
-$lang['L_SQL_RECORDDELETED']="Dataposten har raderats";
-$lang['L_ASKTABLEEMPTY']="Skall tabellen `%s` verkligen tömmas?";
-$lang['L_SQL_RECORDEDIT']="ändra dataposten";
-$lang['L_SQL_RECORDNEW']="infoga datapost";
-$lang['L_ASKDELETERECORD']="Skall dataposten verkligen raderas?";
-$lang['L_ASKDELETETABLE']="Skall tabellen `%s` verkligen raderas?";
-$lang['L_SQL_BEFEHLE']="SQL-kommandon";
-$lang['L_SQL_BEFEHLNEU']="nytt kommando";
-$lang['L_SQL_BEFEHLSAVED1']="SQL-kommando";
-$lang['L_SQL_BEFEHLSAVED2']="har lagts till";
-$lang['L_SQL_BEFEHLSAVED3']="har sparats";
-$lang['L_SQL_BEFEHLSAVED4']="har flyttats upp";
-$lang['L_SQL_BEFEHLSAVED5']="har raderats";
-$lang['L_SQL_QUERYENTRY']="Frågan innehåller";
-$lang['L_SQL_COLUMNS']="Kolumner";
-$lang['L_ASKDBDELETE']="Vill du verkligen radera databasen `%s` samt dess innehåll?";
-$lang['L_ASKDBEMPTY']="Vill du verkligen tömma databasen `%s`?";
-$lang['L_ASKDBCOPY']="Vill du kopiera innehållet i databasen `%s` till databasen `%s`?";
-$lang['L_SQL_TABLENEW']="Bearbeta tabeller";
-$lang['L_SQL_OUTPUT']="SQL-resultat";
-$lang['L_DO_NOW']="utför nu";
-$lang['L_SQL_NAMEDEST_MISSING']="Namn saknas för måldatabasen!";
-$lang['L_ASKDELETEFIELD']="Skall fältet verkligen raderas?";
-$lang['L_SQL_COMMANDS_IN']="rader bearbetade i";
-$lang['L_SQL_COMMANDS_IN2']="sekund(er).";
-$lang['L_SQL_OUT1']="Det har utförts";
-$lang['L_SQL_OUT2']="kommandon";
-$lang['L_SQL_OUT3']="Det fanns";
-$lang['L_SQL_OUT4']="kommantarer";
-$lang['L_SQL_OUT5']="Eftersom resultatet har över 5000 rader visas det ej här.";
-$lang['L_SQL_SELECDB']="Välj databas";
-$lang['L_SQL_TABLESOFDB']="Tabeller i databasen";
-$lang['L_SQL_EDIT']="bearbeta";
-$lang['L_SQL_NOFIELDDELETE']="Radering ej möjlig eftersom en tabell måste innehålla minst ett fält.";
-$lang['L_SQL_FIELDDELETE1']="Fältet";
-$lang['L_SQL_DELETED']="har raderats.";
-$lang['L_SQL_CHANGED']="har ändrats.";
-$lang['L_SQL_CREATED']="har skapats.";
-$lang['L_SQL_NODEST_COPY']="Utan mål kan kopiering ej utföras!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Måltabellen existerar redan!";
-$lang['L_SQL_SCOPY']="Tabellenstrukturen i `%s` har kopierats till tabellen `%s`.";
-$lang['L_SQL_TCOPY']="Tabell `%s` kopierades med datan till tabell `%s`.";
-$lang['L_SQL_TABLENONAME']="Tabellen måste ha ett namn!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tabellens namn får ej vara tomt!";
-$lang['L_SQL_COLLATENOTMATCH']="Teckensats och sortering passar ej ihop!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Fel: fältnamnet ej giltigt";
-$lang['L_SQL_CREATETABLE']="skapa tabell";
-$lang['L_SQL_COPYTABLE']="Kopiera tabellen";
-$lang['L_SQL_STRUCTUREONLY']="endast struktur";
-$lang['L_SQL_STRUCTUREDATA']="Struktur och data";
-$lang['L_SQL_NOTABLESINDB']="Det finns inga tabeller i databasen";
-$lang['L_SQL_SELECTTABLE']="välj tabell";
-$lang['L_SQL_SHOWDATATABLE']="Visa datan i tabellen";
-$lang['L_SQL_TBLPROPSOF']="Tabellegenskaper för";
-$lang['L_SQL_EDITFIELD']="Bearbeta fält";
-$lang['L_SQL_NEWFIELD']="Nytt fält";
-$lang['L_SQL_INDEXES']="Index";
-$lang['L_SQL_ATPOSITION']="infoga vid position";
-$lang['L_SQL_FIRST']="först";
-$lang['L_SQL_AFTER']="efter";
-$lang['L_SQL_CHANGEFIELD']="ändra fält";
-$lang['L_SQL_INSERTFIELD']="infoga fält";
-$lang['L_SQL_INSERTNEWFIELD']="infoga nytt fält";
-$lang['L_SQL_TABLEINDEXES']="Index i tabellen";
-$lang['L_SQL_ALLOWDUPS']="Tillåt duplikat";
-$lang['L_SQL_CARDINALITY']="Kardinalitet";
-$lang['L_SQL_TABLENOINDEXES']="Tabellen innehåller inga index";
-$lang['L_SQL_CREATEINDEX']="skapa nytt index";
-$lang['L_SQL_WASEMPTIED']="har tömts";
-$lang['L_SQL_RENAMEDTO']="har ombenämnts till";
-$lang['L_SQL_DBCOPY']="Innehållet i databas `%s` har kopierats till databas `%s`.";
-$lang['L_SQL_DBSCOPY']="Strukturen i databas `%s` har kopierats till databas `%s`.";
-$lang['L_SQL_WASCREATED']="har skapats";
-$lang['L_SQL_RENAMEDB']="Ombenämn databas";
-$lang['L_SQL_ACTIONS']="Aktioner";
-$lang['L_SQL_CHOOSEACTION']="Välj aktion";
-$lang['L_SQL_DELETEDB']="Radera databasen";
-$lang['L_SQL_EMPTYDB']="Töm databasen";
-$lang['L_SQL_COPYDATADB']="Kopiera hela databasen till";
-$lang['L_SQL_COPYSDB']="Kopiera databasens struktur";
-$lang['L_SQL_IMEXPORT']="Import/export";
-$lang['L_INFO_RECORDS']="dataposter";
-$lang['L_NAME']="Namn";
-$lang['L_ASKTABLEEMPTYKEYS']="Skall tabellen `%s` tömmas och indexen återställas?";
-$lang['L_EDIT']="redigera";
-$lang['L_DELETE']="radera";
-$lang['L_EMPTY']="töm";
-$lang['L_EMPTYKEYS']="töm och återställ index";
-$lang['L_SQL_TABLEEMPTIED']="Tabellen `%s` har tömts.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Tabellen `%s` har tömts och index har återställts.";
-$lang['L_SQL_LIBRARY']="SQL-bibliotek";
-$lang['L_SQL_ATTRIBUTES']="Attribut";
-$lang['L_SQL_UPLOADEDFILE']="laddad fil: ";
-$lang['L_SQL_IMPORT']="Import till databasen `%s`";
-$lang['L_EXPORT']="Export";
-$lang['L_IMPORT']="Import";
-$lang['L_IMPORTOPTIONS']="Importoptioner";
-$lang['L_CSVOPTIONS']="CSV-optioner";
-$lang['L_IMPORTTABLE']="Import till tabellen";
-$lang['L_NEWTABLE']="ny tabell";
-$lang['L_IMPORTSOURCE']="Importkälla";
-$lang['L_FROMTEXTBOX']="ur textfält";
-$lang['L_FROMFILE']="ur fil";
-$lang['L_EMPTYTABLEBEFORE']="Töm tabellen före";
-$lang['L_CREATEAUTOINDEX']="Skapa auto-index";
-$lang['L_CSV_NAMEFIRSTLINE']="Fältnamn i första raden";
-$lang['L_CSV_FIELDSEPERATE']="Fält separerade med";
-$lang['L_CSV_FIELDSENCLOSED']="Fält inneslutna av";
-$lang['L_CSV_FIELDSESCAPE']="Fält escaped från";
-$lang['L_CSV_EOL']="Raderna separerade med";
-$lang['L_CSV_NULL']="Ersätt NULL med";
-$lang['L_CSV_FILEOPEN']="Öppna CSV-fil";
-$lang['L_IMPORTIEREN']="importera";
-$lang['L_SQL_EXPORT']="Export ur databasen `%s`";
-$lang['L_EXPORTOPTIONS']="Exportoptioner";
-$lang['L_EXCEL2003']="Excel från och med 2003";
-$lang['L_SHOWRESULT']="Visa resultatet";
-$lang['L_SENDRESULTASFILE']="Skicka resultatet som fil";
-$lang['L_EXPORTLINES']="<strong>%s</strong> rader har exporterats";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Antalet tabell-fält stämmer ej överens med antalet som skall importeras (%d istället för %d).";
-$lang['L_CSV_FIELDSLINES']="%d fält fastställda, totalt %d rader";
-$lang['L_CSV_ERRORCREATETABLE']="Fel när tabellen `%s` skulle skapas!";
-$lang['L_FM_UPLOADFILEREQUEST']="Ange en fil.";
-$lang['L_CSV_NODATA']="Ingen data kunde hittas för import!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="allmäna funktioner";
-$lang['L_SQLLIB_RESETAUTO']="återställ auto-värde";
-$lang['L_SQLLIB_BOARDS']="Forum";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="Deaktivera forumet";
-$lang['L_SQLLIB_ACTIVATEBOARD']="Aktivera forumet";
-$lang['L_SQL_NOTABLESSELECTED']="Inga tabeller har valts!";
-$lang['L_TOOLS']="Verktyg";
-$lang['L_TOOLS_TOOLBOX']="Välj databas / Databasfunktioner / Import/Export ";
-$lang['L_SQL_OPENFILE']="Öppna SQL-fil";
-$lang['L_SQL_OPENFILE_BUTTON']="Ladda upp";
-$lang['L_MAX_UPLOAD_SIZE']="Maximal filstorlek";
-$lang['L_SQL_SEARCH']="Sökning";
-$lang['L_SQL_SEARCHWORDS']="Sökord";
-$lang['L_START_SQL_SEARCH']="Starta sökningen";
-$lang['L_RESET_SEARCHWORDS']="Återställ inmatningen";
-$lang['L_SEARCH_OPTIONS']="Sökinställningar";
-$lang['L_SEARCH_RESULTS']="Sökningen på \"<b>%s</b>\" i tabellen \"<b>%s</b>\" gav följande resultat";
-$lang['L_SEARCH_NO_RESULTS']="Sökningen på \"<b>%s</b>\" i tabellen \"<b>%s</b>\" gav inga träffar!";
-$lang['L_NO_ENTRIES']="Tabellen \"<b>%s</b>\" är tom och har inga poster.";
-$lang['L_SEARCH_ACCESS_KEYS']="Bläddra: framåt=ALT+V, tillbaka=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="en kolumn måste innehålla minst ett sökord (ELLER-sökning)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="en datapost måste innehålla alla sökord, dessa kan dock befinna sig i olika kolumner (stor serverbelastning!)";
-$lang['L_SEARCH_OPTIONS_AND']="en kolumn måste innehålla alla sökord (OCH-sökning)";
-$lang['L_SEARCH_IN_TABLE']="Sök i tabell";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Bearbeta tabellens struktur";
-$lang['L_DEFAULT_CHARSET']="Standardteckensats";
-$lang['L_TITLE_KEY_PRIMARY']="Primär nyckel";
-$lang['L_TITLE_KEY_UNIQUE']="Unik nyckel";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Fulltextnyckel";
-$lang['L_TITLE_NOKEY']="Ingen nyckel";
-$lang['L_TITLE_SEARCH']="Sök";
-$lang['L_TITLE_MYSQL_HELP']="MySQL dokumentation";
-$lang['L_TITLE_UPLOAD']="Ladda upp SQL-fil";
-$lang['L_PRIMARYKEY_DELETED']="Den primära nyckeln har raderats";
-$lang['L_PRIMARYKEY_NOTFOUND']="Den primära nyckeln kunde ej hittas";
-$lang['L_PRIMARYKEYS_CHANGED']="Den primära nyckeln har ändrats";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Ett fel uppträdde när den primära nyckeln skulle ändras";
-$lang['L_SQL_VIEW_COMPACT']="Visning: kompakt";
-$lang['L_SQL_VIEW_STANDARD']="Visning: normal";
-$lang['L_FIELDS_OF_TABLE']="Fält i tabellen";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Användarnamn";
-$lang['L_PASSWORD']="Lösenord";
-$lang['L_PASSWORD_REPEAT']="Upprepa lösenord";
-$lang['L_INFO_SIZE']="Storlek";
-$lang['L_TABLE_TYPE']="Typ";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Kommando';
+$lang['L_IMPORT_NOTABLE'] = 'Ingen tabell har valts för importen!';
+$lang['L_PASSWORD_STRENGTH'] = 'Lösenordets säkerhet';
+$lang['L_SQL_WARNING'] = 'Utförs SQL-kommandon kan detta förändra data! Autorn ansvarar ej för förlust av data.';
+$lang['L_SQL_EXEC'] = 'Utför SQL-kommandot';
+$lang['L_SQL_DATAVIEW'] = 'Datavy';
+$lang['L_SQL_TABLEVIEW'] = 'Tabellvy';
+$lang['L_SQL_VONINS'] = 'av totalt';
+$lang['L_SQL_NODATA'] = 'inga dataposter';
+$lang['L_SQL_RECORDUPDATED'] = 'Dataposten har ändrats';
+$lang['L_SQL_RECORDINSERTED'] = 'Dataposten har sparats';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'tillbaka till databas-översikten';
+$lang['L_SQL_RECORDDELETED'] = 'Dataposten har raderats';
+$lang['L_ASKTABLEEMPTY'] = 'Skall tabellen `%s` verkligen tömmas?';
+$lang['L_SQL_RECORDEDIT'] = 'ändra dataposten';
+$lang['L_SQL_RECORDNEW'] = 'infoga datapost';
+$lang['L_ASKDELETERECORD'] = 'Skall dataposten verkligen raderas?';
+$lang['L_ASKDELETETABLE'] = 'Skall tabellen `%s` verkligen raderas?';
+$lang['L_SQL_BEFEHLE'] = 'SQL-kommandon';
+$lang['L_SQL_BEFEHLNEU'] = 'nytt kommando';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL-kommando';
+$lang['L_SQL_BEFEHLSAVED2'] = 'har lagts till';
+$lang['L_SQL_BEFEHLSAVED3'] = 'har sparats';
+$lang['L_SQL_BEFEHLSAVED4'] = 'har flyttats upp';
+$lang['L_SQL_BEFEHLSAVED5'] = 'har raderats';
+$lang['L_SQL_QUERYENTRY'] = 'Frågan innehåller';
+$lang['L_SQL_COLUMNS'] = 'Kolumner';
+$lang['L_ASKDBDELETE'] = 'Vill du verkligen radera databasen `%s` samt dess innehåll?';
+$lang['L_ASKDBEMPTY'] = 'Vill du verkligen tömma databasen `%s`?';
+$lang['L_ASKDBCOPY'] = 'Vill du kopiera innehållet i databasen `%s` till databasen `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Bearbeta tabeller';
+$lang['L_SQL_OUTPUT'] = 'SQL-resultat';
+$lang['L_DO_NOW'] = 'utför nu';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Namn saknas för måldatabasen!';
+$lang['L_ASKDELETEFIELD'] = 'Skall fältet verkligen raderas?';
+$lang['L_SQL_COMMANDS_IN'] = 'rader bearbetade i';
+$lang['L_SQL_COMMANDS_IN2'] = 'sekund(er).';
+$lang['L_SQL_OUT1'] = 'Det har utförts';
+$lang['L_SQL_OUT2'] = 'kommandon';
+$lang['L_SQL_OUT3'] = 'Det fanns';
+$lang['L_SQL_OUT4'] = 'kommantarer';
+$lang['L_SQL_OUT5'] = 'Eftersom resultatet har över 5000 rader visas det ej här.';
+$lang['L_SQL_SELECDB'] = 'Välj databas';
+$lang['L_SQL_TABLESOFDB'] = 'Tabeller i databasen';
+$lang['L_SQL_EDIT'] = 'bearbeta';
+$lang['L_SQL_NOFIELDDELETE'] = 'Radering ej möjlig eftersom en tabell måste innehålla minst ett fält.';
+$lang['L_SQL_FIELDDELETE1'] = 'Fältet';
+$lang['L_SQL_DELETED'] = 'har raderats.';
+$lang['L_SQL_CHANGED'] = 'har ändrats.';
+$lang['L_SQL_CREATED'] = 'har skapats.';
+$lang['L_SQL_NODEST_COPY'] = 'Utan mål kan kopiering ej utföras!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Måltabellen existerar redan!';
+$lang['L_SQL_SCOPY'] = 'Tabellenstrukturen i `%s` har kopierats till tabellen `%s`.';
+$lang['L_SQL_TCOPY'] = 'Tabell `%s` kopierades med datan till tabell `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'Tabellen måste ha ett namn!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tabellens namn får ej vara tomt!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Teckensats och sortering passar ej ihop!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Fel: fältnamnet ej giltigt';
+$lang['L_SQL_CREATETABLE'] = 'skapa tabell';
+$lang['L_SQL_COPYTABLE'] = 'Kopiera tabellen';
+$lang['L_SQL_STRUCTUREONLY'] = 'endast struktur';
+$lang['L_SQL_STRUCTUREDATA'] = 'Struktur och data';
+$lang['L_SQL_NOTABLESINDB'] = 'Det finns inga tabeller i databasen';
+$lang['L_SQL_SELECTTABLE'] = 'välj tabell';
+$lang['L_SQL_SHOWDATATABLE'] = 'Visa datan i tabellen';
+$lang['L_SQL_TBLPROPSOF'] = 'Tabellegenskaper för';
+$lang['L_SQL_EDITFIELD'] = 'Bearbeta fält';
+$lang['L_SQL_NEWFIELD'] = 'Nytt fält';
+$lang['L_SQL_INDEXES'] = 'Index';
+$lang['L_SQL_ATPOSITION'] = 'infoga vid position';
+$lang['L_SQL_FIRST'] = 'först';
+$lang['L_SQL_AFTER'] = 'efter';
+$lang['L_SQL_CHANGEFIELD'] = 'ändra fält';
+$lang['L_SQL_INSERTFIELD'] = 'infoga fält';
+$lang['L_SQL_INSERTNEWFIELD'] = 'infoga nytt fält';
+$lang['L_SQL_TABLEINDEXES'] = 'Index i tabellen';
+$lang['L_SQL_ALLOWDUPS'] = 'Tillåt duplikat';
+$lang['L_SQL_CARDINALITY'] = 'Kardinalitet';
+$lang['L_SQL_TABLENOINDEXES'] = 'Tabellen innehåller inga index';
+$lang['L_SQL_CREATEINDEX'] = 'skapa nytt index';
+$lang['L_SQL_WASEMPTIED'] = 'har tömts';
+$lang['L_SQL_RENAMEDTO'] = 'har ombenämnts till';
+$lang['L_SQL_DBCOPY'] = 'Innehållet i databas `%s` har kopierats till databas `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'Strukturen i databas `%s` har kopierats till databas `%s`.';
+$lang['L_SQL_WASCREATED'] = 'har skapats';
+$lang['L_SQL_RENAMEDB'] = 'Ombenämn databas';
+$lang['L_SQL_ACTIONS'] = 'Aktioner';
+$lang['L_SQL_CHOOSEACTION'] = 'Välj aktion';
+$lang['L_SQL_DELETEDB'] = 'Radera databasen';
+$lang['L_SQL_EMPTYDB'] = 'Töm databasen';
+$lang['L_SQL_COPYDATADB'] = 'Kopiera hela databasen till';
+$lang['L_SQL_COPYSDB'] = 'Kopiera databasens struktur';
+$lang['L_SQL_IMEXPORT'] = 'Import/export';
+$lang['L_INFO_RECORDS'] = 'dataposter';
+$lang['L_NAME'] = 'Namn';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Skall tabellen `%s` tömmas och indexen återställas?';
+$lang['L_EDIT'] = 'redigera';
+$lang['L_DELETE'] = 'radera';
+$lang['L_EMPTY'] = 'töm';
+$lang['L_EMPTYKEYS'] = 'töm och återställ index';
+$lang['L_SQL_TABLEEMPTIED'] = 'Tabellen `%s` har tömts.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Tabellen `%s` har tömts och index har återställts.';
+$lang['L_SQL_LIBRARY'] = 'SQL-bibliotek';
+$lang['L_SQL_ATTRIBUTES'] = 'Attribut';
+$lang['L_SQL_UPLOADEDFILE'] = 'laddad fil: ';
+$lang['L_SQL_IMPORT'] = 'Import till databasen `%s`';
+$lang['L_EXPORT'] = 'Export';
+$lang['L_IMPORT'] = 'Import';
+$lang['L_IMPORTOPTIONS'] = 'Importoptioner';
+$lang['L_CSVOPTIONS'] = 'CSV-optioner';
+$lang['L_IMPORTTABLE'] = 'Import till tabellen';
+$lang['L_NEWTABLE'] = 'ny tabell';
+$lang['L_IMPORTSOURCE'] = 'Importkälla';
+$lang['L_FROMTEXTBOX'] = 'ur textfält';
+$lang['L_FROMFILE'] = 'ur fil';
+$lang['L_EMPTYTABLEBEFORE'] = 'Töm tabellen före';
+$lang['L_CREATEAUTOINDEX'] = 'Skapa auto-index';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Fältnamn i första raden';
+$lang['L_CSV_FIELDSEPERATE'] = 'Fält separerade med';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Fält inneslutna av';
+$lang['L_CSV_FIELDSESCAPE'] = 'Fält escaped från';
+$lang['L_CSV_EOL'] = 'Raderna separerade med';
+$lang['L_CSV_NULL'] = 'Ersätt NULL med';
+$lang['L_CSV_FILEOPEN'] = 'Öppna CSV-fil';
+$lang['L_IMPORTIEREN'] = 'importera';
+$lang['L_SQL_EXPORT'] = 'Export ur databasen `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Exportoptioner';
+$lang['L_EXCEL2003'] = 'Excel från och med 2003';
+$lang['L_SHOWRESULT'] = 'Visa resultatet';
+$lang['L_SENDRESULTASFILE'] = 'Skicka resultatet som fil';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> rader har exporterats';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Antalet tabell-fält stämmer ej överens med antalet som skall importeras (%d istället för %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d fält fastställda, totalt %d rader';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Fel när tabellen `%s` skulle skapas!';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Ange en fil.';
+$lang['L_CSV_NODATA'] = 'Ingen data kunde hittas för import!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'allmäna funktioner';
+$lang['L_SQLLIB_RESETAUTO'] = 'återställ auto-värde';
+$lang['L_SQLLIB_BOARDS'] = 'Forum';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'Deaktivera forumet';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'Aktivera forumet';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Inga tabeller har valts!';
+$lang['L_TOOLS'] = 'Verktyg';
+$lang['L_TOOLS_TOOLBOX'] = 'Välj databas / Databasfunktioner / Import/Export ';
+$lang['L_SQL_OPENFILE'] = 'Öppna SQL-fil';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Ladda upp';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maximal filstorlek';
+$lang['L_SQL_SEARCH'] = 'Sökning';
+$lang['L_SQL_SEARCHWORDS'] = 'Sökord';
+$lang['L_START_SQL_SEARCH'] = 'Starta sökningen';
+$lang['L_RESET_SEARCHWORDS'] = 'Återställ inmatningen';
+$lang['L_SEARCH_OPTIONS'] = 'Sökinställningar';
+$lang['L_SEARCH_RESULTS'] = 'Sökningen på "<b>%s</b>" i tabellen "<b>%s</b>" gav följande resultat';
+$lang['L_SEARCH_NO_RESULTS'] = 'Sökningen på "<b>%s</b>" i tabellen "<b>%s</b>" gav inga träffar!';
+$lang['L_NO_ENTRIES'] = 'Tabellen "<b>%s</b>" är tom och har inga poster.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Bläddra: framåt=ALT+V, tillbaka=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'en kolumn måste innehålla minst ett sökord (ELLER-sökning)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'en datapost måste innehålla alla sökord, dessa kan dock befinna sig i olika kolumner (stor serverbelastning!)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'en kolumn måste innehålla alla sökord (OCH-sökning)';
+$lang['L_SEARCH_IN_TABLE'] = 'Sök i tabell';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Bearbeta tabellens struktur';
+$lang['L_DEFAULT_CHARSET'] = 'Standardteckensats';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primär nyckel';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Unik nyckel';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Fulltextnyckel';
+$lang['L_TITLE_NOKEY'] = 'Ingen nyckel';
+$lang['L_TITLE_SEARCH'] = 'Sök';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQL dokumentation';
+$lang['L_TITLE_UPLOAD'] = 'Ladda upp SQL-fil';
+$lang['L_PRIMARYKEY_DELETED'] = 'Den primära nyckeln har raderats';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Den primära nyckeln kunde ej hittas';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Den primära nyckeln har ändrats';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Ett fel uppträdde när den primära nyckeln skulle ändras';
+$lang['L_SQL_VIEW_COMPACT'] = 'Visning: kompakt';
+$lang['L_SQL_VIEW_STANDARD'] = 'Visning: normal';
+$lang['L_FIELDS_OF_TABLE'] = 'Fält i tabellen';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Användarnamn';
+$lang['L_PASSWORD'] = 'Lösenord';
+$lang['L_PASSWORD_REPEAT'] = 'Upprepa lösenord';
+$lang['L_INFO_SIZE'] = 'Storlek';
+$lang['L_TABLE_TYPE'] = 'Typ';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/tr/help.html b/msd/language/tr/help.html
new file mode 100644
index 00000000..64a1411b
--- /dev/null
+++ b/msd/language/tr/help.html
@@ -0,0 +1,147 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/tr/help.php b/msd/language/tr/help.php
deleted file mode 100644
index 6bf4b7c1..00000000
--- a/msd/language/tr/help.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Bu Proje hakkinda</h3>
-Bu projenin kurucusu Daniel Schlichtholz'dur.<p>2004 yilinda <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper panosunu </a>kurdu,
-kisa bir süre sonra baskalari tarafindan destek gördü ve birçok kisinin katilimlari ile yazilim genisletilmeye baslandi. <p>istekleriniz veya önerileriniz için <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper-Panosuna</a> katilabilirsiniz.<p>
-<br><p><h4>MySQLDumper-Ekibi</h4>
-
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-<br>
-
-<h3>MySQLDumper Yardimi</h3>
-
-<h4>Indirme</h4>
-Bu yazilimi MySQLDumper Sitesinden temin edebilirsiniz.<br>
-Güncellemeler ve destek için Sitemizi sik sik takip etmenizi tavsiye ederiz.<br>
-Site adresi: <a href="http://www.mysqldumper.de" target="_blank">
-http://www.mysqldumper.de</a>
-
-<h4>Sistem gereksinimleri</h4>
-Mysqldumper her sunucuda çalisir (Windows, Linux, ...) <br>
-PHP sürümü >=  4.3.4 GZip-destekli, MySQL (3.23 sürümünden itibaren), JavaScript (aktiv olmak zorunda).
-
-<a href="install.php?language=de" target="_top"><h4>Kurulum</h4></a>
-Kurulumu çok basittir.
-Sikistirilmis dosyayi herhangi bir klasör içerisinde açiniz.<br>
-Açilann dosyalari FTP ile Sunucunuza yükleyiniz. (Örnegin root [sizindomain/]MySQLDumper)<br>
-... bitti!<br>
-Artik MySQLDumper'i tarayiciniz ile "http://sizindomain/MySQLDumper" adresini girerek açabilirsiniz,<br>
-kurulumu tamamlamak için saadece Sistemin sorularini cevaplamaniz yeterlidir.<br>
-<br><b>ÖNEMLI:</b><br><i>Sunucunuzda </i><tt>safe_mode</tt><i> açik ise, yazilimin klasör olusturma imkani yoktur.<br>
-Gerekli klasörleri kendiniz olusturmaniz gerekir, MySqlDumper'in çalisabilmesi için belli bir düzende klasörlerin bulunmasi gerekir.<br>
-Bu durumda yazilim kurulumu hata belirterek durduracaktir!<br>
-Verilen hataya göre klasörleri olusturdugunuz taktirde yaziliminiz normal bir sekilde islev görecektir.</i>
-
-<a name="perl"></a><h4>Perlskript kullanimi</h4>
-Sunucularin birçogu Perl Scripleri destekler. <br>
-Bu scriptlerin belli bir klasör içerisinde bulunmasi gerekebilir, klasörün adresi genellikle http://sizindomain/cgi-bin/ dir.
-<br>
-<br>
-Bu durumda yapilmasi gereken islemler:<br><br>
-
-1. MySQLDumper'i açtiktan sonra Yedekleme sayfasini açiniz ve "Yedekleme Perl" tusunu tiklayiniz. <br>
-2. Crondump.pl de kayitli adres absolute_path_of_configdir: in arkasinda bulunan kayidi kopyalayiniz. <br>
-3. "crondump.pl" Editör ile açiniz.<br>
-4. Kopyaladiginiz adresi absolute_path_of_configdir´in arkasina yapistiriniz (bosluk birakilmayacak).<br>
-5. Crondump.pl i kapatarak kayit ediniz.<br>
-6. Crondump.pl, perltest.pl ve simpletest.pl dosyalarini cgi-bin-klasörüne kopyalayiniz (FTP ile Ascii-Modüsünde).<br>
-7. Dosyalarin haklarini 755 olarak belirleyiniz (CHMOD). <br>
-7b. Dosyabitimi cgi olmasi gerekiyorsa her 3 dosyanin adinin degistiriniz  pl -> cgi. <br>
-8. Ayar Merkez, sayfasini açiniz.<br>
-9. Cronscript e tiklayiniz. <br>
-10. Perl veriyolunu /cgi-bin/ seklinde degistiriniz.<br>
-10b. Kullanilan dosyabitimi  seçiniz.<br>
-11. Ayarlari kayit ediniz. <br><br>
-
-Ayarlar tamamlanmistir, Scriptleri yedekleme sayfasindan çalistirabilirsiniz.<br><br>
-
-Perli her klasörden çalistirma yetkiniz bulunuyorsa:<br><br>
-
-1. MySQLDumper'i açtiktan sonra Yedekleme sayfasini açiniz ve "Yedekleme Perl" tusunu tiklayiniz. <br>
-2. Crondump.pl de kayitli adres absolute_path_of_configdir: in arkasinda bulunan kayidi kopyalayiniz. <br>
-3. "crondump.pl" Editör ile açiniz. <br>
-4. Kopyaladiginiz adresi absolute_path_of_configdir´in arkasina yapistiriniz (bosluk birakilmayacak).<br>
-5. Crondump.pl i kapatarak kayit ediniz.<br>
-6. Dosyalarin haklarini 755 olarak belirleyiniz (CHMOD). <br>
-6b. Dosyabitimi cgi olmasi gerekiyorsa her 3 dosyanin adinin degistiriniz  pl -> cgi. <br>
-(Gerekirse yukaridaki 10b+11 ci adimlari da uygulayiniz)<br>
-<br>
-
-Windows kullanicilarinin Scriptlerin ilk satirinda /cgi-bin/ veriyolunu degistirmeleri gerekir:<br>
-#!/usr/bin/perl -w yerine <br>
-#!C:\perl\bin\perl.exe -w yazilacak<br>
-
-<h4>Kullanim</h4><ul>
-
-<h6>Menü</h6>
-islenecek Veritabanini burada seçeceksiniz.<br>
-Bütün islemler burada beelirlenmis olan Veritabanina uygulanir.
-
-<h6>Ana Sayfa</h6>
-Burada kullandiginiz sistem hakkinda bilgiler bulabilirsiniz, yüklenmis
-sürümler, Veritabanilari vs..<br>
-Veritabni ismine tiklandiginda tablolarin listesine ulasilabilir.
-Kayitsayisi ebat ve son güncelleme bilgilerini burada bulabilirsiniz.
-
-<h6>Ayar Merkezi</h6>
-Sistem ayarlarini burada belirleyebilir, yedeklemeden geri dönüstürebilir veya sifirlayabilirsiniz.
-<ul><br>
-    <li><a name="conf1"></a><strong>Veritabanlari:</strong> Veritabanlari Listesi. Aktiv olan Veritabani <b>kalin</b> yazilmistir. </li>
-    <li><a name="conf2"></a><strong>Tablo ön eki:</strong> Burada belirleyeceginiz filtre tedeklenecek tablolarda uygulanacaktir
-    	 (örnegin: "phpBB_" ile baslayan tablolar). Veritabaninin bütün tablolarini yedeklemek istiyorsanin burasini bos birakiniz.</li>
-    <li><a name="conf3"></a><strong>Sikistirma:</strong> Sikistirmayi burada açabilirsiniz. Sikistirmayi kullanmanizi tavsiye ederiz.</li>
-    <li><a name="conf5"></a><strong>Yedekleme ekli Mail:</strong> Bu Opsyon kullanildiginda, islemin sonunda gönderilecek mail'e yedekleme dosyasi eklenecektir. Sikistirmanin aktiv olmasini öneririz !).</li>
-    <li><a name="conf6"></a><strong>Email-Adresi:</strong> Mailin ulastirilacagi adres.</li>
-    <li><a name="conf7"></a><strong>Email göndericisi:</strong> gönderilecek mailin kimin adina gönderildigi.</li>
-    <li><a name="conf13"></a><strong>FTP-Transferi: </strong>Bu Opsyon kullanildiginda, islem sonunda yedekleme dosyasi FTP ile gönderilir.</li>
-    <li><a name="conf14"></a><strong>FTP Sunucusu: </strong>Die FTP sunucusunun adress (örnegin: ftp.mybackups.de).</li>
-    <li><a name="conf15"></a><strong>FTP Sunucu Portu: </strong>FTP-Sunucusunun Portu (Genelde 21).</li>
-    <li><a name="conf16"></a><strong>FTP Kulanicisi: </strong>FTP-kullanicisinin adi. </li>
-    <li><a name="conf17"></a><strong>FTP sifresi: </strong>FTP-kullanicisinin  sifresi. </li>
-    <li><a name="conf18"></a><strong>FTP yükleme klasörü: </strong>Yedekleme dosyasinin yüklenecegi klasörün adi. (UYARI: CHMOD ayarlarini göz önünde bulundurunuz).</li>
-    <li><a name="conf8"></a><strong>Otomatik dosya silme:</strong> Bu Opsyon kullanildiginda, belirlenecek kurallara göre yedekleme dosyalari silinecektir.</li>
-    <li><a name="conf10"></a><strong>Dosya sayisi:</strong> 0 dan büyük bir deger, bu degeri asan dosya sayisindan fazla olan dosyalari silecektir.</li>
-    <li><a name="conf11"></a><strong>Dil:</strong> MySQL Dumperin kullanacagi dili burada belirlersiniz.</li>
-    <li><a name="conf12"></a><strong>Cronjob zamandilimi:</strong> Saniye olarak belirlenecek deger, Cronjob için geçerli olan süreyi (eger yetkiniz varsa) yükseltmege deger.</li>
-</ul>
-
-<h6>Dosya yönetimi</h6>
-Dosya islemleri burada yapilir
-Yedekleme Klasörünüzde bulunan dosyalar listelenir.<br>
-islemlerin uygulanabilmesi için bir dosyanin seçilmis olmasi gerekiyor.
-<UL>
-    <li><strong>Restore:</strong> Burada veritabani, seçilmis dosya ile dönüstürülür.</li>
-    <li><strong>Delete:</strong> Seçilmis yedekleme dosyalari silinir.</li>
-    <li><strong>Yeni Yedekleme baslat:</strong> Ayarlarda belirlenmis sartlarla yeni bir yedekleme olusturulur.</li>
-</UL>
-
-<h6>Raporlar</h6>
-Burada rapor dosyalarini görebilir veya silebilirsiniz.
-<h6>Künye / Yardim</h6>
-bu Sayfa.
-</ul>
\ No newline at end of file
diff --git a/msd/language/tr/lang.php b/msd/language/tr/lang.php
index b723009c..ab459fd0 100644
--- a/msd/language/tr/lang.php
+++ b/msd/language/tr/lang.php
@@ -1,112 +1,109 @@
 <?php
-$lang['L_YES']="evet";
-$lang['L_TO']="e";
-$lang['L_ACTIVATED']="etkin";
-$lang['L_NOT_ACTIVATED']="etkin değil";
-$lang['L_ERROR']="Hata";
-$lang['L_OF']=" / ";
-$lang['L_ADDED']="eklendi";
-$lang['L_DB']="Veritabanı";
-$lang['L_DBS']="Veritabanları";
-$lang['L_TABLES']="Tablolar";
-$lang['L_TABLE']="Tablo";
-$lang['L_RECORDS']="Kayıtlar";
-$lang['L_COMPRESSED']="Sıkıştırılmış (gz)";
-$lang['L_NOTCOMPRESSED']="normal (sıkıştırılmamış)";
-$lang['L_GENERAL']="Genel";
-$lang['L_COMMENT']="Yorum";
-$lang['L_FILESIZE']="Dosya boyutu";
-$lang['L_ALL']="hepsi";
-$lang['L_NONE']="hiç biri";
-$lang['L_WITH']="ile";
-$lang['L_DIR']="Klasör";
-$lang['L_RECHTE']="Haklar (CHMOD)";
-$lang['L_STATUS']="durum";
-$lang['L_FINISHED']="Tamamlandı";
-$lang['L_FILE']="Dosya";
-$lang['L_FIELDS']="Alanlar";
-$lang['L_NEW']="yeni";
-$lang['L_CHARSET']="Dil Kodlaması";
-$lang['L_COLLATION']="Sıralama";
-$lang['L_CHANGE']="değiştir";
-$lang['L_IN']="de";
-$lang['L_DO']="çalıştır";
-$lang['L_VIEW']="görüntüle";
-$lang['L_EXISTING']="bulunan";
-$lang['L_BACK']="geri";
-$lang['L_DB_HOST']="Veritabanı sunucusunun adı";
-$lang['L_DB_USER']="Veritabanı kullanıcısı";
-$lang['L_DB_PASS']="Veritabanı şifresi";
-$lang['L_INFO_SCRIPTDIR']="MySQLDumper Veriyolu";
-$lang['L_INFO_ACTDB']="Geçerli Veritabanı";
-$lang['L_WRONGCONNECTIONPARS']="Bağlantı parametreleri verilmemiş veya hatalı!";
-$lang['L_CONN_NOT_POSSIBLE']="Bağlantı kurulamıyor";
-$lang['L_SERVERCAPTION']="Sunucuyu göster";
-$lang['L_HELP_SERVERCAPTION']="Çeşitli sunucularda kullanıldığında sunucu adresinin değişik renkli olması faydalı olabilir.";
-$lang['L_ACTIVATE_MULTIDUMP']="Parçalı yedeklemeyi etkinleştir";
-$lang['L_SAVE']="Kaydet";
-$lang['L_RESET']="Sıfırla";
-$lang['L_PRAEFIX']="Tablo ön eki";
-$lang['L_AUTODELETE']="Otomatik yedekleme silinmesi";
-$lang['L_MAX_BACKUP_FILES_EACH2']="Her Veritabanı için";
-$lang['L_SAVING_DB_FORM']="Veritabanı";
-$lang['L_TESTCONNECTION']="Bağlantıyı denetle";
-$lang['L_BACK_TO_MINISQL']="Veritabanını düzenle";
-$lang['L_CREATE']="oluştur";
-$lang['L_VARIABELN']="Değişkenler";
-$lang['L_STATUSINFORMATIONEN']="Durum Bilgisi";
-$lang['L_VERSIONSINFORMATIONEN']="Sürüm Bilgileri";
-$lang['L_MSD_INFO']="MyOOS [Dumper] bilgileri";
-$lang['L_BACKUPFILESANZAHL']="Yedekleme klasöründe bulunan dosyalar:";
-$lang['L_LASTBACKUP']="Son yedekleme";
-$lang['L_NOTAVAIL']="<em>ulaşılamıyor</em>";
-$lang['L_VOM']="den";
-$lang['L_MYSQLVARS']="MySQL Değişkenleri";
-$lang['L_MYSQLSYS']="MySQL komutları";
-$lang['L_STATUS']="Durum";
-$lang['L_PROZESSE']="İşlemler";
-$lang['L_INFO_NOVARS']="Değişkenler bulunmuyor";
-$lang['L_INHALT']="İçerik";
-$lang['L_INFO_NOSTATUS']="durum tespit edilemiyor";
-$lang['L_INFO_NOPROCESSES']="Çalışır işlem yok";
-$lang['L_FM_FREESPACE']="Sunucuda mevcut kullanılabilir hacim";
-$lang['L_LOAD_DATABASE']="Veritabanlarını tekrar yükle";
-$lang['L_HOME']="Anasayfa";
-$lang['L_CONFIG']="Ayar Merkezi";
-$lang['L_DUMP']="Yedekleme";
-$lang['L_RESTORE']="Dönüştürüm";
-$lang['L_FILE_MANAGE']="Yönetim";
-$lang['L_LOG']="Rapor";
-$lang['L_CHOOSE_DB']="Veritabanı seçimi";
-$lang['L_CREDITS']="Künye/Yardım";
-$lang['L_MULTI_PART']="Parçalı yedekleme";
-$lang['L_LOGFILENOTWRITABLE']="Rapor Dosyasına yazılamıyor!";
-$lang['L_SQL_ERROR1']="Sorguda hata oluştu:";
-$lang['L_SQL_ERROR2']="MySQL bildirisi:";
-$lang['L_UNKNOWN']="bilinmeyen";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="bilinmeyen";
-$lang['L_OK']="tamam";
-$lang['L_CRON_COMPLETELOG']="Çıktıları tamamen raporla";
-$lang['L_NO']="hayır";
-$lang['L_CREATE_DATABASE']="Yeni Veritabanı oluştur";
-$lang['L_EXPORTFINISHED']="ihrac tamamlanmıştır";
-$lang['L_SQL_BROWSER']="SQL-Tarayıcısı";
-$lang['L_SERVER']="Sunucu";
-$lang['L_MYSQL_CONNECTION_ENCODING']="MYSQL Sunucunun sabit karakter seti";
-$lang['L_TITLE_SHOW_DATA']="Verileri göster";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Birincil anahtar gerçekten silmek istermisin?";
-$lang['L_SETPRIMARYKEYSFOR']="Tablonun yeni birincil anahtar ayarlar";
-$lang['L_PRIMARYKEY_FIELD']="Anahtar alanı";
-$lang['L_PRIMARYKEYS_SAVE']="Birincil anahtar kaydet";
-$lang['L_CANCEL']="İptal";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Yedeklemeler";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
 
-
-?>
\ No newline at end of file
+$lang['L_YES'] = 'evet';
+$lang['L_TO'] = 'e';
+$lang['L_ACTIVATED'] = 'etkin';
+$lang['L_NOT_ACTIVATED'] = 'etkin değil';
+$lang['L_ERROR'] = 'Hata';
+$lang['L_OF'] = ' / ';
+$lang['L_ADDED'] = 'eklendi';
+$lang['L_DB'] = 'Veritabanı';
+$lang['L_DBS'] = 'Veritabanları';
+$lang['L_TABLES'] = 'Tablolar';
+$lang['L_TABLE'] = 'Tablo';
+$lang['L_RECORDS'] = 'Kayıtlar';
+$lang['L_COMPRESSED'] = 'Sıkıştırılmış (gz)';
+$lang['L_NOTCOMPRESSED'] = 'normal (sıkıştırılmamış)';
+$lang['L_COMMENT'] = 'Yorum';
+$lang['L_FILESIZE'] = 'Dosya boyutu';
+$lang['L_ALL'] = 'hepsi';
+$lang['L_NONE'] = 'hiç biri';
+$lang['L_WITH'] = 'ile';
+$lang['L_DIR'] = 'Klasör';
+$lang['L_RECHTE'] = 'Haklar (CHMOD)';
+$lang['L_STATUS'] = 'durum';
+$lang['L_FINISHED'] = 'Tamamlandı';
+$lang['L_FILE'] = 'Dosya';
+$lang['L_FIELDS'] = 'Alanlar';
+$lang['L_NEW'] = 'yeni';
+$lang['L_CHARSET'] = 'Dil Kodlaması';
+$lang['L_COLLATION'] = 'Sıralama';
+$lang['L_CHANGE'] = 'değiştir';
+$lang['L_IN'] = 'de';
+$lang['L_DO'] = 'çalıştır';
+$lang['L_VIEW'] = 'görüntüle';
+$lang['L_EXISTING'] = 'bulunan';
+$lang['L_BACK'] = 'geri';
+$lang['L_DB_HOST'] = 'Veritabanı sunucusunun adı';
+$lang['L_DB_USER'] = 'Veritabanı kullanıcısı';
+$lang['L_DB_PASS'] = 'Veritabanı şifresi';
+$lang['L_INFO_SCRIPTDIR'] = 'MyOOS [Dumper] Veriyolu';
+$lang['L_INFO_ACTDB'] = 'Geçerli Veritabanı';
+$lang['L_WRONGCONNECTIONPARS'] = 'Bağlantı parametreleri verilmemiş veya hatalı!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Bağlantı kurulamıyor';
+$lang['L_SERVERCAPTION'] = 'Sunucuyu göster';
+$lang['L_HELP_SERVERCAPTION'] = 'Çeşitli sunucularda kullanıldığında sunucu adresinin değişik renkli olması faydalı olabilir.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'Parçalı yedeklemeyi etkinleştir';
+$lang['L_SAVE'] = 'Kaydet';
+$lang['L_RESET'] = 'Sıfırla';
+$lang['L_PRAEFIX'] = 'Tablo ön eki';
+$lang['L_AUTODELETE'] = 'Otomatik yedekleme silinmesi';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'Her Veritabanı için';
+$lang['L_SAVING_DB_FORM'] = 'Veritabanı';
+$lang['L_TESTCONNECTION'] = 'Bağlantıyı denetle';
+$lang['L_BACK_TO_MINISQL'] = 'Veritabanını düzenle';
+$lang['L_CREATE'] = 'oluştur';
+$lang['L_VARIABELN'] = 'Değişkenler';
+$lang['L_STATUSINFORMATIONEN'] = 'Durum Bilgisi';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Sürüm Bilgileri';
+$lang['L_MOD_INFO'] = 'MyOOS [Dumper] bilgileri';
+$lang['L_BACKUPFILESANZAHL'] = 'Yedekleme klasöründe bulunan dosyalar:';
+$lang['L_LASTBACKUP'] = 'Son yedekleme';
+$lang['L_NOTAVAIL'] = '<em>ulaşılamıyor</em>';
+$lang['L_VOM'] = 'den';
+$lang['L_MYSQLVARS'] = 'MySQL Değişkenleri';
+$lang['L_MYSQLSYS'] = 'MySQL komutları';
+$lang['L_STATUS'] = 'Durum';
+$lang['L_PROZESSE'] = 'İşlemler';
+$lang['L_INFO_NOVARS'] = 'Değişkenler bulunmuyor';
+$lang['L_INHALT'] = 'İçerik';
+$lang['L_INFO_NOSTATUS'] = 'durum tespit edilemiyor';
+$lang['L_INFO_NOPROCESSES'] = 'Çalışır işlem yok';
+$lang['L_FM_FREESPACE'] = 'Sunucuda mevcut kullanılabilir hacim';
+$lang['L_LOAD_DATABASE'] = 'Veritabanlarını tekrar yükle';
+$lang['L_HOME'] = 'Anasayfa';
+$lang['L_CONFIG'] = 'Ayar Merkezi';
+$lang['L_DUMP'] = 'Yedekleme';
+$lang['L_RESTORE'] = 'Dönüştürüm';
+$lang['L_FILE_MANAGE'] = 'Yönetim';
+$lang['L_LOG'] = 'Rapor';
+$lang['L_CHOOSE_DB'] = 'Veritabanı seçimi';
+$lang['L_CREDITS'] = 'Künye/Yardım';
+$lang['L_MULTI_PART'] = 'Parçalı yedekleme';
+$lang['L_LOGFILENOTWRITABLE'] = 'Rapor Dosyasına yazılamıyor!';
+$lang['L_SQL_ERROR1'] = 'Sorguda hata oluştu:';
+$lang['L_SQL_ERROR2'] = 'MySQL bildirisi:';
+$lang['L_UNKNOWN'] = 'bilinmeyen';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'bilinmeyen';
+$lang['L_OK'] = 'tamam';
+$lang['L_CRON_COMPLETELOG'] = 'Çıktıları tamamen raporla';
+$lang['L_NO'] = 'hayır';
+$lang['L_CREATE_DATABASE'] = 'Yeni Veritabanı oluştur';
+$lang['L_EXPORTFINISHED'] = 'ihrac tamamlanmıştır';
+$lang['L_SQL_BROWSER'] = 'SQL-Tarayıcısı';
+$lang['L_SERVER'] = 'Sunucu';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'MYSQL Sunucunun sabit karakter seti';
+$lang['L_TITLE_SHOW_DATA'] = 'Verileri göster';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Birincil anahtar gerçekten silmek istermisin?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Tablonun yeni birincil anahtar ayarlar';
+$lang['L_PRIMARYKEY_FIELD'] = 'Anahtar alanı';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Birincil anahtar kaydet';
+$lang['L_CANCEL'] = 'İptal';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Yedeklemeler';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/tr/lang_config_overview.php b/msd/language/tr/lang_config_overview.php
index 120a0919..b1c584c8 100644
--- a/msd/language/tr/lang_config_overview.php
+++ b/msd/language/tr/lang_config_overview.php
@@ -1,110 +1,123 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Ayar Merkezi";
-$lang['L_SAVE_SUCCESS']="Ayarlar başarı ile \"%s\" isimli doyaya kaydedildi";
-$lang['L_CONFIG_LOADED']="Ayarlar \"%s\" başarı ile yüklendi";
-$lang['L_SAVE_ERROR']="Ayarlar kayıt edilemedi!";
-$lang['L_CONFIG_EMAIL']="Email-bildirisi";
-$lang['L_CONFIG_AUTODELETE']="Otomatik silme";
-$lang['L_CONFIG_INTERFACE']="Arayüzü";
-$lang['L_MULTI_PART_GROESSE']="en yüksek dosya boyutu";
-$lang['L_HELP_MULTIPART']="Aktiv parçalı yedeklemede birden fazla dosya oluşturulur, dosyaların büyüklüğü altta bulunan ayarlarla belirlenir.";
-$lang['L_HELP_MULTIPARTGROESSE']="Parçalı yedeklemede oluşturulacak dosyaların büyüklü burada belirlenebilir";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Veritabanını dönüştürmeden sil";
-$lang['L_ALLPARS']="Bütün parametreler";
-$lang['L_CRON_EXTENDER']="Dosya adı uzantısı";
-$lang['L_CRON_SAVEPATH']="Ayar dosyası";
-$lang['L_CRON_PRINTOUT']="Yazı çıktısı";
-$lang['L_CONFIG_CRONPERL']="Perlscript'in Crondump ayarları";
-$lang['L_CRON_MAILPRG']="Mail programı";
-$lang['L_OPTIMIZE']="Tabloları yedeklemeden arındırma";
-$lang['L_HELP_OPTIMIZE']="Aktiv durumda Tablolar yedeklemeden arındırılır";
-$lang['L_HELP_FTPTIMEOUT']="FTP sisteminin kapanmadan önceki hareketsizilik süresi, standart 90 saniyedir.";
-$lang['L_FTP_TIMEOUT']="Bağlantı zaman aşımı";
-$lang['L_HELP_FTPSSL']="Güvenli SSL bağlantısının kullanılmasını belirler";
-$lang['L_CONFIG_ASKLOAD']="Ayarları gerçekten Fabrika Ayarlarına geri getirmek istiyor musun?";
-$lang['L_LOAD']="Fabrika Ayarları yükle";
-$lang['L_LOAD_SUCCESS']="Fabrika Ayarları yüklendi";
-$lang['L_CRON_CRONDBINDEX']="Cron işlemi için veritabanı ve tablo öneki";
-$lang['L_WITHATTACH']="eklentili";
-$lang['L_WITHOUTATTACH']="eklentisiz";
-$lang['L_MULTIDUMPCONF']="=Parçalı yedekleme ayarları=";
-$lang['L_MULTIDUMPALL']="=Bütün veritabanları=";
-$lang['L_GZIP']="GZip-Sıkıştırma";
-$lang['L_SEND_MAIL_FORM']="Email gönder";
-$lang['L_SEND_MAIL_DUMP']="Yedekleme dosyasını ekle";
-$lang['L_EMAIL_ADRESS']="Email-Adresi";
-$lang['L_EMAIL_SENDER']="Mail gönderenin adı";
-$lang['L_EMAIL_MAXSIZE']="Eklenen dosyanın en yüksek boyutu";
-$lang['L_NUMBER_OF_FILES_FORM']="Yedek dosyaların sayısı";
-$lang['L_LANGUAGE']="Dil";
-$lang['L_LIST_DB']="Ayarlanmış veritabanları:";
-$lang['L_CONFIG_FTP']="Yedekleme dosyasının FTP Transferi";
-$lang['L_FTP_TRANSFER']="FTP-Transferi";
-$lang['L_FTP_SERVER']="Sunucu";
-$lang['L_FTP_PORT']="Port";
-$lang['L_FTP_USER']="Kullanıcı";
-$lang['L_FTP_PASS']="Şifre";
-$lang['L_FTP_DIR']="klasör";
-$lang['L_FTP_SSL']="Güvenli SSL-FTP-Bağlantısı";
-$lang['L_FTP_USESSL']="Güvenli SSL-bağlantısı kullan";
-$lang['L_SQLBOXHEIGHT']="SQL-kutusunun yüksekliği";
-$lang['L_SQLLIMIT']="Sayfa başı gösterilecek kayıt sayısı";
-$lang['L_BBPARAMS']="BB-Code ayarları";
-$lang['L_BBTEXTCOLOR']="Yazı rengi";
-$lang['L_HELP_COMMANDS']="Yedeklemeden önce ve sonra komutlar uygulanabilir. Bunlar SQL komutları veya sistem komutları olabilir (örneğin scriptler).";
-$lang['L_COMMAND']="Komut";
-$lang['L_WRONG_CONNECTIONPARS']="Bağlantı parametrelerinde sorun var!";
-$lang['L_CONNECTIONPARS']="Bağlantı parametreleri";
-$lang['L_EXTENDEDPARS']="Gelişmiş parametreler";
-$lang['L_FADE_IN_OUT']="göster /gizle";
-$lang['L_DB_BACKUPPARS']="Veritabanları yedekleme ayarları";
-$lang['L_GENERAL']="Genel";
-$lang['L_MAXSIZE']="en yüksek boyut";
-$lang['L_ERRORHANDLING_RESTORE']="Dönüşümde oluşan hataların nasıl işleneceği";
-$lang['L_EHRESTORE_CONTINUE']="devam et ve hatasları raporuna ekle";
-$lang['L_EHRESTORE_STOP']="Durdur";
-$lang['L_IN_MAINFRAME']="Ana ekranda";
-$lang['L_IN_LEFTFRAME']="Sol ekranda";
-$lang['L_WIDTH']="Genişlik";
-$lang['L_SQL_BEFEHLE']="SQL Komutları";
-$lang['L_DOWNLOAD_LANGUAGES']="Başka dil indir";
-$lang['L_DOWNLOAD_STYLES']="Başka tema indir";
-$lang['L_CONNECT_TO']="Bağlanacak:";
-$lang['L_CHANGEDIR']="Gidilecek klasör: ";
-$lang['L_CHANGEDIRERROR']="Klasör değiştirilemedi!";
-$lang['L_FTP_OK']="Bağlantı başarılı olarak kuruldu.";
-$lang['L_INSTALL']="Yükleme";
-$lang['L_NOFTPPOSSIBLE']="FTP komutları mevcut değil!";
-$lang['L_FOUND_DB']="bulunan veritabanları:";
-$lang['L_FTP_CHOOSE_MODE']="FTP-gönderim şekli";
-$lang['L_FTP_PASSIVE']="passiv bağlantı kullan ";
-$lang['L_HELP_FTP_MODE']="FTP bağlantısını belirler. Aktiv bağlantıda sorun oluşursa, pasiv bağlantı kullanmalısınız.";
-$lang['L_DB_IN_LIST']="'%s' Veritabanı eklenemedi, cünkü mevcut.";
-$lang['L_ADD_DB_MANUALLY']="Veritabanını elden ekle";
-$lang['L_DB_MANUAL_ERROR']="'%s' veritabanına bağlantı kurulamadı";
-$lang['L_DB_MANUAL_FILE_ERROR']="Dosya hatası: '%s' veritabanı kayıt edilemedi.";
-$lang['L_NO_DB_FOUND']="Veritabanı bulunamadı.
-Bağlantı parametrelerini açarak veritabanının adını elden giriniz!";
-$lang['L_CONFIGFILES']="Ayar dosyaları";
-$lang['L_CONFIGFILE']="Ayar dosyası";
-$lang['L_MYSQL_DATA']="MySQL Verileri";
-$lang['L_CONFIGURATIONS']="Ayarlar";
-$lang['L_ACTION']="İşlem";
-$lang['L_FTP_SEND_TO']="adress <strong>%s</strong><br>klasör <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="CC-Alıcı";
-$lang['L_NAME']="İsim";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Ayar dosyası %s gerçekten silinsin mi ?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Hata oluştu: Ayar dosyası %s silinemedi";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="Ayar dosyası %s başarıyla silindi.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="%s isimli ayar dosyası başarı ile oluşturuldu";
-$lang['L_ERROR_CONFIGFILE_NAME']="Dosya ismi \"%s\" izin verilmeyen karakter içeriyor";
-$lang['L_CREATE_CONFIGFILE']="Yeni ayar dosyası oluştur";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Ayar dosyası \"%s\" yüklenemedi";
-$lang['L_BACKUP_DBS_PHP']="yedeklenecek veritabanları (PHP)";
-$lang['L_BACKUP_DBS_PERL']="yedeklenecek veritabanları (PERL)";
-$lang['L_CRON_COMMENT']="Not ekle";
-$lang['L_AUTODETECT']="otomatik bul";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Ayar Merkezi';
+$lang['L_SAVE_SUCCESS'] = 'Ayarlar başarı ile "%s" isimli doyaya kaydedildi';
+$lang['L_CONFIG_LOADED'] = 'Ayarlar "%s" başarı ile yüklendi';
+$lang['L_SAVE_ERROR'] = 'Ayarlar kayıt edilemedi!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Email-bildirisi';
+$lang['L_CONFIG_AUTODELETE'] = 'Otomatik silme';
+$lang['L_CONFIG_INTERFACE'] = 'Arayüzü';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'en yüksek dosya boyutu';
+$lang['L_HELP_MULTIPART'] = 'Aktiv parçalı yedeklemede birden fazla dosya oluşturulur, dosyaların büyüklüğü altta bulunan ayarlarla belirlenir.';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Parçalı yedeklemede oluşturulacak dosyaların büyüklü burada belirlenebilir';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Veritabanını dönüştürmeden sil';
+$lang['L_ALLPARS'] = 'Bütün parametreler';
+$lang['L_CRON_EXTENDER'] = 'Dosya adı uzantısı';
+$lang['L_CRON_SAVEPATH'] = 'Ayar dosyası';
+$lang['L_CRON_PRINTOUT'] = 'Yazı çıktısı';
+$lang['L_CONFIG_CRONPERL'] = "Perlscript'in Crondump ayarları";
+$lang['L_CRON_MAILPRG'] = 'Mail programı';
+$lang['L_OPTIMIZE'] = 'Tabloları yedeklemeden arındırma';
+$lang['L_HELP_OPTIMIZE'] = 'Aktiv durumda Tablolar yedeklemeden arındırılır';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'FTP sisteminin kapanmadan önceki hareketsizilik süresi, standart 90 saniyedir.';
+$lang['L_FTP_TIMEOUT'] = 'Bağlantı zaman aşımı';
+$lang['L_HELP_FTPSSL'] = 'Güvenli SSL bağlantısının kullanılmasını belirler';
+$lang['L_SFTP_TIMEOUT'] = 'Bağlantı zaman aşımı';
+$lang['L_HELP_SFTPSSL'] = 'Güvenli SSL bağlantısının kullanılmasını belirler';
+$lang['L_CONFIG_ASKLOAD'] = 'Ayarları gerçekten Fabrika Ayarlarına geri getirmek istiyor musun?';
+$lang['L_LOAD'] = 'Fabrika Ayarları yükle';
+$lang['L_LOAD_SUCCESS'] = 'Fabrika Ayarları yüklendi';
+$lang['L_CRON_CRONDBINDEX'] = 'Cron işlemi için veritabanı ve tablo öneki';
+$lang['L_WITHATTACH'] = 'eklentili';
+$lang['L_WITHOUTATTACH'] = 'eklentisiz';
+$lang['L_MULTIDUMPCONF'] = '=Parçalı yedekleme ayarları=';
+$lang['L_MULTIDUMPALL'] = '=Bütün veritabanları=';
+$lang['L_GZIP'] = 'GZip-Sıkıştırma';
+$lang['L_SEND_MAIL_FORM'] = 'Email gönder';
+$lang['L_SEND_MAIL_DUMP'] = 'Yedekleme dosyasını ekle';
+$lang['L_EMAIL_ADRESS'] = 'Email-Adresi';
+$lang['L_EMAIL_SENDER'] = 'Mail gönderenin adı';
+$lang['L_EMAIL_MAXSIZE'] = 'Eklenen dosyanın en yüksek boyutu';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Yedek dosyaların sayısı';
+$lang['L_LANGUAGE'] = 'Dil';
+$lang['L_LIST_DB'] = 'Ayarlanmış veritabanları:';
+$lang['L_CONFIG_FTP'] = 'Yedekleme dosyasının FTP Transferi';
+$lang['L_FTP_TRANSFER'] = 'FTP-Transferi';
+$lang['L_FTP_SERVER'] = 'Sunucu';
+$lang['L_FTP_PORT'] = 'Port';
+$lang['L_FTP_USER'] = 'Kullanıcı';
+$lang['L_FTP_PASS'] = 'Şifre';
+$lang['L_FTP_DIR'] = 'klasör';
+$lang['L_FTP_SSL'] = 'Güvenli SSL-FTP-Bağlantısı';
+$lang['L_FTP_USESSL'] = 'Güvenli SSL-bağlantısı kullan';
+$lang['L_CONFIG_SFTP'] = 'Yedekleme dosyasının SFTP Transferi';
+$lang['L_SFTP_TRANSFER'] = 'SFTP-Transferi';
+$lang['L_SFTP_SERVER'] = 'Sunucu';
+$lang['L_SFTP_PORT'] = 'Port';
+$lang['L_SFTP_USER'] = 'Kullanıcı';
+$lang['L_SFTP_PASS'] = 'Şifre';
+$lang['L_SFTP_DIR'] = 'klasör';
+$lang['L_SQLBOXHEIGHT'] = 'SQL-kutusunun yüksekliği';
+$lang['L_SQLLIMIT'] = 'Sayfa başı gösterilecek kayıt sayısı';
+$lang['L_BBPARAMS'] = 'BB-Code ayarları';
+$lang['L_BBTEXTCOLOR'] = 'Yazı rengi';
+$lang['L_HELP_COMMANDS'] = 'Yedeklemeden önce ve sonra komutlar uygulanabilir. Bunlar SQL komutları veya sistem komutları olabilir (örneğin scriptler).';
+$lang['L_COMMAND'] = 'Komut';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Bağlantı parametrelerinde sorun var!';
+$lang['L_CONNECTIONPARS'] = 'Bağlantı parametreleri';
+$lang['L_EXTENDEDPARS'] = 'Gelişmiş parametreler';
+$lang['L_FADE_IN_OUT'] = 'göster /gizle';
+$lang['L_DB_BACKUPPARS'] = 'Veritabanları yedekleme ayarları';
+$lang['L_GENERAL'] = 'Genel';
+$lang['L_MAXSIZE'] = 'en yüksek boyut';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Dönüşümde oluşan hataların nasıl işleneceği';
+$lang['L_EHRESTORE_CONTINUE'] = 'devam et ve hatasları raporuna ekle';
+$lang['L_EHRESTORE_STOP'] = 'Durdur';
+$lang['L_IN_MAINFRAME'] = 'Ana ekranda';
+$lang['L_IN_LEFTFRAME'] = 'Sol ekranda';
+$lang['L_WIDTH'] = 'Genişlik';
+$lang['L_SQL_BEFEHLE'] = 'SQL Komutları';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'Başka dil indir';
+$lang['L_DOWNLOAD_STYLES'] = 'Başka tema indir';
+$lang['L_CONNECT_TO'] = 'Bağlanacak:';
+$lang['L_CHANGEDIR'] = 'Gidilecek klasör: ';
+$lang['L_CHANGEDIRERROR'] = 'Klasör değiştirilemedi!';
+$lang['L_FTP_OK'] = 'Bağlantı başarılı olarak kuruldu.';
+$lang['L_INSTALL'] = 'Yükleme';
+$lang['L_NOFTPPOSSIBLE'] = 'FTP komutları mevcut değil!';
+$lang['L_FOUND_DB'] = 'bulunan veritabanları:';
+$lang['L_FTP_CHOOSE_MODE'] = 'FTP-gönderim şekli';
+$lang['L_FTP_PASSIVE'] = 'passiv bağlantı kullan ';
+$lang['L_HELP_FTP_MODE'] = 'FTP bağlantısını belirler. Aktiv bağlantıda sorun oluşursa, pasiv bağlantı kullanmalısınız.';
+$lang['L_SFTP_PASSIVE'] = 'passiv bağlantı kullan ';
+$lang['L_DB_IN_LIST'] = "'%s' Veritabanı eklenemedi, cünkü mevcut.";
+$lang['L_ADD_DB_MANUALLY'] = 'Veritabanını elden ekle';
+$lang['L_DB_MANUAL_ERROR'] = "'%s' veritabanına bağlantı kurulamadı";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Dosya hatası: '%s' veritabanı kayıt edilemedi.";
+$lang['L_NO_DB_FOUND'] = 'Veritabanı bulunamadı.
+Bağlantı parametrelerini açarak veritabanının adını elden giriniz!';
+$lang['L_CONFIGFILES'] = 'Ayar dosyaları';
+$lang['L_CONFIGFILE'] = 'Ayar dosyası';
+$lang['L_MYSQL_DATA'] = 'MySQL Verileri';
+$lang['L_CONFIGURATIONS'] = 'Ayarlar';
+$lang['L_ACTION'] = 'İşlem';
+$lang['L_FTP_SEND_TO'] = 'adress <strong>%s</strong><br>klasör <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'CC-Alıcı';
+$lang['L_NAME'] = 'İsim';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Ayar dosyası %s gerçekten silinsin mi ?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Hata oluştu: Ayar dosyası %s silinemedi';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'Ayar dosyası %s başarıyla silindi.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = '%s isimli ayar dosyası başarı ile oluşturuldu';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Dosya ismi "%s" izin verilmeyen karakter içeriyor';
+$lang['L_CREATE_CONFIGFILE'] = 'Yeni ayar dosyası oluştur';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Ayar dosyası "%s" yüklenemedi';
+$lang['L_BACKUP_DBS_PHP'] = 'yedeklenecek veritabanları (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'yedeklenecek veritabanları (PERL)';
+$lang['L_CRON_COMMENT'] = 'Not ekle';
+$lang['L_AUTODETECT'] = 'otomatik bul';
diff --git a/msd/language/tr/lang_dump.php b/msd/language/tr/lang_dump.php
index d8169f66..300d334a 100644
--- a/msd/language/tr/lang_dump.php
+++ b/msd/language/tr/lang_dump.php
@@ -1,56 +1,57 @@
 <?php
-$lang['L_DUMP_HEADLINE']="yedekleme oluşturuluyor...";
-$lang['L_GZIP_COMPRESSION']="GZip-sıkıştırma ";
-$lang['L_SAVING_TABLE']="Tablo kaytediliyor ";
-$lang['L_OF']="tarihinde";
-$lang['L_ACTUAL_TABLE']="Geçerli tablo";
-$lang['L_PROGRESS_TABLE']="Tablo işlem durumu";
-$lang['L_PROGRESS_OVER_ALL']="Genel işlem durumu";
-$lang['L_ENTRY']="Kayıt";
-$lang['L_DONE']="Tamamlandı!";
-$lang['L_DUMP_SUCCESSFUL']=" Başarıyla tamamlandı.";
-$lang['L_UPTO']="kadar";
-$lang['L_EMAIL_WAS_SEND']="Email başarıyla gönderildi. Alıcı:";
-$lang['L_BACK_TO_CONTROL']="Devam";
-$lang['L_BACK_TO_OVERVIEW']="Veritabanı listesi";
-$lang['L_DUMP_FILENAME']="Yedeklenen dosyanın ismi: ";
-$lang['L_WITHPRAEFIX']="Önekli";
-$lang['L_DUMP_NOTABLES']="`<b>%s</b>` Veritabanında tablo bulunamadı.";
-$lang['L_DUMP_ENDERGEBNIS']=" <b>%s</b> tabloda <b>%s</b> kayıt yedeklendi.<br>";
-$lang['L_MAILERROR']="Mail gönderiminde hata oluştu!";
-$lang['L_EMAILBODY_ATTACH']="Ekte veritabanıyın yedeklemesi bulunuyor.<br>yedeklenen Veritabanı `%s`
-<br><br>Oluşturulan dosya:<br><br>%s <br><br>Sevgilerler<br><br>MySQLDumper<br><a href=\"http://www.mysqldumper.de/\">www.mysqldumper.de</a>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Çok parçalı yedekleme oluşturuldu.<br> Dosyalar eklenti olarak gönderilmiyor!<br>yedeklenen Veritabanı `%s`
-<br><br>oluşturulan dosyalar:<br><br>%s<br><br><br>Sevgilerle<br><br>MySQLDumper<br><a href=\"http://www.mysqldumper.de/\">www.mysqldumper.de</a>";
-$lang['L_EMAILBODY_MP_ATTACH']="Çok parçalı yedekleme oluşturuldu.<br>Dosyalar eklenti olarak gönderilmiyor!Dosyalar ayrı bir mail ile gönderiliyor!<br>Yedeklenen Veritabanı `%s`
-<br><br>oluşturulan dosyalar:<br><br>%s<br><br><br>Sevgilerle<br><br>MySQLDumper<br><a href=\"http://www.mysqldumper.de/\">www.mysqldumper.de</a>";
-$lang['L_EMAILBODY_FOOTER']="<br><br><br>Sevgiler<br><br>MySQLDumper<br><a href=\"http://www.mysqldumper.de/\">www.mysqldumper.de</a>";
-$lang['L_EMAILBODY_TOOBIG']="Yedekleme boyutu maximumu boyut olan %s aştıgından dolayı eklenti olarak gönderilemiyor.<br>Yedeklenen Veritabanı `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'yedekleme oluşturuluyor...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'GZip-sıkıştırma ';
+$lang['L_SAVING_TABLE'] = 'Tablo kaytediliyor ';
+$lang['L_OF'] = 'tarihinde';
+$lang['L_ACTUAL_TABLE'] = 'Geçerli tablo';
+$lang['L_PROGRESS_TABLE'] = 'Tablo işlem durumu';
+$lang['L_PROGRESS_OVER_ALL'] = 'Genel işlem durumu';
+$lang['L_ENTRY'] = 'Kayıt';
+$lang['L_DONE'] = 'Tamamlandı!';
+$lang['L_DUMP_SUCCESSFUL'] = ' Başarıyla tamamlandı.';
+$lang['L_UPTO'] = 'kadar';
+$lang['L_EMAIL_WAS_SEND'] = 'Email başarıyla gönderildi. Alıcı:';
+$lang['L_BACK_TO_CONTROL'] = 'Devam';
+$lang['L_BACK_TO_OVERVIEW'] = 'Veritabanı listesi';
+$lang['L_DUMP_FILENAME'] = 'Yedeklenen dosyanın ismi: ';
+$lang['L_WITHPRAEFIX'] = 'Önekli';
+$lang['L_DUMP_NOTABLES'] = '`<b>%s</b>` Veritabanında tablo bulunamadı.';
+$lang['L_DUMP_ENDERGEBNIS'] = ' <b>%s</b> tabloda <b>%s</b> kayıt yedeklendi.<br>';
+$lang['L_MAILERROR'] = 'Mail gönderiminde hata oluştu!';
+$lang['L_EMAILBODY_ATTACH'] = 'Ekte veritabanıyın yedeklemesi bulunuyor.<br>yedeklenen Veritabanı `%s`
+<br><br>Oluşturulan dosya:<br><br>%s <br><br>Sevgilerler<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Çok parçalı yedekleme oluşturuldu.<br> Dosyalar eklenti olarak gönderilmiyor!<br>yedeklenen Veritabanı `%s`
+<br><br>oluşturulan dosyalar:<br><br>%s<br><br><br>Sevgilerle<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Çok parçalı yedekleme oluşturuldu.<br>Dosyalar eklenti olarak gönderilmiyor!Dosyalar ayrı bir mail ile gönderiliyor!<br>Yedeklenen Veritabanı `%s`
+<br><br>oluşturulan dosyalar:<br><br>%s<br><br><br>Sevgilerle<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '<br><br><br>Sevgiler<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Yedekleme boyutu maximumu boyut olan %s aştıgından dolayı eklenti olarak gönderilemiyor.<br>Yedeklenen Veritabanı `%s`
 <br><br>oluşturulan dosyalar:<br><br>%s
-<br><br>Saygılarla<br><br>MySQLDumper<br><a href=\"http://www.mysqldumper.de/\">www.mysqldumper.de</a>";
-$lang['L_EMAILBODY_NOATTACH']="Yedekleme dosyaları maalesef eklenememiştir.<br>yedeklenen Veritabanı `%s`
+<br><br>Saygılarla<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Yedekleme dosyaları maalesef eklenememiştir.<br>yedeklenen Veritabanı `%s`
 <br><br>Oluşturulan Dosyalar:<br><br>%s
-<br><br>Sevgilerle<br><br>MySQLDumper<br><a href=\"http://www.mysqldumper.de/\">www.mysqldumper.de</a>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... sadece eklentiler";
-$lang['L_TABLESELECTION']="Tablo seçimi";
-$lang['L_SELECTALL']="hepsini seç";
-$lang['L_DESELECTALL']="hepsini kaldır";
-$lang['L_STARTDUMP']="Yedeklemeyi başlat";
-$lang['L_LASTBUFROM']="son yedekleme tarihi";
-$lang['L_NOT_SUPPORTED']="Bu yedekleme istenilen fonksiyonu desteklemiyor.";
-$lang['L_MULTIDUMP']="Parçalı yedekleme:<b>%d</b> Veritabanları yedeklendi.";
-$lang['L_FILESENDFTP']="Dosya FTP ile gönderiliyor... lütfen biraz bekleyiniz. ";
-$lang['L_FTPCONNERROR']="FTP-Bağlantısı kurulmadı! Bağlantı  ";
-$lang['L_FTPCONNERROR1']=" Kullanıcı";
-$lang['L_FTPCONNERROR2']=" mümkün değil";
-$lang['L_FTPCONNERROR3']="FTP-Yüklemesi başarısız! ";
-$lang['L_FTPCONNECTED1']="Kullanılan bağlantı";
-$lang['L_FTPCONNECTED2']=" ile ";
-$lang['L_FTPCONNECTED3']=" kayıt edilen";
-$lang['L_NR_TABLES_SELECTED']="-  %s seçilmiş tablolar";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s Tablo arındırıldı.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">Hata %s oluştu: <a href=\"log.php?r=3\">göster</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Hata oluştu: CREATE komutu '%s'tablosu '%s' veritabanında okunamadı<br>Tabloları onarmanızı öneriyoruz.";
-
-
-?>
\ No newline at end of file
+<br><br>Sevgilerle<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... sadece eklentiler';
+$lang['L_TABLESELECTION'] = 'Tablo seçimi';
+$lang['L_SELECTALL'] = 'hepsini seç';
+$lang['L_DESELECTALL'] = 'hepsini kaldır';
+$lang['L_STARTDUMP'] = 'Yedeklemeyi başlat';
+$lang['L_LASTBUFROM'] = 'son yedekleme tarihi';
+$lang['L_NOT_SUPPORTED'] = 'Bu yedekleme istenilen fonksiyonu desteklemiyor.';
+$lang['L_MULTIDUMP'] = 'Parçalı yedekleme:<b>%d</b> Veritabanları yedeklendi.';
+$lang['L_FILESENDFTP'] = 'Dosya FTP ile gönderiliyor... lütfen biraz bekleyiniz. ';
+$lang['L_FTPCONNERROR'] = 'FTP-Bağlantısı kurulmadı! Bağlantı  ';
+$lang['L_FTPCONNERROR1'] = ' Kullanıcı';
+$lang['L_FTPCONNERROR2'] = ' mümkün değil';
+$lang['L_FTPCONNERROR3'] = 'FTP-Yüklemesi başarısız! ';
+$lang['L_FTPCONNECTED1'] = 'Kullanılan bağlantı';
+$lang['L_FTPCONNECTED2'] = ' ile ';
+$lang['L_FTPCONNECTED3'] = ' kayıt edilen';
+$lang['L_FILESENDSFTP'] = 'Dosya SFTP ile gönderiliyor... lütfen biraz bekleyiniz. ';
+$lang['L_SFTPCONNERROR'] = 'SFTP-Bağlantısı kurulmadı! Bağlantı  ';
+$lang['L_NR_TABLES_SELECTED'] = '-  %s seçilmiş tablolar';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s Tablo arındırıldı.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">Hata %s oluştu: <a href="log.php?r=3">göster</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Hata oluştu: CREATE komutu '%s'tablosu '%s' veritabanında okunamadı<br>Tabloları onarmanızı öneriyoruz.";
diff --git a/msd/language/tr/lang_filemanagement.php b/msd/language/tr/lang_filemanagement.php
index fe9fbeda..2d1fe06a 100644
--- a/msd/language/tr/lang_filemanagement.php
+++ b/msd/language/tr/lang_filemanagement.php
@@ -1,76 +1,76 @@
 <?php
-$lang['L_CONVERT_START']="Çeviriyi başlat";
-$lang['L_CONVERT_TITLE']="MSD-Formatına çevir";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Yanlış Parametre! Çeviri mümkün değil.";
-$lang['L_FM_UPLOADFILEREQUEST']="Dosya adını giriniz.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Bu dosya tipi geçerli değil.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Geçerli dosya tipleri: *.gz und *.sql-Dosyaları";
-$lang['L_FM_UPLOADMOVEERROR']="Yüklenen dosya yerine sürülemedi.";
-$lang['L_FM_UPLOADFAILED']="Yükleme yapılamadı!";
-$lang['L_FM_UPLOADFILEEXISTS']="Bu isimde bir dosya zaten bulunmakta!";
-$lang['L_FM_NOFILE']="Dosya seçmediniz!";
-$lang['L_FM_DELETE1']="Dosya ";
-$lang['L_FM_DELETE2']=" silindi.";
-$lang['L_FM_DELETE3']=" silinemedi!";
-$lang['L_FM_CHOOSE_FILE']="Seçilmiş dosya:";
-$lang['L_FM_FILESIZE']="Dosya boyutu";
-$lang['L_FM_FILEDATE']="Tarih";
-$lang['L_FM_NOFILESFOUND']="Dosya bulunamadı.";
-$lang['L_FM_TABLES']="Tablolar";
-$lang['L_FM_RECORDS']="Kayıtlar";
-$lang['L_FM_ALL_BU']="Tüm yedeklemeler";
-$lang['L_FM_ANZ_BU']="Yedeklemeler";
-$lang['L_FM_LAST_BU']="Son yedekleme";
-$lang['L_FM_TOTALSIZE']="Toplam boyut";
-$lang['L_FM_SELECTTABLES']="Tablo seçimi";
-$lang['L_FM_COMMENT']="Not ekle";
-$lang['L_FM_RESTORE']="Dönüştür";
-$lang['L_FM_ALERTRESTORE1']="Veritabanı";
-$lang['L_FM_ALERTRESTORE2']="Dosyanın içeriği ile";
-$lang['L_FM_ALERTRESTORE3']="dönüştürülsünmü?";
-$lang['L_FM_DELETE']="Seçilen dosyaları sil";
-$lang['L_FM_ASKDELETE1']="Seçilen dosya ";
-$lang['L_FM_ASKDELETE2']="gerçekten silinsinmi?";
-$lang['L_FM_ASKDELETE3']="Otomatik dosya silinmesi belirlenmiş ayarlara göre şimdi uygulansınmı?";
-$lang['L_FM_ASKDELETE4']="Tüm yedeklemeleri şimdi silmek istiyormusun?";
-$lang['L_FM_ASKDELETE5']="tüm yedeklemeleri (... ile)";
-$lang['L_FM_ASKDELETE5_2']="_* özelliğine sahip tüm yedeklemeler silinsinmi?";
-$lang['L_FM_DELETEAUTO']="Otomatik Dosya Silinmesi";
-$lang['L_FM_DELETEALL']="Hepsini sil ";
-$lang['L_FM_DELETEALLFILTER']="Sil: ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Yeni yedeklemeyi başlat";
-$lang['L_FM_FILEUPLOAD']="Dosya yükle";
-$lang['L_FM_DBNAME']="Veritabanının ismi";
-$lang['L_FM_FILES1']="Veritabanı yedeklemeleri";
-$lang['L_FM_FILES2']="Veritabanı-yapısı";
-$lang['L_FM_AUTODEL1']="Otomatik temizleme: Maximim dosya sayısı aştığı için silinen dosyalar:";
-$lang['L_DELETE_FILE_SUCCESS']="Dosya \"%s\" başarıyla silindi.";
-$lang['L_FM_DUMPSETTINGS']="Yedekleme ayarları";
-$lang['L_FM_OLDBACKUP']="(bilinmiyor)";
-$lang['L_FM_RESTORE_HEADER']="Veritabanı \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Dosya \"%s\" silinemedi!";
-$lang['L_FM_DUMP_HEADER']="Yedekleme";
-$lang['L_DOCRONBUTTON']="Perl-Cronscript'i çalıştır";
-$lang['L_DOPERLTEST']="Perl-Modülerini denetle";
-$lang['L_DOSIMPLETEST']="Perli denetle";
-$lang['L_PERLOUTPUT1']="crondump.pl de kayıtlı adres absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="Tarayıcı veya dışarıdan çağrışım ile çalışan Cronjob";
-$lang['L_PERLOUTPUT3']="Shell den veya Crontab dan çalışması için";
-$lang['L_RESTORE_OF_TABLES']="belirli tabloları geri dönüştürme";
-$lang['L_CONVERTER']="Yedekleme dönüştürücüsü";
-$lang['L_CONVERT_FILE']="dönüştürülecek dosya";
-$lang['L_CONVERT_FILENAME']="Yeni dosya adı (uzantısız)";
-$lang['L_CONVERTING']="Dönüştürüm";
-$lang['L_CONVERT_FILEREAD']="Dosya '%s' okunuyor";
-$lang['L_CONVERT_FINISHED']="Dönüştürme tamamlandı, '%s' oluşturuldu.";
-$lang['L_NO_MSD_BACKUPFILE']="Başka yazılımların dosyaları:";
-$lang['L_MAX_UPLOAD_SIZE']="Maksimum dosya boyutu";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Eğer Yedek dosyanız izin verilen boyuttan büyük ise, o zaman FTP ile \"work/backup\"-Klasörüne yüklemeniz lazım.
-Daha sonra bu dosya Yönetim bölümünde gözüküp geri yükleme işlemi için kullanılabilir duruma gelicektir.";
-$lang['L_ENCODING']="kodlama";
-$lang['L_FM_CHOOSE_ENCODING']="alınacak yedeğin karakter setini seçin";
-$lang['L_CHOOSE_CHARSET']="Maalesef veritabanı yedeğinin hangi karakter seti ile kodlandığını otomatik olarak bulunmadı<br>Hangi karakter setini kullandıysanız onu seçip elle vermeniz gerekiyor.Daha sonra MYSQLDumper veritabanı serveri ile irtibata gecip yedeği yüklemeye başlıyacaktır.<br>Eğer yedek yüklendikten sonra karakter sorunu devam ediyorsa başka bir karakter seti seçip tekrar denemeniz gerekiyor.<br> Bol şans ;)";
-$lang['L_DOWNLOAD_FILE']="Dosya indir";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+
+$lang['L_CONVERT_START'] = 'Çeviriyi başlat';
+$lang['L_CONVERT_TITLE'] = 'MOD-Formatına çevir';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Yanlış Parametre! Çeviri mümkün değil.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Dosya adını giriniz.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Bu dosya tipi geçerli değil.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Geçerli dosya tipleri: *.gz und *.sql-Dosyaları';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Yüklenen dosya yerine sürülemedi.';
+$lang['L_FM_UPLOADFAILED'] = 'Yükleme yapılamadı!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Bu isimde bir dosya zaten bulunmakta!';
+$lang['L_FM_NOFILE'] = 'Dosya seçmediniz!';
+$lang['L_FM_DELETE1'] = 'Dosya ';
+$lang['L_FM_DELETE2'] = ' silindi.';
+$lang['L_FM_DELETE3'] = ' silinemedi!';
+$lang['L_FM_CHOOSE_FILE'] = 'Seçilmiş dosya:';
+$lang['L_FM_FILESIZE'] = 'Dosya boyutu';
+$lang['L_FM_FILEDATE'] = 'Tarih';
+$lang['L_FM_NOFILESFOUND'] = 'Dosya bulunamadı.';
+$lang['L_FM_TABLES'] = 'Tablolar';
+$lang['L_FM_RECORDS'] = 'Kayıtlar';
+$lang['L_FM_ALL_BU'] = 'Tüm yedeklemeler';
+$lang['L_FM_ANZ_BU'] = 'Yedeklemeler';
+$lang['L_FM_LAST_BU'] = 'Son yedekleme';
+$lang['L_FM_TOTALSIZE'] = 'Toplam boyut';
+$lang['L_FM_SELECTTABLES'] = 'Tablo seçimi';
+$lang['L_FM_COMMENT'] = 'Not ekle';
+$lang['L_FM_RESTORE'] = 'Dönüştür';
+$lang['L_FM_ALERTRESTORE1'] = 'Veritabanı';
+$lang['L_FM_ALERTRESTORE2'] = 'Dosyanın içeriği ile';
+$lang['L_FM_ALERTRESTORE3'] = 'dönüştürülsünmü?';
+$lang['L_FM_DELETE'] = 'Seçilen dosyaları sil';
+$lang['L_FM_ASKDELETE1'] = 'Seçilen dosya ';
+$lang['L_FM_ASKDELETE2'] = 'gerçekten silinsinmi?';
+$lang['L_FM_ASKDELETE3'] = 'Otomatik dosya silinmesi belirlenmiş ayarlara göre şimdi uygulansınmı?';
+$lang['L_FM_ASKDELETE4'] = 'Tüm yedeklemeleri şimdi silmek istiyormusun?';
+$lang['L_FM_ASKDELETE5'] = 'tüm yedeklemeleri (... ile)';
+$lang['L_FM_ASKDELETE5_2'] = '_* özelliğine sahip tüm yedeklemeler silinsinmi?';
+$lang['L_FM_DELETEAUTO'] = 'Otomatik Dosya Silinmesi';
+$lang['L_FM_DELETEALL'] = 'Hepsini sil ';
+$lang['L_FM_DELETEALLFILTER'] = 'Sil: ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Yeni yedeklemeyi başlat';
+$lang['L_FM_FILEUPLOAD'] = 'Dosya yükle';
+$lang['L_FM_DBNAME'] = 'Veritabanının ismi';
+$lang['L_FM_FILES1'] = 'Veritabanı yedeklemeleri';
+$lang['L_FM_FILES2'] = 'Veritabanı-yapısı';
+$lang['L_FM_AUTODEL1'] = 'Otomatik temizleme: Maximim dosya sayısı aştığı için silinen dosyalar:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'Dosya "%s" başarıyla silindi.';
+$lang['L_FM_DUMPSETTINGS'] = 'Yedekleme ayarları';
+$lang['L_FM_OLDBACKUP'] = '(bilinmiyor)';
+$lang['L_FM_RESTORE_HEADER'] = 'Veritabanı "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Dosya "%s" silinemedi!';
+$lang['L_FM_DUMP_HEADER'] = 'Yedekleme';
+$lang['L_DOCRONBUTTON'] = "Perl-Cronscript'i çalıştır";
+$lang['L_DOPERLTEST'] = 'Perl-Modülerini denetle';
+$lang['L_DOSIMPLETEST'] = 'Perli denetle';
+$lang['L_PERLOUTPUT1'] = 'crondump.pl de kayıtlı adres absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'Tarayıcı veya dışarıdan çağrışım ile çalışan Cronjob';
+$lang['L_PERLOUTPUT3'] = 'Shell den veya Crontab dan çalışması için';
+$lang['L_RESTORE_OF_TABLES'] = 'belirli tabloları geri dönüştürme';
+$lang['L_CONVERTER'] = 'Yedekleme dönüştürücüsü';
+$lang['L_CONVERT_FILE'] = 'dönüştürülecek dosya';
+$lang['L_CONVERT_FILENAME'] = 'Yeni dosya adı (uzantısız)';
+$lang['L_CONVERTING'] = 'Dönüştürüm';
+$lang['L_CONVERT_FILEREAD'] = "Dosya '%s' okunuyor";
+$lang['L_CONVERT_FINISHED'] = "Dönüştürme tamamlandı, '%s' oluşturuldu.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Başka yazılımların dosyaları:';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Maksimum dosya boyutu';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Eğer Yedek dosyanız izin verilen boyuttan büyük ise, o zaman FTP ile "work/backup"-Klasörüne yüklemeniz lazım.
+Daha sonra bu dosya Yönetim bölümünde gözüküp geri yükleme işlemi için kullanılabilir duruma gelicektir.';
+$lang['L_ENCODING'] = 'kodlama';
+$lang['L_FM_CHOOSE_ENCODING'] = 'alınacak yedeğin karakter setini seçin';
+$lang['L_CHOOSE_CHARSET'] = 'Maalesef veritabanı yedeğinin hangi karakter seti ile kodlandığını otomatik olarak bulunmadı<br>Hangi karakter setini kullandıysanız onu seçip elle vermeniz gerekiyor.Daha sonra MyOOSDumper veritabanı serveri ile irtibata gecip yedeği yüklemeye başlıyacaktır.<br>Eğer yedek yüklendikten sonra karakter sorunu devam ediyorsa başka bir karakter seti seçip tekrar denemeniz gerekiyor.<br> Bol şans ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Dosya indir';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/tr/lang_help.php b/msd/language/tr/lang_help.php
index ca10925c..a38b4dd9 100644
--- a/msd/language/tr/lang_help.php
+++ b/msd/language/tr/lang_help.php
@@ -1,36 +1,40 @@
 <?php
-$lang['L_HELP_DB']="Veritabanlarının listesi";
-$lang['L_HELP_PRAEFIX']="Tablo ön eki, tabloların daha kolay filtrelenebilmesini sağlamak için tablo isimlerinin önüne eklenir.";
-$lang['L_HELP_ZIP']="GZip ile sıkıştırma - etkin olması önerilir'";
-$lang['L_HELP_MEMORYLIMIT']="Byte olarak belirlenir, Scriptin kullanabileceği azami hafızayı belirler
-0 = Devre dışı";
-$lang['L_MEMORY_LIMIT']="Hafıza sınırı";
-$lang['L_HELP_AD1']="Aktiv olduğunda yedekleme dosyaları otomatik olarak silinir.";
-$lang['L_HELP_AD3']="Yedekleme dosyalarının maximum sayısı (Otomatik silme için)
-0 = kullanılmaz";
-$lang['L_HELP_LANG']="Dil seçeneği";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Gereksiz kayıtların silinmesi için, geri dönüıümden önce Veritabanlarının boşaltılmasını sağlayabilirsiniz.";
-$lang['L_HELP_CRONEXTENDER']="Perlscriptinin dosyabitimi, Standard: '.pl'.";
-$lang['L_HELP_CRONSAVEPATH']="Perlskriptinin ayardosyasının adı.";
-$lang['L_HELP_CRONPRINTOUT']="Yazı çıktısı kapalı olursa, sonuçlar belirtilmez.
-Bu fonksiyon rapor dosyasına bağlı değildir.";
-$lang['L_HELP_CRONSAMEDB']="Cronscript için ayarlardaki Veritabanı kullanılsınmı?";
-$lang['L_HELP_CRONDBINDEX']="Cronscript için kullanılacak Veritabanını seçiniz.";
-$lang['L_HELP_FTPTRANSFER']="Seçildiğinde yedekleme den sonra dosya FTP ile gönderilir.";
-$lang['L_HELP_FTPSERVER']="FTP-Sunucusunun adresi.";
-$lang['L_HELP_FTPPORT']="FTP-Sunucusunun Portnumarası, Standart: 21.";
-$lang['L_HELP_FTPUSER']="FTP-Kullanıcısının adı";
-$lang['L_HELP_FTPPASS']="FTP-Kullanıcısının şifresi.";
-$lang['L_HELP_FTPDIR']="Dosyanın gönderileceği yer?";
-$lang['L_HELP_SPEED']="en düşük ve en yüksek hız, standart: 50'den 5000'e kadar
+
+$lang['L_HELP_DB'] = 'Veritabanlarının listesi';
+$lang['L_HELP_PRAEFIX'] = 'Tablo ön eki, tabloların daha kolay filtrelenebilmesini sağlamak için tablo isimlerinin önüne eklenir.';
+$lang['L_HELP_ZIP'] = "GZip ile sıkıştırma - etkin olması önerilir'";
+$lang['L_HELP_MEMORYLIMIT'] = 'Byte olarak belirlenir, Scriptin kullanabileceği azami hafızayı belirler
+0 = Devre dışı';
+$lang['L_MEMORY_LIMIT'] = 'Hafıza sınırı';
+$lang['L_HELP_AD1'] = 'Aktiv olduğunda yedekleme dosyaları otomatik olarak silinir.';
+$lang['L_HELP_AD3'] = 'Yedekleme dosyalarının maximum sayısı (Otomatik silme için)
+0 = kullanılmaz';
+$lang['L_HELP_LANG'] = 'Dil seçeneği';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Gereksiz kayıtların silinmesi için, geri dönüıümden önce Veritabanlarının boşaltılmasını sağlayabilirsiniz.';
+$lang['L_HELP_CRONEXTENDER'] = "Perlscriptinin dosyabitimi, Standard: '.pl'.";
+$lang['L_HELP_CRONSAVEPATH'] = 'Perlskriptinin ayardosyasının adı.';
+$lang['L_HELP_CRONPRINTOUT'] = 'Yazı çıktısı kapalı olursa, sonuçlar belirtilmez.
+Bu fonksiyon rapor dosyasına bağlı değildir.';
+$lang['L_HELP_CRONSAMEDB'] = 'Cronscript için ayarlardaki Veritabanı kullanılsınmı?';
+$lang['L_HELP_CRONDBINDEX'] = 'Cronscript için kullanılacak Veritabanını seçiniz.';
+$lang['L_HELP_FTPTRANSFER'] = 'Seçildiğinde yedekleme den sonra dosya FTP ile gönderilir.';
+$lang['L_HELP_FTPSERVER'] = 'FTP-Sunucusunun adresi.';
+$lang['L_HELP_FTPPORT'] = 'FTP-Sunucusunun Portnumarası, Standart: 21.';
+$lang['L_HELP_FTPUSER'] = 'FTP-Kullanıcısının adı';
+$lang['L_HELP_FTPPASS'] = 'FTP-Kullanıcısının şifresi.';
+$lang['L_HELP_FTPDIR'] = 'Dosyanın gönderileceği yer?';
+$lang['L_HELP_SFTPTRANSFER'] = 'Seçildiğinde yedekleme den sonra dosya SFTP ile gönderilir.';
+$lang['L_HELP_SFTPSERVER'] = 'SFTP-Sunucusunun adresi.';
+$lang['L_HELP_SFTPPORT'] = 'SFTP-Sunucusunun Portnumarası, Standart: 22.';
+$lang['L_HELP_SFTPUSER'] = 'SFTP-Kullanıcısının adı';
+$lang['L_HELP_SFTPPASS'] = 'SFTP-Kullanıcısının şifresi.';
+$lang['L_HELP_SFTPDIR'] = 'Dosyanın gönderileceği yer?';
+$lang['L_HELP_SPEED'] = "en düşük ve en yüksek hız, standart: 50'den 5000'e kadar
 (daha yüksek hız ayarı çalışmayabilir!).";
-$lang['L_SPEED']="Hız";
-$lang['L_HELP_CRONEXECPATH']="Perlskriptin bulunduğu alan.
-HTTP-Adressinden yola çıkarak (Tarayıcıda).";
-$lang['L_CRON_EXECPATH']="Perlskript'in veriyolu";
-$lang['L_HELP_CRONCOMPLETELOG']="Aktiv olması durumunda çıktının komplesi complete_log dosyasına kaydedilir. 
-Textçıktısı ayarlarına bağlı değildir.";
-$lang['L_HELP_FTP_MODE']="Eğer FTP-Transfer esnasında hata oluşursa,lütfen Pasif-Modus yöntemi ile deneyin.";
-
-
-?>
\ No newline at end of file
+$lang['L_SPEED'] = 'Hız';
+$lang['L_HELP_CRONEXECPATH'] = 'Perlskriptin bulunduğu alan.
+HTTP-Adressinden yola çıkarak (Tarayıcıda).';
+$lang['L_CRON_EXECPATH'] = "Perlskript'in veriyolu";
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Aktiv olması durumunda çıktının komplesi complete_log dosyasına kaydedilir. 
+Textçıktısı ayarlarına bağlı değildir.';
+$lang['L_HELP_FTP_MODE'] = 'Eğer FTP-Transfer esnasında hata oluşursa,lütfen Pasif-Modus yöntemi ile deneyin.';
diff --git a/msd/language/tr/lang_install.php b/msd/language/tr/lang_install.php
index 1b45b54f..bfe72a62 100644
--- a/msd/language/tr/lang_install.php
+++ b/msd/language/tr/lang_install.php
@@ -1,89 +1,85 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Kurulum tamamlanmıştır   --> <a href=\"index.php\">MySQLDumper'i başlat </a><br>";
-$lang['L_INSTALL_TOMENU']="Ana Menüye geç";
-$lang['L_INSTALLMENU']="Ana Menüsü";
-$lang['L_STEP']="Adım";
-$lang['L_INSTALL']="Kurulum";
-$lang['L_UNINSTALL']="Kurulumu kaldır";
-$lang['L_TOOLS']="Araçlar";
-$lang['L_EDITCONF']="Ayarları elden düzenle";
-$lang['L_OSWEITER']="Kayıt etmeden devam et";
-$lang['L_ERRORMAN']="Ayarların kaydında hata oluştu!</strong><br>Dosyayı lütfen elden düzenleyiniz ";
-$lang['L_MANUELL']="elden";
-$lang['L_CREATEDIRS']="Klasörler oluşturuluyor";
-$lang['L_INSTALL_CONTINUE']="Kuruluma devam et";
-$lang['L_CONNECTTOMYSQL']=" MySQL ile bağlan ";
-$lang['L_DBPARAMETER']="Veritabanı-Parametreleri";
-$lang['L_CONFIGNOTWRITABLE']="\"config.php\" yazılamıyor. FTP yazılımınız ile CHMOD ayarlarını 0777 ye çevirin.";
-$lang['L_DBCONNECTION']="Bağlantı Parametreleri";
-$lang['L_CONNECTIONERROR']="Hata: bağlantı kurulamıyor.";
-$lang['L_CONNECTION_OK']="Veritabanı bağlantısı kuruldu.";
-$lang['L_SAVEANDCONTINUE']="Kaydet ve kurulumu devam et";
-$lang['L_CONFBASIC']="Asıl Ayarları";
-$lang['L_INSTALL_STEP2FINISHED']="Veritabanı ayarları kayıt edildi.<br><br>
-İsterseniz standart ayarlar ile kurulumu sürdürebilirsiniz, veya ayarları düzenleyebilirsiniz.";
-$lang['L_INSTALL_STEP2_1']="Standart ayarlarla devam";
-$lang['L_LASTSTEP']="Kurulumum tamamlanması";
-$lang['L_FTPMODE']="Klasörler FTP ile oluşturuluyor (safe_mode)";
-$lang['L_IDOMANUAL']="Klasörleri elden oluşturacağım";
-$lang['L_DOFROM']="başlangıç:";
-$lang['L_FTPMODE2']="klasörleri FTP ile oluştur";
-$lang['L_CONNECT']="Bağlantı kur";
-$lang['L_DIRS_CREATED']="Klasörler oluşturuldu.";
-$lang['L_CONNECT_TO']="Bağlantı kur:";
-$lang['L_CHANGEDIR']="Klasöre geç";
-$lang['L_CHANGEDIRERROR']="Klasöre geciş mümkün değil";
-$lang['L_FTP_OK']="FTP-Ayarları geçerli";
-$lang['L_CREATEDIRS2']="Klasörleri oluştur";
-$lang['L_FTP_NOTCONNECTED']="FTP-bağlantısı kurulmadı!";
-$lang['L_CONNWITH']="Kurulacak bağlantı:";
-$lang['L_ASUSER']="Kullanıcı";
-$lang['L_NOTPOSSIBLE']="mümkün değil";
-$lang['L_DIRCR1']="Oluşturuluyor: Çalışma klasörü";
-$lang['L_DIRCR2']="Oluşturuluyor: yedekleme klasörü";
-$lang['L_DIRCR4']="Oluşturuluyor: rapor klasörü";
-$lang['L_DIRCR5']="Oluşturuluyor: ayar klasörü";
-$lang['L_INDIR']="bulunulan klasör";
-$lang['L_CHECK_DIRS']="Kontrol ediliyor";
-$lang['L_DISABLEDFUNCTIONS']="İptal edilmiş fonksiyonlar";
-$lang['L_NOFTPPOSSIBLE']="FTP fonksiyonları kullanılmaz!";
-$lang['L_NOGZPOSSIBLE']="Sıkıştırma fonksiyonları kullanılmıyor!";
-$lang['L_UI1']="Çalışma klasörleri siliniyor (içerisinde bulunan yedekleme dosyaları ile birlikte).";
-$lang['L_UI2']="Eminmisiniz?";
-$lang['L_UI3']="Hayır, hemen iptal et";
-$lang['L_UI4']="Evet, eminim, devam et";
-$lang['L_UI5']="Çalışma klasörü siliniyor";
-$lang['L_UI6']="Hepsi silindi.";
-$lang['L_UI7']="Skript klasörünü lütfen siliniz";
-$lang['L_UI8']="Bir düzey yukarı çık";
-$lang['L_UI9']="Hata oluştu, silme işlemi uygulanamadı</p>Hatanın oluştuğu klasör: ";
-$lang['L_IMPORT']="Ayarları ithal et";
-$lang['L_IMPORT3']="Ayarlar yüklendi...";
-$lang['L_IMPORT4']="Ayarlar yedeklendi.";
-$lang['L_IMPORT5']="MySQLDumper'i başlat";
-$lang['L_IMPORT6']="Kurulum menüsü";
-$lang['L_IMPORT7']="Ayarları yükle";
-$lang['L_IMPORT8']="Yüklemeye geri dön";
-$lang['L_IMPORT9']="Bu bir ayaryedeklemesi değil!";
-$lang['L_IMPORT10']="Ayarlar yüklendi...";
-$lang['L_IMPORT11']="<strong>Hata: </strong>SQL komutları yazarken hata oluştu";
-$lang['L_IMPORT12']="<strong>Hata: </strong>Config.php nin kaydında hata oluştu";
-$lang['L_INSTALL_HELP_PORT']="(boş = Standart port)";
-$lang['L_INSTALL_HELP_SOCKET']="(boş= Standart socket)";
-$lang['L_TRYAGAIN']="Bir daha dene";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Port";
-$lang['L_FOUND_DB']="Bulunan Veritabanı: ";
-$lang['L_FM_FILEUPLOAD']="Dosya yükle";
-$lang['L_PASS']="Şifre";
-$lang['L_NO_DB_FOUND_INFO']="Veritabanı sunucusu ile bağlantı kuruldu.<br>
+
+$lang['L_INSTALLFINISHED'] = "<br>Kurulum tamamlanmıştır   --> <a href=\"index.php\">MyOOS [Dumper]'i başlat </a><br>";
+$lang['L_INSTALL_TOMENU'] = 'Ana Menüye geç';
+$lang['L_INSTALLMENU'] = 'Ana Menüsü';
+$lang['L_STEP'] = 'Adım';
+$lang['L_INSTALL'] = 'Kurulum';
+$lang['L_UNINSTALL'] = 'Kurulumu kaldır';
+$lang['L_TOOLS'] = 'Araçlar';
+$lang['L_EDITCONF'] = 'Ayarları elden düzenle';
+$lang['L_OSWEITER'] = 'Kayıt etmeden devam et';
+$lang['L_ERRORMAN'] = 'Ayarların kaydında hata oluştu!</strong><br>Dosyayı lütfen elden düzenleyiniz ';
+$lang['L_MANUELL'] = 'elden';
+$lang['L_CREATEDIRS'] = 'Klasörler oluşturuluyor';
+$lang['L_INSTALL_CONTINUE'] = 'Kuruluma devam et';
+$lang['L_CONNECTTOMYSQL'] = ' MySQL ile bağlan ';
+$lang['L_DBPARAMETER'] = 'Veritabanı-Parametreleri';
+$lang['L_CONFIGNOTWRITABLE'] = '"config.php" yazılamıyor. FTP yazılımınız ile CHMOD ayarlarını 0777 ye çevirin.';
+$lang['L_DBCONNECTION'] = 'Bağlantı Parametreleri';
+$lang['L_CONNECTIONERROR'] = 'Hata: bağlantı kurulamıyor.';
+$lang['L_CONNECTION_OK'] = 'Veritabanı bağlantısı kuruldu.';
+$lang['L_SAVEANDCONTINUE'] = 'Kaydet ve kurulumu devam et';
+$lang['L_CONFBASIC'] = 'Asıl Ayarları';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Veritabanı ayarları kayıt edildi.<br><br>
+İsterseniz standart ayarlar ile kurulumu sürdürebilirsiniz, veya ayarları düzenleyebilirsiniz.';
+$lang['L_INSTALL_STEP2_1'] = 'Standart ayarlarla devam';
+$lang['L_LASTSTEP'] = 'Kurulumum tamamlanması';
+$lang['L_IDOMANUAL'] = 'Klasörleri elden oluşturacağım';
+$lang['L_DOFROM'] = 'başlangıç:';
+$lang['L_FTPMODE2'] = 'klasörleri FTP ile oluştur';
+$lang['L_CONNECT'] = 'Bağlantı kur';
+$lang['L_DIRS_CREATED'] = 'Klasörler oluşturuldu.';
+$lang['L_CONNECT_TO'] = 'Bağlantı kur:';
+$lang['L_CHANGEDIR'] = 'Klasöre geç';
+$lang['L_CHANGEDIRERROR'] = 'Klasöre geciş mümkün değil';
+$lang['L_FTP_OK'] = 'FTP-Ayarları geçerli';
+$lang['L_CREATEDIRS2'] = 'Klasörleri oluştur';
+$lang['L_FTP_NOTCONNECTED'] = 'FTP-bağlantısı kurulmadı!';
+$lang['L_CONNWITH'] = 'Kurulacak bağlantı:';
+$lang['L_ASUSER'] = 'Kullanıcı';
+$lang['L_NOTPOSSIBLE'] = 'mümkün değil';
+$lang['L_DIRCR1'] = 'Oluşturuluyor: Çalışma klasörü';
+$lang['L_DIRCR2'] = 'Oluşturuluyor: yedekleme klasörü';
+$lang['L_DIRCR4'] = 'Oluşturuluyor: rapor klasörü';
+$lang['L_DIRCR5'] = 'Oluşturuluyor: ayar klasörü';
+$lang['L_INDIR'] = 'bulunulan klasör';
+$lang['L_CHECK_DIRS'] = 'Kontrol ediliyor';
+$lang['L_DISABLEDFUNCTIONS'] = 'İptal edilmiş fonksiyonlar';
+$lang['L_NOFTPPOSSIBLE'] = 'FTP fonksiyonları kullanılmaz!';
+$lang['L_NOGZPOSSIBLE'] = 'Sıkıştırma fonksiyonları kullanılmıyor!';
+$lang['L_UI1'] = 'Çalışma klasörleri siliniyor (içerisinde bulunan yedekleme dosyaları ile birlikte).';
+$lang['L_UI2'] = 'Eminmisiniz?';
+$lang['L_UI3'] = 'Hayır, hemen iptal et';
+$lang['L_UI4'] = 'Evet, eminim, devam et';
+$lang['L_UI5'] = 'Çalışma klasörü siliniyor';
+$lang['L_UI6'] = 'Hepsi silindi.';
+$lang['L_UI7'] = 'Skript klasörünü lütfen siliniz';
+$lang['L_UI8'] = 'Bir düzey yukarı çık';
+$lang['L_UI9'] = 'Hata oluştu, silme işlemi uygulanamadı</p>Hatanın oluştuğu klasör: ';
+$lang['L_IMPORT'] = 'Ayarları ithal et';
+$lang['L_IMPORT3'] = 'Ayarlar yüklendi...';
+$lang['L_IMPORT4'] = 'Ayarlar yedeklendi.';
+$lang['L_IMPORT5'] = "MyOOS [Dumper]'i başlat";
+$lang['L_IMPORT6'] = 'Kurulum menüsü';
+$lang['L_IMPORT7'] = 'Ayarları yükle';
+$lang['L_IMPORT8'] = 'Yüklemeye geri dön';
+$lang['L_IMPORT9'] = 'Bu bir ayaryedeklemesi değil!';
+$lang['L_IMPORT10'] = 'Ayarlar yüklendi...';
+$lang['L_IMPORT11'] = '<strong>Hata: </strong>SQL komutları yazarken hata oluştu';
+$lang['L_IMPORT12'] = '<strong>Hata: </strong>Config.php nin kaydında hata oluştu';
+$lang['L_INSTALL_HELP_PORT'] = '(boş = Standart port)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(boş= Standart socket)';
+$lang['L_TRYAGAIN'] = 'Bir daha dene';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Port';
+$lang['L_FOUND_DB'] = 'Bulunan Veritabanı: ';
+$lang['L_FM_FILEUPLOAD'] = 'Dosya yükle';
+$lang['L_PASS'] = 'Şifre';
+$lang['L_NO_DB_FOUND_INFO'] = 'Veritabanı sunucusu ile bağlantı kuruldu.<br>
 Bağlantı parametreleri doğrulandı, kullanıcı ismi ve şifresi kabul edildi.<br>
 Fakat Sunucuda Veritabanı bulunamadı.<br>
 Otomatik tanıma sunucunuzda kilitli olabilir.<br>
-Kurulum tamamlandıktan sonra lütfen Ayar Merkezi sayfasına gidin ve Bağlantı parametreleri bölümünde \"göster\" tıklayınız.<br>
-Veritabanı ile bağlantı kurulabilmesi için gereken bilgileri oraya girmeniz gerekiyor.";
-$lang['L_SAFEMODEDESC']="Bu sunucudaki PHP ayarlarında \"safe_mode=on\" tespit edilmiştır, bazı klasörleri elden oluşturmanız gerekiyor (mesela FTP Client programı ile)";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+Kurulum tamamlandıktan sonra lütfen Ayar Merkezi sayfasına gidin ve Bağlantı parametreleri bölümünde "göster" tıklayınız.<br>
+Veritabanı ile bağlantı kurulabilmesi için gereken bilgileri oraya girmeniz gerekiyor.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/tr/lang_log.php b/msd/language/tr/lang_log.php
index 3bb9525c..c87e2bd2 100644
--- a/msd/language/tr/lang_log.php
+++ b/msd/language/tr/lang_log.php
@@ -1,9 +1,7 @@
 <?php
-$lang['L_LOG_DELETE']="Raporu sil";
-$lang['L_LOGFILEFORMAT']="Rapor dosyasının biçimi";
-$lang['L_LOGFILENOTWRITABLE']="Rapor dosyasına yazılamıyor!";
-$lang['L_NOREVERSE']="Eski kayıtlar önce";
-$lang['L_REVERSE']="Yeni kayıtlar önce";
 
-
-?>
\ No newline at end of file
+$lang['L_LOG_DELETE'] = 'Raporu sil';
+$lang['L_LOGFILEFORMAT'] = 'Rapor dosyasının biçimi';
+$lang['L_LOGFILENOTWRITABLE'] = 'Rapor dosyasına yazılamıyor!';
+$lang['L_NOREVERSE'] = 'Eski kayıtlar önce';
+$lang['L_REVERSE'] = 'Yeni kayıtlar önce';
diff --git a/msd/language/tr/lang_main.php b/msd/language/tr/lang_main.php
index 7804f9c3..92998593 100644
--- a/msd/language/tr/lang_main.php
+++ b/msd/language/tr/lang_main.php
@@ -1,74 +1,85 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="FTP  işlemleri mümkün değil!";
-$lang['L_INFO_LOCATION']="Bulunduğunuz alan: ";
-$lang['L_INFO_DATABASES']="Sunucuda bulunan Veritabanları:";
-$lang['L_INFO_NODB']="İstenile Veritabanaı bulunamıyor";
-$lang['L_INFO_DBDETAIL']="Detail-bilgiler ";
-$lang['L_INFO_DBEMPTY']="Veritabanı boş!";
-$lang['L_INFO_RECORDS']="Kayıtlar";
-$lang['L_INFO_SIZE']="Ebadı";
-$lang['L_INFO_LASTUPDATE']="Son güncelleme";
-$lang['L_INFO_SUM']="Topyekün";
-$lang['L_INFO_OPTIMIZED']="arındırıldı";
-$lang['L_OPTIMIZE_DATABASES']="Tabloları arındır";
-$lang['L_CHECK_TABLES']="Tablo kontrolü";
-$lang['L_CLEAR_DATABASE']="Veritabanını  boşalt";
-$lang['L_DELETE_DATABASE']="Veritabanını sil";
-$lang['L_INFO_CLEARED']="boşaltıldı";
-$lang['L_INFO_DELETED']="silindi";
-$lang['L_INFO_EMPTYDB1']="Gerçekten";
-$lang['L_INFO_EMPTYDB2']="boşaltılsınmı? (UYARI: Bütün bilgiler silinecektir)";
-$lang['L_INFO_KILLDB']=" Silinsinmi? (UYARI: Bütün bilgiler silinecektir)";
-$lang['L_PROCESSKILL1']="İşlem ";
-$lang['L_PROCESSKILL2']=" durdurulacağını deneniyor.";
-$lang['L_PROCESSKILL3']="Süre: ";
-$lang['L_PROCESSKILL4']=" Saniye, İşlem ";
-$lang['L_HTACC_CREATE']="Klasör koruma oluştur";
-$lang['L_ENCRYPTION_TYPE']="Kodlama türü";
-$lang['L_HTACC_CRYPT']="Crypt (Linux ve Unix-Sistemi)";
-$lang['L_HTACC_MD5']="MD5 (Linux ve Unix-Sistemi)";
-$lang['L_HTACC_NO_ENCRYPTION']="Açık (Windows)";
-$lang['L_HTACCESS8']="Geçerli Klasör Koruma bulundu. Yenisini oluşturduğunuzda eskisi silinecektir!";
-$lang['L_HTACC_NO_USERNAME']="İsim girmediniz!";
-$lang['L_PASSWORDS_UNEQUAL']="Şifreler birbirini tutmuyor!";
-$lang['L_HTACC_CONFIRM_DELETE']="Klasör Koruması şimdi oluşturulsunmu?";
-$lang['L_HTACC_CREATED']="Klasör Koruması oluşturuldu.";
-$lang['L_HTACC_CONTENT']="Dosyanın içeriği";
-$lang['L_HTACC_CREATE_ERROR']="Klasör Koruma oluşturulmasında hata oluştu!<br>Dosyayı lütfen elden oluşturunuz. İçeriği";
-$lang['L_HTACC_PROPOSED']="Önemli";
-$lang['L_HTACC_EDIT']=".htaccess dosyasını düzenle";
-$lang['L_HTACCESS18']=".htaccess dosyasının oluşturulacağı klasör ";
-$lang['L_HTACCESS19']="güncelle ";
-$lang['L_HTACCESS20']="Skript'i çalıştır";
-$lang['L_HTACCESS21']="Handler ekle";
-$lang['L_HTACCESS22']="Çalıştırılır hale getir";
-$lang['L_HTACCESS23']="Klasör listesi";
-$lang['L_HTACCESS24']="Hata dosyası";
-$lang['L_HTACCESS25']="Rewrite'i aç";
-$lang['L_HTACCESS26']="Yasak / Serbest";
-$lang['L_HTACCESS27']="Yönlendir";
-$lang['L_HTACCESS28']="Hata-Log'u";
-$lang['L_HTACCESS29']="Başka örnekler ve belgeler";
-$lang['L_HTACCESS30']="Hosting Şirketi";
-$lang['L_HTACCESS31']="genel";
-$lang['L_HTACCESS32']="Dikat .htaccess dosyası tarayıcıyı anında etkiler. <br>Yanlış ayarlandığında sayfalara ulaşamazsınız.";
-$lang['L_PHPBUG']="zlib de hata var! Sıkıştırma kullanılamaz!";
-$lang['L_DISABLEDFUNCTIONS']="İptal edilmiş fonksiyonlar";
-$lang['L_NOGZPOSSIBLE']="Zlib bulunamadığı için Sıkıştırma kullanılamaz!";
-$lang['L_DELETE_HTACCESS']="Klasör koruması kaldırılsın (.htaccess silinecek)";
-$lang['L_WRONG_RIGHTS']="Dosya yada Klasör '%s' yazılamıyor !.<br> Ya yetkili kullanıcı değilsiniz yada erişim haklarınız kısıtlı (chmod).<br> Lütfen Ftp programınızla gerekli erişim haklarını düzenleyin.<br>Dosya / Klasör için gerekli erişim hakkı %s.<br>";
-$lang['L_CANT_CREATE_DIR']="gerekli olan '%s' Klasörü oluşturulamadı. Lütfen FTP Programınız ile yaratın.";
-$lang['L_TABLE_TYPE']="Tür";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="Dosya bulunamadı";
 
-
-?>
\ No newline at end of file
+$lang['L_NOFTPPOSSIBLE'] = 'FTP  işlemleri mümkün değil!';
+$lang['L_INFO_LOCATION'] = 'Bulunduğunuz alan: ';
+$lang['L_INFO_DATABASES'] = 'Sunucuda bulunan Veritabanları:';
+$lang['L_INFO_NODB'] = 'İstenile Veritabanaı bulunamıyor';
+$lang['L_INFO_DBDETAIL'] = 'Detail-bilgiler ';
+$lang['L_INFO_DBEMPTY'] = 'Veritabanı boş!';
+$lang['L_INFO_RECORDS'] = 'Kayıtlar';
+$lang['L_INFO_SIZE'] = 'Ebadı';
+$lang['L_INFO_LASTUPDATE'] = 'Son güncelleme';
+$lang['L_INFO_SUM'] = 'Topyekün';
+$lang['L_INFO_OPTIMIZED'] = 'arındırıldı';
+$lang['L_OPTIMIZE_DATABASES'] = 'Tabloları arındır';
+$lang['L_CHECK_TABLES'] = 'Tablo kontrolü';
+$lang['L_CLEAR_DATABASE'] = 'Veritabanını  boşalt';
+$lang['L_DELETE_DATABASE'] = 'Veritabanını sil';
+$lang['L_INFO_CLEARED'] = 'boşaltıldı';
+$lang['L_INFO_DELETED'] = 'silindi';
+$lang['L_INFO_EMPTYDB1'] = 'Gerçekten';
+$lang['L_INFO_EMPTYDB2'] = 'boşaltılsınmı? (UYARI: Bütün bilgiler silinecektir)';
+$lang['L_INFO_KILLDB'] = ' Silinsinmi? (UYARI: Bütün bilgiler silinecektir)';
+$lang['L_PROCESSKILL1'] = 'İşlem ';
+$lang['L_PROCESSKILL2'] = ' durdurulacağını deneniyor.';
+$lang['L_PROCESSKILL3'] = 'Süre: ';
+$lang['L_PROCESSKILL4'] = ' Saniye, İşlem ';
+$lang['L_HTACC_CREATE'] = 'Klasör koruma oluştur';
+$lang['L_ENCRYPTION_TYPE'] = 'Kodlama türü';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Geçerli Klasör Koruma bulundu. Yenisini oluşturduğunuzda eskisi silinecektir!';
+$lang['L_HTACC_NO_USERNAME'] = 'İsim girmediniz!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Şifreler birbirini tutmuyor!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Klasör Koruması şimdi oluşturulsunmu?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'Klasör Koruması oluşturuldu.';
+$lang['L_HTACC_CONTENT'] = 'Dosyanın içeriği';
+$lang['L_HTACC_CREATE_ERROR'] = 'Klasör Koruma oluşturulmasında hata oluştu!<br>Dosyayı lütfen elden oluşturunuz. İçeriği';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = '.htaccess dosyasını düzenle';
+$lang['L_HTACCESS18'] = '.htaccess dosyasının oluşturulacağı klasör ';
+$lang['L_HTACCESS19'] = 'güncelle ';
+$lang['L_HTACCESS20'] = "Skript'i çalıştır";
+$lang['L_HTACCESS21'] = 'Handler ekle';
+$lang['L_HTACCESS22'] = 'Çalıştırılır hale getir';
+$lang['L_HTACCESS23'] = 'Klasör listesi';
+$lang['L_HTACCESS24'] = 'Hata dosyası';
+$lang['L_HTACCESS25'] = "Rewrite'i aç";
+$lang['L_HTACCESS26'] = 'Yasak / Serbest';
+$lang['L_HTACCESS27'] = 'Yönlendir';
+$lang['L_HTACCESS28'] = "Hata-Log'u";
+$lang['L_HTACCESS29'] = 'Başka örnekler ve belgeler';
+$lang['L_HTACCESS30'] = 'Hosting Şirketi';
+$lang['L_HTACCESS31'] = 'genel';
+$lang['L_HTACCESS32'] = 'Dikat .htaccess dosyası tarayıcıyı anında etkiler. <br>Yanlış ayarlandığında sayfalara ulaşamazsınız.';
+$lang['L_DISABLEDFUNCTIONS'] = 'İptal edilmiş fonksiyonlar';
+$lang['L_NOGZPOSSIBLE'] = 'Zlib bulunamadığı için Sıkıştırma kullanılamaz!';
+$lang['L_DELETE_HTACCESS'] = 'Klasör koruması kaldırılsın (.htaccess silinecek)';
+$lang['L_WRONG_RIGHTS'] = "Dosya yada Klasör '%s' yazılamıyor !.<br> Ya yetkili kullanıcı değilsiniz yada erişim haklarınız kısıtlı (chmod).<br> Lütfen Ftp programınızla gerekli erişim haklarını düzenleyin.<br>Dosya / Klasör için gerekli erişim hakkı %s.<br>";
+$lang['L_CANT_CREATE_DIR'] = "gerekli olan '%s' Klasörü oluşturulamadı. Lütfen FTP Programınız ile yaratın.";
+$lang['L_TABLE_TYPE'] = 'Tür';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'Dosya bulunamadı';
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/tr/lang_restore.php b/msd/language/tr/lang_restore.php
index cf2b7f50..ce3aec5d 100644
--- a/msd/language/tr/lang_restore.php
+++ b/msd/language/tr/lang_restore.php
@@ -1,21 +1,19 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Şimdiye kadar <b>%d</b> tablo oluşturuldu.";
-$lang['L_FILE_MISSING']="Dosya bulunamadı";
-$lang['L_RESTORE_DB']="Veritabanı: '<b>%s</b>' Sunucu: '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> Tablolar oluşturuldu.";
-$lang['L_RESTORE_RUN1']="<br>Şimdiye kadar <b>%s</b> / <b>%s</b> kayıt işlendi.";
-$lang['L_RESTORE_RUN2']="<br>İşlenen tablo '<b>%s</b>' kayıtlar işleniyor.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> Kayıtlar işlendi.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Şimdiye kadar <b>%d</b> / <b>%d</b> Tablo oluşturuldu.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Tebrikler.</b><br><br>Veritabanı tamamen dönüştürüldü.<br>Yedeklemedeki bulunan bütün bilgiler işlenebildi.<br><br>İşlem tamamlanmıştır. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Hata:<br>Veritabanı seçimi '<b>";
-$lang['L_DB_SELECT_ERROR2']="</b>' Hata oluştu!";
-$lang['L_FILE_OPEN_ERROR']="Hata: Dosya açılamadı.";
-$lang['L_PROGRESS_OVER_ALL']="Süreçin tamamı";
-$lang['L_BACK_TO_OVERVIEW']="Veritabanı listesi";
-$lang['L_RESTORE_RUN0']="<br>Şimdiye kadar <b>%s</b> kayıt başarılı olarak işlendi.";
-$lang['L_UNKNOWN_SQLCOMMAND']="Tanınmayan SQL komudu:";
-$lang['L_NOTICES']="İpuçlar";
 
-
-?>
\ No newline at end of file
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Şimdiye kadar <b>%d</b> tablo oluşturuldu.';
+$lang['L_FILE_MISSING'] = 'Dosya bulunamadı';
+$lang['L_RESTORE_DB'] = "Veritabanı: '<b>%s</b>' Sunucu: '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> Tablolar oluşturuldu.';
+$lang['L_RESTORE_RUN1'] = '<br>Şimdiye kadar <b>%s</b> / <b>%s</b> kayıt işlendi.';
+$lang['L_RESTORE_RUN2'] = "<br>İşlenen tablo '<b>%s</b>' kayıtlar işleniyor.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> Kayıtlar işlendi.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Şimdiye kadar <b>%d</b> / <b>%d</b> Tablo oluşturuldu.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Tebrikler.</b><br><br>Veritabanı tamamen dönüştürüldü.<br>Yedeklemedeki bulunan bütün bilgiler işlenebildi.<br><br>İşlem tamamlanmıştır. :-)';
+$lang['L_DB_SELECT_ERROR'] = "<br>Hata:<br>Veritabanı seçimi '<b>";
+$lang['L_DB_SELECT_ERROR2'] = "</b>' Hata oluştu!";
+$lang['L_FILE_OPEN_ERROR'] = 'Hata: Dosya açılamadı.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Süreçin tamamı';
+$lang['L_BACK_TO_OVERVIEW'] = 'Veritabanı listesi';
+$lang['L_RESTORE_RUN0'] = '<br>Şimdiye kadar <b>%s</b> kayıt başarılı olarak işlendi.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'Tanınmayan SQL komudu:';
+$lang['L_NOTICES'] = 'İpuçlar';
diff --git a/msd/language/tr/lang_sql.php b/msd/language/tr/lang_sql.php
index 6a79b9c1..67342cdf 100644
--- a/msd/language/tr/lang_sql.php
+++ b/msd/language/tr/lang_sql.php
@@ -1,191 +1,190 @@
 <?php
-$lang['L_COMMAND']="Komut";
-$lang['L_IMPORT_NOTABLE']="Yüklenecek tablo seçilmemiş!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="SQL emirleriinin işlenmesi kayıtlarınıza zarar verebilir! Mysqldumper işlemden hiç bir yükümlülük kabul etmez.";
-$lang['L_SQL_EXEC']="SQL komudu çalıştır";
-$lang['L_SQL_DATAVIEW']="Veri görüntüsü";
-$lang['L_SQL_TABLEVIEW']="Tablo görüntüsü";
-$lang['L_SQL_VONINS']="/";
-$lang['L_SQL_NODATA']="Kayıt bulunmuyor";
-$lang['L_SQL_RECORDUPDATED']="Kayıt değiştirildi";
-$lang['L_SQL_RECORDINSERTED']="Kayıt eklendi";
-$lang['L_SQL_BACKDBOVERVIEW']="Veritabanı listesine dön";
-$lang['L_SQL_RECORDDELETED']="Kayıt silindi";
-$lang['L_ASKTABLEEMPTY']="`%s` Tablo boşaltılsın mı?";
-$lang['L_SQL_RECORDEDIT']="Kayıt işleniyor";
-$lang['L_SQL_RECORDNEW']="Kayıt ekle";
-$lang['L_ASKDELETERECORD']="Kayıt silinsinmi?";
-$lang['L_ASKDELETETABLE']="`%s` Tablo silinsinmi?";
-$lang['L_SQL_BEFEHLE']="SQL Komutları";
-$lang['L_SQL_BEFEHLNEU']="yeni komut";
-$lang['L_SQL_BEFEHLSAVED1']="SQL komudu";
-$lang['L_SQL_BEFEHLSAVED2']="Eklendi";
-$lang['L_SQL_BEFEHLSAVED3']="Kayıt işlendi";
-$lang['L_SQL_BEFEHLSAVED4']="üste kaydırıldı";
-$lang['L_SQL_BEFEHLSAVED5']="silindi";
-$lang['L_SQL_QUERYENTRY']="Sorgunun içeriği";
-$lang['L_SQL_COLUMNS']="dizi";
-$lang['L_ASKDBDELETE']="`%s` Veritabınını içeriği ile birlikte silmek istiyormusun?";
-$lang['L_ASKDBEMPTY']="`%s` Veritabanının gerçekten boşaltılsınmı?";
-$lang['L_ASKDBCOPY']=" `%s` ın içeriği `%s` veritabanına kopyalansınmı?";
-$lang['L_SQL_TABLENEW']="Tablolar düzenle";
-$lang['L_SQL_OUTPUT']="SQL-çıktısı";
-$lang['L_DO_NOW']="şimdi çalıştır";
-$lang['L_SQL_NAMEDEST_MISSING']="Gidilecek veritabanının ismi eksik!";
-$lang['L_ASKDELETEFIELD']="Hücre silinsinmi?";
-$lang['L_SQL_COMMANDS_IN']=" Dizinler ";
-$lang['L_SQL_COMMANDS_IN2']=" saniyede işlendi.";
-$lang['L_SQL_OUT1']="Toplam";
-$lang['L_SQL_OUT2']="komut çalıştırıldı";
-$lang['L_SQL_OUT3']=" Toplam";
-$lang['L_SQL_OUT4']="not sayısı";
-$lang['L_SQL_OUT5']="Veri 5000 satırı geçtiği için gösterilmiyor.";
-$lang['L_SQL_SELECDB']="Veritabanı seçiniz";
-$lang['L_SQL_TABLESOFDB']="Veritabanının tabloları";
-$lang['L_SQL_EDIT']="işle";
-$lang['L_SQL_NOFIELDDELETE']="Silinemiyor, bir tabloda en azından bir hücre bulunmalı.";
-$lang['L_SQL_FIELDDELETE1']="Hücre";
-$lang['L_SQL_DELETED']="silindi.";
-$lang['L_SQL_CHANGED']="değiştirildi.";
-$lang['L_SQL_CREATED']="oluşturuldu.";
-$lang['L_SQL_NODEST_COPY']="Hedef belirlenmediği için kopyalanamıyor!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Hedeflenen tablo zaten var!";
-$lang['L_SQL_SCOPY']="`%s` tabloyapısı `%s` tablosuna kopyalandı.";
-$lang['L_SQL_TCOPY']="`%s` Tablosu içeriği ile `%s` tablosuna kopyalandı.";
-$lang['L_SQL_TABLENONAME']="Tabloya isim vermelisiniz!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tablo isimi verilmemiş!";
-$lang['L_SQL_COLLATENOTMATCH']="Karakter Seti ve Dil birbirine uymuyor (collation)!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Hata: alanadı geçersiz";
-$lang['L_SQL_CREATETABLE']="Tablo oluştur";
-$lang['L_SQL_COPYTABLE']="Tabloyu kopyala";
-$lang['L_SQL_STRUCTUREONLY']="Saadece yapı";
-$lang['L_SQL_STRUCTUREDATA']="Yapı ve veriler";
-$lang['L_SQL_NOTABLESINDB']="Veritabanında tablo bulunmuyor";
-$lang['L_SQL_SELECTTABLE']="Tablo seç";
-$lang['L_SQL_SHOWDATATABLE']="Tablonun verilerini göster";
-$lang['L_SQL_TBLPROPSOF']="Tablo özellikleri";
-$lang['L_SQL_EDITFIELD']="Alanı işle";
-$lang['L_SQL_NEWFIELD']="yeni alan";
-$lang['L_SQL_INDEXES']="İndeksler";
-$lang['L_SQL_ATPOSITION']="Posisyona ekle";
-$lang['L_SQL_FIRST']="önce";
-$lang['L_SQL_AFTER']="sonra";
-$lang['L_SQL_CHANGEFIELD']="alanı işle";
-$lang['L_SQL_INSERTFIELD']="Alan ekle";
-$lang['L_SQL_INSERTNEWFIELD']="Yeni alan ekle";
-$lang['L_SQL_TABLEINDEXES']="Tablo indexleri";
-$lang['L_SQL_ALLOWDUPS']="çift kayıt'a müsaade et";
-$lang['L_SQL_CARDINALITY']="Kardinality";
-$lang['L_SQL_TABLENOINDEXES']="Tablonun indexi yok";
-$lang['L_SQL_CREATEINDEX']="yeni index oluştur";
-$lang['L_SQL_WASEMPTIED']="boşaltıldı";
-$lang['L_SQL_RENAMEDTO']="yeniden adlandırıldı";
-$lang['L_SQL_DBCOPY']="`%s` veritabanının içeriği `%s` veritabanına kopyalandı.";
-$lang['L_SQL_DBSCOPY']="`%s`veritabanının yapısı `%s` veritabanına kopyalandı.";
-$lang['L_SQL_WASCREATED']="oluşturuldu";
-$lang['L_SQL_RENAMEDB']="veritabanının adını değiştir";
-$lang['L_SQL_ACTIONS']="İşlem";
-$lang['L_SQL_CHOOSEACTION']="İşlem seç";
-$lang['L_SQL_DELETEDB']="veritabanını sil";
-$lang['L_SQL_EMPTYDB']="veritabanını boşalt";
-$lang['L_SQL_COPYDATADB']="İçeriği veritabanına kopyala";
-$lang['L_SQL_COPYSDB']="Yapıyı veritabanına kopyala";
-$lang['L_SQL_IMEXPORT']="Al / ver ";
-$lang['L_INFO_RECORDS']="Kayıtlar";
-$lang['L_NAME']="İsim";
-$lang['L_ASKTABLEEMPTYKEYS']="`%s` Tablosu boşaltılıp indexler silinsinmi?";
-$lang['L_EDIT']="düzenle";
-$lang['L_DELETE']="Silme";
-$lang['L_EMPTY']="içeriği boşalt";
-$lang['L_EMPTYKEYS']="Boşaltıp indexleri silme";
-$lang['L_SQL_TABLEEMPTIED']="`%s` Tablosu boşaltıldı.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="`%s` Tablosu boşaltıldı ve indexleri silindi.";
-$lang['L_SQL_LIBRARY']="SQL-Kütüphanesi";
-$lang['L_SQL_ATTRIBUTES']="Attributlar";
-$lang['L_SQL_UPLOADEDFILE']="Yüklenen dosya: ";
-$lang['L_SQL_IMPORT']="`%s` Veritabanına dışalım";
-$lang['L_EXPORT']="İhraç";
-$lang['L_IMPORT']="Dışalım";
-$lang['L_IMPORTOPTIONS']="Dışalım Seçenekleri";
-$lang['L_CSVOPTIONS']="CSV Seçenekleri";
-$lang['L_IMPORTTABLE']="Tablosuna dışalım";
-$lang['L_NEWTABLE']="yeni tablo";
-$lang['L_IMPORTSOURCE']="Dışalım kaynağı";
-$lang['L_FROMTEXTBOX']="Metin alanından";
-$lang['L_FROMFILE']="Dosyadan";
-$lang['L_EMPTYTABLEBEFORE']="Tabloyu önce boşalt";
-$lang['L_CREATEAUTOINDEX']="Auto-Index oluştur";
-$lang['L_CSV_NAMEFIRSTLINE']="Sütun isimlerini ilk satıra yaz";
-$lang['L_CSV_FIELDSEPERATE']="Hücreleri ayırmak için ";
-$lang['L_CSV_FIELDSENCLOSED']="Hücreleri kapsayan";
-$lang['L_CSV_FIELDSESCAPE']="Hücrelerin kaçış harfi";
-$lang['L_CSV_EOL']="Satırları ayıran";
-$lang['L_CSV_NULL']="NULL un yerine kullanılacak";
-$lang['L_CSV_FILEOPEN']="CSV-Dosyasını aç";
-$lang['L_IMPORTIEREN']="Dışalım";
-$lang['L_SQL_EXPORT']="`%s` Veritabanından ihraç";
-$lang['L_EXPORTOPTIONS']="İhraç Seçenekleri";
-$lang['L_EXCEL2003']="Excel 2003 ve üstü";
-$lang['L_SHOWRESULT']="Sonuçu göster";
-$lang['L_SENDRESULTASFILE']="Sonuçu dosya olarak gönder";
-$lang['L_EXPORTLINES']="<strong>%s</strong> satır ihraç edildi";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Tablo kayıtlarının sayısı, dışalım edilecek bilgilerle uyuşmuyor (%d yerine %d).";
-$lang['L_CSV_FIELDSLINES']="%d hücre tespit edildi, toplam %d satır";
-$lang['L_CSV_ERRORCREATETABLE']=" `%s` Tablo oluşturmada hata oluştu!";
-$lang['L_FM_UPLOADFILEREQUEST']="Dosya belirtiniz.";
-$lang['L_CSV_NODATA']="Dışalım edilebilecek kayıt bulunamadı!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="genel fonksiyonlar";
-$lang['L_SQLLIB_RESETAUTO']="Auto-değeri geri al";
-$lang['L_SQLLIB_BOARDS']="Paneller";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="Paneli durdur";
-$lang['L_SQLLIB_ACTIVATEBOARD']="Paneli çalştır";
-$lang['L_SQL_NOTABLESSELECTED']="Tablo seçilmedi!";
-$lang['L_TOOLS']="Araçlar";
-$lang['L_TOOLS_TOOLBOX']="Veritabanı seçimi / Veritabanı işlemleri / Al / Ver";
-$lang['L_SQL_OPENFILE']="SQL dosyasını aç";
-$lang['L_SQL_OPENFILE_BUTTON']="yükle";
-$lang['L_MAX_UPLOAD_SIZE']="maximum Dosya boyutu";
-$lang['L_SQL_SEARCH']="Arama";
-$lang['L_SQL_SEARCHWORDS']="aranan kelime(ler)";
-$lang['L_START_SQL_SEARCH']="aramayı başlat";
-$lang['L_RESET_SEARCHWORDS']="arama sonucunu sil";
-$lang['L_SEARCH_OPTIONS']="Arama Seçenekleri";
-$lang['L_SEARCH_RESULTS']="aradığınız \"<b>%s</b>\" kelime sonucu \"<b>%s</b>\" Tablo'da bulunan sonuçlar";
-$lang['L_SEARCH_NO_RESULTS']="aradığınız \"<b>%s</b>\" kelimesi \"<b>%s</b>\" Tablo içersinde bulunamadı !";
-$lang['L_NO_ENTRIES']="\"<b>%s</b>\" isimli Tablo boş ve hiçbirşey yazılmamış.";
-$lang['L_SEARCH_ACCESS_KEYS']="Çevir: ileri=ALT+V, geri=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="Sütunda en azından bir aranılan kelime bulunmalıdır. (VEYA arama)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="Metin'de bütün aranılan kelimeler bir satırda bulunmalıdır, fakat aranılan kelimeler değişik sütunlarda bulunabilir. (Vakit alıcı)";
-$lang['L_SEARCH_OPTIONS_AND']="Sütunun içinde aranan kelimelerin hepsi bulunmalı (VE)";
-$lang['L_SEARCH_IN_TABLE']="Tablonun içinde ara";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Tablo yapısını düzenle";
-$lang['L_DEFAULT_CHARSET']="standart karakter seti";
-$lang['L_TITLE_KEY_PRIMARY']="İndeks";
-$lang['L_TITLE_KEY_UNIQUE']="Eşsiz Anahtar";
-$lang['L_TITLE_INDEX']="İndeks";
-$lang['L_TITLE_KEY_FULLTEXT']="Full Metin Anahtari";
-$lang['L_TITLE_NOKEY']="Anahtar yok";
-$lang['L_TITLE_SEARCH']="Ara";
-$lang['L_TITLE_MYSQL_HELP']="MySQL Klavuzu";
-$lang['L_TITLE_UPLOAD']="SQL dosyasını yükle";
-$lang['L_PRIMARYKEY_DELETED']="Birincil Anahtar silindi";
-$lang['L_PRIMARYKEY_NOTFOUND']="Birincil Anahtar bulunmadı";
-$lang['L_PRIMARYKEYS_CHANGED']="Birincil Anahtar değiştirildi";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Birincil Anahtar değiştirirken bir hata oluştu";
-$lang['L_SQL_VIEW_COMPACT']="Kompakt görünüm";
-$lang['L_SQL_VIEW_STANDARD']="Varsayılan görünüm";
-$lang['L_FIELDS_OF_TABLE']="Tablonun alanları";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="Ebadı";
-$lang['L_TABLE_TYPE']="Tür";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
 
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Komut';
+$lang['L_IMPORT_NOTABLE'] = 'Yüklenecek tablo seçilmemiş!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'SQL emirleriinin işlenmesi kayıtlarınıza zarar verebilir! MyOOSDumper işlemden hiç bir yükümlülük kabul etmez.';
+$lang['L_SQL_EXEC'] = 'SQL komudu çalıştır';
+$lang['L_SQL_DATAVIEW'] = 'Veri görüntüsü';
+$lang['L_SQL_TABLEVIEW'] = 'Tablo görüntüsü';
+$lang['L_SQL_VONINS'] = '/';
+$lang['L_SQL_NODATA'] = 'Kayıt bulunmuyor';
+$lang['L_SQL_RECORDUPDATED'] = 'Kayıt değiştirildi';
+$lang['L_SQL_RECORDINSERTED'] = 'Kayıt eklendi';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'Veritabanı listesine dön';
+$lang['L_SQL_RECORDDELETED'] = 'Kayıt silindi';
+$lang['L_ASKTABLEEMPTY'] = '`%s` Tablo boşaltılsın mı?';
+$lang['L_SQL_RECORDEDIT'] = 'Kayıt işleniyor';
+$lang['L_SQL_RECORDNEW'] = 'Kayıt ekle';
+$lang['L_ASKDELETERECORD'] = 'Kayıt silinsinmi?';
+$lang['L_ASKDELETETABLE'] = '`%s` Tablo silinsinmi?';
+$lang['L_SQL_BEFEHLE'] = 'SQL Komutları';
+$lang['L_SQL_BEFEHLNEU'] = 'yeni komut';
+$lang['L_SQL_BEFEHLSAVED1'] = 'SQL komudu';
+$lang['L_SQL_BEFEHLSAVED2'] = 'Eklendi';
+$lang['L_SQL_BEFEHLSAVED3'] = 'Kayıt işlendi';
+$lang['L_SQL_BEFEHLSAVED4'] = 'üste kaydırıldı';
+$lang['L_SQL_BEFEHLSAVED5'] = 'silindi';
+$lang['L_SQL_QUERYENTRY'] = 'Sorgunun içeriği';
+$lang['L_SQL_COLUMNS'] = 'dizi';
+$lang['L_ASKDBDELETE'] = '`%s` Veritabınını içeriği ile birlikte silmek istiyormusun?';
+$lang['L_ASKDBEMPTY'] = '`%s` Veritabanının gerçekten boşaltılsınmı?';
+$lang['L_ASKDBCOPY'] = ' `%s` ın içeriği `%s` veritabanına kopyalansınmı?';
+$lang['L_SQL_TABLENEW'] = 'Tablolar düzenle';
+$lang['L_SQL_OUTPUT'] = 'SQL-çıktısı';
+$lang['L_DO_NOW'] = 'şimdi çalıştır';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Gidilecek veritabanının ismi eksik!';
+$lang['L_ASKDELETEFIELD'] = 'Hücre silinsinmi?';
+$lang['L_SQL_COMMANDS_IN'] = ' Dizinler ';
+$lang['L_SQL_COMMANDS_IN2'] = ' saniyede işlendi.';
+$lang['L_SQL_OUT1'] = 'Toplam';
+$lang['L_SQL_OUT2'] = 'komut çalıştırıldı';
+$lang['L_SQL_OUT3'] = ' Toplam';
+$lang['L_SQL_OUT4'] = 'not sayısı';
+$lang['L_SQL_OUT5'] = 'Veri 5000 satırı geçtiği için gösterilmiyor.';
+$lang['L_SQL_SELECDB'] = 'Veritabanı seçiniz';
+$lang['L_SQL_TABLESOFDB'] = 'Veritabanının tabloları';
+$lang['L_SQL_EDIT'] = 'işle';
+$lang['L_SQL_NOFIELDDELETE'] = 'Silinemiyor, bir tabloda en azından bir hücre bulunmalı.';
+$lang['L_SQL_FIELDDELETE1'] = 'Hücre';
+$lang['L_SQL_DELETED'] = 'silindi.';
+$lang['L_SQL_CHANGED'] = 'değiştirildi.';
+$lang['L_SQL_CREATED'] = 'oluşturuldu.';
+$lang['L_SQL_NODEST_COPY'] = 'Hedef belirlenmediği için kopyalanamıyor!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Hedeflenen tablo zaten var!';
+$lang['L_SQL_SCOPY'] = '`%s` tabloyapısı `%s` tablosuna kopyalandı.';
+$lang['L_SQL_TCOPY'] = '`%s` Tablosu içeriği ile `%s` tablosuna kopyalandı.';
+$lang['L_SQL_TABLENONAME'] = 'Tabloya isim vermelisiniz!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tablo isimi verilmemiş!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Karakter Seti ve Dil birbirine uymuyor (collation)!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Hata: alanadı geçersiz';
+$lang['L_SQL_CREATETABLE'] = 'Tablo oluştur';
+$lang['L_SQL_COPYTABLE'] = 'Tabloyu kopyala';
+$lang['L_SQL_STRUCTUREONLY'] = 'Saadece yapı';
+$lang['L_SQL_STRUCTUREDATA'] = 'Yapı ve veriler';
+$lang['L_SQL_NOTABLESINDB'] = 'Veritabanında tablo bulunmuyor';
+$lang['L_SQL_SELECTTABLE'] = 'Tablo seç';
+$lang['L_SQL_SHOWDATATABLE'] = 'Tablonun verilerini göster';
+$lang['L_SQL_TBLPROPSOF'] = 'Tablo özellikleri';
+$lang['L_SQL_EDITFIELD'] = 'Alanı işle';
+$lang['L_SQL_NEWFIELD'] = 'yeni alan';
+$lang['L_SQL_INDEXES'] = 'İndeksler';
+$lang['L_SQL_ATPOSITION'] = 'Posisyona ekle';
+$lang['L_SQL_FIRST'] = 'önce';
+$lang['L_SQL_AFTER'] = 'sonra';
+$lang['L_SQL_CHANGEFIELD'] = 'alanı işle';
+$lang['L_SQL_INSERTFIELD'] = 'Alan ekle';
+$lang['L_SQL_INSERTNEWFIELD'] = 'Yeni alan ekle';
+$lang['L_SQL_TABLEINDEXES'] = 'Tablo indexleri';
+$lang['L_SQL_ALLOWDUPS'] = "çift kayıt'a müsaade et";
+$lang['L_SQL_CARDINALITY'] = 'Kardinality';
+$lang['L_SQL_TABLENOINDEXES'] = 'Tablonun indexi yok';
+$lang['L_SQL_CREATEINDEX'] = 'yeni index oluştur';
+$lang['L_SQL_WASEMPTIED'] = 'boşaltıldı';
+$lang['L_SQL_RENAMEDTO'] = 'yeniden adlandırıldı';
+$lang['L_SQL_DBCOPY'] = '`%s` veritabanının içeriği `%s` veritabanına kopyalandı.';
+$lang['L_SQL_DBSCOPY'] = '`%s`veritabanının yapısı `%s` veritabanına kopyalandı.';
+$lang['L_SQL_WASCREATED'] = 'oluşturuldu';
+$lang['L_SQL_RENAMEDB'] = 'veritabanının adını değiştir';
+$lang['L_SQL_ACTIONS'] = 'İşlem';
+$lang['L_SQL_CHOOSEACTION'] = 'İşlem seç';
+$lang['L_SQL_DELETEDB'] = 'veritabanını sil';
+$lang['L_SQL_EMPTYDB'] = 'veritabanını boşalt';
+$lang['L_SQL_COPYDATADB'] = 'İçeriği veritabanına kopyala';
+$lang['L_SQL_COPYSDB'] = 'Yapıyı veritabanına kopyala';
+$lang['L_SQL_IMEXPORT'] = 'Al / ver ';
+$lang['L_INFO_RECORDS'] = 'Kayıtlar';
+$lang['L_NAME'] = 'İsim';
+$lang['L_ASKTABLEEMPTYKEYS'] = '`%s` Tablosu boşaltılıp indexler silinsinmi?';
+$lang['L_EDIT'] = 'düzenle';
+$lang['L_DELETE'] = 'Silme';
+$lang['L_EMPTY'] = 'içeriği boşalt';
+$lang['L_EMPTYKEYS'] = 'Boşaltıp indexleri silme';
+$lang['L_SQL_TABLEEMPTIED'] = '`%s` Tablosu boşaltıldı.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = '`%s` Tablosu boşaltıldı ve indexleri silindi.';
+$lang['L_SQL_LIBRARY'] = 'SQL-Kütüphanesi';
+$lang['L_SQL_ATTRIBUTES'] = 'Attributlar';
+$lang['L_SQL_UPLOADEDFILE'] = 'Yüklenen dosya: ';
+$lang['L_SQL_IMPORT'] = '`%s` Veritabanına dışalım';
+$lang['L_EXPORT'] = 'İhraç';
+$lang['L_IMPORT'] = 'Dışalım';
+$lang['L_IMPORTOPTIONS'] = 'Dışalım Seçenekleri';
+$lang['L_CSVOPTIONS'] = 'CSV Seçenekleri';
+$lang['L_IMPORTTABLE'] = 'Tablosuna dışalım';
+$lang['L_NEWTABLE'] = 'yeni tablo';
+$lang['L_IMPORTSOURCE'] = 'Dışalım kaynağı';
+$lang['L_FROMTEXTBOX'] = 'Metin alanından';
+$lang['L_FROMFILE'] = 'Dosyadan';
+$lang['L_EMPTYTABLEBEFORE'] = 'Tabloyu önce boşalt';
+$lang['L_CREATEAUTOINDEX'] = 'Auto-Index oluştur';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Sütun isimlerini ilk satıra yaz';
+$lang['L_CSV_FIELDSEPERATE'] = 'Hücreleri ayırmak için ';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Hücreleri kapsayan';
+$lang['L_CSV_FIELDSESCAPE'] = 'Hücrelerin kaçış harfi';
+$lang['L_CSV_EOL'] = 'Satırları ayıran';
+$lang['L_CSV_NULL'] = 'NULL un yerine kullanılacak';
+$lang['L_CSV_FILEOPEN'] = 'CSV-Dosyasını aç';
+$lang['L_IMPORTIEREN'] = 'Dışalım';
+$lang['L_SQL_EXPORT'] = '`%s` Veritabanından ihraç';
+$lang['L_EXPORTOPTIONS'] = 'İhraç Seçenekleri';
+$lang['L_EXCEL2003'] = 'Excel 2003 ve üstü';
+$lang['L_SHOWRESULT'] = 'Sonuçu göster';
+$lang['L_SENDRESULTASFILE'] = 'Sonuçu dosya olarak gönder';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> satır ihraç edildi';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Tablo kayıtlarının sayısı, dışalım edilecek bilgilerle uyuşmuyor (%d yerine %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d hücre tespit edildi, toplam %d satır';
+$lang['L_CSV_ERRORCREATETABLE'] = ' `%s` Tablo oluşturmada hata oluştu!';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'Dosya belirtiniz.';
+$lang['L_CSV_NODATA'] = 'Dışalım edilebilecek kayıt bulunamadı!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'genel fonksiyonlar';
+$lang['L_SQLLIB_RESETAUTO'] = 'Auto-değeri geri al';
+$lang['L_SQLLIB_BOARDS'] = 'Paneller';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'Paneli durdur';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'Paneli çalştır';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Tablo seçilmedi!';
+$lang['L_TOOLS'] = 'Araçlar';
+$lang['L_TOOLS_TOOLBOX'] = 'Veritabanı seçimi / Veritabanı işlemleri / Al / Ver';
+$lang['L_SQL_OPENFILE'] = 'SQL dosyasını aç';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'yükle';
+$lang['L_MAX_UPLOAD_SIZE'] = 'maximum Dosya boyutu';
+$lang['L_SQL_SEARCH'] = 'Arama';
+$lang['L_SQL_SEARCHWORDS'] = 'aranan kelime(ler)';
+$lang['L_START_SQL_SEARCH'] = 'aramayı başlat';
+$lang['L_RESET_SEARCHWORDS'] = 'arama sonucunu sil';
+$lang['L_SEARCH_OPTIONS'] = 'Arama Seçenekleri';
+$lang['L_SEARCH_RESULTS'] = "aradığınız \"<b>%s</b>\" kelime sonucu \"<b>%s</b>\" Tablo'da bulunan sonuçlar";
+$lang['L_SEARCH_NO_RESULTS'] = 'aradığınız "<b>%s</b>" kelimesi "<b>%s</b>" Tablo içersinde bulunamadı !';
+$lang['L_NO_ENTRIES'] = '"<b>%s</b>" isimli Tablo boş ve hiçbirşey yazılmamış.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Çevir: ileri=ALT+V, geri=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'Sütunda en azından bir aranılan kelime bulunmalıdır. (VEYA arama)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = "Metin'de bütün aranılan kelimeler bir satırda bulunmalıdır, fakat aranılan kelimeler değişik sütunlarda bulunabilir. (Vakit alıcı)";
+$lang['L_SEARCH_OPTIONS_AND'] = 'Sütunun içinde aranan kelimelerin hepsi bulunmalı (VE)';
+$lang['L_SEARCH_IN_TABLE'] = 'Tablonun içinde ara';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Tablo yapısını düzenle';
+$lang['L_DEFAULT_CHARSET'] = 'standart karakter seti';
+$lang['L_TITLE_KEY_PRIMARY'] = 'İndeks';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Eşsiz Anahtar';
+$lang['L_TITLE_INDEX'] = 'İndeks';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Full Metin Anahtari';
+$lang['L_TITLE_NOKEY'] = 'Anahtar yok';
+$lang['L_TITLE_SEARCH'] = 'Ara';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQL Klavuzu';
+$lang['L_TITLE_UPLOAD'] = 'SQL dosyasını yükle';
+$lang['L_PRIMARYKEY_DELETED'] = 'Birincil Anahtar silindi';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Birincil Anahtar bulunmadı';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Birincil Anahtar değiştirildi';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Birincil Anahtar değiştirirken bir hata oluştu';
+$lang['L_SQL_VIEW_COMPACT'] = 'Kompakt görünüm';
+$lang['L_SQL_VIEW_STANDARD'] = 'Varsayılan görünüm';
+$lang['L_FIELDS_OF_TABLE'] = 'Tablonun alanları';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'Ebadı';
+$lang['L_TABLE_TYPE'] = 'Tür';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/language/vn/help.html b/msd/language/vn/help.html
new file mode 100644
index 00000000..64a1411b
--- /dev/null
+++ b/msd/language/vn/help.html
@@ -0,0 +1,147 @@
+<div id="content">
+<h3><strong>MyOOS [Dumper]</strong> based on MySQLDumper 1.24.4</h3>
+
+<h3>About this project</h3>
+<p><strong>MyOOS [Dumper]</strong> is an improved version of MySQLDumper 1.24.4 (January 24, 2011). This enhancement takes into account the development of PHP.</p>.
+<p>Most of all stability, security and handling are the main focus of <strong>MyOOS [Dumper]</strong>. But also an attractive template is included, which can be edited and adapted to your own needs.</p>.
+
+
+<p><strong>MyOOS [Dumper]</strong> is a backup program for MySQL databases, written in PHP and Perl. With it, backup copies of the data (store, blog, etc.) can be created and restored if necessary. Especially for web space without shell access, MyOOS [Dumper] is a useful alternative.</p>. 
+
+<p>The idea for MySQLDumper came from Daniel Schlichtholz. He opened the MySQLDumper forum in 2004, whereupon programmers wrote new scripts and extended existing ones.</p>
+
+
+
+<h3>Wish List / Future Attractions</h3>.
+<p>Do you have any suggestions for improvements? Feel free to contact the development team via the forum <a href="https://foren.myoos.de/viewforum.php?f=41" target="_blank">https://foren.myoos.de/viewforum.php?f=41</a>.</p>
+
+
+<h3>Contribute</h3>
+<p>If you would like to help us improve the MyOOS project, we welcome your pull requests via GitHub here.</p>
+<a href="https://github.com/r23/MyOOS-Dumper/" target="_blank">https://github.com/r23/MyOOS-Dumper/</a>
+
+
+<h3>Financial Support</h3>.
+<p>You can use PayPal Me<br>.
+<a href="https://www.paypal.com/paypalme/r23de?locale.x=de_DE" target="_blank">https://www.paypal.com/paypalme/r23de?locale.x=de_DE</a></p> 
+
+<p>or via the QR code<br>.  
+<img src="images/qrcode.png" alt="Financial support for MyOOS [Dumper]"></p>
+
+Send money to the MyOOS project. <br>
+
+<p>We hope you enjoy this project.<br><p><h4>The MyOOS [Dumper] Team</h4>
+
+<img src="css/mod/pics/navi_bg.jpg" alt="MyOOS [Dumper]"><br>
+
+<h3>MyOOS [Dumper] Help</h3>
+
+<h4>Download</h4>
+<p>You can always get the latest versions via GitHub<br>.
+<a href="https://github.com/r23/MyOOS-Dumper/releases" target="_blank">https://github.com/r23/MyOOS-Dumper/releases</a></p>
+
+
+<h4>System requirement</h4>.
+<p>The script works on any server (Windows, Linux, ...) <br>
+with PHP >= version 7.4 with GZip support, MySQL (version 4.1 or higher), JavaScript (must be enabled)</p>.
+<p>Copy the mod folder from the MyOOS archive to a separate working folder.</p>.
+
+<h4>Installation</h4></a>.
+The installation process is straightforward.
+<p>From the MyOOS archive, copy the mod folder into any folder.<br>
+Upload all the files from the mod folder to your web server. (For example, to the lowest level in [server web directory/]mod)<br>
+... done!<br>
+You can now call MyOOS [Dumper] in your web browser by "https://example.com/mod/",<br>
+to complete the installation. Just follow the instructions.<br>
+<br><b>Note:</b><br><i>If on your server the script is not allowed to create directories,<br>
+you have to do this manually, because MyOOS [Dumper] stores the data ordered in
+directories.<br> 
+The script aborts with an appropriate statement!<br>
+After you have created the directories (according to the hint), it runs normally and without restrictions.</i>
+
+<a name="perl"></a><h4>Perl script instructions</h4>.
+Most have a cgi-bin directory where perl can be run. <br>
+This is usually accessible by browser via http://www.example.com/cgi-bin/. <br>
+<br>
+For this case, please perform the following steps:<br><br>.
+
+1. call the Backup page in MyOOS [Dumper] and click on "Backup Perl". <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor.<br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces).<br>
+5. save crondump.pl .<br>
+6. copy crondump.pl, as well as perltest.pl and simpletest.pl into the cgi-bin directory (ascii mode in FTP).<br>
+7. give the files the permissions 755.<br>
+7b. If the ending cgi is desired, change the ending of all 3 files from pl -> cgi (rename). <br>
+8. call the configuration in MyOOS [Dumper].<br>
+9. select the page Cronscript. <br>
+10. change perl execution path to /cgi-bin/ .<br>
+10b. If the scripts have .pl, change the file extension to .cgi .<br>
+11.Save the configuration. <br><br>
+
+Done, the scripts can now be called from the backup page.<br><br>.
+
+For those who can run Perl in all directories, the following steps will suffice:<br><br>.
+
+1. call in the MyOOS [Dumper] the page Backup. <br>
+2. copy the path that is behind entry in crondump.pl for $absolute_path_of_configdir:. <br>
+3. open the file "crondump.pl" in the editor. <br>
+4. enter the copied path there at absolute_path_of_configdir (no spaces). <br>
+5. save crondump.pl .<br>
+6. give the files the permissions 755. <br>
+6b. If the extension cgi is desired, change the extension of all 3 files from pl -> cgi (rename). <br>
+(ev. 10b+11 from above)<br>
+<br>
+
+Windowsuser have to change the first line of all scripts, there is the path of Perl. Example: <br>
+instead of: #!/usr/bin/perl -w <br>
+now: #!C:_usr/bin/perl.exe -w <br>
+
+<h4>Operation</h4><ul>.
+
+<h6>Menu</h6>.
+In the selection list above you set the database.<br>
+All actions refer to the database set here.
+
+<h6>Home</h6>
+Here you can learn about your system, the different installed versions and details about the
+versions and details about the configured databases.<br>
+If you click on the database name, you will see a list of the tables with the number of entries
+with the number of entries, the size and the last update date.
+
+<h6>Configuration</h6>.
+Here you can edit your configuration, save it or restore the initial configuration.
+restore.
+<ul><br>
+	<li><a name="conf1"></a><strong>Configured databases:</strong> the listing of configured databases. The active database is listed in <b>bold</b>. </li>
+	<li><a name="conf2"></a><strong>Table prefix:</strong> here you can specify (for each database) a prefix. This is a filter that will take into account for dumps only the tables that start with this prefix (for example, all tables that start with "phpBB_"). If you want all tables in this database to be saved, just leave the field empty.</li>.
+	<li><a name="conf3"></a><strong>GZip compression:</strong> Here you can enable compression. It is recommended to enable it, because the files will be much smaller after all and disk space is always scarce.</li>.
+	<li><a name="conf5"></a><strong>Email with Dumpfile:</strong> If this option is enabled, an email with the dump as an attachment will be sent after the backup is complete (caution, compression should absolutely be on, otherwise the attachment will be too large and may not be sent!).</li>
+	<li><a name="conf6"></a><strong>Email address:</strong> Recipient address for the email.</li>
+	<li><a name="conf7"></a><strong>Sender of the email:</strong> this address appears as the sender in the email.</li>
+	<li><a name="conf13"></a><strong>FTP Transfer: </strong>If this option is enabled, the backup file will be sent via FTP after the backup is completed.</li>
+	<li><a name="conf14"></a><strong>FTP Server: </strong>The address of the FTP server (e.g. ftp.mybackups.com).</li>
+	<li><a name="conf15"></a><strong>FTP Server Port: </strong>The port of the FTP server (usually 21).</li>
+	<li><a name="conf16"></a><strong>FTP User: </strong>The username of the FTP account. </li>
+	<li><a name="conf17"></a><strong>FTP Password: </strong>The password of the FTP account. </li>
+	<li><a name="conf18"></a><strong>FTP Upload Folder: </strong>The directory where the backup file should go (upload permissions must exist!).</li>
+	<li><a name="conf8"></a><strong>Automatic deletion of backups:</strong> If this option is enabled, older backups will be deleted automatically according to the following rules.</li>.
+	<li><a name="conf10"></a><strong>Number of backup files:</strong> A value > 0 deletes all backup files except for the number specified here.</li>
+	<li><a name="conf11"></a><strong>Language:</strong> here you specify the language for the interface.</li>
+</ul>
+
+<h6>Administration</h6>.
+This is where the actual actions are performed.<br>
+It will show you all the files in the backup directory.
+For the actions "Restore" and "Delete" a file must be selected.
+<UL>
+	<li><strong>Restore:</strong> This will update the database with the selected backup file.</li>
+	<li><strong>Delete:</strong> This lets you delete the selected backup file.</li>
+	<li><strong>Start new backup:</strong> Here you start a new backup (dump) according to the parameters set in the configuration.</li>.
+</UL>
+
+<h6>Log</h6>
+Here you can see and delete the log entries.
+<h6>Credits / Help</h6>
+this page.
+</ul>
diff --git a/msd/language/vn/help.php b/msd/language/vn/help.php
deleted file mode 100644
index 7f06e22d..00000000
--- a/msd/language/vn/help.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<div id="content">
-<h3>MyOOS [Dumper] based on MySQLDumper 1.24.4</h3>
-
-<h3>Về dự án này</h3>
-Ý tưởng cho dự án này là của Daniel Schlichtholz.<p>Năm 2004, ông tạo ra diễn đàn <a href="http://forum.mysqldumper.de" target="_blank">MySQLDumper</a> và sau đó, lập trình những đoạn mã mới, bổ sung đoạn mã của Daniel.<br>Sau một thời gian ngắn, mã nguồn phát triển thành một dự án lớn hơn.<p>Nếu bạn có bất cứ góp ý nào nhằm cải tiến mã nguồn, bạn có thể truy cập vào Diễn đàn MySQLDumper: <a href="http://forum.mysqldumper.de" target="_blank">http://forum.mysqldumper.de</a>.<p>Chúc bạn có những giây phút thú vị.<br><br><h4>The MySQLDumper-Team</h4>
-<table><tr><td><img src="images/logo.gif" alt="MySQLDumper" border="0"></td><td valign="top">
-Daniel Schlichtholz</td></tr></table>
-
-<h3>Trợ giúp về MySQLDumper</h3>
-
-<h4>Download</h4>
-Mã nguồn này có thể tải vè từ trang chủ của MySQLDumper.<br>
-Hãy ghé thăm trang chủ của MySQLDumper thường xuyên để có những thông tin mới nhất, đầy đủ nhất về các phiên bản nâng cấp của phần mềm.<br>
-Địa chỉ website là <a href="http://forum.mysqldumper.de" target="_blank">
-http://forum.mysqldumper.de
-</a>
-
-<h4>System Mandatories</h4>
-Mã nguồn này có thể chạy trên các hệ thống máy chủ thông dụng (Windows, Linux, ...) <br>
-và PHP >= Version 4.3.4 với GZip-Library, MySQL (>= 3.23), JavaScript (phải được cho phép).
-
-<a href="install.php?language=vn" target="_top"><h4>Cài đặt</h4></a>
-Chương trình có thể cài đặt rất dễ dàng.
-Giải nén chương trình vào thư mục bất kỳ trên Webserver<br>
-(VD: vào thư mục gốc của Website [Thư mục gốc Server/]MySQLDumper)<br>
-chmod 777 cho file config.php<br>
-... hết!<br>
-Chạy MySQLDumper trên trình duyệt (FireFox, Internet Explorer) bằng cách gõ "http://webserver/MySQLDumper"
-để hoàn thành cài đặt (xem hướng dẫn kèm theo).
-
-<br><b>Chú ý:</b><br><i>Nếu webserver của bạn chạy với tùy chọn safemode=ON thì MySqlDump không thể tạo thư mục.<br>
-Bạn sẽ phải tự mình tạo.<br>
-Trong trường hợp đó, MySqlDump sẽ cho bạn biết mình phải làm gì.<br>
-Sau khi bạn tạo ra các thư mục, MySqlDump sẽ hoạt động bình thường.</i><br>
-
-<a name="perl"></a><h4>Hướng dẫn cho mã nguồn Perl</h4>
-
-Hầu hết thì mọi website đều có một thư mục tên là cgi-bin, trong đó Perl có thể chạy. <br>
-Điều này có nghĩa là có thể truy cập từ trình duyệt vào một địa chỉ có dạng http://www.domain.de/cgi-bin/. <br><br>
-
-Đọc kỹ các hướng dẫn từng bước ở dưới đây.  <br><br>
-
-	
-1. Vào MySQLDumper/ trang "Sao lưu"; bấm vào "Backup Perl" <br> 
-2. Sao chép đường dẫn đứng đằng sau mục nhập trong crondump.pl cho $absolute_path_of_configdir: <br>
-3. Mở tập tin "crondump.pl" bằng trình soạn thảo <br>
-4. Dán đường dẫn đã sao chép với absolute_path_of_configdir (không có khoảng trắng) <br>
-5. Lưu crondump.pl <br>
-6. sao chép crondump.pl, cũng như perltest.pl và simpletest.pl vào thư mục cgi-bin (chế độ ASCII trong chương trình ftp!) <br>
-7. chmod 755 cho nó. <br>
-7b. Nếu muốn phần mở rộng là cgi, chỉ việc đổi tên đuôi pl -> cgi<br>
-8. Vào MySQLDumper / Cấu hình <br>
-9. Nhấp chuột vào <br> Cronscript
-10. Thay đổi đường dẫn Perl đến /cgi-bin/ <br>
-10B. Nếu Script được đổi tên thành *. cgi, đổi Fileextension thành cgi <br>
-11. Ghi lại cấu hình. <br><br>
-
-Sẵn sàng! Các lệnh có sẵn ở trang "Sao lưu" <br><br>
-
-Bạn có thể chạy Perl ở bất cứ đâu, chỉ cần thực hiện các bước sau:  <br><br>
-
-1.  Vào MySQLDumper / "Sao lưu".  <br>
-2.  Sao chép đường dẫn đứng đằng sau mục nhập trong crondump.pl cho $absolute_path_of_configdir:  <br>
-3. Mở file "crondump.pl" <br>
-4. án đường dẫn đã sao chép với absolute_path_of_configdir (không có khoảng trắng) <br>
-5.  Save crondump.pl <br>
-
-6. chmod 755 cho nó.  <br> 
-6b. Nếu muốn phần mở rộng là cgi, chỉ việc đổi tên đuôi pl -> cgi <br>
-(tiếp: 10b+11 như trên) <br><br>
-
-
-Người dùng Windows phải đổi tất cả các dòng đầu của mã nguồn Perl, thành đường dẫn tới Perl.  <br><br>
-
-Ví dụ:  <br>
-
-instead of:  #!/usr/bin/perl w <br>
-now #!C:\perl\bin\perl.exe w<br>
-
-<h4>Hệ thống</h4><ul>
-
-<h6>Menu</h6>
-Hộp chọn cho phép bạn chọn CSDL để làm việc.<br>
-Tất cả các thao tác sẽ được áp dụng cho CSDL đang hiển thị.
-
-<h6>Trang chủ</h6>
-Tại đây bạn có thể xem tất cả các thông tin của hệ thống, phiên bản của phần mềm và chi tiết các cấu hình của hệ thống.<br>
-Khi bạn Click vào một CSDL trong bảng, bạn sẽ thấy danh sách các bảng với số bản ghi, kích cỡ và lần cuối cập nhật stamp.
-
-<h6>Cấu hình</h6>
-Tại đây bạn có thể sửa các cấu hình, ghi hoặc nạp các cấu hình mặc định.
-<ul>
-	<li><a name="conf1"><strong>Cấu hình CSDL:</strong> Danh scahs của cấu hình CSDL. CSDL đang hoạt động được tô đậm.</li>
-	<li><a name="conf2"><strong>Table-Prefix (tiền tố bảng):</strong> bạn có thể chọn 1 tiền tố (prefix) cho mỗi CSDL. Tiền tố là một dạng lọc, nó chỉ thao tác với các bảng trong một khu vực, bắt đầu bằng tiền tố này (vd: tất cả các bagr bắt đầu bằng "phpBB_"). Nếu bạn không muốn sử dụng nó, hãy để trống trường này.</li>
-	<li><a name="conf3"><strong>Nén GZip:</strong> Dùng để kích hoạt chế độ nén. Hãy sử dụng nếu có thể vì nó giúp bạn nén nhỏ file, tiết kiệm dung lượng host, giảm thời gian download và do đó tiết kiệm băng thông.</li>
-	<li><a name="conf19"></a><strong>Số bản ghi khi Sao lưu:</strong> Đây là số của các bản ghi được đọc cùng lúc trong khi sao lưu, trước khi gọi các tập lệnh. Nếu nó làm chậm máy chủ, bạn có thể giảm tham số này để ngăn ngừa timeouts.</li>
-	<li><a name="conf20"></a><strong>Số bản ghi khi phục hồi:</strong> Đây là số của các bản ghi được đọc cùng lúc trong khi sao lưu, trước khi gọi các tập lệnh. Nếu nó làm chậm máy chủ, bạn có thể giảm tham số này để ngăn ngừa timeouts.</li>
-	<li><a name="conf4"></a><strong>Thư mục chứa file Backup:</strong> Chọn thư mục chứa file Backup. Nếu thư mục này chưa có, hệ thống sẽ tạo nó cho bạn. Có thể sử dụng đường dẫn tương đối hoặc tuyệt đối.</li>
-	<li><a name="conf5"></a><strong>Gửi file sao lưu vào email:</strong> Cho phép hệ thống gửi một email đính kèm file backup tới địa chỉ email được chỉ ra bên dưới (cẩn trọng khi sử dụng!, bạn phải chọn tùy chọn nén file khi sử dụng tính năng này vì file quá lớn có thể không gửi vào email được!)</li>
-	<li><a name="conf6"></a><strong>Địa chỉ Email:</strong> Recipient's email address</li>
-	<li><a name="conf7"></a><strong>Tiêu đề của Email:</strong> Tóm lược nội dung email bằng một tiêu dề.</li>
-	<li><a name="conf13"></a><strong>FTP-Transfer: </strong>Tùy chọn này cho phép hệ thống tự động gửi file backup bằng phương thức FTP.</li>
-	<li><a name="conf14"><strong>FTP Server: </strong>Địa chỉ của FTP-Servers (VD: ftp.mangvn.org)</li>
-	<li><a name="conf15"></a><strong>FTP Server Port: </strong>cổng kết nối FTP-Server (mặc định là cổng 21)</li>
-	<li><a name="conf16"></a><strong>FTP User: </strong>tên đăng nhập tài khoản FTP</li>
-	<li><a name="conf17"></a><strong>FTP Passwort: </strong>Mật khẩu  đăng nhập tài khoản FTP</li>
-	<li><a name="conf18"></a><strong>FTP Upload-Ordner: </strong>thư mục chứa file backup (phải được cho phép upload lên!)</li>
-	
-	<li><a name="conf8"></a><strong>Tự động xóa file backup:</strong> Tùy chọn này cho phép tự động xóa theo một quy luật được thiết lập trước.</li>
-	<li><a name="conf10"></a><strong>Xóa file nếu số lượng vượt quá:</strong> Nếu các file có số lương nhiều hơn giá trị được chỉ ra thì file cũ sẽ bị xóa.</li>
-	<li><a name="conf11"></a><strong>Language (ngôn ngữ):</strong> choose your language for the interface (chọn ngôn ngữ bạn muốn sử dụng cho chương trình này).</li>
-</ul>
-
-<h6>Quản lý</h6>
-Danh sách tất cả các thao tác có thể thực hiện sẽ được liệt kê tại đây.<br>
-Bạn có thể thấy tất cacsr các file trong thư mục Backup.
-Thao tác "Phục hồi" và "Xóa" có thể thực hiện ở trước mỗi file.
-<UL>
-	<li><strong>Phục hồi:</strong> bạn có thể phục hồi các bản ghi của file backup đã lựa chọn.</li>
-	<li><strong>Xóa:</strong> bạn có thể xóa file backup đã lựa chọn.</li>
-	<li><strong>Bắt đầu 1 sao lưu (Dump):</strong> tại đây bạn có thể bắt đầu 1 sao lưu (dump) mới với các thông số đã được cấu hình.</li>
-</UL>
-
-<h6>Log / Nhật ký hệ thống</h6>
-Bạn có thể đọc các bản ghi nhật ký và xóa chúng.
-
-<h6>Yêu cầu / Trợ giúp</h6>
-(chính là trang này.)
-</ul>
\ No newline at end of file
diff --git a/msd/language/vn/lang.php b/msd/language/vn/lang.php
index 0ce4212b..8b14c00d 100644
--- a/msd/language/vn/lang.php
+++ b/msd/language/vn/lang.php
@@ -1,115 +1,112 @@
 <?php
-$lang['L_YES']="Có";
-$lang['L_TO']="tới";
-$lang['L_ACTIVATED']="đã kích hoạt";
-$lang['L_NOT_ACTIVATED']="không hoạt động";
-$lang['L_ERROR']="Lỗi";
-$lang['L_OF']=" của ";
-$lang['L_ADDED']="bổ sung";
-$lang['L_DB']="CSDL";
-$lang['L_DBS']="CSDL";
-$lang['L_TABLES']="Bảng";
-$lang['L_TABLE']="Bảng";
-$lang['L_RECORDS']="Bản ghi(Records)";
-$lang['L_COMPRESSED']="nén (gz)";
-$lang['L_NOTCOMPRESSED']="bình thường (không nén)";
-$lang['L_GENERAL']="Tổng quan";
-$lang['L_COMMENT']="Ghi chú";
-$lang['L_FILESIZE']="Cỡ file";
-$lang['L_ALL']="tất cả";
-$lang['L_NONE']="không";
-$lang['L_WITH']=" cùng với ";
-$lang['L_DIR']="Thư mục";
-$lang['L_RECHTE']="Cho phép";
-$lang['L_STATUS']="Trạng thái";
-$lang['L_FINISHED']="đã kết thúc";
-$lang['L_FILE']="File";
-$lang['L_FIELDS']="Trường";
-$lang['L_NEW']="mới";
-$lang['L_CHARSET']="Mã hóa";
-$lang['L_COLLATION']="Đối chiếu";
-$lang['L_CHANGE']="thay đổi";
-$lang['L_IN']="trong";
-$lang['L_DO']="Thực hiện";
-$lang['L_VIEW']="xem";
-$lang['L_EXISTING']="tồn tại";
-$lang['L_BACK']="quay lại";
-$lang['L_DB_HOST']="Hostname";
-$lang['L_DB_USER']="User";
-$lang['L_DB_PASS']="Password";
-$lang['L_INFO_SCRIPTDIR']="Thư mục chứa MySQLDumper";
-$lang['L_INFO_ACTDB']="Cơ sở dữ liệu hiện hành";
-$lang['L_WRONGCONNECTIONPARS']="Thông số kết nối sai hoặc thiếu!";
-$lang['L_CONN_NOT_POSSIBLE']="Không thể kết nối!";
-$lang['L_SERVERCAPTION']="Hiển thị Server";
-$lang['L_HELP_SERVERCAPTION']="Khi sử dụng MySQLDumper trên những tên miền hay những server khác nhau, sẽ hữu ích nếu hiển thị tên miền/server ở trên cùng màn hình.";
-$lang['L_ACTIVATE_MULTIDUMP']="kích hoạt MultiDump";
-$lang['L_SAVE']="Save";
-$lang['L_RESET']="Làm lại";
-$lang['L_PRAEFIX']="Tiền tố bảng";
-$lang['L_AUTODELETE']="Tự động xóa phần sao lưu";
-$lang['L_MAX_BACKUP_FILES_EACH2']="Cho mỗi một CSDL";
-$lang['L_SAVING_DB_FORM']="CSDL";
-$lang['L_TESTCONNECTION']="Kiểm tra Kết nối";
-$lang['L_BACK_TO_MINISQL']="Soạn thảo CSDL";
-$lang['L_CREATE']="Tạo";
-$lang['L_VARIABELN']="Các biến";
-$lang['L_STATUSINFORMATIONEN']="Thông tin Trạng thái";
-$lang['L_VERSIONSINFORMATIONEN']="Thông tin Phiên bản";
-$lang['L_MSD_INFO']="Thông tin MyOOS [Dumper]";
-$lang['L_BACKUPFILESANZAHL']="Trong thư mục Backup có";
-$lang['L_LASTBACKUP']="Sao lưu Cuối cùng";
-$lang['L_NOTAVAIL']="<em>không có</em>";
-$lang['L_VOM']="từ";
-$lang['L_MYSQLVARS']="Biến MySQL";
-$lang['L_MYSQLSYS']="Lệnh MySQL";
-$lang['L_STATUS']="Trạng thái";
-$lang['L_PROZESSE']="Tiến trình";
-$lang['L_INFO_NOVARS']="không có biến nào hợp lệ";
-$lang['L_INHALT']="Giá trị";
-$lang['L_INFO_NOSTATUS']="không có trạng thái nào hợp lệ";
-$lang['L_INFO_NOPROCESSES']="không có tiến trình nào đang chạy";
-$lang['L_FM_FREESPACE']="Dung lượng trống trên Server";
-$lang['L_LOAD_DATABASE']="Nạp lại các CSDL";
-$lang['L_HOME']="Trang chủ";
-$lang['L_CONFIG']="Cấu hình";
-$lang['L_DUMP']="Sao lưu";
-$lang['L_RESTORE']="Phục hồi";
-$lang['L_FILE_MANAGE']="File Admin";
-$lang['L_LOG']="Log";
-$lang['L_CHOOSE_DB']="Chọn CSDL";
-$lang['L_CREDITS']="Yêu cầu / Trợ giúp";
-$lang['L_MULTI_PART']="Sao lưu Nhiều phần";
-$lang['L_LOGFILENOTWRITABLE']="Không thể ghi Logfile!";
-$lang['L_SQL_ERROR1']="Lỗi trong Lệnh truy xuất (Query):";
-$lang['L_SQL_ERROR2']="MySQL báo:";
-$lang['L_UNKNOWN']="không rõ";
-$lang['L_UNKNOWN_NUMBER_OF_RECORDS']="không rõ";
-$lang['L_OK']="OK";
-$lang['L_CRON_COMPLETELOG']="Xuất đầy đủ Log";
-$lang['L_NO']="không";
-$lang['L_CREATE_DATABASE']="Tạo ra cơ sở dữ liệu mới";
-$lang['L_EXPORTFINISHED']="Quá trình xuất đã kết thúc.";
-$lang['L_SQL_BROWSER']="Duyệt SQL";
-$lang['L_SERVER']="Máy chủ";
-$lang['L_MYSQL_CONNECTION_ENCODING']="Mã chuẩn của MySQL-Server
+
+$lang['L_YES'] = 'Có';
+$lang['L_TO'] = 'tới';
+$lang['L_ACTIVATED'] = 'đã kích hoạt';
+$lang['L_NOT_ACTIVATED'] = 'không hoạt động';
+$lang['L_ERROR'] = 'Lỗi';
+$lang['L_OF'] = ' của ';
+$lang['L_ADDED'] = 'bổ sung';
+$lang['L_DB'] = 'CSDL';
+$lang['L_DBS'] = 'CSDL';
+$lang['L_TABLES'] = 'Bảng';
+$lang['L_TABLE'] = 'Bảng';
+$lang['L_RECORDS'] = 'Bản ghi(Records)';
+$lang['L_COMPRESSED'] = 'nén (gz)';
+$lang['L_NOTCOMPRESSED'] = 'bình thường (không nén)';
+$lang['L_COMMENT'] = 'Ghi chú';
+$lang['L_FILESIZE'] = 'Cỡ file';
+$lang['L_ALL'] = 'tất cả';
+$lang['L_NONE'] = 'không';
+$lang['L_WITH'] = ' cùng với ';
+$lang['L_DIR'] = 'Thư mục';
+$lang['L_RECHTE'] = 'Cho phép';
+$lang['L_STATUS'] = 'Trạng thái';
+$lang['L_FINISHED'] = 'đã kết thúc';
+$lang['L_FILE'] = 'File';
+$lang['L_FIELDS'] = 'Trường';
+$lang['L_NEW'] = 'mới';
+$lang['L_CHARSET'] = 'Mã hóa';
+$lang['L_COLLATION'] = 'Đối chiếu';
+$lang['L_CHANGE'] = 'thay đổi';
+$lang['L_IN'] = 'trong';
+$lang['L_DO'] = 'Thực hiện';
+$lang['L_VIEW'] = 'xem';
+$lang['L_EXISTING'] = 'tồn tại';
+$lang['L_BACK'] = 'quay lại';
+$lang['L_DB_HOST'] = 'Hostname';
+$lang['L_DB_USER'] = 'User';
+$lang['L_DB_PASS'] = 'Password';
+$lang['L_INFO_SCRIPTDIR'] = 'Thư mục chứa MyOOS [Dumper]';
+$lang['L_INFO_ACTDB'] = 'Cơ sở dữ liệu hiện hành';
+$lang['L_WRONGCONNECTIONPARS'] = 'Thông số kết nối sai hoặc thiếu!';
+$lang['L_CONN_NOT_POSSIBLE'] = 'Không thể kết nối!';
+$lang['L_SERVERCAPTION'] = 'Hiển thị Server';
+$lang['L_HELP_SERVERCAPTION'] = 'Khi sử dụng MyOOS [Dumper] trên những tên miền hay những server khác nhau, sẽ hữu ích nếu hiển thị tên miền/server ở trên cùng màn hình.';
+$lang['L_ACTIVATE_MULTIDUMP'] = 'kích hoạt MultiDump';
+$lang['L_SAVE'] = 'Save';
+$lang['L_RESET'] = 'Làm lại';
+$lang['L_PRAEFIX'] = 'Tiền tố bảng';
+$lang['L_AUTODELETE'] = 'Tự động xóa phần sao lưu';
+$lang['L_MAX_BACKUP_FILES_EACH2'] = 'Cho mỗi một CSDL';
+$lang['L_SAVING_DB_FORM'] = 'CSDL';
+$lang['L_TESTCONNECTION'] = 'Kiểm tra Kết nối';
+$lang['L_BACK_TO_MINISQL'] = 'Soạn thảo CSDL';
+$lang['L_CREATE'] = 'Tạo';
+$lang['L_VARIABELN'] = 'Các biến';
+$lang['L_STATUSINFORMATIONEN'] = 'Thông tin Trạng thái';
+$lang['L_VERSIONSINFORMATIONEN'] = 'Thông tin Phiên bản';
+$lang['L_MOD_INFO'] = 'Thông tin MyOOS [Dumper]';
+$lang['L_BACKUPFILESANZAHL'] = 'Trong thư mục Backup có';
+$lang['L_LASTBACKUP'] = 'Sao lưu Cuối cùng';
+$lang['L_NOTAVAIL'] = '<em>không có</em>';
+$lang['L_VOM'] = 'từ';
+$lang['L_MYSQLVARS'] = 'Biến MySQL';
+$lang['L_MYSQLSYS'] = 'Lệnh MySQL';
+$lang['L_STATUS'] = 'Trạng thái';
+$lang['L_PROZESSE'] = 'Tiến trình';
+$lang['L_INFO_NOVARS'] = 'không có biến nào hợp lệ';
+$lang['L_INHALT'] = 'Giá trị';
+$lang['L_INFO_NOSTATUS'] = 'không có trạng thái nào hợp lệ';
+$lang['L_INFO_NOPROCESSES'] = 'không có tiến trình nào đang chạy';
+$lang['L_FM_FREESPACE'] = 'Dung lượng trống trên Server';
+$lang['L_LOAD_DATABASE'] = 'Nạp lại các CSDL';
+$lang['L_HOME'] = 'Trang chủ';
+$lang['L_CONFIG'] = 'Cấu hình';
+$lang['L_DUMP'] = 'Sao lưu';
+$lang['L_RESTORE'] = 'Phục hồi';
+$lang['L_FILE_MANAGE'] = 'File Admin';
+$lang['L_LOG'] = 'Log';
+$lang['L_CHOOSE_DB'] = 'Chọn CSDL';
+$lang['L_CREDITS'] = 'Yêu cầu / Trợ giúp';
+$lang['L_MULTI_PART'] = 'Sao lưu Nhiều phần';
+$lang['L_LOGFILENOTWRITABLE'] = 'Không thể ghi Logfile!';
+$lang['L_SQL_ERROR1'] = 'Lỗi trong Lệnh truy xuất (Query):';
+$lang['L_SQL_ERROR2'] = 'MySQL báo:';
+$lang['L_UNKNOWN'] = 'không rõ';
+$lang['L_UNKNOWN_NUMBER_OF_RECORDS'] = 'không rõ';
+$lang['L_OK'] = 'OK';
+$lang['L_CRON_COMPLETELOG'] = 'Xuất đầy đủ Log';
+$lang['L_NO'] = 'không';
+$lang['L_CREATE_DATABASE'] = 'Tạo ra cơ sở dữ liệu mới';
+$lang['L_EXPORTFINISHED'] = 'Quá trình xuất đã kết thúc.';
+$lang['L_SQL_BROWSER'] = 'Duyệt SQL';
+$lang['L_SERVER'] = 'Máy chủ';
+$lang['L_MYSQL_CONNECTION_ENCODING'] = 'Mã chuẩn của MySQL-Server
 
 
-";
-$lang['L_TITLE_SHOW_DATA']="Show data";
-$lang['L_PRIMARYKEY_CONFIRMDELETE']="Really delete primary key?";
-$lang['L_SETPRIMARYKEYSFOR']="Set new primary keys for table";
-$lang['L_PRIMARYKEY_FIELD']="Primary key field";
-$lang['L_PRIMARYKEYS_SAVE']="Save primary keys";
-$lang['L_CANCEL']="Cancel";
-$lang['L_VISIT_HOMEPAGE']="Visit Homepage";
-$lang['L_SECONDS']="Seconds";
-$lang['L_BACKUPS']="Các sao lưu";
-$lang['L_MINUTES']="Minutes";
-$lang['L_PAGE_REFRESHS']="Page refreshs";
-$lang['L_MINUTE']="Minute";
-$lang['L_SETKEYSFOR']="Set new indexes for table";
-$lang['L_KEY_CONFIRMDELETE']="Really delete index?";
-
-
-?>
\ No newline at end of file
+';
+$lang['L_TITLE_SHOW_DATA'] = 'Show data';
+$lang['L_PRIMARYKEY_CONFIRMDELETE'] = 'Really delete primary key?';
+$lang['L_SETPRIMARYKEYSFOR'] = 'Set new primary keys for table';
+$lang['L_PRIMARYKEY_FIELD'] = 'Primary key field';
+$lang['L_PRIMARYKEYS_SAVE'] = 'Save primary keys';
+$lang['L_CANCEL'] = 'Cancel';
+$lang['L_VISIT_HOMEPAGE'] = 'Visit Homepage';
+$lang['L_SECONDS'] = 'Seconds';
+$lang['L_BACKUPS'] = 'Các sao lưu';
+$lang['L_MINUTES'] = 'Minutes';
+$lang['L_PAGE_REFRESHS'] = 'Page refreshs';
+$lang['L_MINUTE'] = 'Minute';
+$lang['L_SETKEYSFOR'] = 'Set new indexes for table';
+$lang['L_KEY_CONFIRMDELETE'] = 'Really delete index?';
diff --git a/msd/language/vn/lang_config_overview.php b/msd/language/vn/lang_config_overview.php
index 34b303ee..865b2688 100644
--- a/msd/language/vn/lang_config_overview.php
+++ b/msd/language/vn/lang_config_overview.php
@@ -1,112 +1,130 @@
 <?php
-$lang['L_CONFIG_HEADLINE']="Cấu hình";
-$lang['L_SAVE_SUCCESS']="Cấu hình vừa được lưu lại thành công vào file cấu hình \"%s\".";
-$lang['L_CONFIG_LOADED']="Cấu hình \"%s\" vừa được nạp thành công.";
-$lang['L_SAVE_ERROR']="Lỗi - không thể lưu cấu hình!";
-$lang['L_CONFIG_EMAIL']="Email Thông báo";
-$lang['L_CONFIG_AUTODELETE']="Tự động xóa";
-$lang['L_CONFIG_INTERFACE']="Giao diện";
-$lang['L_MULTI_PART_GROESSE']="dung lượng File tối đa";
-$lang['L_HELP_MULTIPART']="Nếu chế độ đa phần (Multipart) được bật, Sao lưu tạo ra Nhiều tập tin dự phòng, với kích thước tối đa được xác định bởi cấu hình ở dưới";
-$lang['L_HELP_MULTIPARTGROESSE']="Kích thước tối đa của những tập tin dự phòng được cấu hình ở đây, Nếu chế độ đa phần (Multipart) được bật";
-$lang['L_EMPTY_DB_BEFORE_RESTORE']="Xóa những bảng trước khi hồi phục";
-$lang['L_ALLPARS']="Tất cả các tham số";
-$lang['L_CRON_EXTENDER']="phần mở rộng của File";
-$lang['L_CRON_SAVEPATH']="File Cấu hình";
-$lang['L_CRON_PRINTOUT']="Bản in được xuất ra trên màn hình.";
-$lang['L_CONFIG_CRONPERL']="Thiết đặt Crondump cho Perl script";
-$lang['L_CRON_MAILPRG']="Chương trình Mail";
-$lang['L_OPTIMIZE']="Tối ưu hóa những bảng trước khi Sao lưu";
-$lang['L_HELP_OPTIMIZE']="Nếu tùy chọn này được kích hoạt, tất cả các bảng sẽ được tối ưu hóa trước khi sao lưu";
-$lang['L_HELP_FTPTIMEOUT']="Thiết đặt Mặc định cho thời gian ngắt kết nối (Timeout) là 90 giây.";
-$lang['L_FTP_TIMEOUT']="Thời gian ngắt kết nối";
-$lang['L_HELP_FTPSSL']="Hãy Chọn nếu kết nối sẽ được thiết lập qua SSL.";
-$lang['L_CONFIG_ASKLOAD']="Bạn muốn ghi đè những sự thiết đặt thực tế với những sự thiết đặt mặc định không?";
-$lang['L_LOAD']="Nạp thiết đặt
-mặc định";
-$lang['L_LOAD_SUCCESS']="Những thiết đặt mặc định đã được nạp.";
-$lang['L_CRON_CRONDBINDEX']="Database";
-$lang['L_WITHATTACH']=" đính kèm";
-$lang['L_WITHOUTATTACH']=" không có đính kèm";
-$lang['L_MULTIDUMPCONF']="=Cấu hình Multidump=";
-$lang['L_MULTIDUMPALL']="=tất cả các cơ sở dữ liệu=";
-$lang['L_GZIP']="Nén GZip";
-$lang['L_SEND_MAIL_FORM']="Gửi email báo cáo";
-$lang['L_SEND_MAIL_DUMP']="Đính kèm Sao lưu";
-$lang['L_EMAIL_ADRESS']="Địa chỉ Email";
-$lang['L_EMAIL_SENDER']="Địa chỉ email người gửi";
-$lang['L_EMAIL_MAXSIZE']="Dung lượng tối đa của File đính kèm";
-$lang['L_NUMBER_OF_FILES_FORM']="Xóa bớt file cũ nếu số lượng vượt quá";
-$lang['L_LANGUAGE']="Language (Ngôn ngữ)";
-$lang['L_LIST_DB']="Cấu hình CSDL:";
-$lang['L_CONFIG_FTP']="Chuyển những tập tin backup qua FTP";
-$lang['L_FTP_TRANSFER']="Transfer FTP";
-$lang['L_FTP_SERVER']="Server";
-$lang['L_FTP_PORT']="Cổng";
-$lang['L_FTP_USER']="User";
-$lang['L_FTP_PASS']="Password";
-$lang['L_FTP_DIR']="Thư mục Upload";
-$lang['L_FTP_SSL']="Kết nối an toàn SSL FTP";
-$lang['L_FTP_USESSL']="Sử dụng kết nối SSL";
-$lang['L_SQLBOXHEIGHT']="Height of SQL-Box";
-$lang['L_SQLLIMIT']="Số bản ghi mỗi trang";
-$lang['L_BBPARAMS']="Cấu hình cho BB-Code";
-$lang['L_BBTEXTCOLOR']="Màu chữ";
-$lang['L_HELP_COMMANDS']="Bạn có thể thực hiện một lệnh trước và sau khi sao lưu.
-Lệnh này có thể là 1 lệnh xây dựng SQL hoặc lệnh hệ thống (ví dụ 1 script)";
-$lang['L_COMMAND']="Lệnh";
-$lang['L_WRONG_CONNECTIONPARS']="Tham số Kết nối sai!";
-$lang['L_CONNECTIONPARS']="Tham số Kết nối";
-$lang['L_EXTENDEDPARS']="Tham số Mở rộng";
-$lang['L_FADE_IN_OUT']="Bật/tắt hiển thị";
-$lang['L_DB_BACKUPPARS']="Tham số Sao lưu CSDL";
-$lang['L_GENERAL']="Tổng quan";
-$lang['L_MAXSIZE']="Kích cỡ tối đa";
-$lang['L_ERRORHANDLING_RESTORE']="Lỗi xảy ra trong khi phục hồi";
-$lang['L_EHRESTORE_CONTINUE']="tiếp tục và ghi nhận các lỗi";
-$lang['L_EHRESTORE_STOP']="dừng";
-$lang['L_IN_MAINFRAME']="trong khung chính";
-$lang['L_IN_LEFTFRAME']="trong khung trái";
-$lang['L_WIDTH']="Chiều rộng";
-$lang['L_SQL_BEFEHLE']="Các lệnh SQL";
-$lang['L_DOWNLOAD_LANGUAGES']="tải xuống những ngôn ngữ khác";
-$lang['L_DOWNLOAD_STYLES']="tải xuống những giao diện khác";
-$lang['L_CONNECT_TO']="Kết nối tới";
-$lang['L_CHANGEDIR']="Thay đổi tới Thư mục";
-$lang['L_CHANGEDIRERROR']="Không thể thay đổi thư mục!";
-$lang['L_FTP_OK']="Kết nối thành công.";
-$lang['L_INSTALL']="Cài đặt";
-$lang['L_NOFTPPOSSIBLE']="Bạn không có những chức năng FTP!";
-$lang['L_FOUND_DB']="tìm thấy CSDL";
-$lang['L_FTP_CHOOSE_MODE']="Chế độ FTP";
-$lang['L_FTP_PASSIVE']="sử dụng kiểu bị động (passive)";
-$lang['L_HELP_FTP_MODE']="Chọn dạng kiểu bị động khi bạn thấy có vấn đề trong khi sử dụng chế độ hoạt động (active mode).";
-$lang['L_DB_IN_LIST']="CSDL '%s' không thể thêm vì nó bị trùng với 1 CSDL đã có. ";
-$lang['L_ADD_DB_MANUALLY']="Thêm cơ sở dữ liệu bằng tay";
-$lang['L_DB_MANUAL_ERROR']="Xin lỗi, không thể kết nối tới CSDL '%s'!";
-$lang['L_DB_MANUAL_FILE_ERROR']="Lỗi file: không thể chèn CSDL '%s'!";
-$lang['L_NO_DB_FOUND']="Không thể tự động tìm thấy bất kỳ cơ sở dữ liệu nào!
-Vui lòng thôi ẩn (unhide) các tham số kết nối, và nhập tên của cơ sở dữ liệu của bạn bằng tay.";
-$lang['L_CONFIGFILES']="file cấu hình";
-$lang['L_CONFIGFILE']="file cấu hình";
-$lang['L_MYSQL_DATA']="MySQL-Data";
-$lang['L_CONFIGURATIONS']="Cấu hình";
-$lang['L_ACTION']="Thực hiện";
-$lang['L_FTP_SEND_TO']="tới <strong>%s</strong><br> vào <strong>%s</strong>";
-$lang['L_FTP']="FTP";
-$lang['L_EMAIL_CC']="Đồng gửi";
-$lang['L_NAME']="Tên";
-$lang['L_CONFIRM_CONFIGFILE_DELETE']="Bạn có chắc muốn xóa các tập tin cấu hình %s?";
-$lang['L_ERROR_DELETING_CONFIGFILE']="Lỗi: không thể xóa file cấu hình %s!";
-$lang['L_SUCCESS_DELETING_CONFIGFILE']="File cấu hình %s vừa được xóa thành công.";
-$lang['L_SUCCESS_CONFIGFILE_CREATED']="File cấu hình  %s vừa được tạo thành công.";
-$lang['L_ERROR_CONFIGFILE_NAME']="Tên file \"%s\" có ký tự không phù hợp.";
-$lang['L_CREATE_CONFIGFILE']="Tạo file cấu hình mới";
-$lang['L_ERROR_LOADING_CONFIGFILE']="Không thể tải file cấu hình \"%s\".";
-$lang['L_BACKUP_DBS_PHP']="CSDL để sao lưu (PHP)";
-$lang['L_BACKUP_DBS_PERL']="CSDL để sao lưu (PERL)";
-$lang['L_CRON_COMMENT']="Nhập ghi chú";
-$lang['L_AUTODETECT']="auto detect";
 
-
-?>
\ No newline at end of file
+$lang['L_CONFIG_HEADLINE'] = 'Cấu hình';
+$lang['L_SAVE_SUCCESS'] = 'Cấu hình vừa được lưu lại thành công vào file cấu hình "%s".';
+$lang['L_CONFIG_LOADED'] = 'Cấu hình "%s" vừa được nạp thành công.';
+$lang['L_SAVE_ERROR'] = 'Lỗi - không thể lưu cấu hình!';
+$lang['L_EMAIL_NOTIFICATION'] = 'Email Thông báo';
+$lang['L_CONFIG_AUTODELETE'] = 'Tự động xóa';
+$lang['L_CONFIG_INTERFACE'] = 'Giao diện';
+$lang['L_CONFIG_EMAIL'] = 'E-mail';
+$lang['L_CONFIG_CRONSCRIPT'] = 'Cronscript';
+$lang['L_MULTI_PART_GROESSE'] = 'dung lượng File tối đa';
+$lang['L_HELP_MULTIPART'] = 'Nếu chế độ đa phần (Multipart) được bật, Sao lưu tạo ra Nhiều tập tin dự phòng, với kích thước tối đa được xác định bởi cấu hình ở dưới';
+$lang['L_HELP_MULTIPARTGROESSE'] = 'Kích thước tối đa của những tập tin dự phòng được cấu hình ở đây, Nếu chế độ đa phần (Multipart) được bật';
+$lang['L_EMPTY_DB_BEFORE_RESTORE'] = 'Xóa những bảng trước khi hồi phục';
+$lang['L_ALLPARS'] = 'Tất cả các tham số';
+$lang['L_CRON_EXTENDER'] = 'phần mở rộng của File';
+$lang['L_CRON_SAVEPATH'] = 'File Cấu hình';
+$lang['L_CRON_PRINTOUT'] = 'Bản in được xuất ra trên màn hình.';
+$lang['L_CONFIG_CRONPERL'] = 'Thiết đặt Crondump cho Perl script';
+$lang['L_CRON_MAILPRG'] = 'Chương trình Mail';
+$lang['L_OPTIMIZE'] = 'Tối ưu hóa những bảng trước khi Sao lưu';
+$lang['L_HELP_OPTIMIZE'] = 'Nếu tùy chọn này được kích hoạt, tất cả các bảng sẽ được tối ưu hóa trước khi sao lưu';
+$lang['L_BINARY'] = 'Export binary data in hex format';
+$lang['L_HELP_BINARY'] = 'If this option is activated, binary data are exported in hex format to avoid coding problems.';
+$lang['SFTP'] = 'Thiết đặt Mặc định cho thời gian ngắt kết nối (Timeout) là 90 giây.';
+$lang['L_FTP_TIMEOUT'] = 'Thời gian ngắt kết nối';
+$lang['L_HELP_FTPSSL'] = 'Hãy Chọn nếu kết nối sẽ được thiết lập qua SSL.';
+$lang['L_SFTP_TIMEOUT'] = 'Thời gian ngắt kết nối';
+$lang['L_HELP_SFTPSSL'] = 'Hãy Chọn nếu kết nối sẽ được thiết lập qua SSL.';
+$lang['L_CONFIG_ASKLOAD'] = 'Bạn muốn ghi đè những sự thiết đặt thực tế với những sự thiết đặt mặc định không?';
+$lang['L_LOAD'] = 'Nạp thiết đặt
+mặc định';
+$lang['L_LOAD_SUCCESS'] = 'Những thiết đặt mặc định đã được nạp.';
+$lang['L_CRON_CRONDBINDEX'] = 'Database';
+$lang['L_WITHATTACH'] = ' đính kèm';
+$lang['L_WITHOUTATTACH'] = ' không có đính kèm';
+$lang['L_MULTIDUMPCONF'] = '=Cấu hình Multidump=';
+$lang['L_MULTIDUMPALL'] = '=tất cả các cơ sở dữ liệu=';
+$lang['L_GZIP'] = 'Nén GZip';
+$lang['L_SEND_MAIL_FORM'] = 'Gửi email báo cáo';
+$lang['L_SEND_MAIL_DUMP'] = 'Đính kèm Sao lưu';
+$lang['L_EMAIL_ADRESS'] = 'Địa chỉ Email';
+$lang['L_EMAIL_SENDER'] = 'Địa chỉ email người gửi';
+$lang['L_EMAIL_MAXSIZE'] = 'Dung lượng tối đa của File đính kèm';
+$lang['L_NUMBER_OF_FILES_FORM'] = 'Xóa bớt file cũ nếu số lượng vượt quá';
+$lang['L_LANGUAGE'] = 'Language (Ngôn ngữ)';
+$lang['L_LIST_DB'] = 'Cấu hình CSDL:';
+$lang['L_CONFIG_FTP'] = 'Chuyển những tập tin backup qua FTP';
+$lang['L_FTP_TRANSFER'] = 'Transfer FTP';
+$lang['L_FTP_SERVER'] = 'Server';
+$lang['L_FTP_PORT'] = 'Cổng';
+$lang['L_FTP_USER'] = 'User';
+$lang['L_FTP_PASS'] = 'Password';
+$lang['L_FTP_DIR'] = 'Thư mục Upload';
+$lang['L_FTP_SSL'] = 'Kết nối an toàn SSL FTP';
+$lang['L_FTP_USESSL'] = 'Sử dụng kết nối SSL';
+$lang['L_CONFIG_SFTP'] = 'Chuyển những tập tin backup qua SFTP';
+$lang['L_SFTP_TRANSFER'] = 'Transfer SFTP';
+$lang['L_SFTP_SERVER'] = 'Server';
+$lang['L_SFTP_PORT'] = 'Cổng';
+$lang['L_SFTP_USER'] = 'User';
+$lang['L_SFTP_PASS'] = 'Password';
+$lang['L_SFTP_DIR'] = 'Thư mục Upload';
+$lang['L_SFTP_SFTP_PATH_TO_PRIVATE_KEY'] = 'Path to Private Key';
+$lang['L_SFTP_SECRET_PASSPHRASE_FOR_PRIVATE_KEY'] = 'Passphrase';
+$lang['L_SFTP_FINGERPRINT'] = 'Host Fingerprint';
+$lang['L_SQLBOXHEIGHT'] = 'Height of SQL-Box';
+$lang['L_SQLLIMIT'] = 'Số bản ghi mỗi trang';
+$lang['L_BBPARAMS'] = 'Cấu hình cho BB-Code';
+$lang['L_BBTEXTCOLOR'] = 'Màu chữ';
+$lang['L_HELP_COMMANDS'] = 'Bạn có thể thực hiện một lệnh trước và sau khi sao lưu.
+Lệnh này có thể là 1 lệnh xây dựng SQL hoặc lệnh hệ thống (ví dụ 1 script)';
+$lang['L_COMMAND'] = 'Lệnh';
+$lang['L_WRONG_CONNECTIONPARS'] = 'Tham số Kết nối sai!';
+$lang['L_CONNECTIONPARS'] = 'Tham số Kết nối';
+$lang['L_EXTENDEDPARS'] = 'Tham số Mở rộng';
+$lang['L_FADE_IN_OUT'] = 'Bật/tắt hiển thị';
+$lang['L_DB_BACKUPPARS'] = 'Tham số Sao lưu CSDL';
+$lang['L_GENERAL'] = 'Tổng quan';
+$lang['L_MAXSIZE'] = 'Kích cỡ tối đa';
+$lang['L_ERRORHANDLING_RESTORE'] = 'Lỗi xảy ra trong khi phục hồi';
+$lang['L_EHRESTORE_CONTINUE'] = 'tiếp tục và ghi nhận các lỗi';
+$lang['L_EHRESTORE_STOP'] = 'dừng';
+$lang['L_IN_MAINFRAME'] = 'trong khung chính';
+$lang['L_IN_LEFTFRAME'] = 'trong khung trái';
+$lang['L_WIDTH'] = 'Chiều rộng';
+$lang['L_SQL_BEFEHLE'] = 'Các lệnh SQL';
+$lang['L_DOWNLOAD_LANGUAGES'] = 'tải xuống những ngôn ngữ khác';
+$lang['L_DOWNLOAD_STYLES'] = 'tải xuống những giao diện khác';
+$lang['L_CONNECT_TO'] = 'Kết nối tới';
+$lang['L_CHANGEDIR'] = 'Thay đổi tới Thư mục';
+$lang['L_CHANGEDIRERROR'] = 'Không thể thay đổi thư mục!';
+$lang['L_FTP_OK'] = 'Kết nối thành công.';
+$lang['L_INSTALL'] = 'Cài đặt';
+$lang['L_NOFTPPOSSIBLE'] = 'Bạn không có những chức năng FTP!';
+$lang['L_FOUND_DB'] = 'tìm thấy CSDL';
+$lang['L_FTP_CHOOSE_MODE'] = 'Chế độ FTP';
+$lang['L_FTP_PASSIVE'] = 'sử dụng kiểu bị động (passive)';
+$lang['L_HELP_FTP_MODE'] = 'Chọn dạng kiểu bị động khi bạn thấy có vấn đề trong khi sử dụng chế độ hoạt động (active mode).';
+$lang['L_SFTP_PASSIVE'] = 'sử dụng kiểu bị động (passive)';
+$lang['L_DB_IN_LIST'] = "CSDL '%s' không thể thêm vì nó bị trùng với 1 CSDL đã có. ";
+$lang['L_ADD_DB_MANUALLY'] = 'Thêm cơ sở dữ liệu bằng tay';
+$lang['L_DB_MANUAL_ERROR'] = "Xin lỗi, không thể kết nối tới CSDL '%s'!";
+$lang['L_DB_MANUAL_FILE_ERROR'] = "Lỗi file: không thể chèn CSDL '%s'!";
+$lang['L_NO_DB_FOUND'] = 'Không thể tự động tìm thấy bất kỳ cơ sở dữ liệu nào!
+Vui lòng thôi ẩn (unhide) các tham số kết nối, và nhập tên của cơ sở dữ liệu của bạn bằng tay.';
+$lang['L_CONFIGFILES'] = 'file cấu hình';
+$lang['L_CONFIGFILE'] = 'file cấu hình';
+$lang['L_MYSQL_DATA'] = 'MySQL-Data';
+$lang['L_CONFIGURATIONS'] = 'Cấu hình';
+$lang['L_ACTION'] = 'Thực hiện';
+$lang['L_FTP_SEND_TO'] = 'tới <strong>%s</strong><br> vào <strong>%s</strong>';
+$lang['L_FTP'] = 'FTP';
+$lang['L_SFTP_SEND_TO'] = 'tới <strong>%s</strong><br> vào <strong>%s</strong>';
+$lang['L_SFTP_SEND_TO'] = 'tới <strong>%s</strong><br> vào <strong>%s</strong>';
+$lang['L_SFTP'] = 'SFTP';
+$lang['L_EMAIL_CC'] = 'Đồng gửi';
+$lang['L_NAME'] = 'Tên';
+$lang['L_CONFIRM_CONFIGFILE_DELETE'] = 'Bạn có chắc muốn xóa các tập tin cấu hình %s?';
+$lang['L_ERROR_DELETING_CONFIGFILE'] = 'Lỗi: không thể xóa file cấu hình %s!';
+$lang['L_SUCCESS_DELETING_CONFIGFILE'] = 'File cấu hình %s vừa được xóa thành công.';
+$lang['L_SUCCESS_CONFIGFILE_CREATED'] = 'File cấu hình  %s vừa được tạo thành công.';
+$lang['L_ERROR_CONFIGFILE_NAME'] = 'Tên file "%s" có ký tự không phù hợp.';
+$lang['L_CREATE_CONFIGFILE'] = 'Tạo file cấu hình mới';
+$lang['L_ERROR_LOADING_CONFIGFILE'] = 'Không thể tải file cấu hình "%s".';
+$lang['L_BACKUP_DBS_PHP'] = 'CSDL để sao lưu (PHP)';
+$lang['L_BACKUP_DBS_PERL'] = 'CSDL để sao lưu (PERL)';
+$lang['L_CRON_COMMENT'] = 'Nhập ghi chú';
+$lang['L_AUTODETECT'] = 'auto detect';
diff --git a/msd/language/vn/lang_dump.php b/msd/language/vn/lang_dump.php
index ccb3924d..a09fadd6 100644
--- a/msd/language/vn/lang_dump.php
+++ b/msd/language/vn/lang_dump.php
@@ -1,58 +1,59 @@
 <?php
-$lang['L_DUMP_HEADLINE']="Sao lưu...";
-$lang['L_GZIP_COMPRESSION']="Nén GZip";
-$lang['L_SAVING_TABLE']="Đang lưu các bảng dữ liệu ";
-$lang['L_OF']="của";
-$lang['L_ACTUAL_TABLE']="Bảng hiện tại";
-$lang['L_PROGRESS_TABLE']="Tiến trình của bảng";
-$lang['L_PROGRESS_OVER_ALL']="Toàn bộ tiến trình";
-$lang['L_ENTRY']="Mục";
-$lang['L_DONE']="Xong!";
-$lang['L_DUMP_SUCCESSFUL']=" được tạo thành công.";
-$lang['L_UPTO']="lên trên";
-$lang['L_EMAIL_WAS_SEND']="Email vừa được gửi thành công tới ";
-$lang['L_BACK_TO_CONTROL']="Tiếp tục";
-$lang['L_BACK_TO_OVERVIEW']="Tổng quan Cơ sở dữ liệu";
-$lang['L_DUMP_FILENAME']="File Backup: ";
-$lang['L_WITHPRAEFIX']="với tiền tố";
-$lang['L_DUMP_NOTABLES']="Không tìm thấy trong cơ sở dữ liệu các bảng `<b>%s</b>` ";
-$lang['L_DUMP_ENDERGEBNIS']="File chứa <b>%s</b> bảng với <b>%s</b> bản ghi.<br>";
-$lang['L_MAILERROR']="Gửi email thất bại!";
-$lang['L_EMAILBODY_ATTACH']="File đính kèm chứa đựng nội dung sao lưu MySQL.<br>Sao lưu Cơ sở dữ liệu `%s`
-<br><br>File sau đã được tạo:<br><br>%s <br><br>Trân trọng!<br><br>MySQLDumper - http://mangvn.org<br>";
-$lang['L_EMAILBODY_MP_NOATTACH']="Một Sao lưu Nhiều phần được tạo ra.<br>Những tập tin dự phòng không được gửi kèm email!<br>Sao lưu Cơ sở dữ liệu `%s`
+
+$lang['L_DUMP_HEADLINE'] = 'Sao lưu...';
+$lang['L_DUMP_INFO'] = 'Please wait! The database tables are optimized before the backup.';
+$lang['L_GZIP_COMPRESSION'] = 'Nén GZip';
+$lang['L_SAVING_TABLE'] = 'Đang lưu các bảng dữ liệu ';
+$lang['L_OF'] = 'của';
+$lang['L_ACTUAL_TABLE'] = 'Bảng hiện tại';
+$lang['L_PROGRESS_TABLE'] = 'Tiến trình của bảng';
+$lang['L_PROGRESS_OVER_ALL'] = 'Toàn bộ tiến trình';
+$lang['L_ENTRY'] = 'Mục';
+$lang['L_DONE'] = 'Xong!';
+$lang['L_DUMP_SUCCESSFUL'] = ' được tạo thành công.';
+$lang['L_UPTO'] = 'lên trên';
+$lang['L_EMAIL_WAS_SEND'] = 'Email vừa được gửi thành công tới ';
+$lang['L_BACK_TO_CONTROL'] = 'Tiếp tục';
+$lang['L_BACK_TO_OVERVIEW'] = 'Tổng quan Cơ sở dữ liệu';
+$lang['L_DUMP_FILENAME'] = 'File Backup: ';
+$lang['L_WITHPRAEFIX'] = 'với tiền tố';
+$lang['L_DUMP_NOTABLES'] = 'Không tìm thấy trong cơ sở dữ liệu các bảng `<b>%s</b>` ';
+$lang['L_DUMP_ENDERGEBNIS'] = 'File chứa <b>%s</b> bảng với <b>%s</b> bản ghi.<br>';
+$lang['L_MAILERROR'] = 'Gửi email thất bại!';
+$lang['L_EMAILBODY_ATTACH'] = 'File đính kèm chứa đựng nội dung sao lưu MySQL.<br>Sao lưu Cơ sở dữ liệu `%s`
+<br><br>File sau đã được tạo:<br><br>%s <br><br>Trân trọng!<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_NOATTACH'] = 'Một Sao lưu Nhiều phần được tạo ra.<br>Những tập tin dự phòng không được gửi kèm email!<br>Sao lưu Cơ sở dữ liệu `%s`
 <br><br>Những file Sau đã được tạo ra<br><br>%s
-<br><br>Trân trọng!<br><br>MySQLDumper - http://mangvn.org<br>";
-$lang['L_EMAILBODY_MP_ATTACH']="Một Sao lưu Nhiều phần được tạo ra.<br>Những tập tin dự phòng đã được gửi kèm email!<br>Sao lưu Cơ sở dữ liệu `%s`
-<br><br>Những file sau đã được tạo ra:<br><br>%s <br><br>Trân trọng!<br><br>MySQLDumper - http://mangvn.org<br>";
-$lang['L_EMAILBODY_FOOTER']="`<br><br>Trân trọng!<br><br>MySQLDumper - http://mangvn.org<br>";
-$lang['L_EMAILBODY_TOOBIG']="Tập tin sao lưu vượt hơn kích thước lớn nhất của %s và nó không được đính kèm email.<br>Sao lưu Cơ sở dữ liệu `%s`
+<br><br>Trân trọng!<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_MP_ATTACH'] = 'Một Sao lưu Nhiều phần được tạo ra.<br>Những tập tin dự phòng đã được gửi kèm email!<br>Sao lưu Cơ sở dữ liệu `%s`
+<br><br>Những file sau đã được tạo ra:<br><br>%s <br><br>Trân trọng!<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_FOOTER'] = '`<br><br>Trân trọng!<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_TOOBIG'] = 'Tập tin sao lưu vượt hơn kích thước lớn nhất của %s và nó không được đính kèm email.<br>Sao lưu Cơ sở dữ liệu `%s`
 <br><br>File sau đã được tạo ra:<br><br>%s
-<br><br>Trân trọng!<br><br>MySQLDumper - http://mangvn.org<br>";
-$lang['L_EMAILBODY_NOATTACH']="Files không được đính kèm email này!<br>Sao lưu của CSDL `%s`
+<br><br>Trân trọng!<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAILBODY_NOATTACH'] = 'Files không được đính kèm email này!<br>Sao lưu của CSDL `%s`
 <br><br>File sau đã được tạo ra:<br><br>%s
-<br><br>Trân trọng!<br><br>MySQLDumper - http://mangvn.org<br>";
-$lang['L_EMAIL_ONLY_ATTACHMENT']=" ... chỉ đính kèm.";
-$lang['L_TABLESELECTION']="Chọn Bảng";
-$lang['L_SELECTALL']="Chọn tất cả";
-$lang['L_DESELECTALL']="Thôi chọn tất cả";
-$lang['L_STARTDUMP']="Bắt đầu sao lưu";
-$lang['L_LASTBUFROM']="cập nhật lần cuối từ";
-$lang['L_NOT_SUPPORTED']="Sao lưu này không hỗ trợ chức năng này.";
-$lang['L_MULTIDUMP']="Multidump: Sao lưu của <b>%d</b> Những cơ sở dữ liệu xong.";
-$lang['L_FILESENDFTP']="gửi file qua FTP... hãy đợi. ";
-$lang['L_FTPCONNERROR']="Kết nối FTP không được thiết lập! Kết nối với ";
-$lang['L_FTPCONNERROR1']=" như người sử dụng ";
-$lang['L_FTPCONNERROR2']=" không thể xảy ra";
-$lang['L_FTPCONNERROR3']="Upload FTP hỏng! ";
-$lang['L_FTPCONNECTED1']="Đã kết nối với ";
-$lang['L_FTPCONNECTED2']=" trên ";
-$lang['L_FTPCONNECTED3']=" chuyển đổi thành công";
-$lang['L_NR_TABLES_SELECTED']="- với %s bảng đã được chọn";
-$lang['L_NR_TABLES_OPTIMIZED']="<span class=\"small\">%s những bảng đã được tối ưu hóa.</span>";
-$lang['L_DUMP_ERRORS']="<p class=\"error\">%s những lỗi xuất hiện: <a href=\"log.php?r=3\">xem</a></p>";
-$lang['L_FATAL_ERROR_DUMP']="Lỗi nghiêm trọng: CREATE-Statement của bảng '%s' trong CSDL '%s' không thể đọc!<br>
+<br><br>Trân trọng!<br><br>MyOOS [Dumper]<br>';
+$lang['L_EMAIL_ONLY_ATTACHMENT'] = ' ... chỉ đính kèm.';
+$lang['L_TABLESELECTION'] = 'Chọn Bảng';
+$lang['L_SELECTALL'] = 'Chọn tất cả';
+$lang['L_DESELECTALL'] = 'Thôi chọn tất cả';
+$lang['L_STARTDUMP'] = 'Bắt đầu sao lưu';
+$lang['L_LASTBUFROM'] = 'cập nhật lần cuối từ';
+$lang['L_NOT_SUPPORTED'] = 'Sao lưu này không hỗ trợ chức năng này.';
+$lang['L_MULTIDUMP'] = 'Multidump: Sao lưu của <b>%d</b> Những cơ sở dữ liệu xong.';
+$lang['L_FILESENDFTP'] = 'gửi file qua FTP... hãy đợi. ';
+$lang['L_FTPCONNERROR'] = 'Kết nối FTP không được thiết lập! Kết nối với ';
+$lang['L_FTPCONNERROR1'] = ' như người sử dụng ';
+$lang['L_FTPCONNERROR2'] = ' không thể xảy ra';
+$lang['L_FTPCONNERROR3'] = 'Upload FTP hỏng! ';
+$lang['L_FTPCONNECTED1'] = 'Đã kết nối với ';
+$lang['L_FTPCONNECTED2'] = ' trên ';
+$lang['L_FTPCONNECTED3'] = ' chuyển đổi thành công';
+$lang['L_FILESENDSFTP'] = 'gửi file qua FTP... hãy đợi. ';
+$lang['L_SFTPCONNERROR'] = 'Kết nối FTP không được thiết lập! Kết nối với ';
+$lang['L_NR_TABLES_SELECTED'] = '- với %s bảng đã được chọn';
+$lang['L_NR_TABLES_OPTIMIZED'] = '<span class="small">%s những bảng đã được tối ưu hóa.</span>';
+$lang['L_DUMP_ERRORS'] = '<p class="error">%s những lỗi xuất hiện: <a href="log.php?r=3">xem</a></p>';
+$lang['L_FATAL_ERROR_DUMP'] = "Lỗi nghiêm trọng: CREATE-Statement của bảng '%s' trong CSDL '%s' không thể đọc!<br>
 Kiểm tra lại bảng này để tìm lỗi.";
-
-
-?>
\ No newline at end of file
diff --git a/msd/language/vn/lang_filemanagement.php b/msd/language/vn/lang_filemanagement.php
index 4800d272..ba616e68 100644
--- a/msd/language/vn/lang_filemanagement.php
+++ b/msd/language/vn/lang_filemanagement.php
@@ -1,79 +1,79 @@
 <?php
-$lang['L_CONVERT_START']="Bắt đầu Chuyển đổi";
-$lang['L_CONVERT_TITLE']="Chuyển đổi Dump thành dạng MSD";
-$lang['L_CONVERT_WRONG_PARAMETERS']="Sai tham số!  Chương trình chuyển đổi không hoạt động.";
-$lang['L_FM_UPLOADFILEREQUEST']="chọn 1 file.";
-$lang['L_FM_UPLOADNOTALLOWED1']="Kiểu file này không được hỗ trợ.";
-$lang['L_FM_UPLOADNOTALLOWED2']="Các định dạng file được chấp nhận: *.gz và *.sql";
-$lang['L_FM_UPLOADMOVEERROR']="Không thể di chuyển file đã chọn tới thư mục upload";
-$lang['L_FM_UPLOADFAILED']="Upload bị lỗi!";
-$lang['L_FM_UPLOADFILEEXISTS']="Một file với tên giống như vậy đã tồn tại!";
-$lang['L_FM_NOFILE']="Bạn chưa chọn file!";
-$lang['L_FM_DELETE1']="File ";
-$lang['L_FM_DELETE2']=" đã xóa thành công.";
-$lang['L_FM_DELETE3']=" không thể xóa!";
-$lang['L_FM_CHOOSE_FILE']="Chọn file:";
-$lang['L_FM_FILESIZE']="Cỡ File";
-$lang['L_FM_FILEDATE']="Ngày";
-$lang['L_FM_NOFILESFOUND']="Không tìm thấy file.";
-$lang['L_FM_TABLES']="Các bảng";
-$lang['L_FM_RECORDS']="Bản ghi";
-$lang['L_FM_ALL_BU']="Tất cả bản sao lưu";
-$lang['L_FM_ANZ_BU']="Các sao lưu";
-$lang['L_FM_LAST_BU']="Sao lưu cuối cùng";
-$lang['L_FM_TOTALSIZE']="Tổng dung lượng";
-$lang['L_FM_SELECTTABLES']="Chọn bảng";
-$lang['L_FM_COMMENT']="Nhập lệnh";
-$lang['L_FM_RESTORE']="Phục hồi";
-$lang['L_FM_ALERTRESTORE1']="Bạn có muốn CSDL";
-$lang['L_FM_ALERTRESTORE2']="được phục hồi với những bản ghi từ file";
-$lang['L_FM_ALERTRESTORE3']=" ?";
-$lang['L_FM_DELETE']="Xóa";
-$lang['L_FM_ASKDELETE1']="Bạn có muốn file ";
-$lang['L_FM_ASKDELETE2']="bị xóa?";
-$lang['L_FM_ASKDELETE3']="Bạn muốn xóa tự động ngay bây giờ bằng cách sử dụng những quy tắc đã được cấu hình không?";
-$lang['L_FM_ASKDELETE4']="Bạn muốn xóa tất cả các tập tin dự phòng không?";
-$lang['L_FM_ASKDELETE5']="Bạn muốn xóa tất cả các tập tin dự phòng dạng ";
-$lang['L_FM_ASKDELETE5_2']="_* ?";
-$lang['L_FM_DELETEAUTO']="Chạy tự động xóa bằng tay";
-$lang['L_FM_DELETEALL']="Xóa tất cả các tập tin dự phòng";
-$lang['L_FM_DELETEALLFILTER']="Xóa mọi thứ dạng ";
-$lang['L_FM_DELETEALLFILTER2']="_*";
-$lang['L_FM_STARTDUMP']="Bắt đầu Sao lưu Mới";
-$lang['L_FM_FILEUPLOAD']="Upload file";
-$lang['L_FM_DBNAME']="Tên CSDL";
-$lang['L_FM_FILES1']="Sao lưu CSDL";
-$lang['L_FM_FILES2']="Cấu trúc CSDL";
-$lang['L_FM_AUTODEL1']="Xóa tự động: các file đã bị xóa vì dung lượng các file sao lưu lớn quá quy định:";
-$lang['L_DELETE_FILE_SUCCESS']="File \"%s\" was deleted successfully.";
-$lang['L_FM_DUMPSETTINGS']="Cấu hình cho";
-$lang['L_FM_OLDBACKUP']="(không hiểu)";
-$lang['L_FM_RESTORE_HEADER']="Phục hồi cSDL \"<strong>%s</strong>\"";
-$lang['L_DELETE_FILE_ERROR']="Error deleting file \"%s\"!";
-$lang['L_FM_DUMP_HEADER']="Backup";
-$lang['L_DOCRONBUTTON']="Chạy Perl Cron script";
-$lang['L_DOPERLTEST']="Kiểm tra Perl Modules";
-$lang['L_DOSIMPLETEST']="Kiểm tra Perl";
-$lang['L_PERLOUTPUT1']="Các mục trong crondump.pl cho absolute_path_of_configdir";
-$lang['L_PERLOUTPUT2']="URL cho tronhf duyệt hoặc ngoài Cron job";
-$lang['L_PERLOUTPUT3']="Dòng lệnh trong Shell hoặc cho Crontab";
-$lang['L_RESTORE_OF_TABLES']="Chọn Bảng để phục hồi";
-$lang['L_CONVERTER']="Chương trình chuyển đổi sao lưu";
-$lang['L_CONVERT_FILE']="File cần được chuyển đổi";
-$lang['L_CONVERT_FILENAME']="Tên file xuất ra (bỏ qua phần mở rộng)";
-$lang['L_CONVERTING']="Đang chuyển đổi";
-$lang['L_CONVERT_FILEREAD']="Đọc file '%s'";
-$lang['L_CONVERT_FINISHED']="Kết thúc chuyển đổi, '%s' vừa tạo thành công.";
-$lang['L_NO_MSD_BACKUPFILE']="Sao lưu script khác";
-$lang['L_MAX_UPLOAD_SIZE']="Dung lượng tối đa cho file";
-$lang['L_MAX_UPLOAD_SIZE_INFO']="Nếu file sao lưu của các bạn lớn hơn giới hạn được quy định ở trên, bạn phải nạp dữ liệu nó qua FTP vào trong thư mục \"work/backup\".
-Sau đó bạn có thể chọn nó để bắt đầu phục hồi. ";
-$lang['L_ENCODING']="mã hóa";
-$lang['L_FM_CHOOSE_ENCODING']="Chọn chế độ mã hóa của file sao lưu";
-$lang['L_CHOOSE_CHARSET']="MySQLDumper đã không thể phát hiện ra sự mã hóa của File sao lưu một cách tự động.
+
+$lang['L_CONVERT_START'] = 'Bắt đầu Chuyển đổi';
+$lang['L_CONVERT_TITLE'] = 'Chuyển đổi Dump thành dạng MOD';
+$lang['L_CONVERT_WRONG_PARAMETERS'] = 'Sai tham số!  Chương trình chuyển đổi không hoạt động.';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'chọn 1 file.';
+$lang['L_FM_UPLOADNOTALLOWED1'] = 'Kiểu file này không được hỗ trợ.';
+$lang['L_FM_UPLOADNOTALLOWED2'] = 'Các định dạng file được chấp nhận: *.gz và *.sql';
+$lang['L_FM_UPLOADMOVEERROR'] = 'Không thể di chuyển file đã chọn tới thư mục upload';
+$lang['L_FM_UPLOADFAILED'] = 'Upload bị lỗi!';
+$lang['L_FM_UPLOADFILEEXISTS'] = 'Một file với tên giống như vậy đã tồn tại!';
+$lang['L_FM_NOFILE'] = 'Bạn chưa chọn file!';
+$lang['L_FM_DELETE1'] = 'File ';
+$lang['L_FM_DELETE2'] = ' đã xóa thành công.';
+$lang['L_FM_DELETE3'] = ' không thể xóa!';
+$lang['L_FM_CHOOSE_FILE'] = 'Chọn file:';
+$lang['L_FM_FILESIZE'] = 'Cỡ File';
+$lang['L_FM_FILEDATE'] = 'Ngày';
+$lang['L_FM_NOFILESFOUND'] = 'Không tìm thấy file.';
+$lang['L_FM_TABLES'] = 'Các bảng';
+$lang['L_FM_RECORDS'] = 'Bản ghi';
+$lang['L_FM_ALL_BU'] = 'Tất cả bản sao lưu';
+$lang['L_FM_ANZ_BU'] = 'Các sao lưu';
+$lang['L_FM_LAST_BU'] = 'Sao lưu cuối cùng';
+$lang['L_FM_TOTALSIZE'] = 'Tổng dung lượng';
+$lang['L_FM_SELECTTABLES'] = 'Chọn bảng';
+$lang['L_FM_COMMENT'] = 'Nhập lệnh';
+$lang['L_FM_RESTORE'] = 'Phục hồi';
+$lang['L_FM_ALERTRESTORE1'] = 'Bạn có muốn CSDL';
+$lang['L_FM_ALERTRESTORE2'] = 'được phục hồi với những bản ghi từ file';
+$lang['L_FM_ALERTRESTORE3'] = ' ?';
+$lang['L_FM_DELETE'] = 'Xóa';
+$lang['L_FM_ASKDELETE1'] = 'Bạn có muốn file ';
+$lang['L_FM_ASKDELETE2'] = 'bị xóa?';
+$lang['L_FM_ASKDELETE3'] = 'Bạn muốn xóa tự động ngay bây giờ bằng cách sử dụng những quy tắc đã được cấu hình không?';
+$lang['L_FM_ASKDELETE4'] = 'Bạn muốn xóa tất cả các tập tin dự phòng không?';
+$lang['L_FM_ASKDELETE5'] = 'Bạn muốn xóa tất cả các tập tin dự phòng dạng ';
+$lang['L_FM_ASKDELETE5_2'] = '_* ?';
+$lang['L_FM_DELETEAUTO'] = 'Chạy tự động xóa bằng tay';
+$lang['L_FM_DELETEALL'] = 'Xóa tất cả các tập tin dự phòng';
+$lang['L_FM_DELETEALLFILTER'] = 'Xóa mọi thứ dạng ';
+$lang['L_FM_DELETEALLFILTER2'] = '_*';
+$lang['L_FM_STARTDUMP'] = 'Bắt đầu Sao lưu Mới';
+$lang['L_FM_FILEUPLOAD'] = 'Upload file';
+$lang['L_FM_DBNAME'] = 'Tên CSDL';
+$lang['L_FM_FILES1'] = 'Sao lưu CSDL';
+$lang['L_FM_FILES2'] = 'Cấu trúc CSDL';
+$lang['L_FM_AUTODEL1'] = 'Xóa tự động: các file đã bị xóa vì dung lượng các file sao lưu lớn quá quy định:';
+$lang['L_DELETE_FILE_SUCCESS'] = 'File "%s" was deleted successfully.';
+$lang['L_FM_DUMPSETTINGS'] = 'Cấu hình cho';
+$lang['L_FM_OLDBACKUP'] = '(không hiểu)';
+$lang['L_FM_RESTORE_HEADER'] = 'Phục hồi cSDL "<strong>%s</strong>"';
+$lang['L_DELETE_FILE_ERROR'] = 'Error deleting file "%s"!';
+$lang['L_FM_DUMP_HEADER'] = 'Backup';
+$lang['L_DOCRONBUTTON'] = 'Chạy Perl Cron script';
+$lang['L_DOPERLTEST'] = 'Kiểm tra Perl Modules';
+$lang['L_DOSIMPLETEST'] = 'Kiểm tra Perl';
+$lang['L_PERLOUTPUT1'] = 'Các mục trong crondump.pl cho absolute_path_of_configdir';
+$lang['L_PERLOUTPUT2'] = 'URL cho tronhf duyệt hoặc ngoài Cron job';
+$lang['L_PERLOUTPUT3'] = 'Dòng lệnh trong Shell hoặc cho Crontab';
+$lang['L_RESTORE_OF_TABLES'] = 'Chọn Bảng để phục hồi';
+$lang['L_CONVERTER'] = 'Chương trình chuyển đổi sao lưu';
+$lang['L_CONVERT_FILE'] = 'File cần được chuyển đổi';
+$lang['L_CONVERT_FILENAME'] = 'Tên file xuất ra (bỏ qua phần mở rộng)';
+$lang['L_CONVERTING'] = 'Đang chuyển đổi';
+$lang['L_CONVERT_FILEREAD'] = "Đọc file '%s'";
+$lang['L_CONVERT_FINISHED'] = "Kết thúc chuyển đổi, '%s' vừa tạo thành công.";
+$lang['L_NO_MOD_BACKUPFILE'] = 'Sao lưu script khác';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Dung lượng tối đa cho file';
+$lang['L_MAX_UPLOAD_SIZE_INFO'] = 'Nếu file sao lưu của các bạn lớn hơn giới hạn được quy định ở trên, bạn phải nạp dữ liệu nó qua FTP vào trong thư mục "work/backup".
+Sau đó bạn có thể chọn nó để bắt đầu phục hồi. ';
+$lang['L_ENCODING'] = 'mã hóa';
+$lang['L_FM_CHOOSE_ENCODING'] = 'Chọn chế độ mã hóa của file sao lưu';
+$lang['L_CHOOSE_CHARSET'] = 'MyOOS [Dumper] đã không thể phát hiện ra sự mã hóa của File sao lưu một cách tự động.
 <br>Bạn phải chọn charset đúng với định dạng đã được sao lưu.
 <br>Nếu bạn thấy bất kỳ vấn đề nào sau khi khôi phục, bạn có thể lặp lại quá trình sao lưu và sau đó chọn charset khác.
-<br>Chúc may mắn. ;)";
-$lang['L_DOWNLOAD_FILE']="Download file";
-$lang['L_BACKUP_NOT_POSSIBLE'] = "A backup of the system database `%s` is not possible!";
-?>
\ No newline at end of file
+<br>Chúc may mắn. ;)';
+$lang['L_DOWNLOAD_FILE'] = 'Download file';
+$lang['L_BACKUP_NOT_POSSIBLE'] = 'A backup of the system database `%s` is not possible!';
diff --git a/msd/language/vn/lang_help.php b/msd/language/vn/lang_help.php
index 1a6c163a..84623e7a 100644
--- a/msd/language/vn/lang_help.php
+++ b/msd/language/vn/lang_help.php
@@ -1,39 +1,40 @@
 <?php
-$lang['L_HELP_DB']="Đây là danh sách (của) tất cả các cơ sở dữ liệu";
-$lang['L_HELP_PRAEFIX']="tiền tố là một chuỗi ký tự bắt đầu cho một tên bảng, nó làm việc  như một bộ lọc.";
-$lang['L_HELP_ZIP']="Nén với GZip - nên 'kích hoạt'";
-$lang['L_HELP_MEMORYLIMIT']="Số lượng tối đã (tính bằng Byte) cho script
-0 = ngưng kích hoạt";
-$lang['L_MEMORY_LIMIT']="Giới hạn bộ nhớ";
-$lang['L_HELP_AD1']="Nếu được kích hoạt, file sao lưu sẽ được tự động xóa.";
-$lang['L_HELP_AD3']="số lượng file sao lưu tối đa (sẽ bị xóa tự động)
-0 = không khống chế";
-$lang['L_HELP_LANG']="select your language";
-$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE']="Để loại trừ dữ liệu vô ích bạn có thể chỉ dẫn làm trống rỗng cơ sở dữ liệu trước khi khôi phục";
-$lang['L_HELP_CRONEXTENDER']="Phần mở rộng của mã nguồn Perl, mặc định là '.pl'";
-$lang['L_HELP_CRONSAVEPATH']="Tên của file cấu hình cho mã nguồn Perl";
-$lang['L_HELP_CRONPRINTOUT']="Nếu ngưng kích hoạt, kết quả sẽ không xxược in ra màn hình.
-Nó độc lập với việc in trong logfile.";
-$lang['L_HELP_CRONSAMEDB']="Use same database in Cron job like configured under Database?";
-$lang['L_HELP_CRONDBINDEX']="choose the database for Cron job";
-$lang['L_HELP_FTPTRANSFER']="nếu kích hoạt, file sẽ được gửi qua FTP.";
-$lang['L_HELP_FTPSERVER']="Địa chỉ của FTP-Server";
-$lang['L_HELP_FTPPORT']="Cổng của FTP-Server, chuẩn là: 21";
-$lang['L_HELP_FTPUSER']="nhập username truy cập FTP";
-$lang['L_HELP_FTPPASS']="nhập mật khẩu truy cập FTP";
-$lang['L_HELP_FTPDIR']="thư mục upload ở đâu? nhập đường dẫn!";
-$lang['L_HELP_SPEED']="Tốc độ tối thiểu và tối đa, mặc định là 50 tới 5000";
-$lang['L_SPEED']="Điều khiển tốc độ";
-$lang['L_HELP_CRONEXECPATH']="Nơi của Perl scripts.
+
+$lang['L_HELP_DB'] = 'Đây là danh sách (của) tất cả các cơ sở dữ liệu';
+$lang['L_HELP_PRAEFIX'] = 'tiền tố là một chuỗi ký tự bắt đầu cho một tên bảng, nó làm việc  như một bộ lọc.';
+$lang['L_HELP_ZIP'] = "Nén với GZip - nên 'kích hoạt'";
+$lang['L_HELP_MEMORYLIMIT'] = 'Số lượng tối đã (tính bằng Byte) cho script
+0 = ngưng kích hoạt';
+$lang['L_MEMORY_LIMIT'] = 'Giới hạn bộ nhớ';
+$lang['L_HELP_AD1'] = 'Nếu được kích hoạt, file sao lưu sẽ được tự động xóa.';
+$lang['L_HELP_AD3'] = 'số lượng file sao lưu tối đa (sẽ bị xóa tự động)
+0 = không khống chế';
+$lang['L_HELP_LANG'] = 'select your language';
+$lang['L_HELP_EMPTY_DB_BEFORE_RESTORE'] = 'Để loại trừ dữ liệu vô ích bạn có thể chỉ dẫn làm trống rỗng cơ sở dữ liệu trước khi khôi phục';
+$lang['L_HELP_CRONEXTENDER'] = "Phần mở rộng của mã nguồn Perl, mặc định là '.pl'";
+$lang['L_HELP_CRONSAVEPATH'] = 'Tên của file cấu hình cho mã nguồn Perl';
+$lang['L_HELP_CRONPRINTOUT'] = 'Nếu ngưng kích hoạt, kết quả sẽ không xxược in ra màn hình.
+Nó độc lập với việc in trong logfile.';
+$lang['L_HELP_CRONSAMEDB'] = 'Use same database in Cron job like configured under Database?';
+$lang['L_HELP_CRONDBINDEX'] = 'choose the database for Cron job';
+$lang['L_HELP_FTPTRANSFER'] = 'nếu kích hoạt, file sẽ được gửi qua FTP.';
+$lang['L_HELP_FTPSERVER'] = 'Địa chỉ của FTP-Server';
+$lang['L_HELP_FTPPORT'] = 'Cổng của FTP-Server, chuẩn là: 21';
+$lang['L_HELP_FTPUSER'] = 'nhập username truy cập FTP';
+$lang['L_HELP_FTPPASS'] = 'nhập mật khẩu truy cập FTP';
+$lang['L_HELP_FTPDIR'] = 'thư mục upload ở đâu? nhập đường dẫn!';
+$lang['L_HELP_SFTPTRANSFER'] = 'nếu kích hoạt, file sẽ được gửi qua SFTP.';
+$lang['L_HELP_SFTPSERVER'] = 'Địa chỉ của SFTP-Server';
+$lang['L_HELP_SFTPPORT'] = 'Cổng của SFTP-Server, chuẩn là: 22';
+$lang['L_HELP_SFTPUSER'] = 'nhập username truy cập SFTP';
+$lang['L_HELP_SFTPPASS'] = 'nhập mật khẩu truy cập SFTP';
+$lang['L_HELP_SFTPDIR'] = 'thư mục upload ở đâu? nhập đường dẫn!';
+$lang['L_HELP_SPEED'] = 'Tốc độ tối thiểu và tối đa, mặc định là 50 tới 5000';
+$lang['L_SPEED'] = 'Điều khiển tốc độ';
+$lang['L_HELP_CRONEXECPATH'] = 'Nơi của Perl scripts.
 Xuất phát từ HTTP-Address (giống địa chỉ ở trình duyệt)
-được sử dụng địa chỉ tuyệt đối hay tương đối.";
-$lang['L_CRON_EXECPATH']="Đường dẫn của Perl scripts";
-$lang['L_HELP_CRONCOMPLETELOG']="Khi được kích hoạt, đường ra đầy đủ được ghi trong complete_log-file.
-Cái này độc lập với văn bản đang in";
-$lang['L_HELP_FTP_MODE']="Khi có vấn đề xuất hiện với việc chuyển qua FTP, thử sử dụng chế độ bị động (passive mode).
-
-
-";
-
-
-?>
\ No newline at end of file
+được sử dụng địa chỉ tuyệt đối hay tương đối.';
+$lang['L_CRON_EXECPATH'] = 'Đường dẫn của Perl scripts';
+$lang['L_HELP_CRONCOMPLETELOG'] = 'Khi được kích hoạt, đường ra đầy đủ được ghi trong complete_log-file.
+Cái này độc lập với văn bản đang in';
+$lang['L_HELP_FTP_MODE'] = 'Khi có vấn đề xuất hiện với việc chuyển qua FTP, thử sử dụng chế độ bị động (passive mode).';
diff --git a/msd/language/vn/lang_install.php b/msd/language/vn/lang_install.php
index 9bac34f2..11fee07f 100644
--- a/msd/language/vn/lang_install.php
+++ b/msd/language/vn/lang_install.php
@@ -1,92 +1,86 @@
 <?php
-$lang['L_INSTALLFINISHED']="<br>Cài đặt thành công  --> <a href=\"index.php\">Bắt đầu MySQLDumper</a><br>";
-$lang['L_INSTALL_TOMENU']="Quay lại menu chính";
-$lang['L_INSTALLMENU']="Menu chính";
-$lang['L_STEP']="SBước";
-$lang['L_INSTALL']="Cài đặt";
-$lang['L_UNINSTALL']="Gỡ cài đặt";
-$lang['L_TOOLS']="Công cụ";
-$lang['L_EDITCONF']="Sửa cấu hình";
-$lang['L_OSWEITER']="Tiếp tục (bỏ qua không Lưu)";
-$lang['L_ERRORMAN']="<strong>Lỗi trong khi Lưu cấu hình!</strong><br>Sửa lại File ";
-$lang['L_MANUELL']="bằng tay";
-$lang['L_CREATEDIRS']="Tạo ra những thư mục";
-$lang['L_INSTALL_CONTINUE']="Tiếp tục với sự cài đặt";
-$lang['L_CONNECTTOMYSQL']="Kết nối tới MySQL ";
-$lang['L_DBPARAMETER']="Những tham số Cơ sở dữ liệu";
-$lang['L_CONFIGNOTWRITABLE']="Tôi không thể viết vào file \"config.php\".
-Hãy dùng trình FTP của bạn và chmod afile này thành 0777.";
-$lang['L_DBCONNECTION']="Kết nối Cơ sở dữ liệu";
-$lang['L_CONNECTIONERROR']="Lỗi: Không thể nối.";
-$lang['L_CONNECTION_OK']="Kết nối Cơ sở dữ liệu được thiết lập.";
-$lang['L_SAVEANDCONTINUE']="Lưu lại và tiếp tục sự cài đặt";
-$lang['L_CONFBASIC']="Tham số Cơ bản";
-$lang['L_INSTALL_STEP2FINISHED']="Những tham số Cơ sở dữ liệu được Lưu lại thành công.";
-$lang['L_INSTALL_STEP2_1']="Tiếp tục cài đặt với những thiết đặt mặc định";
-$lang['L_LASTSTEP']="Kết thúc Cài đặt";
-$lang['L_FTPMODE']="Tạo ra những thư mục cần thiết Trong safe-mode";
-$lang['L_IDOMANUAL']="Tôi tạo ra những thư mục của tôi";
-$lang['L_DOFROM']="bắt đầu từ";
-$lang['L_FTPMODE2']="Tạo các thư mục với FTP:";
-$lang['L_CONNECT']="kết nối";
-$lang['L_DIRS_CREATED']="Các thư mục được tạo ra và được chấp nhận.";
-$lang['L_CONNECT_TO']="kết nối tới";
-$lang['L_CHANGEDIR']="đổi thư mục";
-$lang['L_CHANGEDIRERROR']="không thể đổi thư mục";
-$lang['L_FTP_OK']="tham số FTP được chấp nhận";
-$lang['L_CREATEDIRS2']="Tạo các thư mục";
-$lang['L_FTP_NOTCONNECTED']="Kết nối FTP không được thiết lập!";
-$lang['L_CONNWITH']="Kết nối Với";
-$lang['L_ASUSER']="như người sử dụng";
-$lang['L_NOTPOSSIBLE']="không thể";
-$lang['L_DIRCR1']="tạo thư mục work";
-$lang['L_DIRCR2']="tạo thư mục backup";
-$lang['L_DIRCR4']="tạo thư mục log";
-$lang['L_DIRCR5']="tạo thư mục configuration";
-$lang['L_INDIR']="đang ở thư mục";
-$lang['L_CHECK_DIRS']="Kiểm tra các thư mục";
-$lang['L_DISABLEDFUNCTIONS']="Vô hiệu hóa những tính năng";
-$lang['L_NOFTPPOSSIBLE']="Bạn không có những tính năng FTP !";
-$lang['L_NOGZPOSSIBLE']="Bạn không có những tính năng nén !";
-$lang['L_UI1']="Tất cả các thư mục làm việc mà có thể chứa đựng những sao lưu sẽ được xóa.";
-$lang['L_UI2']="Bạn chắc chắn bạn muốn điều đó?";
-$lang['L_UI3']="không, bỏ qua ngay lập tức";
-$lang['L_UI4']="có, cứ tiếp tục";
-$lang['L_UI5']="xóa những thư mục làm việc";
-$lang['L_UI6']="mọi thứ đã bị xóa thành công.";
-$lang['L_UI7']="Xin xóa thư mục script";
-$lang['L_UI8']="lên mức trên";
-$lang['L_UI9']="Có lỗi, không thể xóa</p>Lỗi với thư mục ";
-$lang['L_IMPORT']="Nhập Cấu hình";
-$lang['L_IMPORT3']="Cấu hình được tải ...";
-$lang['L_IMPORT4']="Đã ghi cấu hình.";
-$lang['L_IMPORT5']="Chạy MySQLDumper";
-$lang['L_IMPORT6']="Menu cài đặt";
-$lang['L_IMPORT7']="Upload cấu hình";
-$lang['L_IMPORT8']="quay lại để upload";
-$lang['L_IMPORT9']="Đây không là một sao lưu cấu hình !";
-$lang['L_IMPORT10']="Cấu hình được upload thành công ...";
-$lang['L_IMPORT11']="<strong>Lỗi: </strong>Có vấn đề khi đang viết sql_statements";
-$lang['L_IMPORT12']="<strong>Lỗi: </strong>Có vấn đề khi đang viết config.php";
-$lang['L_INSTALL_HELP_PORT']="(để trống = Cổng mặc định)";
-$lang['L_INSTALL_HELP_SOCKET']="(để trống = Socket mặc định)";
-$lang['L_TRYAGAIN']="Thử lại";
-$lang['L_SOCKET']="Socket";
-$lang['L_PORT']="Cổng";
-$lang['L_FOUND_DB']="tìm thấy db";
-$lang['L_FM_FILEUPLOAD']="Upload file";
-$lang['L_PASS']="Password";
-$lang['L_NO_DB_FOUND_INFO']="Kết nối tới cSDL được thiết lập thành công.<br>
+
+$lang['L_INSTALLFINISHED'] = '<br>Cài đặt thành công  --> <a href="index.php">Bắt đầu MyOOS [Dumper]</a><br>';
+$lang['L_INSTALL_TOMENU'] = 'Quay lại menu chính';
+$lang['L_INSTALLMENU'] = 'Menu chính';
+$lang['L_STEP'] = 'SBước';
+$lang['L_INSTALL'] = 'Cài đặt';
+$lang['L_UNINSTALL'] = 'Gỡ cài đặt';
+$lang['L_TOOLS'] = 'Công cụ';
+$lang['L_EDITCONF'] = 'Sửa cấu hình';
+$lang['L_OSWEITER'] = 'Tiếp tục (bỏ qua không Lưu)';
+$lang['L_ERRORMAN'] = '<strong>Lỗi trong khi Lưu cấu hình!</strong><br>Sửa lại File ';
+$lang['L_MANUELL'] = 'bằng tay';
+$lang['L_CREATEDIRS'] = 'Tạo ra những thư mục';
+$lang['L_INSTALL_CONTINUE'] = 'Tiếp tục với sự cài đặt';
+$lang['L_CONNECTTOMYSQL'] = 'Kết nối tới MySQL ';
+$lang['L_DBPARAMETER'] = 'Những tham số Cơ sở dữ liệu';
+$lang['L_CONFIGNOTWRITABLE'] = 'Tôi không thể viết vào file "config.php".
+Hãy dùng trình FTP của bạn và chmod afile này thành 0777.';
+$lang['L_DBCONNECTION'] = 'Kết nối Cơ sở dữ liệu';
+$lang['L_CONNECTIONERROR'] = 'Lỗi: Không thể nối.';
+$lang['L_CONNECTION_OK'] = 'Kết nối Cơ sở dữ liệu được thiết lập.';
+$lang['L_SAVEANDCONTINUE'] = 'Lưu lại và tiếp tục sự cài đặt';
+$lang['L_CONFBASIC'] = 'Tham số Cơ bản';
+$lang['L_INSTALL_STEP2FINISHED'] = 'Những tham số Cơ sở dữ liệu được Lưu lại thành công.';
+$lang['L_INSTALL_STEP2_1'] = 'Tiếp tục cài đặt với những thiết đặt mặc định';
+$lang['L_LASTSTEP'] = 'Kết thúc Cài đặt';
+$lang['L_FTPMODE'] = 'Tạo ra những thư mục cần thiết Trong safe-mode';
+$lang['L_IDOMANUAL'] = 'Tôi tạo ra những thư mục của tôi';
+$lang['L_DOFROM'] = 'bắt đầu từ';
+$lang['L_FTPMODE2'] = 'Tạo các thư mục với FTP:';
+$lang['L_CONNECT'] = 'kết nối';
+$lang['L_DIRS_CREATED'] = 'Các thư mục được tạo ra và được chấp nhận.';
+$lang['L_CONNECT_TO'] = 'kết nối tới';
+$lang['L_CHANGEDIR'] = 'đổi thư mục';
+$lang['L_CHANGEDIRERROR'] = 'không thể đổi thư mục';
+$lang['L_FTP_OK'] = 'tham số FTP được chấp nhận';
+$lang['L_CREATEDIRS2'] = 'Tạo các thư mục';
+$lang['L_FTP_NOTCONNECTED'] = 'Kết nối FTP không được thiết lập!';
+$lang['L_CONNWITH'] = 'Kết nối Với';
+$lang['L_ASUSER'] = 'như người sử dụng';
+$lang['L_NOTPOSSIBLE'] = 'không thể';
+$lang['L_DIRCR1'] = 'tạo thư mục work';
+$lang['L_DIRCR2'] = 'tạo thư mục backup';
+$lang['L_DIRCR4'] = 'tạo thư mục log';
+$lang['L_DIRCR5'] = 'tạo thư mục configuration';
+$lang['L_INDIR'] = 'đang ở thư mục';
+$lang['L_CHECK_DIRS'] = 'Kiểm tra các thư mục';
+$lang['L_DISABLEDFUNCTIONS'] = 'Vô hiệu hóa những tính năng';
+$lang['L_NOFTPPOSSIBLE'] = 'Bạn không có những tính năng FTP !';
+$lang['L_NOGZPOSSIBLE'] = 'Bạn không có những tính năng nén !';
+$lang['L_UI1'] = 'Tất cả các thư mục làm việc mà có thể chứa đựng những sao lưu sẽ được xóa.';
+$lang['L_UI2'] = 'Bạn chắc chắn bạn muốn điều đó?';
+$lang['L_UI3'] = 'không, bỏ qua ngay lập tức';
+$lang['L_UI4'] = 'có, cứ tiếp tục';
+$lang['L_UI5'] = 'xóa những thư mục làm việc';
+$lang['L_UI6'] = 'mọi thứ đã bị xóa thành công.';
+$lang['L_UI7'] = 'Xin xóa thư mục script';
+$lang['L_UI8'] = 'lên mức trên';
+$lang['L_UI9'] = 'Có lỗi, không thể xóa</p>Lỗi với thư mục ';
+$lang['L_IMPORT'] = 'Nhập Cấu hình';
+$lang['L_IMPORT3'] = 'Cấu hình được tải ...';
+$lang['L_IMPORT4'] = 'Đã ghi cấu hình.';
+$lang['L_IMPORT5'] = 'Chạy MyOOS [Dumper]';
+$lang['L_IMPORT6'] = 'Menu cài đặt';
+$lang['L_IMPORT7'] = 'Upload cấu hình';
+$lang['L_IMPORT8'] = 'quay lại để upload';
+$lang['L_IMPORT9'] = 'Đây không là một sao lưu cấu hình !';
+$lang['L_IMPORT10'] = 'Cấu hình được upload thành công ...';
+$lang['L_IMPORT11'] = '<strong>Lỗi: </strong>Có vấn đề khi đang viết sql_statements';
+$lang['L_IMPORT12'] = '<strong>Lỗi: </strong>Có vấn đề khi đang viết config.php';
+$lang['L_INSTALL_HELP_PORT'] = '(để trống = Cổng mặc định)';
+$lang['L_INSTALL_HELP_SOCKET'] = '(để trống = Socket mặc định)';
+$lang['L_TRYAGAIN'] = 'Thử lại';
+$lang['L_SOCKET'] = 'Socket';
+$lang['L_PORT'] = 'Cổng';
+$lang['L_FOUND_DB'] = 'tìm thấy db';
+$lang['L_FM_FILEUPLOAD'] = 'Upload file';
+$lang['L_PASS'] = 'Password';
+$lang['L_NO_DB_FOUND_INFO'] = 'Kết nối tới cSDL được thiết lập thành công.<br>
 Dữ liệu thành viên hợp lệ và được MySQL-Server chấp nhận.<br>
-Nhưng MySQLDumper không thể tìm thấy bất kỳ cơ sở dữ liệu nào.<br>
+Nhưng MyOOS [Dumper] không thể tìm thấy bất kỳ cơ sở dữ liệu nào.<br>
 Dò tìm tự động qua script bị cấm trên một vài server.<br>
 Bạn phải vào databasename của bạn bằng tay sau khi sự cài đặt (thì) kết thúc.
-Click \"cấu hình\" \"Tham số Kết nối - hiển thị\" và nhập tên CSDL đó.";
-$lang['L_SAFEMODEDESC']="Vì PHP đang chạy trong chế độ safe_mode nên bạn phải tạo thư mục bằng cách sử dụng chương trình FTP:
-
-
-";
-$lang['L_ENTER_DB_INFO']="First click the button \"Connect to MySQL\". Only if no database could be detected you need to provide a database name here.";
-
-
-?>
\ No newline at end of file
+Click "cấu hình" "Tham số Kết nối - hiển thị" và nhập tên CSDL đó.';
+$lang['L_ENTER_DB_INFO'] = 'First click the button "Connect to MySQL". Only if no database could be detected you need to provide a database name here.';
diff --git a/msd/language/vn/lang_log.php b/msd/language/vn/lang_log.php
index 9d3ebbe3..e04e8aad 100644
--- a/msd/language/vn/lang_log.php
+++ b/msd/language/vn/lang_log.php
@@ -1,12 +1,10 @@
 <?php
-$lang['L_LOG_DELETE']="xóa Log";
-$lang['L_LOGFILEFORMAT']="Định dạng file nhật ký (logfile)";
-$lang['L_LOGFILENOTWRITABLE']="Không thể ghi file nhật ký Logfile !";
-$lang['L_NOREVERSE']="Cũ lên trên";
-$lang['L_REVERSE']="Mới lên trên
+
+$lang['L_LOG_DELETE'] = 'xóa Log';
+$lang['L_LOGFILEFORMAT'] = 'Định dạng file nhật ký (logfile)';
+$lang['L_LOGFILENOTWRITABLE'] = 'Không thể ghi file nhật ký Logfile !';
+$lang['L_NOREVERSE'] = 'Cũ lên trên';
+$lang['L_REVERSE'] = 'Mới lên trên
 
 
-";
-
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/vn/lang_main.php b/msd/language/vn/lang_main.php
index 6b317c61..e26f5bc3 100644
--- a/msd/language/vn/lang_main.php
+++ b/msd/language/vn/lang_main.php
@@ -1,81 +1,89 @@
 <?php
-$lang['L_NOFTPPOSSIBLE']="Bạn không có những chức năng FTP!";
-$lang['L_INFO_LOCATION']="vị trí của bạn ở ";
-$lang['L_INFO_DATABASES']="CSDL sau đây ở trên Server của bạn:";
-$lang['L_INFO_NODB']="cơ sở dữ liệu không tồn tại.";
-$lang['L_INFO_DBDETAIL']="Thông tin Chi tiết (của) cơ sở dữ liệu ";
-$lang['L_INFO_DBEMPTY']="Cơ sở dữ liệu rỗng !";
-$lang['L_INFO_RECORDS']="các bản ghi";
-$lang['L_INFO_SIZE']="kích thước";
-$lang['L_INFO_LASTUPDATE']="Cập nhật Cuối cùng";
-$lang['L_INFO_SUM']="tổng số";
-$lang['L_INFO_OPTIMIZED']="tối ưu hóa";
-$lang['L_OPTIMIZE_DATABASES']="Tối ưu hóa các bảng";
-$lang['L_CHECK_TABLES']="Kiểm tra Tables";
-$lang['L_CLEAR_DATABASE']="Làm sạch CSDL";
-$lang['L_DELETE_DATABASE']="xóa CSDL";
-$lang['L_INFO_CLEARED']="vừa được làm sạch";
-$lang['L_INFO_DELETED']="vừa bị xóa";
-$lang['L_INFO_EMPTYDB1']="Muốn các CSDL";
-$lang['L_INFO_EMPTYDB2']=" bị cắt bớt? (Chú ý: Tất cả Dữ liệu sẽ mất vĩnh viễn!)";
-$lang['L_INFO_KILLDB']=" bị xóa? (Chú ý: Tất cả Dữ liệu sẽ mất vĩnh viễn!)";
-$lang['L_PROCESSKILL1']="Script cố dừng tiến trình ";
-$lang['L_PROCESSKILL2']="để dừng.";
-$lang['L_PROCESSKILL3']="Script thử từ  ";
-$lang['L_PROCESSKILL4']=" sec. để dừng tiến trình ";
-$lang['L_HTACC_CREATE']="Tạo Mật mã bảo vệ thư mục";
-$lang['L_ENCRYPTION_TYPE']="Cách mã hóa";
-$lang['L_HTACC_CRYPT']="Crypt (Linux và hệ thống Unix)";
-$lang['L_HTACC_MD5']="MD5 (Linux và hệ thống Unix)";
-$lang['L_HTACC_NO_ENCRYPTION']="plain text (chữ đơn thuần), không mã hóa (Windows)";
-$lang['L_HTACCESS8']="Đã tồn tại một mật mã bảo vệ thư mục. Nếu bạn tạo mật mã mới, mật mã cũ sẽ bị ghi đè!";
-$lang['L_HTACC_NO_USERNAME']="Bạn phải nhập vào một tên!";
-$lang['L_PASSWORDS_UNEQUAL']="Mật khẩu nhập lại không giống hoặc đã bị để trống!";
-$lang['L_HTACC_CONFIRM_DELETE']="Có bảo vệ thư mục hay không?";
-$lang['L_HTACC_CREATED']="Thư mục đã được bảo vệ";
-$lang['L_HTACC_CONTENT']="Nội dung của file";
-$lang['L_HTACC_CREATE_ERROR']="Đã có lỗi khi tạo file bảo vệ thư mục!<br>Hãy tạo ra 2 file bằng tay với nội dung sau đây";
-$lang['L_HTACC_PROPOSED']="Thông báo khẩn";
-$lang['L_HTACC_EDIT']="Sửa .htaccess";
-$lang['L_HTACCESS18']="Tạo .htaccess trong ";
-$lang['L_HTACCESS19']="Nạp lại ";
-$lang['L_HTACCESS20']="Thực hiện script";
-$lang['L_HTACCESS21']="Thêm người điều khiển";
-$lang['L_HTACCESS22']="Làm cho có thể thực hiện";
-$lang['L_HTACCESS23']="Danh sách Thư mục";
-$lang['L_HTACCESS24']="Tài liệu Lỗi";
-$lang['L_HTACCESS25']="Kích hoạt Viết lại";
-$lang['L_HTACCESS26']="Từ chối / Cho phép";
-$lang['L_HTACCESS27']="Gửi một lần nữa";
-$lang['L_HTACCESS28']="Danh sách lỗi được ghi nhận";
-$lang['L_HTACCESS29']="Xem thêm ví dụ và tài liệu";
-$lang['L_HTACCESS30']="Nhà cung cấp";
-$lang['L_HTACCESS31']="Tổng quan";
-$lang['L_HTACCESS32']="Chú ý! file .htaccess trực tiếp ảnh hưởng đến hoạt động của trình duyệt.<br>Với nội dung sai, những trang này có thể bị chặn truy cập.";
-$lang['L_PHPBUG']="Lỗi trong zlib ! Không thể nén!";
-$lang['L_DISABLEDFUNCTIONS']="Vô hiệu hóa những chức năng";
-$lang['L_NOGZPOSSIBLE']="Vì Zlib chưa được cài đặt, bạn không thể sử dụng thư viện GZip!";
-$lang['L_DELETE_HTACCESS']="Bỏ bảo vệ thư mục (xóa .htaccess)";
-$lang['L_WRONG_RIGHTS']="File hay thư mục '%s' không cho phép ghi.<br>
+
+$lang['L_NOFTPPOSSIBLE'] = 'Bạn không có những chức năng FTP!';
+$lang['L_INFO_LOCATION'] = 'vị trí của bạn ở ';
+$lang['L_INFO_DATABASES'] = 'CSDL sau đây ở trên Server của bạn:';
+$lang['L_INFO_NODB'] = 'cơ sở dữ liệu không tồn tại.';
+$lang['L_INFO_DBDETAIL'] = 'Thông tin Chi tiết (của) cơ sở dữ liệu ';
+$lang['L_INFO_DBEMPTY'] = 'Cơ sở dữ liệu rỗng !';
+$lang['L_INFO_RECORDS'] = 'các bản ghi';
+$lang['L_INFO_SIZE'] = 'kích thước';
+$lang['L_INFO_LASTUPDATE'] = 'Cập nhật Cuối cùng';
+$lang['L_INFO_SUM'] = 'tổng số';
+$lang['L_INFO_OPTIMIZED'] = 'tối ưu hóa';
+$lang['L_OPTIMIZE_DATABASES'] = 'Tối ưu hóa các bảng';
+$lang['L_CHECK_TABLES'] = 'Kiểm tra Tables';
+$lang['L_CLEAR_DATABASE'] = 'Làm sạch CSDL';
+$lang['L_DELETE_DATABASE'] = 'xóa CSDL';
+$lang['L_INFO_CLEARED'] = 'vừa được làm sạch';
+$lang['L_INFO_DELETED'] = 'vừa bị xóa';
+$lang['L_INFO_EMPTYDB1'] = 'Muốn các CSDL';
+$lang['L_INFO_EMPTYDB2'] = ' bị cắt bớt? (Chú ý: Tất cả Dữ liệu sẽ mất vĩnh viễn!)';
+$lang['L_INFO_KILLDB'] = ' bị xóa? (Chú ý: Tất cả Dữ liệu sẽ mất vĩnh viễn!)';
+$lang['L_PROCESSKILL1'] = 'Script cố dừng tiến trình ';
+$lang['L_PROCESSKILL2'] = 'để dừng.';
+$lang['L_PROCESSKILL3'] = 'Script thử từ  ';
+$lang['L_PROCESSKILL4'] = ' sec. để dừng tiến trình ';
+$lang['L_HTACC_CREATE'] = 'Tạo Mật mã bảo vệ thư mục';
+$lang['L_ENCRYPTION_TYPE'] = 'Cách mã hóa';
+$lang['L_HTACC_BCRYPT'] = 'bcrypt - (Apache 2.4+, all systems)';
+$lang['L_HTACC_MD5'] = 'MD5(APR) - (all systems)';
+$lang['L_HTACC_SHA1'] = 'SHA1 - (all systems)';
+$lang['L_HTACC_CRYPT'] = 'CRYPT - 8 characters maximum (Linux)';
+$lang['L_HTACC_NO_ENCRYPTION'] = 'PLAIN TEXT - unencrypted (Windows)';
+$lang['L_HTACCESS8'] = 'Đã tồn tại một mật mã bảo vệ thư mục. Nếu bạn tạo mật mã mới, mật mã cũ sẽ bị ghi đè!';
+$lang['L_HTACC_NO_USERNAME'] = 'Bạn phải nhập vào một tên!';
+$lang['L_PASSWORDS_UNEQUAL'] = 'Mật khẩu nhập lại không giống hoặc đã bị để trống!';
+$lang['L_HTACC_CONFIRM_CREATE'] = 'Có bảo vệ thư mục hay không?';
+$lang['L_HTACC_CONFIRM_DELETE'] = 'Are you sure you want to remove directory protection?';
+$lang['L_HTACC_CREATED'] = 'Thư mục đã được bảo vệ';
+$lang['L_HTACC_CONTENT'] = 'Nội dung của file';
+$lang['L_HTACC_CREATE_ERROR'] = 'Đã có lỗi khi tạo file bảo vệ thư mục!<br>Hãy tạo ra 2 file bằng tay với nội dung sau đây';
+$lang['L_HTACC_CHECK_ERROR'] = 'It could not be checked whether the program is protected!<br>The simulated external access could not be carried out.';
+$lang['L_HTACC_NOT_NEEDED'] = 'The program is protected by higher-level authorizations; local directory protection is not required.';
+$lang['L_HTACC_COMPLETE'] = 'The program is protected, the directory protection is complete.';
+$lang['L_HTACC_INCOMPLETE'] = 'The program is not protected, the directory protection is incomplete!';
+$lang['L_HTACC_PROPOSED'] = 'The program is not protected, directory protection is strongly recommended!';
+$lang['L_HTACC_EDIT'] = 'Sửa .htaccess';
+$lang['L_HTACCESS18'] = 'Tạo .htaccess trong ';
+$lang['L_HTACCESS19'] = 'Nạp lại ';
+$lang['L_HTACCESS20'] = 'Thực hiện script';
+$lang['L_HTACCESS21'] = 'Thêm người điều khiển';
+$lang['L_HTACCESS22'] = 'Làm cho có thể thực hiện';
+$lang['L_HTACCESS23'] = 'Danh sách Thư mục';
+$lang['L_HTACCESS24'] = 'Tài liệu Lỗi';
+$lang['L_HTACCESS25'] = 'Kích hoạt Viết lại';
+$lang['L_HTACCESS26'] = 'Từ chối / Cho phép';
+$lang['L_HTACCESS27'] = 'Gửi một lần nữa';
+$lang['L_HTACCESS28'] = 'Danh sách lỗi được ghi nhận';
+$lang['L_HTACCESS29'] = 'Xem thêm ví dụ và tài liệu';
+$lang['L_HTACCESS30'] = 'Nhà cung cấp';
+$lang['L_HTACCESS31'] = 'Tổng quan';
+$lang['L_HTACCESS32'] = 'Chú ý! file .htaccess trực tiếp ảnh hưởng đến hoạt động của trình duyệt.<br>Với nội dung sai, những trang này có thể bị chặn truy cập.';
+$lang['L_DISABLEDFUNCTIONS'] = 'Vô hiệu hóa những chức năng';
+$lang['L_NOGZPOSSIBLE'] = 'Vì Zlib chưa được cài đặt, bạn không thể sử dụng thư viện GZip!';
+$lang['L_DELETE_HTACCESS'] = 'Bỏ bảo vệ thư mục (xóa .htaccess)';
+$lang['L_WRONG_RIGHTS'] = "File hay thư mục '%s' không cho phép ghi.<br>
 Chế độ chmod không đúng hoặc nó không dành cho chúng ta.<br>
 Đặt lại thuộc tính cho đúng bằng cách sử dụng trình FTP.<br>
 File hay thư mục cần được thiết lập thành %s.<br>";
-$lang['L_CANT_CREATE_DIR']="Không thể tạo thư mục '%s'. 
-Hãy tạo ra nó bằng cách sử dụng trình FTP.
-
-
-";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_CHECK']="check";
-$lang['L_HTACC_SHA1']="SHA1 (all Systems)";
-$lang['L_OS']="Operating system";
-$lang['L_MSD_VERSION']="MyOOS [Dumper] - Version";
-$lang['L_MYSQL_VERSION']="MySQL-Version";
-$lang['L_PHP_VERSION']="PHP-Version";
-$lang['L_MAX_EXECUTION_TIME']="Max execution time";
-$lang['L_PHP_EXTENSIONS']="PHP-Extensions";
-$lang['L_MEMORY']="Memory";
-$lang['L_FILE_MISSING']="không tìm thấy file";
-
-
-?>
\ No newline at end of file
+$lang['L_CANT_CREATE_DIR'] = "Không thể tạo thư mục '%s'.
+Hãy tạo ra nó bằng cách sử dụng trình FTP.";
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_CHECK'] = 'check';
+$lang['L_OS'] = 'Operating system';
+$lang['L_MOD_VERSION'] = 'MyOOS [Dumper] - Version';
+$lang['L_NEW_MOD_VERSION'] = 'New Version';
+$lang['L_NEW_MOD_VERSION_INFO'] = 'There is a new version of MyOOS [Dumper] available.';
+$lang['L_UPDATED_IMPORTANT'] = 'Important: Before updating, please backup your files.';
+$lang['L_UPDATE'] = 'Update now';
+$lang['L_MYSQL_VERSION'] = 'MySQL-Version';
+$lang['L_PHP_VERSION'] = 'PHP-Version';
+$lang['L_MAX_EXECUTION_TIME'] = 'Max execution time';
+$lang['L_PHP_EXTENSIONS'] = 'PHP-Extensions';
+$lang['L_MEMORY'] = 'Memory';
+$lang['L_FILE_MISSING'] = 'không tìm thấy file';
+$lang['L_INSTALLING_UPDATES'] = 'Installing Updates';
+$lang['L_UPDATE_SUCCESSFUL'] = 'Update successful';
+$lang['L_UPDATE_FAILED'] = 'Update failed';
+$lang['L_UP_TO_DATE'] = 'Current Version is up to date';
diff --git a/msd/language/vn/lang_restore.php b/msd/language/vn/lang_restore.php
index ae23c45f..a513edfc 100644
--- a/msd/language/vn/lang_restore.php
+++ b/msd/language/vn/lang_restore.php
@@ -1,24 +1,22 @@
 <?php
-$lang['L_RESTORE_TABLES_COMPLETED0']="Cho tới giờ, <b>%d</b> bảng đã được tạo ra.";
-$lang['L_FILE_MISSING']="không tìm thấy file";
-$lang['L_RESTORE_DB']="'<b>%s</b>' CSDL trong '<b>%s</b>'.";
-$lang['L_RESTORE_COMPLETE']="<b>%s</b> bảng đã được tạo ra.";
-$lang['L_RESTORE_RUN1']="<br>Tính đến giờ, <b>%s</b> trong số <b>%s</b> bản ghi đã được thêm vào thành công.";
-$lang['L_RESTORE_RUN2']="<br>Hiện tại bảng '<b>%s</b>' đang được phục hồi.<br><br>";
-$lang['L_RESTORE_COMPLETE2']="<b>%s</b> bản ghi được chèn vào.";
-$lang['L_RESTORE_TABLES_COMPLETED']="Tính đến giờ, <b>%d</b> trong số <b>%d</b> table đã được tạo.";
-$lang['L_RESTORE_TOTAL_COMPLETE']="<br><b>Chúc mừng.</b><br><br>Việc phục hồi cơ sở dữ liệu đã xong.<br>Tất cả dữ liệu Sao lưu đã được phục hồi.<br><br>Mọi việc đã kết thúc. :-)";
-$lang['L_DB_SELECT_ERROR']="<br>Lỗi:<br>Lựa chọn CSDL <b>";
-$lang['L_DB_SELECT_ERROR2']="</b> thất bại!";
-$lang['L_FILE_OPEN_ERROR']="Lỗi: Không thể mở file.";
-$lang['L_PROGRESS_OVER_ALL']="Toàn bộ tiến trình";
-$lang['L_BACK_TO_OVERVIEW']="Tổng quan Cơ sở dữ liệu";
-$lang['L_RESTORE_RUN0']="<br>Tính đến giờ, <b>%s</b> bản ghi đã được thêm vào thành công.";
-$lang['L_UNKNOWN_SQLCOMMAND']="không hiểu lệnh SQL";
-$lang['L_NOTICES']="Chú ý
+
+$lang['L_RESTORE_TABLES_COMPLETED0'] = 'Cho tới giờ, <b>%d</b> bảng đã được tạo ra.';
+$lang['L_FILE_MISSING'] = 'không tìm thấy file';
+$lang['L_RESTORE_DB'] = "'<b>%s</b>' CSDL trong '<b>%s</b>'.";
+$lang['L_RESTORE_COMPLETE'] = '<b>%s</b> bảng đã được tạo ra.';
+$lang['L_RESTORE_RUN1'] = '<br>Tính đến giờ, <b>%s</b> trong số <b>%s</b> bản ghi đã được thêm vào thành công.';
+$lang['L_RESTORE_RUN2'] = "<br>Hiện tại bảng '<b>%s</b>' đang được phục hồi.<br><br>";
+$lang['L_RESTORE_COMPLETE2'] = '<b>%s</b> bản ghi được chèn vào.';
+$lang['L_RESTORE_TABLES_COMPLETED'] = 'Tính đến giờ, <b>%d</b> trong số <b>%d</b> table đã được tạo.';
+$lang['L_RESTORE_TOTAL_COMPLETE'] = '<br><b>Chúc mừng.</b><br><br>Việc phục hồi cơ sở dữ liệu đã xong.<br>Tất cả dữ liệu Sao lưu đã được phục hồi.<br><br>Mọi việc đã kết thúc. :-)';
+$lang['L_DB_SELECT_ERROR'] = '<br>Lỗi:<br>Lựa chọn CSDL <b>';
+$lang['L_DB_SELECT_ERROR2'] = '</b> thất bại!';
+$lang['L_FILE_OPEN_ERROR'] = 'Lỗi: Không thể mở file.';
+$lang['L_PROGRESS_OVER_ALL'] = 'Toàn bộ tiến trình';
+$lang['L_BACK_TO_OVERVIEW'] = 'Tổng quan Cơ sở dữ liệu';
+$lang['L_RESTORE_RUN0'] = '<br>Tính đến giờ, <b>%s</b> bản ghi đã được thêm vào thành công.';
+$lang['L_UNKNOWN_SQLCOMMAND'] = 'không hiểu lệnh SQL';
+$lang['L_NOTICES'] = 'Chú ý
 
 
-";
-
-
-?>
\ No newline at end of file
+';
diff --git a/msd/language/vn/lang_sql.php b/msd/language/vn/lang_sql.php
index 9eb7bb08..6a3b713e 100644
--- a/msd/language/vn/lang_sql.php
+++ b/msd/language/vn/lang_sql.php
@@ -1,194 +1,190 @@
 <?php
-$lang['L_COMMAND']="Lệnh";
-$lang['L_IMPORT_NOTABLE']="Không có bảng được lựa chọn nhập vào (import)!";
-$lang['L_PASSWORD_STRENGTH']="Password strength";
-$lang['L_SQL_WARNING']="Sự thực hiện những câu lệnh SQL có thể thao tác vào dữ liệu. Cẩn thận! Tác giả không chấp nhận đền bù bất kỳ thiệt hại nào nếu dữ liệu bị hư hại hay bị mất.";
-$lang['L_SQL_EXEC']="Thực hiện câu lệnh SQL";
-$lang['L_SQL_DATAVIEW']="Xem dữ liệu";
-$lang['L_SQL_TABLEVIEW']="Xem bảng";
-$lang['L_SQL_VONINS']="từ tổng thể";
-$lang['L_SQL_NODATA']="không có bản ghi nào";
-$lang['L_SQL_RECORDUPDATED']="Bản ghi vừa được cập nhật";
-$lang['L_SQL_RECORDINSERTED']="Bản ghi vừa được thêm";
-$lang['L_SQL_BACKDBOVERVIEW']="Quay trở lại Tổng quan";
-$lang['L_SQL_RECORDDELETED']="Bản ghi vừa được xóa";
-$lang['L_ASKTABLEEMPTY']="Bảng `%s` bị rỗng?";
-$lang['L_SQL_RECORDEDIT']="bản ghi soạn thảo";
-$lang['L_SQL_RECORDNEW']="bản ghi mới";
-$lang['L_ASKDELETERECORD']="Bạn chắc chắn xóa bản ghi này?";
-$lang['L_ASKDELETETABLE']="Bảng `%s` sẽ bị xóa?";
-$lang['L_SQL_BEFEHLE']="Lệnh SQL";
-$lang['L_SQL_BEFEHLNEU']="Lệnh mới";
-$lang['L_SQL_BEFEHLSAVED1']="Lệnh SQL";
-$lang['L_SQL_BEFEHLSAVED2']="vừa thêm";
-$lang['L_SQL_BEFEHLSAVED3']="vừa lưu";
-$lang['L_SQL_BEFEHLSAVED4']="vừa chuyển lên";
-$lang['L_SQL_BEFEHLSAVED5']="vừa xóa";
-$lang['L_SQL_QUERYENTRY']="Nội dung Yêu cầu";
-$lang['L_SQL_COLUMNS']="Các cột";
-$lang['L_ASKDBDELETE']="Bạn muốn xóa Cơ sở dữ liệu `%s` với nội dung bên trong?";
-$lang['L_ASKDBEMPTY']="Bạn muốn Làm trống rỗng Cơ sở dữ liệu `%s` ?";
-$lang['L_ASKDBCOPY']="Bạn muốn sao chép cơ sở dữ liệu `%s` thành CSDL `%s`?";
-$lang['L_SQL_TABLENEW']="Sửa các bảng";
-$lang['L_SQL_OUTPUT']="xuất SQL";
-$lang['L_DO_NOW']="vận hành bây giờ";
-$lang['L_SQL_NAMEDEST_MISSING']="Tên chỗ ghi bị lỗi !";
-$lang['L_ASKDELETEFIELD']="Bạn có muốn xóa các Trường?";
-$lang['L_SQL_COMMANDS_IN']=" ở dòng ";
-$lang['L_SQL_COMMANDS_IN2']="  sec. parsed.";
-$lang['L_SQL_OUT1']="Được thực hiện ";
-$lang['L_SQL_OUT2']="Lệnh";
-$lang['L_SQL_OUT3']="Nó có ";
-$lang['L_SQL_OUT4']="Lệnh";
-$lang['L_SQL_OUT5']="Bởi vì nội dung xuất ra chứa hơn 5000 hàng nên nó không được trình bày hết.";
-$lang['L_SQL_SELECDB']="Lựa chọn Cơ sở dữ liệu";
-$lang['L_SQL_TABLESOFDB']="Những bảng của Cơ sở dữ liệu";
-$lang['L_SQL_EDIT']="sửa";
-$lang['L_SQL_NOFIELDDELETE']="Không thể xóa vì Bảng phải chứa ít nhất một Trường.";
-$lang['L_SQL_FIELDDELETE1']="Trường";
-$lang['L_SQL_DELETED']="đã bị xóa";
-$lang['L_SQL_CHANGED']="đã được thay đổi.";
-$lang['L_SQL_CREATED']="đã được tạo ra.";
-$lang['L_SQL_NODEST_COPY']="Không copi bỏ qua đích đến!";
-$lang['L_SQL_DESTTABLE_EXISTS']="Bảng (table) Đến bị trùng !";
-$lang['L_SQL_SCOPY']="Cấu trúc bảng dữ liệu của `%s` đã được copi từ bảng dữ liệu `%s`.";
-$lang['L_SQL_TCOPY']="Bảng dữ liệu `%s` vừa được copi với dữ liệu từ bảng `%s`.";
-$lang['L_SQL_TABLENONAME']="Đặt tên cho Bảng dữ liệu!";
-$lang['L_SQL_TBLNAMEEMPTY']="Tên Bảng không được để trống!";
-$lang['L_SQL_COLLATENOTMATCH']="Charset và Collation không phù hợp với nhau!";
-$lang['L_SQL_FIELDNAMENOTVALID']="Lỗi: Tên Trường không hợp lệ";
-$lang['L_SQL_CREATETABLE']="tạo bảng";
-$lang['L_SQL_COPYTABLE']="copy bảng";
-$lang['L_SQL_STRUCTUREONLY']="Chỉ cấu trúc";
-$lang['L_SQL_STRUCTUREDATA']="Cấu trúc và dữ liệu";
-$lang['L_SQL_NOTABLESINDB']="Không thấy bảng nào trong CSDL";
-$lang['L_SQL_SELECTTABLE']="Chọn bảng";
-$lang['L_SQL_SHOWDATATABLE']="Hiện dữ liệu của bảng";
-$lang['L_SQL_TBLPROPSOF']="Thuộc tính Bảng của";
-$lang['L_SQL_EDITFIELD']="Vùng sửa đổi";
-$lang['L_SQL_NEWFIELD']="Vùng mới";
-$lang['L_SQL_INDEXES']="Chỉ số";
-$lang['L_SQL_ATPOSITION']="chèn tại vị trí";
-$lang['L_SQL_FIRST']="đầu tiên";
-$lang['L_SQL_AFTER']="sau";
-$lang['L_SQL_CHANGEFIELD']="đổi vùng";
-$lang['L_SQL_INSERTFIELD']="chèn vào";
-$lang['L_SQL_INSERTNEWFIELD']="chèn vùng mới";
-$lang['L_SQL_TABLEINDEXES']="Những chỉ số của bảng";
-$lang['L_SQL_ALLOWDUPS']="Những bản sao được cho phép";
-$lang['L_SQL_CARDINALITY']="Lực lượng";
-$lang['L_SQL_TABLENOINDEXES']="Không có chỉ số nào trong Bảng";
-$lang['L_SQL_CREATEINDEX']="tạo ra chỉ số mới";
-$lang['L_SQL_WASEMPTIED']="đã được làm rỗng";
-$lang['L_SQL_RENAMEDTO']="được đổi tên thành";
-$lang['L_SQL_DBCOPY']="Nội dung của Cơ sở dữ liệu `%s` được sao chép trong Cơ sở dữ liệu `%s`.";
-$lang['L_SQL_DBSCOPY']="Cấu trúc của Cơ sở dữ liệu `%s` được sao chép trong Cơ sở dữ liệu `%s`.";
-$lang['L_SQL_WASCREATED']="được tạo ra";
-$lang['L_SQL_RENAMEDB']="Đổi tên Cơ sở dữ liệu";
-$lang['L_SQL_ACTIONS']="Những hành động";
-$lang['L_SQL_CHOOSEACTION']="Chọn hành động";
-$lang['L_SQL_DELETEDB']="Xóa Cơ sở dữ liệu";
-$lang['L_SQL_EMPTYDB']="Cơ sở dữ liệu Trống rỗng";
-$lang['L_SQL_COPYDATADB']="Sao chép Cơ sở dữ liệu đầy đủ tới";
-$lang['L_SQL_COPYSDB']="Sao chép cấu trúc của CSDL";
-$lang['L_SQL_IMEXPORT']="Nhập-Xuất";
-$lang['L_INFO_RECORDS']="bản ghi";
-$lang['L_NAME']="Tên";
-$lang['L_ASKTABLEEMPTYKEYS']="Làm rỗng bảng `%s` và lặp lại các chỉ số?";
-$lang['L_EDIT']="sửa";
-$lang['L_DELETE']="xóa";
-$lang['L_EMPTY']="rỗng";
-$lang['L_EMPTYKEYS']="làm rỗng và đặt lại các chỉ số";
-$lang['L_SQL_TABLEEMPTIED']="Table `%s` vừa bị xóa.";
-$lang['L_SQL_TABLEEMPTIEDKEYS']="Table `%s` vừa bị xóa và các chỉ số được đặt lại.";
-$lang['L_SQL_LIBRARY']="Thư viện SQL";
-$lang['L_SQL_ATTRIBUTES']="Những thuộc tính";
-$lang['L_SQL_UPLOADEDFILE']="Nạp file: ";
-$lang['L_SQL_IMPORT']="Nhập trong CSDL `%s`";
-$lang['L_EXPORT']="Xuất";
-$lang['L_IMPORT']="Nhập";
-$lang['L_IMPORTOPTIONS']="Tùy chọn nhập";
-$lang['L_CSVOPTIONS']="Tùy chọn CSV";
-$lang['L_IMPORTTABLE']="Nhập trong Bảng";
-$lang['L_NEWTABLE']="Bảng mới";
-$lang['L_IMPORTSOURCE']="Nguồn nhập";
-$lang['L_FROMTEXTBOX']="từ text box";
-$lang['L_FROMFILE']="từ file";
-$lang['L_EMPTYTABLEBEFORE']="Làm rỗng bảng trước khi";
-$lang['L_CREATEAUTOINDEX']="Tạo ra chỉ số tự động";
-$lang['L_CSV_NAMEFIRSTLINE']="Tên các Trường trong hàng đầu tiên";
-$lang['L_CSV_FIELDSEPERATE']="Các Trường được phân chia bởi";
-$lang['L_CSV_FIELDSENCLOSED']="Các Trường đi kèm với";
-$lang['L_CSV_FIELDSESCAPE']="Các Trường kết thúc bằng";
-$lang['L_CSV_EOL']="xuống dòng bằng";
-$lang['L_CSV_NULL']="Thay NULL bằng";
-$lang['L_CSV_FILEOPEN']="Mở file CSV";
-$lang['L_IMPORTIEREN']="Nhập";
-$lang['L_SQL_EXPORT']="Xuất từ CSDL `%s`";
-$lang['L_EXPORTOPTIONS']="Tùy chọn xuất";
-$lang['L_EXCEL2003']="Excel from 2003";
-$lang['L_SHOWRESULT']="hiện kết quả";
-$lang['L_SENDRESULTASFILE']="gửi kết quả dạng file";
-$lang['L_EXPORTLINES']="<strong>%s</strong> dòng được xuất";
-$lang['L_CSV_FIELDCOUNT_NOMATCH']="Việc đếm các Trường không đồng nghĩa rằng dữ liệu xuất ra (%d thay vì %d).";
-$lang['L_CSV_FIELDSLINES']="%d Trường được ghi nhận, tổng số %d dòng";
-$lang['L_CSV_ERRORCREATETABLE']="Lỗi trong khi tạo bảng `%s` !";
-$lang['L_FM_UPLOADFILEREQUEST']="chọn 1 file file.";
-$lang['L_CSV_NODATA']="Không tìm thấy dữ liệu nhập vào!";
-$lang['L_SQLLIB_GENERALFUNCTIONS']="những chức năng chung";
-$lang['L_SQLLIB_RESETAUTO']="chạy lại auto-increment (tự đánh số)";
-$lang['L_SQLLIB_BOARDS']="Boards";
-$lang['L_SQLLIB_DEACTIVATEBOARD']="ngưng kích hoạt Board";
-$lang['L_SQLLIB_ACTIVATEBOARD']="kích hoạt Board";
-$lang['L_SQL_NOTABLESSELECTED']="Chưa chọn bảng !";
-$lang['L_TOOLS']="Những công cụ";
-$lang['L_TOOLS_TOOLBOX']="Chọn CSDL / Tính năng của CSDL / Nhập - Xuất ";
-$lang['L_SQL_OPENFILE']="Mở SQL-File";
-$lang['L_SQL_OPENFILE_BUTTON']="Upload";
-$lang['L_MAX_UPLOAD_SIZE']="Cỡ file tối đa";
-$lang['L_SQL_SEARCH']="Tìm";
-$lang['L_SQL_SEARCHWORDS']="Từ khóa";
-$lang['L_START_SQL_SEARCH']="bắt đầu tìm";
-$lang['L_RESET_SEARCHWORDS']="xóa";
-$lang['L_SEARCH_OPTIONS']="Tùy chọn tìm kiếm";
-$lang['L_SEARCH_RESULTS']="Kết quả tìm kiếm \"<b>%s</b>\" trong bảng \"<b>%s</b>\" như sau";
-$lang['L_SEARCH_NO_RESULTS']="Tìm kiếm cho \"<b>%s</b>\" trong bảng \"<b>%s</b>\" không mang lại bất cứ kết quả nào!";
-$lang['L_NO_ENTRIES']="Bảng \"<b>%s</b>\" trống rỗng và không có bất kỳ mục vào nào.";
-$lang['L_SEARCH_ACCESS_KEYS']="Duyệt: trở đi=ALT+V, trở lại=ALT+C";
-$lang['L_SEARCH_OPTIONS_OR']="Mỗi cột phải có 1 từ khóa (OR-search)";
-$lang['L_SEARCH_OPTIONS_CONCAT']="một dòng phải chứa tất cả các từ khóa trừ phi họ có thể trong bất kỳ cột nào (thỉnh thoảng có thể ngoại lệ)";
-$lang['L_SEARCH_OPTIONS_AND']="cột phải chứa tất cả từ khóa (AND-search)";
-$lang['L_SEARCH_IN_TABLE']="Tìm trong Bảng";
-$lang['L_SQL_EDIT_TABLESTRUCTURE']="Sửa cấu trúc bảng";
-$lang['L_DEFAULT_CHARSET']="Đặt bảng làm mặc định
 
-
-";
-$lang['L_TITLE_KEY_PRIMARY']="Primary key";
-$lang['L_TITLE_KEY_UNIQUE']="Unique key";
-$lang['L_TITLE_INDEX']="Index";
-$lang['L_TITLE_KEY_FULLTEXT']="Fulltext key";
-$lang['L_TITLE_NOKEY']="No key";
-$lang['L_TITLE_SEARCH']="Search";
-$lang['L_TITLE_MYSQL_HELP']="MySQl Documentation";
-$lang['L_TITLE_UPLOAD']="Upload SQL file";
-$lang['L_PRIMARYKEY_DELETED']="Primary key deleted";
-$lang['L_PRIMARYKEY_NOTFOUND']="Primary key not found";
-$lang['L_PRIMARYKEYS_CHANGED']="Primary keys changed";
-$lang['L_PRIMARYKEYS_CHANGINGERROR']="Error changing primary keys";
-$lang['L_SQL_VIEW_COMPACT']="View: compact";
-$lang['L_SQL_VIEW_STANDARD']="View: standard";
-$lang['L_FIELDS_OF_TABLE']="Fields of table";
-$lang['L_ENGINE']="Engine";
-$lang['L_USERNAME']="Username";
-$lang['L_PASSWORD']="Password";
-$lang['L_PASSWORD_REPEAT']="Password (repeat)";
-$lang['L_INFO_SIZE']="kích thước";
-$lang['L_TABLE_TYPE']="Type";
-$lang['L_KEY_DELETED']="Index deleted";
-$lang['L_KEY_DELETEERROR']="Error deleting index";
-$lang['L_KEY_ADDED']="Index added";
-$lang['L_KEY_ADDERROR']="Error adding index";
-
-
-?>
\ No newline at end of file
+$lang['L_COMMAND'] = 'Lệnh';
+$lang['L_IMPORT_NOTABLE'] = 'Không có bảng được lựa chọn nhập vào (import)!';
+$lang['L_PASSWORD_STRENGTH'] = 'Password strength';
+$lang['L_SQL_WARNING'] = 'Sự thực hiện những câu lệnh SQL có thể thao tác vào dữ liệu. Cẩn thận! Tác giả không chấp nhận đền bù bất kỳ thiệt hại nào nếu dữ liệu bị hư hại hay bị mất.';
+$lang['L_SQL_EXEC'] = 'Thực hiện câu lệnh SQL';
+$lang['L_SQL_DATAVIEW'] = 'Xem dữ liệu';
+$lang['L_SQL_TABLEVIEW'] = 'Xem bảng';
+$lang['L_SQL_VONINS'] = 'từ tổng thể';
+$lang['L_SQL_NODATA'] = 'không có bản ghi nào';
+$lang['L_SQL_RECORDUPDATED'] = 'Bản ghi vừa được cập nhật';
+$lang['L_SQL_RECORDINSERTED'] = 'Bản ghi vừa được thêm';
+$lang['L_SQL_BACKDBOVERVIEW'] = 'Quay trở lại Tổng quan';
+$lang['L_SQL_RECORDDELETED'] = 'Bản ghi vừa được xóa';
+$lang['L_ASKTABLEEMPTY'] = 'Bảng `%s` bị rỗng?';
+$lang['L_SQL_RECORDEDIT'] = 'bản ghi soạn thảo';
+$lang['L_SQL_RECORDNEW'] = 'bản ghi mới';
+$lang['L_ASKDELETERECORD'] = 'Bạn chắc chắn xóa bản ghi này?';
+$lang['L_ASKDELETETABLE'] = 'Bảng `%s` sẽ bị xóa?';
+$lang['L_SQL_BEFEHLE'] = 'Lệnh SQL';
+$lang['L_SQL_BEFEHLNEU'] = 'Lệnh mới';
+$lang['L_SQL_BEFEHLSAVED1'] = 'Lệnh SQL';
+$lang['L_SQL_BEFEHLSAVED2'] = 'vừa thêm';
+$lang['L_SQL_BEFEHLSAVED3'] = 'vừa lưu';
+$lang['L_SQL_BEFEHLSAVED4'] = 'vừa chuyển lên';
+$lang['L_SQL_BEFEHLSAVED5'] = 'vừa xóa';
+$lang['L_SQL_QUERYENTRY'] = 'Nội dung Yêu cầu';
+$lang['L_SQL_COLUMNS'] = 'Các cột';
+$lang['L_ASKDBDELETE'] = 'Bạn muốn xóa Cơ sở dữ liệu `%s` với nội dung bên trong?';
+$lang['L_ASKDBEMPTY'] = 'Bạn muốn Làm trống rỗng Cơ sở dữ liệu `%s` ?';
+$lang['L_ASKDBCOPY'] = 'Bạn muốn sao chép cơ sở dữ liệu `%s` thành CSDL `%s`?';
+$lang['L_SQL_TABLENEW'] = 'Sửa các bảng';
+$lang['L_SQL_OUTPUT'] = 'xuất SQL';
+$lang['L_DO_NOW'] = 'vận hành bây giờ';
+$lang['L_SQL_NAMEDEST_MISSING'] = 'Tên chỗ ghi bị lỗi !';
+$lang['L_ASKDELETEFIELD'] = 'Bạn có muốn xóa các Trường?';
+$lang['L_SQL_COMMANDS_IN'] = ' ở dòng ';
+$lang['L_SQL_COMMANDS_IN2'] = '  sec. parsed.';
+$lang['L_SQL_OUT1'] = 'Được thực hiện ';
+$lang['L_SQL_OUT2'] = 'Lệnh';
+$lang['L_SQL_OUT3'] = 'Nó có ';
+$lang['L_SQL_OUT4'] = 'Lệnh';
+$lang['L_SQL_OUT5'] = 'Bởi vì nội dung xuất ra chứa hơn 5000 hàng nên nó không được trình bày hết.';
+$lang['L_SQL_SELECDB'] = 'Lựa chọn Cơ sở dữ liệu';
+$lang['L_SQL_TABLESOFDB'] = 'Những bảng của Cơ sở dữ liệu';
+$lang['L_SQL_EDIT'] = 'sửa';
+$lang['L_SQL_NOFIELDDELETE'] = 'Không thể xóa vì Bảng phải chứa ít nhất một Trường.';
+$lang['L_SQL_FIELDDELETE1'] = 'Trường';
+$lang['L_SQL_DELETED'] = 'đã bị xóa';
+$lang['L_SQL_CHANGED'] = 'đã được thay đổi.';
+$lang['L_SQL_CREATED'] = 'đã được tạo ra.';
+$lang['L_SQL_NODEST_COPY'] = 'Không copi bỏ qua đích đến!';
+$lang['L_SQL_DESTTABLE_EXISTS'] = 'Bảng (table) Đến bị trùng !';
+$lang['L_SQL_SCOPY'] = 'Cấu trúc bảng dữ liệu của `%s` đã được copi từ bảng dữ liệu `%s`.';
+$lang['L_SQL_TCOPY'] = 'Bảng dữ liệu `%s` vừa được copi với dữ liệu từ bảng `%s`.';
+$lang['L_SQL_TABLENONAME'] = 'Đặt tên cho Bảng dữ liệu!';
+$lang['L_SQL_TBLNAMEEMPTY'] = 'Tên Bảng không được để trống!';
+$lang['L_SQL_COLLATENOTMATCH'] = 'Charset và Collation không phù hợp với nhau!';
+$lang['L_SQL_FIELDNAMENOTVALID'] = 'Lỗi: Tên Trường không hợp lệ';
+$lang['L_SQL_CREATETABLE'] = 'tạo bảng';
+$lang['L_SQL_COPYTABLE'] = 'copy bảng';
+$lang['L_SQL_STRUCTUREONLY'] = 'Chỉ cấu trúc';
+$lang['L_SQL_STRUCTUREDATA'] = 'Cấu trúc và dữ liệu';
+$lang['L_SQL_NOTABLESINDB'] = 'Không thấy bảng nào trong CSDL';
+$lang['L_SQL_SELECTTABLE'] = 'Chọn bảng';
+$lang['L_SQL_SHOWDATATABLE'] = 'Hiện dữ liệu của bảng';
+$lang['L_SQL_TBLPROPSOF'] = 'Thuộc tính Bảng của';
+$lang['L_SQL_EDITFIELD'] = 'Vùng sửa đổi';
+$lang['L_SQL_NEWFIELD'] = 'Vùng mới';
+$lang['L_SQL_INDEXES'] = 'Chỉ số';
+$lang['L_SQL_ATPOSITION'] = 'chèn tại vị trí';
+$lang['L_SQL_FIRST'] = 'đầu tiên';
+$lang['L_SQL_AFTER'] = 'sau';
+$lang['L_SQL_CHANGEFIELD'] = 'đổi vùng';
+$lang['L_SQL_INSERTFIELD'] = 'chèn vào';
+$lang['L_SQL_INSERTNEWFIELD'] = 'chèn vùng mới';
+$lang['L_SQL_TABLEINDEXES'] = 'Những chỉ số của bảng';
+$lang['L_SQL_ALLOWDUPS'] = 'Những bản sao được cho phép';
+$lang['L_SQL_CARDINALITY'] = 'Lực lượng';
+$lang['L_SQL_TABLENOINDEXES'] = 'Không có chỉ số nào trong Bảng';
+$lang['L_SQL_CREATEINDEX'] = 'tạo ra chỉ số mới';
+$lang['L_SQL_WASEMPTIED'] = 'đã được làm rỗng';
+$lang['L_SQL_RENAMEDTO'] = 'được đổi tên thành';
+$lang['L_SQL_DBCOPY'] = 'Nội dung của Cơ sở dữ liệu `%s` được sao chép trong Cơ sở dữ liệu `%s`.';
+$lang['L_SQL_DBSCOPY'] = 'Cấu trúc của Cơ sở dữ liệu `%s` được sao chép trong Cơ sở dữ liệu `%s`.';
+$lang['L_SQL_WASCREATED'] = 'được tạo ra';
+$lang['L_SQL_RENAMEDB'] = 'Đổi tên Cơ sở dữ liệu';
+$lang['L_SQL_ACTIONS'] = 'Những hành động';
+$lang['L_SQL_CHOOSEACTION'] = 'Chọn hành động';
+$lang['L_SQL_DELETEDB'] = 'Xóa Cơ sở dữ liệu';
+$lang['L_SQL_EMPTYDB'] = 'Cơ sở dữ liệu Trống rỗng';
+$lang['L_SQL_COPYDATADB'] = 'Sao chép Cơ sở dữ liệu đầy đủ tới';
+$lang['L_SQL_COPYSDB'] = 'Sao chép cấu trúc của CSDL';
+$lang['L_SQL_IMEXPORT'] = 'Nhập-Xuất';
+$lang['L_INFO_RECORDS'] = 'bản ghi';
+$lang['L_NAME'] = 'Tên';
+$lang['L_ASKTABLEEMPTYKEYS'] = 'Làm rỗng bảng `%s` và lặp lại các chỉ số?';
+$lang['L_EDIT'] = 'sửa';
+$lang['L_DELETE'] = 'xóa';
+$lang['L_EMPTY'] = 'rỗng';
+$lang['L_EMPTYKEYS'] = 'làm rỗng và đặt lại các chỉ số';
+$lang['L_SQL_TABLEEMPTIED'] = 'Table `%s` vừa bị xóa.';
+$lang['L_SQL_TABLEEMPTIEDKEYS'] = 'Table `%s` vừa bị xóa và các chỉ số được đặt lại.';
+$lang['L_SQL_LIBRARY'] = 'Thư viện SQL';
+$lang['L_SQL_ATTRIBUTES'] = 'Những thuộc tính';
+$lang['L_SQL_UPLOADEDFILE'] = 'Nạp file: ';
+$lang['L_SQL_IMPORT'] = 'Nhập trong CSDL `%s`';
+$lang['L_EXPORT'] = 'Xuất';
+$lang['L_IMPORT'] = 'Nhập';
+$lang['L_IMPORTOPTIONS'] = 'Tùy chọn nhập';
+$lang['L_CSVOPTIONS'] = 'Tùy chọn CSV';
+$lang['L_IMPORTTABLE'] = 'Nhập trong Bảng';
+$lang['L_NEWTABLE'] = 'Bảng mới';
+$lang['L_IMPORTSOURCE'] = 'Nguồn nhập';
+$lang['L_FROMTEXTBOX'] = 'từ text box';
+$lang['L_FROMFILE'] = 'từ file';
+$lang['L_EMPTYTABLEBEFORE'] = 'Làm rỗng bảng trước khi';
+$lang['L_CREATEAUTOINDEX'] = 'Tạo ra chỉ số tự động';
+$lang['L_CSV_NAMEFIRSTLINE'] = 'Tên các Trường trong hàng đầu tiên';
+$lang['L_CSV_FIELDSEPERATE'] = 'Các Trường được phân chia bởi';
+$lang['L_CSV_FIELDSENCLOSED'] = 'Các Trường đi kèm với';
+$lang['L_CSV_FIELDSESCAPE'] = 'Các Trường kết thúc bằng';
+$lang['L_CSV_EOL'] = 'xuống dòng bằng';
+$lang['L_CSV_NULL'] = 'Thay NULL bằng';
+$lang['L_CSV_FILEOPEN'] = 'Mở file CSV';
+$lang['L_IMPORTIEREN'] = 'Nhập';
+$lang['L_SQL_EXPORT'] = 'Xuất từ CSDL `%s`';
+$lang['L_EXPORTOPTIONS'] = 'Tùy chọn xuất';
+$lang['L_EXCEL2003'] = 'Excel from 2003';
+$lang['L_SHOWRESULT'] = 'hiện kết quả';
+$lang['L_SENDRESULTASFILE'] = 'gửi kết quả dạng file';
+$lang['L_EXPORTLINES'] = '<strong>%s</strong> dòng được xuất';
+$lang['L_CSV_FIELDCOUNT_NOMATCH'] = 'Việc đếm các Trường không đồng nghĩa rằng dữ liệu xuất ra (%d thay vì %d).';
+$lang['L_CSV_FIELDSLINES'] = '%d Trường được ghi nhận, tổng số %d dòng';
+$lang['L_CSV_ERRORCREATETABLE'] = 'Lỗi trong khi tạo bảng `%s` !';
+$lang['L_FM_UPLOADFILEREQUEST'] = 'chọn 1 file file.';
+$lang['L_CSV_NODATA'] = 'Không tìm thấy dữ liệu nhập vào!';
+$lang['L_SQLLIB_GENERALFUNCTIONS'] = 'những chức năng chung';
+$lang['L_SQLLIB_RESETAUTO'] = 'chạy lại auto-increment (tự đánh số)';
+$lang['L_SQLLIB_BOARDS'] = 'Boards';
+$lang['L_SQLLIB_DEACTIVATEBOARD'] = 'ngưng kích hoạt Board';
+$lang['L_SQLLIB_ACTIVATEBOARD'] = 'kích hoạt Board';
+$lang['L_SQL_NOTABLESSELECTED'] = 'Chưa chọn bảng !';
+$lang['L_TOOLS'] = 'Những công cụ';
+$lang['L_TOOLS_TOOLBOX'] = 'Chọn CSDL / Tính năng của CSDL / Nhập - Xuất ';
+$lang['L_SQL_OPENFILE'] = 'Mở SQL-File';
+$lang['L_SQL_OPENFILE_BUTTON'] = 'Upload';
+$lang['L_MAX_UPLOAD_SIZE'] = 'Cỡ file tối đa';
+$lang['L_SQL_SEARCH'] = 'Tìm';
+$lang['L_SQL_SEARCHWORDS'] = 'Từ khóa';
+$lang['L_START_SQL_SEARCH'] = 'bắt đầu tìm';
+$lang['L_RESET_SEARCHWORDS'] = 'xóa';
+$lang['L_SEARCH_OPTIONS'] = 'Tùy chọn tìm kiếm';
+$lang['L_SEARCH_RESULTS'] = 'Kết quả tìm kiếm "<b>%s</b>" trong bảng "<b>%s</b>" như sau';
+$lang['L_SEARCH_NO_RESULTS'] = 'Tìm kiếm cho "<b>%s</b>" trong bảng "<b>%s</b>" không mang lại bất cứ kết quả nào!';
+$lang['L_NO_ENTRIES'] = 'Bảng "<b>%s</b>" trống rỗng và không có bất kỳ mục vào nào.';
+$lang['L_SEARCH_ACCESS_KEYS'] = 'Duyệt: trở đi=ALT+V, trở lại=ALT+C';
+$lang['L_SEARCH_OPTIONS_OR'] = 'Mỗi cột phải có 1 từ khóa (OR-search)';
+$lang['L_SEARCH_OPTIONS_CONCAT'] = 'một dòng phải chứa tất cả các từ khóa trừ phi họ có thể trong bất kỳ cột nào (thỉnh thoảng có thể ngoại lệ)';
+$lang['L_SEARCH_OPTIONS_AND'] = 'cột phải chứa tất cả từ khóa (AND-search)';
+$lang['L_SEARCH_IN_TABLE'] = 'Tìm trong Bảng';
+$lang['L_ERROR_NO_FIELDS'] = 'Search error: it could not be determined which fields the table "%s" has!';
+$lang['L_SQL_EDIT_TABLESTRUCTURE'] = 'Sửa cấu trúc bảng';
+$lang['L_DEFAULT_CHARSET'] = 'Đặt bảng làm mặc định';
+$lang['L_TITLE_KEY_PRIMARY'] = 'Primary key';
+$lang['L_TITLE_KEY_UNIQUE'] = 'Unique key';
+$lang['L_TITLE_INDEX'] = 'Index';
+$lang['L_TITLE_KEY_FULLTEXT'] = 'Fulltext key';
+$lang['L_TITLE_NOKEY'] = 'No key';
+$lang['L_TITLE_SEARCH'] = 'Search';
+$lang['L_TITLE_MYSQL_HELP'] = 'MySQl Documentation';
+$lang['L_TITLE_UPLOAD'] = 'Upload SQL file';
+$lang['L_PRIMARYKEY_DELETED'] = 'Primary key deleted';
+$lang['L_PRIMARYKEY_NOTFOUND'] = 'Primary key not found';
+$lang['L_PRIMARYKEYS_CHANGED'] = 'Primary keys changed';
+$lang['L_PRIMARYKEYS_CHANGINGERROR'] = 'Error changing primary keys';
+$lang['L_SQL_VIEW_COMPACT'] = 'View: compact';
+$lang['L_SQL_VIEW_STANDARD'] = 'View: standard';
+$lang['L_FIELDS_OF_TABLE'] = 'Fields of table';
+$lang['L_ENGINE'] = 'Engine';
+$lang['L_USERNAME'] = 'Username';
+$lang['L_PASSWORD'] = 'Password';
+$lang['L_PASSWORD_REPEAT'] = 'Password (repeat)';
+$lang['L_INFO_SIZE'] = 'kích thước';
+$lang['L_TABLE_TYPE'] = 'Type';
+$lang['L_KEY_DELETED'] = 'Index deleted';
+$lang['L_KEY_DELETEERROR'] = 'Error deleting index';
+$lang['L_KEY_ADDED'] = 'Index added';
+$lang['L_KEY_ADDERROR'] = 'Error adding index';
diff --git a/msd/license.txt b/msd/license.txt
new file mode 100644
index 00000000..207a79cb
--- /dev/null
+++ b/msd/license.txt
@@ -0,0 +1,278 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
diff --git a/msd/log.php b/msd/log.php
index 0c72d35d..6c7042d5 100644
--- a/msd/log.php
+++ b/msd/log.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,148 +18,148 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-include ( './inc/header.php' );
-include_once ( './language/' . $config['language'] . '/lang_log.php' );
-echo MSDHeader();
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
 
-if (isset($_POST['r'])) $r=$_POST['r'];
-else $r=( isset($_GET['r']) ) ? $_GET['r'] : 0;
+include './inc/header.php';
+include_once './language/'.$config['language'].'/lang_log.php';
+echo MODHeader();
 
-$revers=( isset($_GET['revers']) ) ? $_GET['revers'] : 0;
+if (isset($_POST['r'])) {
+    $r = $_POST['r'];
+} else {
+    $r = (isset($_GET['r'])) ? $_GET['r'] : 0;
+}
+
+$revers = (isset($_GET['revers'])) ? $_GET['revers'] : 0;
 
 //loeschen
-if (isset($_POST['kill']))
-{
-	if ($_POST['r'] == 0)
-	{
-		DeleteLog();
-	}
-	elseif ($_POST['r'] == 1)
-	{
-		@unlink($config['files']['perllog']);
-		@unlink($config['files']['perllog'] . '.gz');
-	}
-	elseif ($_POST['r'] == 2)
-	{
-		@unlink($config['files']['perllogcomplete']);
-		@unlink($config['files']['perllogcomplete'] . '.gz');
-	}
-	elseif ($_POST['r'] == 3)
-	{
-		@unlink($config['paths']['log'] . "error.log");
-		@unlink($config['paths']['log'] . "error.log.gz");
-	}
-	$r=0;
+if (isset($_POST['kill'])) {
+    if (0 == $_POST['r']) {
+        DeleteLog();
+    } elseif (1 == $_POST['r']) {
+        @unlink($config['files']['perllog']);
+        @unlink($config['files']['perllog'].'.gz');
+    } elseif (2 == $_POST['r']) {
+        @unlink($config['files']['perllogcomplete']);
+        @unlink($config['files']['perllogcomplete'].'.gz');
+    } elseif (3 == $_POST['r']) {
+        @unlink($config['paths']['log'].'error.log');
+        @unlink($config['paths']['log'].'error.log.gz');
+    }
+    $r = 0;
 }
 
-if ($r == 0)
-{
-	$lfile=$config['files']['log'];
-	$lcap="PHP-Log";
+if (0 == $r) {
+    $lfile = $config['files']['log'];
+    $lcap = 'PHP-Log';
+} elseif (1 == $r) {
+    $lfile = $config['files']['perllog'];
+    $lcap = 'Perl-Log';
+} elseif (2 == $r) {
+    $lfile = $config['files']['perllogcomplete'];
+    $lcap = 'Perl-Complete Log';
+} elseif (3 == $r) {
+    $lfile = $config['paths']['log'].'error.log';
+    $lcap = 'PHP Error-Log';
 }
-elseif ($r == 1)
-{
-	$lfile=$config['files']['perllog'];
-	$lcap="Perl-Log";
+
+if (isset($config['logcompression']) && 1 == $config['logcompression']) {
+    $lfile .= '.gz';
 }
-elseif ($r == 2)
-{
-	$lfile=$config['files']['perllogcomplete'];
-	$lcap="Perl-Complete Log";
+if (!file_exists($lfile) && 0 == $r) {
+    DeleteLog();
 }
-elseif ($r == 3)
-{
-	$lfile=$config['paths']['log'] . "error.log";
-	$lcap="PHP Error-Log";
-}
-if ($config['logcompression'] == 1) $lfile.=".gz";
-if (!file_exists($lfile) && $r == 0)
-{
-	DeleteLog();
-}
-$loginfo=LogFileInfo($config['logcompression']);
+$nLogcompression = isset($config['logcompression']) ? $config['logcompression'] : 0;
+$loginfo = LogFileInfo($nLogcompression);
 
 echo headline($lcap);
-if (!is_writable($config['paths']['log'])) die('<p class="error">ERROR !<br>Logdir is not writable</p>');
+if (!is_writable($config['paths']['log'])) {
+    exit('<p class="error">ERROR !<br>Logdir is not writable</p>');
+}
 
 //lesen
-$errorbutton='';
-$perlbutton='';
-$perlbutton2='';
+$errorbutton = '';
+$perlbutton = '';
+$perlbutton2 = '';
 
-if (file_exists($loginfo['errorlog'])) $errorbutton='<td><input class="Formbutton" type="button" onclick="location.href=\'log.php?r=3\'" value="Error-Log"></td>';
-if (file_exists($loginfo['perllog'])) $perlbutton='<td><input type="button" onclick="location.href=\'log.php?r=1\'" class="Formbutton" value="Perl-Log"></td>';
-if (file_exists($loginfo['perllogcomplete'])) $perlbutton2='<td><input class="Formbutton" type="button" onclick="location.href=\'log.php?r=2\'" value="Perl-Complete Log"></td>';
+if (file_exists($loginfo['errorlog'])) {
+    $errorbutton = '<td><input class="Formbutton" type="button" onclick="location.href=\'log.php?r=3\'" value="Error-Log"></td>';
+}
+if (file_exists($loginfo['perllog'])) {
+    $perlbutton = '<td><input type="button" onclick="location.href=\'log.php?r=1\'" class="Formbutton" value="Perl-Log"></td>';
+}
+if (file_exists($loginfo['perllogcomplete'])) {
+    $perlbutton2 = '<td><input class="Formbutton" type="button" onclick="location.href=\'log.php?r=2\'" value="Perl-Complete Log"></td>';
+}
 
 //anzeigen
 echo '<form action="log.php" method="post"><table><tr>';
 echo '<td><input class="Formbutton" type="button" onclick="location.href=\'log.php?r=0\'" value="PHP-Log"></td>';
-echo "\n" . $errorbutton . "\n" . $perlbutton . "\n" . $perlbutton2 . "\n";
+echo "\n".$errorbutton."\n".$perlbutton."\n".$perlbutton2."\n";
 echo '</tr></table><br>';
 
 //Status Logfiles
-echo '<div align="left"><table class="bdr"><tr><td><table><tr><td valign="top"><strong>' . $lang['L_LOGFILEFORMAT'] . '</strong><br><br>' . ( ( $config['logcompression'] == 1 ) ? '<img src="' . $config['files']['iconpath'] . 'gz.gif" width="32" height="32" alt="compressed" align="left">' : '<img src="' . $icon['blank'].'" width="32" height="32" alt="" align="left">' );
-echo '' . ( ( $config['logcompression'] == 1 ) ? $lang['L_COMPRESSED'] : $lang['L_NOTCOMPRESSED'] ) . '</td>';
+$icon['blank'] = isset($icon['blank']) ? $icon['blank'] : $config['files']['iconpath'].'blank.gif';
+echo '<div align="left"><table class="bdr"><tr><td><table><tr><td valign="top"><strong>'.$lang['L_LOGFILEFORMAT'].'</strong><br><br>'.((isset($config['logcompression']) && (1 == $config['logcompression'])) ? '<img src="'.$config['files']['iconpath'].'gz.gif" width="32" height="32" alt="compressed" align="left">' : '<img src="'.$icon['blank'].'" width="32" height="32" alt="" align="left">');
+echo ''.(((isset($config['logcompression']) && 1 == $config['logcompression'])) ? $lang['L_COMPRESSED'] : $lang['L_NOTCOMPRESSED']).'</td>';
 echo '<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td valign="top" align="right">';
-echo '<a href="' . $loginfo['log'] . '">' . substr($loginfo['log'],strrpos($loginfo['log'],"/") + 1) . '</a><br>';
-echo ( $loginfo['errorlog_size'] > 0 ) ? '<a href="' . $loginfo['errorlog'] . '">' . substr($loginfo['errorlog'],strrpos($loginfo['errorlog'],"/") + 1) . '</a><br>' : substr($loginfo['errorlog'],strrpos($loginfo['errorlog'],"/") + 1) . '<br>';
-echo ( $loginfo['perllog_size'] > 0 ) ? '<a href="' . $loginfo['perllog'] . '">' . substr($loginfo['perllog'],strrpos($loginfo['perllog'],"/") + 1) . '</a><br>' : substr($loginfo['perllog'],strrpos($loginfo['perllog'],"/") + 1) . '<br>';
-echo ( $loginfo['perllogcomplete_size'] > 0 ) ? '<a href="' . $loginfo['perllogcomplete'] . '">' . substr($loginfo['perllogcomplete'],strrpos($loginfo['perllogcomplete'],"/") + 1) . '</a><br>' : substr($loginfo['perllogcomplete'],strrpos($loginfo['perllogcomplete'],"/") + 1) . '<br>';
-echo '<strong>total</strong></td><td valign="top" align="right">' . byte_output($loginfo['log_size']) . '<br>' . byte_output($loginfo['errorlog_size']) . '<br>' . byte_output($loginfo['perllog_size']) . '<br>' . byte_output($loginfo['perllogcomplete_size']) . '<br><strong>' . byte_output($loginfo['log_totalsize']) . '</strong></td>';
-echo '</tr><tr><td colspan="3" align="center"><a class="small" href="log.php?r=' . $r . '&amp;revers=0">' . $lang['L_NOREVERSE'] . '</a>&nbsp;&nbsp;&nbsp;<a class="small" href="log.php?r=' . $r . '&amp;revers=1">' . $lang['L_REVERSE'] . '</a></td></tr></table></td></tr></table></div>';
+echo '<a href="'.$loginfo['log'].'">'.substr($loginfo['log'], strrpos($loginfo['log'], '/') + 1).'</a><br>';
+echo ($loginfo['errorlog_size'] > 0) ? '<a href="'.$loginfo['errorlog'].'">'.substr($loginfo['errorlog'], strrpos($loginfo['errorlog'], '/') + 1).'</a><br>' : substr($loginfo['errorlog'], strrpos($loginfo['errorlog'], '/') + 1).'<br>';
+echo ($loginfo['perllog_size'] > 0) ? '<a href="'.$loginfo['perllog'].'">'.substr($loginfo['perllog'], strrpos($loginfo['perllog'], '/') + 1).'</a><br>' : substr($loginfo['perllog'], strrpos($loginfo['perllog'], '/') + 1).'<br>';
+echo ($loginfo['perllogcomplete_size'] > 0) ? '<a href="'.$loginfo['perllogcomplete'].'">'.substr($loginfo['perllogcomplete'], strrpos($loginfo['perllogcomplete'], '/') + 1).'</a><br>' : substr($loginfo['perllogcomplete'], strrpos($loginfo['perllogcomplete'], '/') + 1).'<br>';
+echo '<strong>total</strong></td><td valign="top" align="right">'.byte_output($loginfo['log_size']).'<br>'.byte_output($loginfo['errorlog_size']).'<br>'.byte_output($loginfo['perllog_size']).'<br>'.byte_output($loginfo['perllogcomplete_size']).'<br><strong>'.byte_output($loginfo['log_totalsize']).'</strong></td>';
+echo '</tr><tr><td colspan="3" align="center"><a class="small" href="log.php?r='.$r.'&amp;revers=0">'.$lang['L_NOREVERSE'].'</a>&nbsp;&nbsp;&nbsp;<a class="small" href="log.php?r='.$r.'&amp;revers=1">'.$lang['L_REVERSE'].'</a></td></tr></table></td></tr></table></div>';
 
-$out='';
-if ($r != 2) $out.='<pre>';
-
-if (file_exists($lfile))
-{
-	$zeilen=( $config['logcompression'] == 1 ) ? gzfile($lfile) : file($lfile);
-	if ($r == 30)
-	{
-		echo '<pre>' . print_r($zeilen,true) . '</pre>';
-		exit();
-	}
-	if ($revers == 1) $zeilen=array_reverse($zeilen);
-	foreach ($zeilen as $zeile)
-	{
-		if ($r == 2)
-		{
-			$out.=$zeile . '<br>';
-		}
-		elseif ($r == 3)
-		{
-			$z=explode("|:|",$zeile);
-			for ($i=0; $i < count($z); $i++)
-			{
-				$out.='<span>' . substr($z[$i],0,strpos($z[$i],": ")) . '</span> ' . substr($z[$i],strpos($z[$i],": ")) . "<br>";
-			}
-		}
-		else
-			$out.=$zeile;
-	}
+$out = '';
+if (2 != $r) {
+    $out .= '<pre>';
 }
-if ($r != 2) $out.='</pre>';
 
-$suchen=array(
+if (file_exists($lfile)) {
+    $zeilen = ((isset($config['logcompression']) && 1 == $config['logcompression'])) ? gzfile($lfile) : file($lfile);
+    if (30 == $r) {
+        echo '<pre>'.print_r($zeilen, true).'</pre>';
+        exit();
+    }
+    if (1 == $revers) {
+        $zeilen = array_reverse($zeilen);
+    }
+    foreach ($zeilen as $zeile) {
+        if (2 == $r) {
+            $out .= $zeile.'<br>';
+        } elseif (3 == $r) {
+            $z = explode('|:|', $zeile);
+            for ($i = 0; $i < count($z); ++$i) {
+                $out .= '<span>'.substr($z[$i], 0, strpos($z[$i], ': ')).'</span> '.substr($z[$i], strpos($z[$i], ': ')).'<br>';
+            }
+        } else {
+            $out .= $zeile;
+        }
+    }
+}
+if (2 != $r) {
+    $out .= '</pre>';
+}
 
-			'</html>',
-			'</body>'
-);
-$ersetzen=array(
+$suchen = [
+            '</html>',
+            '</body>',
+];
+$ersetzen = [
+                '',
+                '',
+];
+$out = str_replace($suchen, $ersetzen, $out);
 
-				'',
-				''
-);
-$out=str_replace($suchen,$ersetzen,$out);
-
-if ($out != "")
-{
-	echo '<div align="left" style="width:100%"><br>';
-	echo '<input type="hidden" name="r" value="' . $r . '"><input class="Formbutton" type="submit" name="kill" value="' . $lang['L_LOG_DELETE'] . '">';
-	echo '<br><br><div id="ilog">' . $out . '</div></div>';
+if ('' != $out) {
+    echo '<div align="left" style="width:100%"><br>';
+    echo '<input type="hidden" name="r" value="'.$r.'"><input class="Formbutton" type="submit" name="kill" value="'.$lang['L_LOG_DELETE'].'">';
+    echo '<br><br><div id="ilog">'.$out.'</div></div>';
 }
 
 echo '</form>';
-echo MSDFooter();
+echo MODFooter();
 ob_end_flush();
+exit();
diff --git a/msd/main.php b/msd/main.php
index 36e0da24..146bd43a 100644
--- a/msd/main.php
+++ b/msd/main.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,41 +18,101 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-include_once ('./inc/header.php');
-include_once ('./inc/runtime.php');
-include_once ('./language/'.$config['language'].'/lang_main.php');
-include ('./inc/template.php');
+error_reporting(E_ALL & ~E_STRICT);
 
-$action=(isset($_GET['action'])) ? $_GET['action'] : 'status';
-
-if ($action=='phpinfo')
-{
-	// output phpinfo
-	echo '<p align="center"><a href="main.php">&lt;&lt; Home</a></p>';
-	phpinfo();
-	echo '<p align="center"><a href="main.php">&lt;&lt; Home</a></p>';
-	exit();
+if (function_exists('ini_set')) {
+    ini_set('display_errors', true);
+}
+
+
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
+use VisualAppeal\AutoUpdate;
+
+$autoloader = require_once './vendor/autoload.php';
+
+include_once './inc/header.php';
+include_once './inc/runtime.php';
+include_once './language/'.$config['language'].'/lang_main.php';
+include './inc/template.php';
+
+$action = (isset($_GET['action'])) ? $_GET['action'] : 'status';
+
+if ('phpinfo' == $action) {
+    // output phpinfo
+    echo '<p align="center"><a href="main.php">&lt;&lt; Home</a></p>';
+    phpinfo();
+    echo '<p align="center"><a href="main.php">&lt;&lt; Home</a></p>';
+    exit();
+}
+
+if (isset($_POST['htaccess']) || 'schutz' == $action) {
+    include './inc/home/protection_create.php';
+}
+if ('edithtaccess' == $action) {
+    include './inc/home/protection_edit.php';
+}
+if ('deletehtaccess' == $action) {
+    include './inc/home/protection_delete.php';
+}
+
+$check_update = false;
+if (extension_loaded('zlib')) {
+    $update = new AutoUpdate($config['paths']['temp'], $config['paths']['root'], 60);
+    $update->setCurrentVersion(MOD_VERSION);
+
+    // Replace with your server update directory
+    $update->setUpdateUrl('https://oos-shop.de/modserver');
+
+    // Custom logger (optional)
+    $logger = new \Monolog\Logger("default");
+    $logger->pushHandler(new Monolog\Handler\StreamHandler($config['paths']['log'] . 'update.log'));
+    $update->setLogger($logger);
+
+
+    // Cache (optional but recommended)
+    $cache = new Desarrolla2\Cache\File($config['paths']['cache']);
+    $update->setCache($cache, 3600);
+
+    // Check for a new update
+    if ($update->checkUpdate() === false) {
+        // die('Could not check for updates! See log file for details.');
+        $check_update = false;
+    } else {
+        $check_update = true;
+    }
+
+    if ('update' == $action) {
+        echo MODHeader();
+        require_once './inc/home/update.php';
+        echo MODFooter();
+        exit;
+    }
 }
 
-if (isset($_POST['htaccess'])||$action=='schutz') include ('./inc/home/protection_create.php');
-if ($action=='edithtaccess') include ('./inc/home/protection_edit.php');
-if ($action=='deletehtaccess') include ('./inc/home/protection_delete.php');
 
 // Output headnavi
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'show' => 'tpl/home/headnavi.tpl'));
-$tpl->assign_vars(array(
-	'HEADER' => MSDHeader(),
-	'HEADLINE' => headline('Home')));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'show' => 'tpl/home/headnavi.tpl', ]);
+$tpl->assign_vars([
+    'HEADER' => MODHeader(),
+    'HEADLINE' => headline($lang['L_HOME']), ]);
 $tpl->pparse('show');
 
-MSD_mysql_connect();
-if ($action=='status') include ('./inc/home/home.php');
-elseif ($action=='db') include ('./inc/home/databases.php');
-elseif ($action=='sys') include ('./inc/home/system.php');
-elseif ($action=='vars') include ('./inc/home/mysql_variables.php');
+mod_mysqli_connect();
+if ('status' == $action) {
+    include './inc/home/home.php';
+} elseif ('db' == $action) {
+    include './inc/home/databases.php';
+} elseif ('sys' == $action) {
+    include './inc/home/system.php';
+} elseif ('vars' == $action) {
+    include './inc/home/mysql_variables.php';
+}
 
-echo MSDFooter();
+echo MODFooter();
 ob_end_flush();
+exit();
diff --git a/msd/menu.php b/msd/menu.php
index d55ab2db..7bd6a4ce 100644
--- a/msd/menu.php
+++ b/msd/menu.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,135 +18,131 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-include_once ('./inc/header.php');
-include ('./inc/template.php');
-$lang_old=$config['language'];
-$config_refresh='';
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
+include_once './inc/header.php';
+include './inc/template.php';
+$lang_old = $config['language'];
+$config_refresh = '';
 
 // define template
-$tpl=new MSDTemplate();
-$tpl->set_filenames(array(
-	'header' => 'tpl/menu/header.tpl',
-	'footer' => 'tpl/menu/footer.tpl',
-	'content' => 'tpl/menu/content.tpl'));
+$tpl = new MODTemplate();
+$tpl->set_filenames([
+    'header' => 'tpl/menu/header.tpl',
+    'footer' => 'tpl/menu/footer.tpl',
+    'content' => 'tpl/menu/content.tpl', ]);
 
-$tpl->assign_vars(array(
-	'MSD_VERSION' => MSD_VERSION,
-	'CONFIG_HOMEPAGE' => $config['homepage'],
-	'CONFIG_THEME' => $config['theme']));
+$tpl->assign_vars([
+    'MOD_VERSION' => MOD_VERSION,
+    'CONFIG_HOMEPAGE' => $config['homepage'],
+    'CONFIG_THEME' => $config['theme'], ]);
 
-if (isset($_POST['selected_config'])||isset($_GET['config']))
-{
-	if (isset($_POST['selected_config'])) $new_config=$_POST['selected_config'];
-	// Configuration was switched in content frame?
-	if (isset($_GET['config'])) $new_config=$_GET['config'];
-	// restore the last active menuitem
-	if (is_readable($config['paths']['config'].$new_config.'.php'))
-	{
-		clearstatcache();
-		unset($databases);
-		$databases=array();
-		if (read_config($new_config))
-		{
-			$config['config_file']=$new_config;
-			$_SESSION['config_file']=$new_config; //$config['config_file'];
-			$config_refresh='
-			<script language="JavaScript" type="text/javascript">
+if (isset($_POST['selected_config']) || isset($_GET['config'])) {
+    if (isset($_POST['selected_config'])) {
+        $new_config = $_POST['selected_config'];
+    }
+    // Configuration was switched in content frame?
+    if (isset($_GET['config'])) {
+        $new_config = $_GET['config'];
+    }
+    // restore the last active menuitem
+    if (is_readable($config['paths']['config'].$new_config.'.php')) {
+        clearstatcache();
+        unset($databases);
+        $databases = [];
+        if (read_config($new_config)) {
+            $config['config_file'] = $new_config;
+            $_SESSION['config_file'] = $new_config; //$config['config_file'];
+            $config_refresh = '
+			<script>
 			if (parent.MyOOS_Dumper_content.location.href.indexOf("config_overview.php")!=-1)
 			{
 				var selected_div=parent.MyOOS_Dumper_content.document.getElementById("sel").value;
 			}
 			else selected_div=\'\';
 			parent.MyOOS_Dumper_content.location.href=\'config_overview.php?config='.urlencode($new_config).'&sel=\'+selected_div</script>';
-		}
-		if (isset($_GET['config'])) $config_refresh=''; //Neu-Aufruf bei Uebergabe aus Content-Bereich verhindern
-	}
+        }
+        if (isset($_GET['config'])) {
+            $config_refresh = '';
+        } //Neu-Aufruf bei Uebergabe aus Content-Bereich verhindern
+    }
 }
 
-echo MSDHeader(1);
-echo headline('',0);
+echo MODHeader(1);
+echo headline('', 0);
 
-if ($config_refresh>'')
-{
-	$tpl->assign_block_vars('CONFIG_REFRESH_TRUE',array());
-	$tpl->assign_var('CONFIG_REFRESH',$config_refresh);
+if ($config_refresh > '') {
+    $tpl->assign_block_vars('CONFIG_REFRESH_TRUE', []);
+    $tpl->assign_var('CONFIG_REFRESH', $config_refresh);
 }
 
 // changed language
-if ($config['language']!=$lang_old)
-{
-	$tpl->assign_block_vars('CHANGED_LANGUAGE',array());
+if ($config['language'] != $lang_old) {
+    $tpl->assign_block_vars('CHANGED_LANGUAGE', []);
 }
 
-if (isset($_GET['action']))
-{
-	if ($_GET['action']=='dbrefresh')
-	{
-		// remember the name of the selected database
-		$old_dbname=isset($databases['Name'][$databases['db_selected_index']]) ? $databases['Name'][$databases['db_selected_index']] : '';
-		SetDefault();
-		// select old database if it still is there
-		SelectDB($old_dbname);
-		$tpl->assign_block_vars('DB_REFRESH',array());
-	}
+if (isset($_GET['action'])) {
+    if ('dbrefresh' == $_GET['action']) {
+        // remember the name of the selected database
+        $old_dbname = isset($databases['Name'][$databases['db_selected_index']]) ? $databases['Name'][$databases['db_selected_index']] : '';
+        SetDefault();
+        // select old database if it still is there
+        SelectDB($old_dbname);
+        $tpl->assign_block_vars('DB_REFRESH', []);
+    }
 }
 
-if (isset($_POST['dbindex']))
-{
-	$dbindex=intval($_POST['dbindex']);
-	$databases['db_selected_index']=$dbindex;
-	$databases['db_actual']=$databases['Name'][$dbindex];
+if (isset($_POST['dbindex'])) {
+    $dbindex = intval($_POST['dbindex']);
+    $databases['db_selected_index'] = $dbindex;
+    $databases['db_actual'] = $databases['Name'][$dbindex];
 
-	SelectDB($dbindex);
-	WriteParams(0);
-	$tpl->assign_block_vars('DB_REFRESH',array());
-}
-else
-	$dbindex=0;
-
-if (isset($_GET['dbindex']))
-{
-	$dbindex=intval($_GET['dbindex']);
-	$databases['db_selected_index']=$dbindex;
-	$databases['db_actual']=$databases['Name'][$dbindex];
-	SelectDB($dbindex);
-	WriteParams(0);
+    SelectDB($dbindex);
+    WriteParams(0);
+    $tpl->assign_block_vars('DB_REFRESH', []);
+} else {
+    $dbindex = 0;
 }
 
-if (isset($databases['Name'])&&count($databases['Name'])>0)
-{
-	$tpl->assign_block_vars('MAINTENANCE',array());
-	$tpl->assign_vars(array(
-		'DB_ACTUAL' => $databases['db_actual'],
-		'DB_SELECTED_INDEX' => $databases['db_selected_index']));
+if (isset($_GET['dbindex'])) {
+    $dbindex = intval($_GET['dbindex']);
+    $databases['db_selected_index'] = $dbindex;
+    $databases['db_actual'] = $databases['Name'][$dbindex];
+    SelectDB($dbindex);
+    WriteParams(0);
 }
-$tpl->assign_var('GET_FILELIST',get_config_filelist());
 
-if (isset($databases['Name'])&&count($databases['Name'])>0)
-{
-	$tpl->assign_block_vars('DB_LIST',array());
-	$datenbanken=count($databases['Name']);
-	for ($i=0; $i<$datenbanken; $i++)
-	{
-		$selected=($i==$databases['db_selected_index']) ? ' selected' : '';
-		$tpl->assign_block_vars('DB_LIST.DB_ROW',array(
-			'ID' => $i,
-			'NAME' => $databases['Name'][$i],
-			'SELECTED' => $selected));
-	}
+if (isset($databases['Name']) && count($databases['Name']) > 0) {
+    $tpl->assign_block_vars('MAINTENANCE', []);
+    $tpl->assign_vars([
+        'DB_ACTUAL' => $databases['db_actual'],
+        'DB_SELECTED_INDEX' => $databases['db_selected_index'], ]);
 }
-else
-	$tpl->assign_block_vars('NO_DB_FOUND',array());
+$tpl->assign_var('GET_FILELIST', get_config_filelist());
 
-$tpl->assign_var('PIC_CACHE',PicCache());
-
-if (!isset($databases['Name'])||count($databases['Name'])<1)
-{
-	$tpl->assign_block_vars('DB_NAME_TRUE',array());
+if (isset($databases['Name']) && count($databases['Name']) > 0) {
+    $tpl->assign_block_vars('DB_LIST', []);
+    $datenbanken = count($databases['Name']);
+    for ($i = 0; $i < $datenbanken; ++$i) {
+        $selected = ($i == $databases['db_selected_index']) ? ' selected' : '';
+        $tpl->assign_block_vars('DB_LIST.DB_ROW', [
+            'ID' => $i,
+            'NAME' => $databases['Name'][$i],
+            'SELECTED' => $selected, ]);
+    }
+} else {
+    $tpl->assign_block_vars('NO_DB_FOUND', []);
+}
+
+$tpl->assign_var('PIC_CACHE', PicCache());
+
+if (!isset($databases['Name']) || count($databases['Name']) < 1) {
+    $tpl->assign_block_vars('DB_NAME_TRUE', []);
+} else {
+    $tpl->assign_block_vars('DB_NAME_FALSE', []);
 }
-else
-	$tpl->assign_block_vars('DB_NAME_FALSE',array());
 
 $tpl->pparse('header');
 $tpl->pparse('content');
diff --git a/msd/msd_cron/crondump.pl b/msd/mod_cron/crondump.pl
similarity index 93%
rename from msd/msd_cron/crondump.pl
rename to msd/mod_cron/crondump.pl
index 51f5900d..b0a42f1c 100644
--- a/msd/msd_cron/crondump.pl
+++ b/msd/mod_cron/crondump.pl
@@ -1,9 +1,9 @@
 #!/usr/bin/perl -w
 #
 #   MyOOS [Dumper]
-#   http://www.oos-shop.de/
+#   https://www.oos-shop.de/
 #
-#   Copyright (c) 2016 by the MyOOS Development Team.
+#   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
 #   ----------------------------------------------------------------------
 #   Based on:
 #
@@ -20,30 +20,26 @@
 #
 # 2004-2010 by Steffen Kamper, Daniel Schlichtholz
 # additional scripting: Detlev Richter, Jonathan Tietz
-#
-# for support etc. visit http://forum.mysqldumper.de
 # 
 # This file is part of MySQLDumper released under the GNU/GPL 2 license
 # http://www.mysqldumper.net 
 # @package             MySQLDumper
 # @version             Rev: 1371 $
 # @author              Author: dsb1971 $
-# @lastmodified        Date: 2011-01-24 21:15:21 +0100 (Mo, 24. Jan 2011) 
-# @filesource          URL: https://mysqldumper.svn.sourceforge.net/svnroot/mysqldumper/branches/msd1.24.3/msd_cron/crondump.pl 
 #
 ########################################################################################
 # Script-Version
-my $pcd_version='1.24.4';
+my $pcd_version='5.0.20';
 
 ########################################################################################
 # please enter the absolute path of the config-dir
-# when calling the script without parameters the default_configfile (mysqldumper.conf.php) will be loaded
+# when calling the script without parameters the default_configfile (myoosdumper.conf.php) will be loaded
 # e.g. - (zum Beispiel): 
-# my $absolute_path_of_configdir="/home/www/doc/8176/mysqldumper.de/www/mysqldumper/work/config/";
+# my $absolute_path_of_configdir="/home/www/doc/8176/example.org/www/myoosdumper/work/config/";
 
-my $absolute_path_of_configdir="/var/www/web360/htdocs/leitgedanken_utf8/msd/work/config/";
+my $absolute_path_of_configdir="/var/www/web360/htdocs/leitgedanken_php8/msd/work/config/";
 my $cgibin_path=""; # this is needed for MIME::Lite if it is in cgi-bin
-my $default_configfile="mysqldumper.conf.php";
+my $default_configfile="myoosdumper.conf.php";
 
 ########################################################################################
 # nothing to edit below this line !!!
@@ -87,7 +83,7 @@ $mod_ftpssl @multipartfiles %db_tables @tablenames $tablename $opttbl $command $
 
 $memory_limit=100000;
 $mysql_commentstring="-- ";
-$character_set="utf8";
+$character_set="utf8mb4";
 $sql_text='';
 $sql_file='';
 $punktzaehler=0;
@@ -183,25 +179,25 @@ if($absolute_path_of_configdir eq "" || ! -d $absolute_path_of_configdir)
     if ($i=~m#^(.*)\\#) {
         #windows
             $current_dir = $1;
-            $current_dir =~ s/msd\_cron//g;
+            $current_dir =~ s/mod\_cron//g;
 
             #set default log-files
-            $logdatei= $current_dir ."work\\log\\mysqldump_perl.log";
-            $completelogdatei= $current_dir . "work\\log\\mysqldump_perl.complete.log";
+            $logdatei= $current_dir ."work\\log\\myoosdump_perl.log";
+            $completelogdatei= $current_dir . "work\\log\\myoosdump_perl.complete.log";
 
             $absolute_path_of_configdir = $current_dir ."work\\config\\";
     } elsif ($i=~m#^(.*)\/# ) {
         #*nix
             $current_dir = $1;
-            $current_dir =~ s/msd\_cron//g;
+            $current_dir =~ s/mod\_cron//g;
 
             #set default log-files
-            $logdatei= $current_dir ."work/log/mysqldump_perl.log";
-            $completelogdatei= $current_dir . "work/log/mysqldump_perl.complete.log";
+            $logdatei= $current_dir ."work/log/myoosdump_perl.log";
+            $completelogdatei= $current_dir . "work/log/myoosdump_perl.complete.log";
 
             $absolute_path_of_configdir = $current_dir."work/config/";
     }
-    #$absolute_path_of_configdir =~ s/msd\_cron//g;
+    #$absolute_path_of_configdir =~ s/mod\_cron//g;
     $backup_path = $absolute_path_of_configdir;
     $backup_path =~ s/config/backup/g;
 
@@ -482,7 +478,23 @@ sub DoDump {
                         
         if ($dump_table==1)
         {
-            $r+=$db_tables{$tablename}{Rows}; #calculate nr of records
+
+			#www.betanet-web.ch - 30.04.2019
+			#Erweitert mit SQL Abfrage für Ausgabe Anzahl der Einträge in der Tabelle (analog PHP)
+			$sql_create = "SELECT COUNT(*) FROM `$tablename`";	
+			$sth = $dbh->prepare($sql_create);
+            if (!$sth)
+			{
+				err_trap("<font color=\"red\">Fatal error sending Query '".$sql_create."'! MySQL-Error: ".$DBI::errstr);
+			}				
+				
+			$sth->execute || err_trap("Couldn't execute ".$sql_create);
+			$rct = $sth->fetchrow;
+			$sth->finish;
+				
+			$r+=$rct;
+			#Ende der Erweiterung			
+
             push(@tables,$db_tables{$tablename}{Name}); # add tablename to backuped tables
             $t++;
             if (!defined $db_tables{$tablename}{Update_time})
@@ -502,10 +514,14 @@ sub DoDump {
     #    Aufbau Backupflags (1 Zeichen pro Flag, 0 oder 1, 2=unbekannt)
     #    (complete inserts)(extended inserts)(ignore inserts)(delayed inserts)(downgrade)(lock tables)(optimize tables)
     #
+	my $version=0;
+	$version=$mysql_version[0];
+	while ($version =~ s/:/--/) {} 
+	while ($my_comment =~ s/:/--/) {} 
     $status_start=$mysql_commentstring."Status:$t:$r:";
     my $flags="1$optimize_tables_beforedump";
-    $status_end=":$dbname:perl:$pcd_version:$my_comment:$mysql_version[0]:$flags";
-    $status_end.=":$command_beforedump:$command_afterdump:$character_set:EXTINFO$st_e\n".$mysql_commentstring."Dump created on $CTIME_String by PERL Cron-Script\n".$mysql_commentstring."Dump by MySQLDumper (http://www.mysqldumper.net/)\n\n";
+    $status_end=":$dbname:perl:$pcd_version:$my_comment:$version:$flags";
+    $status_end.=":$command_beforedump:$command_afterdump:$character_set:EXTINFO$st_e\n".$mysql_commentstring."Dump created on $CTIME_String by PERL Cron-Script\n".$mysql_commentstring."Dump by MyOOS Dumper (https://www.oos-shop.de/)\n\n";
 
 
     if($mp>0) 
@@ -581,8 +597,23 @@ sub DoDump {
                 $fieldlist=substr($fieldlist,0,length($fieldlist)-1).")";
 
                 # how many rows
-                $rct=$db_tables{$tablename}{Rows};
-
+		
+				#www.betanet-web.ch - 30.04.2019
+				#Erweitert mit SQL Abfrage für Ausgabe Anzahl der Einträge in der Tabelle (analog PHP)
+				$sql_create = "SELECT COUNT(*) FROM `$tablename`";	
+				$sth = $dbh->prepare($sql_create);
+                if (!$sth)
+                {
+                    err_trap("<font color=\"red\">Fatal error sending Query '".$sql_create."'! MySQL-Error: ".$DBI::errstr);
+                }				
+				
+				$sth->execute || err_trap("Couldn't execute ".$sql_create);
+				$rct = $sth->fetchrow;
+				$sth->finish;
+			
+				#Ende der Erweiterung
+				
+				
                 for (my $ttt=0;$ttt<$rct;$ttt+=$perlspeed) 
                 {
                     # default beginning for INSERT-String
@@ -693,14 +724,14 @@ sub PrintHeader {
     {
         print $cgi->header(-type => 'text/html; charset=utf-8', -cache_control => 'no-cache, no-store, must-revalidate');
         print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
-        print "<html>\n<head>\n<title>MySQLDumper - Perl CronDump [Version $pcd_version (using perl $perlversion)]</title>\n";
+        print "<html>\n<head>\n<title>MyOOS [Dumper] - Perl CronDump [Version $pcd_version (using perl $perlversion)]</title>\n";
         print "<style type=\"text/css\">\nbody { padding:20px; font-family:Verdana,Helvetica,Sans-Serif;font-size: 0.9em !important;}</style>\n";
-        print "</head>\n<body><h3>MySQLDumper - Perl CronDump [Version $pcd_version (using perl $perlversion)]</h3>\n";
+        print "</head>\n<body><h3>MyOOS [Dumper] - Perl CronDump [Version $pcd_version (using perl $perlversion)]</h3>\n";
     }
     else
     {
         #small output for external cronjobs, which expect a small returnvalue
-        print "MySQLDumper - Perl CronDump [Version $pcd_version] started successfully (using perl $perlversion)\n";
+        print "MyOOS [Dumper] - Perl CronDump [Version $pcd_version] started successfully (using perl $perlversion)\n";
     }
 }
 
@@ -729,15 +760,15 @@ sub PrintOut {
             
             if ( ($logcompression==0) || ($mod_gz==0)) 
             {
-                open(DATEI,">>$completelogdatei") || err_trap('can\'t open mysqldump_perl.complete.log ('.$completelogdatei.').');
-                print DATEI "$dt $output\n" || err_trap('can\'t write to mysqldump_perl.complete.log ('.$completelogdatei.').');
-                close(DATEI)|| err_trap('can\'t close mysqldump_perl.complete.log ('.$completelogdatei.').');
+                open(DATEI,">>$completelogdatei") || err_trap('can\'t open myoosdump_perl.complete.log ('.$completelogdatei.').');
+                print DATEI "$dt $output\n" || err_trap('can\'t write to myoosdump_perl.complete.log ('.$completelogdatei.').');
+                close(DATEI)|| err_trap('can\'t close myoosdump_perl.complete.log ('.$completelogdatei.').');
                 chmod(0777,$completelogdatei);
             }
             else
             {
-                $gz = gzopen($completelogdatei, "ab") || err_trap("Cannot open mysqldump_perl.complete.log.gz. ");
-                $gz->gzwrite("$dt $output\n")  || err_trap("Error writing mysqldump_perl.complete.log.gz. ");
+                $gz = gzopen($completelogdatei, "ab") || err_trap("Cannot open myoosdump_perl.complete.log.gz. ");
+                $gz->gzwrite("$dt $output\n")  || err_trap("Error writing myoosdump_perl.complete.log.gz. ");
                 $gz->gzclose ;
                 chmod(0777,$completelogdatei);
             }
@@ -911,7 +942,7 @@ sub send_mail {
             $Body.="\n<br>$mpdatei (".(byte_output($filesize))." )";
         }
     }
-    $Body.="\n\n<br><br>Best regards,<br><br>MySQLDumper<br>If you have any questions, feel free and visit the support board at:<br><a href=\"http://forum.mysqldumper.de\">http://forum.mysqldumper.de</a>";
+    $Body.="\n\n<br><br>Best regards,<br><br>MyOOS [Dumper]<br>If you have any questions, feel free and visit the support board at:<br><a href=\"https://foren.myoos.de/viewforum.php?f=40\">https://foren.myoos.de/viewforum.php?f=40</a>";
 
     if ($cron_use_sendmail==1)
     {    
@@ -926,7 +957,7 @@ sub send_mail {
         From    => $cronmailfrom,
         To      => $cronmailto,
         Cc    => $cronmailto_cc,
-        Subject => "MSD (Perl) - Backup of DB ".$dbname,
+        Subject => "MOD (Perl) - Backup of DB ".$dbname,
         Type    => 'text/html; charset=iso-8859-1',
         Data    => "<body>\n".$Body."</body>\n"
     );
@@ -961,7 +992,7 @@ sub send_mail {
                 From    => $cronmailfrom,
                 To      => $cronmailto,
                 Cc    => $cronmailto_cc,
-                Subject => "MSD (Perl) - Backup of DB $dbname File ".$str[1]." of ".@mparray ,
+                Subject => "MOD (Perl) - Backup of DB $dbname File ".$str[1]." of ".@mparray ,
                 Type    => 'text/html; charset=iso-8859-1',
                 Data    => "<body>\n".$Body."</body>\n"
             );
@@ -1134,7 +1165,7 @@ sub AutoDeleteCount {
         }
         else
         {
-            PrintOut("No Statusline in `<strong>$fname</strong>` found. Seems not to be a MySQLDumper file. Skipping file.");
+            PrintOut("No Statusline in `<strong>$fname</strong>` found. Seems not to be a MyOOS [Dumper] file. Skipping file.");
         }
     }
 }
@@ -1282,8 +1313,8 @@ sub ExecuteCommand
                 if($cad[$i] ne '')
                 {
                     $err='';
-                    # replace $$MSD$$ back to ';'
-                    $cad[$i] =~ s/\$\$MSD\$\$/\;/g;
+                    # replace $$MOD$$ back to ';'
+                    $cad[$i] =~ s/\$\$MOD\$\$/\;/g;
                     $sth = $dbh->prepare($cad[$i]);
                     $sth->execute or $err=$sth->errstr();
                     if ($err ne '') 
@@ -1381,14 +1412,15 @@ sub optimise_tables
     PrintOut("<span style=\"font-size:11px;\">$opttbl tables have been optimized</span><br>") if($opttbl>0) ;
 }
 
-# replace in querystring all ';' in VALUES with '$$MSD$$'
+# replace in querystring all ';' in VALUES with '$$MOD$$'
 sub replaceQueryStringSimple{
     my $string = shift(@_);
     
     if ($string =~ m#(.*)\'(.*)\;(.*)\'(.*)#){
         # if found search for more ';'
-        return replaceQueryStringSimple($1.'\''.$2.'$$MSD$$'.$3.'\''.$4);;
+        return replaceQueryStringSimple($1.'\''.$2.'$$MOD$$'.$3.'\''.$4);;
     }else{
         return $string;
     }
-}
\ No newline at end of file
+}
+
diff --git a/msd/msd_cron/perltest.pl b/msd/mod_cron/perltest.pl
similarity index 94%
rename from msd/msd_cron/perltest.pl
rename to msd/mod_cron/perltest.pl
index 15ffe965..b8af21a5 100644
--- a/msd/msd_cron/perltest.pl
+++ b/msd/mod_cron/perltest.pl
@@ -1,9 +1,9 @@
 #!/usr/bin/perl -w
 #
 #   MyOOS [Dumper]
-#   http://www.oos-shop.de/
+#   https://www.oos-shop.de/
 #
-#   Copyright (c) 2016 by the MyOOS Development Team.
+#   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
 #   ----------------------------------------------------------------------
 #   Based on:
 #
@@ -20,8 +20,7 @@
 # @package 			MySQLDumper
 # @version 			Rev: 1351 
 # @author 			Author: jtietz 
-# @lastmodified 	Date: 2011-01-16 20:55:42 +0100 (So, 16. Jan 2011) 
-# @filesource 		URL: https://mysqldumper.svn.sourceforge.net/svnroot/mysqldumper/branches/msd1.24.3/msd_cron/perltest.pl 
+
 
 use strict;
 use Socket;
@@ -48,7 +47,7 @@ my $zlib_version='unknown';
 my $cgi = CGI->new();
 print $cgi->header(-type => 'text/html; charset=utf-8', -cache_control => 'no-cache, no-store, must-revalidate');
 print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
-print "<html><head><title>MySQLDumper Perl modul test</title>\n";
+print "<html><head><title>MyOOS [Dumper] Perl modul test</title>\n";
 print '<style type="text/css">body { padding-left:18px; font-family:Verdana,Helvetica,Sans-Serif;}</style></head>';
 print "<body><h2>Testing needed Perl-Moduls in order to run the Perl script crondump.pl</h2>\n";
 print "<h4 style=\"background-color:#ccffcc;\">Necessary Modules for crondump.pl</h4>";
diff --git a/msd/msd_cron/simpletest.pl b/msd/mod_cron/simpletest.pl
similarity index 77%
rename from msd/msd_cron/simpletest.pl
rename to msd/mod_cron/simpletest.pl
index f53771f0..794e59ba 100644
--- a/msd/msd_cron/simpletest.pl
+++ b/msd/mod_cron/simpletest.pl
@@ -9,15 +9,15 @@
 # Frage Deinen Hoster, ob und wie Du Perl aktivieren kannst.
 #
 # Sample Apache-Config:
-# <Directory /usr/local/apache2/htdocs/mysqldumper/msd_cron>
+# <Directory /usr/local/apache2/htdocs/myoosdumper/mod_cron>
 #    Options ExecCGI
-#    AddHandler cgi-script cgi pl
+#    AddHandler cgi-script .cgi .pl
 # </Directory>
 #
 #   MyOOS [Dumper]
-#   http://www.oos-shop.de/
+#   https://www.oos-shop.de/
 #
-#   Copyright (c) 2016 by the MyOOS Development Team.
+#   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
 #   ----------------------------------------------------------------------
 #   Based on:
 #
@@ -35,8 +35,8 @@
 # @package 			MySQLDumper
 # @version 			Rev: 1351 
 # @author 			Author: jtietz 
-# @lastmodified 	Date: 2011-01-16 20:55:42 +0100 (So, 16. Jan 2011) 
-# @filesource 		URL: https://mysqldumper.svn.sourceforge.net/svnroot/mysqldumper/branches/msd1.24.3/msd_cron/simpletest.pl 
+
+
 
 use strict;
 use CGI::Carp qw(warningsToBrowser fatalsToBrowser);  
@@ -44,7 +44,7 @@ warningsToBrowser(1);
 
 print "Content-type: text/html\n\n";
 print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
-print "<html><head><title>MySQLDumper - simple Perl test</title>\n";
+print "<html><head><title>MyOOS [Dumper] - simple Perl test</title>\n";
 print '<style type="text/css">body { padding-left:18px; font-family:Verdana,Helvetica,Sans-Serif;}</style>';
 print "\n</head><body>\n";
 print "<p>If you see this perl works fine on your system !<br><br>";
diff --git a/msd/refresh_dblist.php b/msd/refresh_dblist.php
index 0e86b708..5bd40ddc 100644
--- a/msd/refresh_dblist.php
+++ b/msd/refresh_dblist.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -16,30 +16,28 @@
    Released under the GNU General Public License
    ---------------------------------------------------------------------- */
 
-
-// Konfigurationsdateien, die aktualisiert werden sollen
-// configurations to update
-// mehrere Dateien so angeben | enter more than one configurationsfile like this
-// $configurationfiles=array('mysqldumper','db2');
-/////////////////////////////////////////////////////////////////////////
-$configurationfiles=array(
-						'myoosdumper'
-);
-
+/**
+ * configurations to update.
+ *
+ * enter more than one configurationsfile like this
+ * $configurationfiles=array('myoosdumper','db2');
+ */
+$configurationfiles = [
+                        'myoosdumper',
+];
 
 define('OOS_VALID_MOD', true);
 
-define('APPLICATION_PATH',realpath(dirname(__FILE__)));
-chdir(APPLICATION_PATH);
-include_once ( APPLICATION_PATH . '/inc/functions.php' );
-$config['language']='en';
-$config['theme']="msd";
-$config['files']['iconpath']='css/' . $config['theme'] . '/icons/';
+define('APPLICATION_PATH', '/' == dirname(__FILE__) ? '' : dirname(__FILE__));
+include_once APPLICATION_PATH.'/inc/functions.php';
 
-foreach ($configurationfiles as $conf)
-{
-	$config['config_file']=$conf;
-	include ( $config['paths']['config'] . $conf . '.php' );
-	GetLanguageArray();
-	SetDefault();
+$config['language'] = 'en';
+$config['theme'] = 'mod';
+$config['files']['iconpath'] = 'css/'.$config['theme'].'/icons/';
+
+foreach ($configurationfiles as $conf) {
+    $config['config_file'] = $conf;
+    include $config['paths']['config'].$conf.'.php';
+    GetLanguageArray();
+    SetDefault();
 }
diff --git a/msd/restore.php b/msd/restore.php
index 439edc9c..11b6fcb4 100644
--- a/msd/restore.php
+++ b/msd/restore.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,310 +18,323 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
 session_name('MyOOSDumperID');
 session_start();
-include ('./inc/functions.php');
-include ('./inc/functions_restore.php');
-include ('./inc/mysql.php');
-if (isset($_GET['filename']))
-{
-	// Arrays uebernehmen
-	foreach ($_POST as $key=>$val)
-	{
-		if (is_array($val))
-		{
-			foreach ($val as $key2=>$val2)
-			{
-				if ($config['magic_quotes_gpc']) $restore[stripslashes($key)][stripslashes($key2)]=stripslashes($val2);
-				else
-					$restore[$key][$key2]=$val2;
-			}
-		}
-	}
-	include ('./'.$config['files']['parameter']);
-	$restore['max_zeit']=intval($config['max_execution_time']*$config['time_buffer']);
-	if ($restore['max_zeit']==0) $restore['max_zeit']=20;
-	$restore['startzeit']=time();
-	$restore['xtime']=(isset($_POST['xtime'])) ? $_POST['xtime'] : time();
-	$restore['fileEOF']=false; // Ende des Files erreicht?
-	$restore['actual_table']=(!empty($_POST['actual_table'])) ? $_POST['actual_table'] : 'unbekannt';
-	$restore['offset']=(!empty($_POST['offset'])) ? $_POST['offset'] : 0;
-	$restore['aufruf']=(!empty($_POST['aufruf'])) ? $_POST['aufruf'] : 0;
-	$restore['table_ready']=(!empty($_POST['table_ready'])) ? $_POST['table_ready'] : 0;
-	$restore['part']=(isset($_POST['part'])) ? $_POST['part'] : 0;
-	$restore['do_it']=(isset($_POST['do_it'])) ? $_POST['do_it'] : false;
-	$restore['errors']=(isset($_POST['err'])) ? $_POST['err'] : 0;
-	$restore['notices']=(isset($_POST['notices'])) ? $_POST['notices'] : 0;
-	$restore['anzahl_eintraege']=(isset($_POST['anzahl_eintraege'])) ? $_POST['anzahl_eintraege'] : 0;
-	$restore['anzahl_tabellen']=(isset($_POST['anzahl_tabellen'])) ? $_POST['anzahl_tabellen'] : 0;
-	$restore['filename']=(isset($_POST['filename'])) ? urldecode($_POST['filename']) : '';
-	if (isset($_GET['filename'])) $restore['filename']=urldecode($_GET['filename']);
-	$restore['actual_fieldcount']=(isset($_POST['actual_fieldcount'])) ? $_POST['actual_fieldcount'] : 0;
-	$restore['eintraege_ready']=(isset($_POST['eintraege_ready'])) ? $_POST['eintraege_ready'] : 0;
-	$restore['anzahl_zeilen']=(isset($_POST['anzahl_zeilen'])) ? $_POST['anzahl_zeilen'] : $config['minspeed'];
-	$restore['summe_eintraege']=(isset($_POST['summe_eintraege'])) ? $_POST['summe_eintraege'] : 0;
-	$restore['erweiterte_inserts']=(isset($_POST['erweiterte_inserts'])) ? $_POST['erweiterte_inserts'] : 0;
-	$restore['flag']=(isset($_POST['flag'])) ? $_POST['flag'] : -1;
-	$restore['EOB']=false;
-	$restore['dump_encoding']=(isset($_POST['dump_encoding'])) ? $_POST['dump_encoding'] : 'utf8';
-	if (isset($_GET['dump_encoding'])) $restore['dump_encoding']=$_GET['dump_encoding'];
-	$restore['compressed']=(substr(strtolower($restore['filename']),-2)=='gz') ? 1 : 0;
-	// wurden nur bestimmte Tabellen ausgwaehlt?
-	if (!isset($databases['db_actual_tableselected'])) $databases['db_actual_tableselected']='';
-	if ($databases['db_actual_tableselected']!='')
-	{
-		$restore['tables_to_restore']=explode('|',$databases['db_actual_tableselected']);
-	}
-	else
-		$restore['tables_to_restore']=false;
-	$_SESSION['config']=$config;
-	$_SESSION['databases']=$databases;
+include './inc/functions.php';
+include './inc/functions_restore.php';
+include './inc/mysqli.php';
+if (isset($_GET['filename'])) {
+    // Arrays uebernehmen
+    foreach ($_POST as $key => $val) {
+        if (is_array($val)) {
+            foreach ($val as $key2 => $val2) {
+                $restore[$key][$key2] = $val2;
+            }
+        }
+    }
+    include './'.$config['files']['parameter'];
+    $restore['max_zeit'] = intval($config['max_execution_time'] * $config['time_buffer']);
+    if (0 == $restore['max_zeit']) {
+        $restore['max_zeit'] = 20;
+    }
+    $restore['startzeit'] = time();
+    $restore['xtime'] = (isset($_POST['xtime'])) ? $_POST['xtime'] : time();
+    $restore['fileEOF'] = false; // Ende des Files erreicht?
+    $restore['actual_table'] = (!empty($_POST['actual_table'])) ? $_POST['actual_table'] : 'unbekannt';
+    $restore['offset'] = (!empty($_POST['offset'])) ? $_POST['offset'] : 0;
+    $restore['aufruf'] = (!empty($_POST['aufruf'])) ? $_POST['aufruf'] : 0;
+    $restore['table_ready'] = (!empty($_POST['table_ready'])) ? $_POST['table_ready'] : 0;
+    $restore['part'] = (isset($_POST['part'])) ? $_POST['part'] : 0;
+    $restore['do_it'] = (isset($_POST['do_it'])) ? $_POST['do_it'] : false;
+    $restore['errors'] = (isset($_POST['err'])) ? $_POST['err'] : 0;
+    $restore['notices'] = (isset($_POST['notices'])) ? $_POST['notices'] : 0;
+    $restore['anzahl_eintraege'] = (isset($_POST['anzahl_eintraege'])) ? $_POST['anzahl_eintraege'] : 0;
+    $restore['anzahl_tabellen'] = (isset($_POST['anzahl_tabellen'])) ? $_POST['anzahl_tabellen'] : 0;
+    $restore['filename'] = (isset($_POST['filename'])) ? urldecode($_POST['filename']) : '';
+    if (isset($_GET['filename'])) {
+        $restore['filename'] = urldecode($_GET['filename']);
+    }
+    $restore['actual_fieldcount'] = (isset($_POST['actual_fieldcount'])) ? $_POST['actual_fieldcount'] : 0;
+    $restore['eintraege_ready'] = (isset($_POST['eintraege_ready'])) ? $_POST['eintraege_ready'] : 0;
+    $restore['anzahl_zeilen'] = (isset($_POST['anzahl_zeilen'])) ? $_POST['anzahl_zeilen'] : $config['minspeed'];
+    $restore['summe_eintraege'] = (isset($_POST['summe_eintraege'])) ? $_POST['summe_eintraege'] : 0;
+    $restore['erweiterte_inserts'] = (isset($_POST['erweiterte_inserts'])) ? $_POST['erweiterte_inserts'] : 0;
+    $restore['flag'] = (isset($_POST['flag'])) ? $_POST['flag'] : -1;
+    $restore['EOB'] = false;
+    $restore['dump_encoding'] = (isset($_POST['dump_encoding'])) ? $_POST['dump_encoding'] : 'utf8';
+    if (isset($_GET['dump_encoding'])) {
+        $restore['dump_encoding'] = $_GET['dump_encoding'];
+    }
+    $restore['compressed'] = ('gz' == substr(strtolower($restore['filename']), -2)) ? 1 : 0;
+    // wurden nur bestimmte Tabellen ausgwaehlt?
+    if (!isset($databases['db_actual_tableselected'])) {
+        $databases['db_actual_tableselected'] = '';
+    }
+    if ('' != $databases['db_actual_tableselected']) {
+        $restore['tables_to_restore'] = explode('|', $databases['db_actual_tableselected']);
+    } else {
+        $restore['tables_to_restore'] = false;
+    }
+    $_SESSION['config'] = $config;
+    $_SESSION['databases'] = $databases;
+} else {
+    $config = $_SESSION['config'];
+    $databases = $_SESSION['databases'];
+    $restore = $_SESSION['restore'];
+    $restore['startzeit'] = time();
+    // some Server limit the number of vars that can be saved in a session
+    // if this is the case and we lost the language-var we simply include the configuration again
+    // this way the include is skipped on servers with unlimited vars
+    if (!isset($config['language'])) {
+        include './'.$config['files']['parameter'];
+    }
 }
-else
-{
-	$config=$_SESSION['config'];
-	$databases=$_SESSION['databases'];
-	$restore=$_SESSION['restore'];
-	$restore['startzeit']=time();
-	// some Server limit the number of vars that can be saved in a session
-	// if this is the case and we lost the language-var we simply include the configuration again
-	// this way the include is skipped on servers with unlimited vars
-	if (!isset($config['language'])) include ('./'.$config['files']['parameter']);
-}
-include ('./language/'.$config['language'].'/lang.php');
-include ('./language/'.$config['language'].'/lang_restore.php');
-$config['files']['iconpath']='./css/'.$config['theme'].'/icons/';
-$aus=Array();
-$pageheader=MSDheader().headline($lang['L_RESTORE']);
-$aus1=$page_parameter='';
-$RestoreFertig=$eingetragen=$dauer=$filegroesse=0;
-MSD_mysql_connect($restore['dump_encoding'],true,$restore['actual_table']);
-@mysqli_select_db($config['dbconnection'], $databases['db_actual']) or die($lang['L_DB_SELECT_ERROR'].$databases['db_actual'].$lang['L_DB_SELECT_ERROR2']);
+include './language/'.$config['language'].'/lang.php';
+include './language/'.$config['language'].'/lang_restore.php';
+$config['files']['iconpath'] = './css/'.$config['theme'].'/icons/';
+$aus = [];
+$pageheader = MODheader().headline($lang['L_RESTORE']);
+$aus1 = $page_parameter = '';
+$RestoreFertig = $eingetragen = $dauer = $filegroesse = 0;
+mod_mysqli_connect($restore['dump_encoding'], true, $restore['actual_table']);
+@mysqli_select_db($config['dbconnection'], $databases['db_actual']) or exit($lang['L_DB_SELECT_ERROR'].$databases['db_actual'].$lang['L_DB_SELECT_ERROR2']);
 
 // open backup file
-$restore['filehandle']=($restore['compressed']==1) ? gzopen($config['paths']['backup'].$restore['filename'],'r') : fopen($config['paths']['backup'].$restore['filename'],'r');
-if ($restore['filehandle'])
-{
-	//nur am Anfang Logeintrag
-	if ($restore['offset']==0&&$restore['anzahl_tabellen']==0)
-	{
-		// Statuszeile auslesen
-		$restore['part']=0;
-		$statusline=($restore['compressed']==1) ? gzgets($restore['filehandle']) : fgets($restore['filehandle']);
-		$sline=ReadStatusline($statusline,true);
+$restore['filehandle'] = (1 == $restore['compressed']) ? gzopen($config['paths']['backup'].$restore['filename'], 'r') : fopen($config['paths']['backup'].$restore['filename'], 'r');
+if ($restore['filehandle']) {
+    //nur am Anfang Logeintrag
+    if (0 == $restore['offset'] && 0 == $restore['anzahl_tabellen']) {
+        // Statuszeile auslesen
+        $restore['part'] = 0;
+        $statusline = (1 == $restore['compressed']) ? gzgets($restore['filehandle']) : fgets($restore['filehandle']);
+        $sline = ReadStatusline($statusline, true);
 
-		$restore['anzahl_tabellen']=$sline['tables'];
-		$restore['anzahl_eintraege']=$sline['records'];
-		if ($sline['part']!='MP_0') $restore['part']=1; //substr($sline['part'],3);
-		if ($config['empty_db_before_restore']==1) EmptyDB($databases['db_actual']);
-		$restore['tablelock']=0;
-		$restore['erweiterte_inserts']=0;
+        $restore['anzahl_tabellen'] = $sline['tables'];
+        $restore['anzahl_eintraege'] = $sline['records'];
+        if ('MP_0' != $sline['part']) {
+            $restore['part'] = 1;
+        } //substr($sline['part'],3);
+        if (1 == $config['empty_db_before_restore']) {
+            EmptyDB($databases['db_actual']);
+        }
+        $restore['tablelock'] = 0;
+        $restore['erweiterte_inserts'] = 0;
 
-		if ($sline['tables']=='-1') ($restore['compressed']) ? gzseek($restore['filehandle'],0) : fseek($restore['filehandle'],0);
-		if ($restore['part']>0) WriteLog('Start Multipart-Restore \''.$restore['filename'].'\'');
-		else
-			WriteLog('Start Restore \''.$restore['filename'].'\'');
+        if ('-1' == $sline['tables']) {
+            ($restore['compressed']) ? gzseek($restore['filehandle'], 0) : fseek($restore['filehandle'], 0);
+        }
+        if ($restore['part'] > 0) {
+            WriteLog('Start Multipart-Restore \''.$restore['filename'].'\'');
+        } else {
+            WriteLog('Start Restore \''.$restore['filename'].'\'');
+        }
+    } else {
+        if (0 == $restore['compressed']) {
+            $filegroesse = filesize($config['paths']['backup'].$restore['filename']);
+        }
+        // Dateizeiger an die richtige Stelle setzen
+        ($restore['compressed']) ? gzseek($restore['filehandle'], $restore['offset']) : fseek($restore['filehandle'], $restore['offset']);
 
-	}
-	else
-	{
-		if ($restore['compressed']==0) $filegroesse=filesize($config['paths']['backup'].$restore['filename']);
-		// Dateizeiger an die richtige Stelle setzen
-		($restore['compressed']) ? gzseek($restore['filehandle'],$restore['offset']) : fseek($restore['filehandle'],$restore['offset']);
+        // Jetzt basteln wir uns mal unsere Befehle zusammen...
+        $a = 0;
+        $dauer = 0;
+        $restore['EOB'] = false;
+        // Disable Keys of actual table to speed up restoring
+        if (is_array($restore['tables_to_restore']) && sizeof($restore['tables_to_restore']) > 0 && in_array($restore['actual_table'], $restore['tables_to_restore'])) {
+            @mysqli_query($config['dbconnection'], '/*!40000 ALTER TABLE `'.$restore['actual_table'].'` DISABLE KEYS */;');
+        } elseif (!is_array($restore['tables_to_restore']) &&
+            (is_array($restore['tables_to_restore']) && 0 == sizeof($restore['tables_to_restore'])) &&
+            ($restore['actual_table'] > '' && 'unbekannt' != $restore['actual_table'])) {
+            @mysqli_query($config['dbconnection'], '/*!40000 ALTER TABLE `'.$restore['actual_table'].'` DISABLE KEYS */;');
+        }
 
-		// Jetzt basteln wir uns mal unsere Befehle zusammen...
-		$a=0;
-		$dauer=0;
-		$restore['EOB']=false;
-		// Disable Keys of actual table to speed up restoring
-		if (is_array($restore['tables_to_restore'])&&sizeof($restore['tables_to_restore'])>0&&in_array($restore['actual_table'],$restore['tables_to_restore']))
-		{
-			@mysqli_query($config['dbconnection'], '/*!40000 ALTER TABLE `'.$restore['actual_table'].'` DISABLE KEYS */;');
-		}
-		elseif (sizeof($restore['tables_to_restore'])==0&&($restore['actual_table']>''&&$restore['actual_table']!='unbekannt')) @mysqli_query($config['dbconnection'], '/*!40000 ALTER TABLE `'.$restore['actual_table'].'` DISABLE KEYS */;');
+        while (($a < $restore['anzahl_zeilen']) && (!$restore['fileEOF']) && ($dauer < $restore['max_zeit']) && !$restore['EOB']) {
+            $sql_command = get_sqlbefehl();
+            if ($sql_command > '') {
+                //WriteLog(htmlspecialchars($sql_command));
+                $res = mysqli_query($config['dbconnection'], $sql_command);
+                if (false === !$res) {
+                    $anzsql = mysqli_affected_rows($config['dbconnection']);
+                    // Anzahl der eingetragenen Datensaetze ermitteln (Indexaktionen nicht zaehlen)
+                    $command = strtoupper(substr($sql_command, 0, 7));
+                    if ('INSERT ' == $command) {
+                        $anzsql = mysqli_affected_rows($config['dbconnection']);
+                        if ($anzsql > 0) {
+                            $restore['eintraege_ready'] += $anzsql;
+                        }
+                    }
+                } else {
+                    // Bei MySQL-Fehlern sofort abbrechen und Info ausgeben
+                    $meldung = mysqli_error($config['dbconnection']);
+                    if ('' != $meldung) {
+                        if ('duplicate entry' == strtolower(substr($meldung, 0, 15))) {
+                            ErrorLog('RESTORE', $databases['db_actual'], $sql_command, $meldung, 1);
+                            ++$restore['notices'];
+                        } else {
+                            if (0 == $config['stop_with_error']) {
+                                Errorlog('RESTORE', $databases['db_actual'], $sql_command, $meldung);
+                                ++$restore['errors'];
+                            } else {
+                                Errorlog('RESTORE', $databases['db_actual'], $sql_command, 'Restore failed: '.$meldung, 0);
+                                SQLError($sql_command, $meldung);
+                                exit($sql_command.' -> '.$meldung);
+                            }
+                        }
+                    }
+                }
+            }
+            ++$a;
+            $dauer = time() - $restore['startzeit'];
+        }
+        $eingetragen = $a - 1;
+    }
 
-		while (($a<$restore['anzahl_zeilen'])&&(!$restore['fileEOF'])&&($dauer<$restore['max_zeit'])&&!$restore['EOB'])
-		{
-			$sql_command=get_sqlbefehl();
-			if ($sql_command>'')
-			{
-				//WriteLog(htmlspecialchars($sql_command));
-				$res=mysqli_query($config['dbconnection'], $sql_command);
-				if (!$res===false)
-				{
-					$anzsql=mysqli_affected_rows($config['dbconnection']);
-					// Anzahl der eingetragenen Datensaetze ermitteln (Indexaktionen nicht zaehlen)
-					$command=strtoupper(substr($sql_command,0,7));
-					if ($command=='INSERT ')
-					{
-						$anzsql=mysqli_affected_rows($config['dbconnection']);
-						if ($anzsql>0) $restore['eintraege_ready']+=$anzsql;
-					}
-				}
-				else
-				{
-					// Bei MySQL-Fehlern sofort abbrechen und Info ausgeben
-					$meldung=@mysqli_error($config['dbconnection']);
-					if ($meldung!='')
-					{
-						if (strtolower(substr($meldung,0,15))=='duplicate entry')
-						{
-							ErrorLog('RESTORE',$databases['db_actual'],$sql_command,$meldung,1);
-							$restore['notices']++;
-						}
-						else
-						{
-							if ($config['stop_with_error']==0)
-							{
-								Errorlog('RESTORE',$databases['db_actual'],$sql_command,$meldung);
-								$restore['errors']++;
-							}
-							else
-							{
-								Errorlog('RESTORE',$databases['db_actual'],$sql_command,'Restore failed: '.$meldung,0);
-								SQLError($sql_command,$meldung);
-								die($sql_command.' -> '.$meldung);
-							}
-						}
-					}
-				}
-			}
-			$a++;
-			$dauer=time()-$restore['startzeit'];
-		}
-		$eingetragen=$a-1;
-	}
+    $restore['offset'] = ($restore['compressed']) ? gztell($restore['filehandle']) : ftell($restore['filehandle']);
+    $restore['compressed'] ? gzclose($restore['filehandle']) : fclose($restore['filehandle']);
+    ++$restore['aufruf'];
+    if (!$restore['compressed']) {
+        $prozent = ($filegroesse > 0) ? ($restore['offset'] * 100) / $filegroesse : 0;
+    } else {
+        if ($restore['anzahl_eintraege'] > 0) {
+            $prozent = $restore['eintraege_ready'] * 100 / $restore['anzahl_eintraege'];
+        } else {
+            $prozent = 0;
+        }
+    }
+    if ($prozent > 100) {
+        $prozent = 100;
+    }
 
-	$restore['offset']=($restore['compressed']) ? gztell($restore['filehandle']) : ftell($restore['filehandle']);
-	$restore['compressed'] ? gzclose($restore['filehandle']) : fclose($restore['filehandle']);
-	$restore['aufruf']++;
-	if (!$restore['compressed']) $prozent=($filegroesse>0) ? ($restore['offset']*100)/$filegroesse : 0;
-	else
-	{
-		if ($restore['anzahl_eintraege']>0) $prozent=$restore['eintraege_ready']*100/$restore['anzahl_eintraege'];
-		else
-			$prozent=0;
-	}
-	if ($prozent>100) $prozent=100;
+    if ('' != $aus1) {
+        $aus[] = '<br>'.$aus1.'<br><br>';
+    }
+    $aus[] = sprintf($lang['L_RESTORE_DB'], $databases['db_actual'], $config['dbhost']).'<br>'.$lang['L_FILE'].': <b>'.$restore['filename'].'</b><br>'.$lang['L_CHARSET'].': <strong>'.$restore['dump_encoding'].'</strong><br>';
+    if ($restore['part'] > 0) {
+        $aus[] = '<br>Multipart File <strong>'.$restore['part'].'</strong><br>';
+    }
+    $tabellen_fertig = ($restore['table_ready'] > 0) ? $restore['table_ready'] : '0';
+    $to_do = ($restore['anzahl_tabellen'] > 0) ? $restore['anzahl_tabellen'] : $lang['L_UNKNOWN'];
+    if ($restore['anzahl_tabellen'] > 0) {
+        $aus[] = sprintf($lang['L_RESTORE_TABLES_COMPLETED'], $tabellen_fertig, $to_do);
+    } else {
+        $aus[] = sprintf($lang['L_RESTORE_TABLES_COMPLETED0'], $tabellen_fertig);
+    }
+    $done = number_format($restore['eintraege_ready'], 0, ',', '.');
+    $to_do = number_format($restore['anzahl_eintraege'], 0, ',', '.');
+    if ($restore['anzahl_eintraege'] > 0) {
+        $aus[] = sprintf($lang['L_RESTORE_RUN1'], $done, $to_do);
+    } else {
+        $aus[] = sprintf($lang['L_RESTORE_RUN0'], $done);
+    }
+    $aus[] = sprintf($lang['L_RESTORE_RUN2'], $restore['actual_table']).$lang['L_PROGRESS_OVER_ALL'].'<br>';
 
-	if ($aus1!='') $aus[]='<br>'.$aus1.'<br><br>';
-	$aus[]=sprintf($lang['L_RESTORE_DB'],$databases['db_actual'],$config['dbhost']).'<br>'.$lang['L_FILE'].': <b>'.$restore['filename'].'</b><br>'.$lang['L_CHARSET'].': <strong>'.$restore['dump_encoding'].'</strong><br>';
-	if ($restore['part']>0) $aus[]='<br>Multipart File <strong>'.$restore['part'].'</strong><br>';
-	$tabellen_fertig=($restore['table_ready']>0) ? $restore['table_ready'] : '0';
-	$to_do=($restore['anzahl_tabellen']>0) ? $restore['anzahl_tabellen'] : $lang['L_UNKNOWN'];
-	if ($restore['anzahl_tabellen']>0) $aus[]=sprintf($lang['L_RESTORE_TABLES_COMPLETED'],$tabellen_fertig,$to_do);
-	else
-		$aus[]=sprintf($lang['L_RESTORE_TABLES_COMPLETED0'],$tabellen_fertig);
-	$done=number_format($restore['eintraege_ready'],0,',','.');
-	$to_do=number_format($restore['anzahl_eintraege'],0,',','.');
-	if ($restore['anzahl_eintraege']>0) $aus[]=sprintf($lang['L_RESTORE_RUN1'],$done,$to_do);
-	else
-		$aus[]=sprintf($lang['L_RESTORE_RUN0'],$done);
-	$aus[]=sprintf($lang['L_RESTORE_RUN2'],$restore['actual_table']).$lang['L_PROGRESS_OVER_ALL'].'<br>';
+    //Fortschrittsbalken
+    $prozentbalken = (round($prozent, 0) * 3);
+    if ($restore['anzahl_eintraege'] > 0 && false === $restore['tables_to_restore']) {
+        $aus[] = '<table border="0" width="440"><tr>';
+        if ($prozentbalken >= 3) {
+            $aus[] = '<td width="'.$prozentbalken.'" nowrap="nowrap">
+		<img src="'.$config['files']['iconpath'].'progressbar_restore.gif" name="restorebalken" alt="" width="'.$prozentbalken.'" height="16" border="0"></td>'.'<td width="'.(round(100 - $prozent, 0) * 3).'">&nbsp;</td>'.'<td width="80" align="right" nowrap="nowrap"><b>'.(number_format($prozent, 2, ',', '.')).' %</b></td></tr></table>';
+        }
+    } else {
+        $aus[] = ' <b>'.$lang['L_UNKNOWN_NUMBER_OF_RECORDS'].'</b><br><br>';
+    }
 
-	//Fortschrittsbalken
-	$prozentbalken=(round($prozent,0)*3);
-	if ($restore['anzahl_eintraege']>0&&$restore['tables_to_restore']===false)
-	{
-		$aus[]='<table border="0" width="440"><tr>';
-		if ($prozentbalken>=3) $aus[]='<td width="'.$prozentbalken.'" nowrap="nowrap">
-		<img src="'.$config['files']['iconpath'].'progressbar_restore.gif" name="restorebalken" alt="" width="'.$prozentbalken.'" height="16" border="0"></td>'.'<td width="'.(round(100-$prozent,0)*3).'">&nbsp;</td>'.'<td width="80" align="right" nowrap="nowrap"><b>'.(number_format($prozent,2,",",".")).' %</b></td></tr></table>';
-	}
-	else
-		$aus[]=' <b>'.$lang['L_UNKNOWN_NUMBER_OF_RECORDS'].'</b><br><br>';
+    //Speed-Anzeige
+    $fw = ($config['maxspeed'] == $config['minspeed']) ? 300 : round(($restore['anzahl_zeilen'] - $config['minspeed']) / ($config['maxspeed'] - $config['minspeed']) * 300, 0);
+    $aus[] = '<br><table border="0" cellpadding="0" cellspacing="0"><tr>'.'<td width="60" valign="top" align="center" style="color:#990000; font-size:10px;" >'.'<strong>Speed</strong><br>'.$restore['anzahl_zeilen'].'</td><td width="300">'.'<table border="0" width="100%" cellpadding="0" cellspacing="0"><tr>'.'<td align="left"class="small" width="300" nowrap="nowrap">'.'<img src="'.$config['files']['iconpath'].'progressbar_speed.gif" name="speedbalken" alt="" width="'.$fw.'" height="12" border="0" vspace="0" hspace="0">'.'</td></tr></table><table border="0" width="100%" cellpadding="0" cellspacing="0">'.'<tr style="padding:0;margin:0;"><td align="left" nowrap="nowrap" style="font-size:10px;" >'.$config['minspeed'].'</td>'.'<td style="text-align:right;font-size:10px;" nowrap="nowrap">'.$config['maxspeed'].'</td>'.'</tr></table></td></tr></table>';
 
-	//Speed-Anzeige
-	$fw=($config['maxspeed']==$config['minspeed']) ? 300 : round(($restore['anzahl_zeilen']-$config['minspeed'])/($config['maxspeed']-$config['minspeed'])*300,0);
-	$aus[]='<br><table border="0" cellpadding="0" cellspacing="0"><tr>'.'<td width="60" valign="top" align="center" style="color:#990000; font-size:10px;" >'.'<strong>Speed</strong><br>'.$restore['anzahl_zeilen'].'</td><td width="300">'.'<table border="0" width="100%" cellpadding="0" cellspacing="0"><tr>'.'<td align="left"class="small" width="300" nowrap="nowrap">'.'<img src="'.$config['files']['iconpath'].'progressbar_speed.gif" name="speedbalken" alt="" width="'.$fw.'" height="12" border="0" vspace="0" hspace="0">'.'</td></tr></table><table border="0" width="100%" cellpadding="0" cellspacing="0">'.'<tr style="padding:0;margin:0;"><td align="left" nowrap="nowrap" style="font-size:10px;" >'.$config['minspeed'].'</td>'.'<td style="text-align:right;font-size:10px;" nowrap="nowrap">'.$config['maxspeed'].'</td>'.'</tr></table></td></tr></table>';
+    //Status-Text
+    $aus[] = '<p class="small">'.zeit_format(time() - $restore['xtime']).', '.$restore['aufruf'].' '.$lang['L_PAGE_REFRESHS'].(($restore['part'] > 0) ? ', file '.$restore['part'] : '').(($restore['errors'] > 0) ? ', <span class="error">'.$restore['errors'].' errors</span>' : '').(($restore['notices'] > 0) ? ', <span class="notice">'.$restore['notices'].' notices</span>' : '').'</p>';
+    $restore['summe_eintraege'] += $eingetragen;
 
-	//Status-Text
-	$aus[]='<p class="small">'.zeit_format(time()-$restore['xtime']).', '.$restore['aufruf'].' '.$lang['L_PAGE_REFRESHS'].(($restore['part']>0) ? ', file '.$restore['part'] : '').(($restore['errors']>0) ? ', <span class="error">'.$restore['errors'].' errors</span>' : '').(($restore['notices']>0) ? ', <span class="notice">'.$restore['notices'].' notices</span>' : '').'</p>';
-	$restore['summe_eintraege']+=$eingetragen;
-
-	//Zeitanpassung
-	if ($dauer<$restore['max_zeit'])
-	{
-		$restore['anzahl_zeilen']=$restore['anzahl_zeilen']*$config['tuning_add'];
-		// wenn wir mehr als die Haelfte der Zeit noch haetten nutzen koennen: Anzahl direkt um fast das Doppelte erhoehen
-		if ($dauer<$restore['max_zeit']/2) $restore['anzahl_zeilen']=$restore['anzahl_zeilen']*1.8;
-		if ($restore['anzahl_zeilen']>$config['maxspeed']) $restore['anzahl_zeilen']=$config['maxspeed'];
-	}
-	else
-	{
-		$restore['anzahl_zeilen']=$restore['anzahl_zeilen']*$config['tuning_sub'];
-		if ($restore['anzahl_zeilen']<$config['minspeed']) $restore['anzahl_zeilen']=$config['minspeed'];
-	}
-	$restore['anzahl_zeilen']=intval($restore['anzahl_zeilen']);
-	if ($restore['fileEOF']&&$restore['part']==0) $restore['EOB']=true;
-	if ($restore['EOB'])
-	{
-		// Uff, geschafft! Jetzt darf die Leitung wieder abkuehlen. :-)
-		unset($aus);
-		$aus=array();
-		$restore['xtime']=time()-$restore['xtime'];
-		WriteLog("Restore '".$restore['filename']."' finished in ".zeit_format($restore['xtime']).".");
-		$aus[]=$lang['L_RESTORE_TOTAL_COMPLETE']."<br>";
-		$aus[]=$lang['L_FILE'].': <b>'.$restore['filename'].'</b><br><br>';
-		$aus[]=sprintf($lang['L_RESTORE_COMPLETE'],$restore['table_ready']).'<br>';
-		$aus[]=sprintf($lang['L_RESTORE_COMPLETE2'],number_format($restore['eintraege_ready'],0,",","."));
-		$aus[]='<p class="small">'.zeit_format($restore['xtime']).', '.$restore['aufruf'].' '.$lang['L_PAGE_REFRESHS'].' </p>';
-		if ($restore['errors']>0) $aus[]=$lang['L_ERRORS'].': '.$restore['errors'].'  <a href="log.php?r=3">&raquo; '.$lang['L_VIEW'].'</a><br>';
-		if ($restore['notices']>0) $aus[]=$lang['L_NOTICES'].': '.$restore['notices'].'  <a href="log.php?r=3">&raquo; '.$lang['L_VIEW'].'</a><br>';
-		$aus[]="<br>&nbsp;&nbsp;&nbsp;<input class=\"Formbutton\" type=\"button\" value=\"".$lang['L_BACK_TO_MINISQL']."\" onclick=\"self.location.href='sql.php'\">";
-		$aus[]="&nbsp;&nbsp;&nbsp;<input class=\"Formbutton\" type=\"button\" value=\"".$lang['L_BACK_TO_OVERVIEW']."\" onclick=\"self.location.href='main.php?action=db&dbid=".$databases['db_selected_index']."#dbid'\">";
-		$RestoreFertig=1;
-	}
-	else
-	{
-		if ($restore['fileEOF'])
-		{
-			//Multipart-Restore
-			$restore['fileEOF']=false;
-			$nextfile=NextPart($restore['filename'],0,true);
-			if (!file_exists($config['paths']['backup'].$nextfile))
-			{
-				$done=number_format($restore['eintraege_ready'],0,",",".");
-				$to_do=number_format($restore['anzahl_eintraege'],0,",",".");
-				$aus=array();
-				$aus[]='<h3>'.$lang['L_RESTORE'].'</h3>';
-				$aus[]=sprintf($lang['L_RESTORE_DB'],$databases['db_actual'],$config['dbhost']);
-				$aus[]='<p class="error">'.$lang['L_MULTI_PART'].': '.$lang['L_FILE_MISSING'].' \''.$nextfile.'\' !</p>';
-				$aus[]=sprintf($lang['L_RESTORE_RUN1'],$done,$to_do);
-				$aus[]=sprintf($lang['L_RESTORE_RUN2'],$restore['actual_table']);
-				$aus[]='<p class="small">'.zeit_format(time()-$restore['xtime']).', '.$restore['aufruf'].' '.$lang['L_PAGE_REFRESHS'];
-				$aus[]=($restore['part']>0) ? ', '.$lang['L_FILE'].' '.$restore['part'] : '';
-				$aus[]=($restore['errors']>0) ? ', <span class="error">'.$restore['errors'].' errors</span>' : '';
-				$aus[]='</p>';
-				WriteLog('Restore unsuccessful: Cannot find Multipartfile \''.$nextfile.'\'');
-				$RestoreFertig=1;
-			}
-			else
-			{
-				$restore['filename']=$nextfile;
-				$restore['offset']=0;
-				$restore['part']++;
-				WriteLog("Continue Multipart-Restore with File '".$restore['filename']."'");
-			}
-		}
-	}
+    //Zeitanpassung
+    if ($dauer < $restore['max_zeit']) {
+        $restore['anzahl_zeilen'] = $restore['anzahl_zeilen'] * $config['tuning_add'];
+        // wenn wir mehr als die Haelfte der Zeit noch haetten nutzen koennen: Anzahl direkt um fast das Doppelte erhoehen
+        if ($dauer < $restore['max_zeit'] / 2) {
+            $restore['anzahl_zeilen'] = $restore['anzahl_zeilen'] * 1.8;
+        }
+        if ($restore['anzahl_zeilen'] > $config['maxspeed']) {
+            $restore['anzahl_zeilen'] = $config['maxspeed'];
+        }
+    } else {
+        $restore['anzahl_zeilen'] = $restore['anzahl_zeilen'] * $config['tuning_sub'];
+        if ($restore['anzahl_zeilen'] < $config['minspeed']) {
+            $restore['anzahl_zeilen'] = $config['minspeed'];
+        }
+    }
+    $restore['anzahl_zeilen'] = intval($restore['anzahl_zeilen']);
+    if ($restore['fileEOF'] && 0 == $restore['part']) {
+        $restore['EOB'] = true;
+    }
+    if ($restore['EOB']) {
+        // Uff, geschafft! Jetzt darf die Leitung wieder abkuehlen. :-)
+        unset($aus);
+        $aus = [];
+        $restore['xtime'] = time() - $restore['xtime'];
+        WriteLog("Restore '".$restore['filename']."' finished in ".zeit_format($restore['xtime']).'.');
+        $aus[] = $lang['L_RESTORE_TOTAL_COMPLETE'].'<br>';
+        $aus[] = $lang['L_FILE'].': <b>'.$restore['filename'].'</b><br><br>';
+        $aus[] = sprintf($lang['L_RESTORE_COMPLETE'], $restore['table_ready']).'<br>';
+        $aus[] = sprintf($lang['L_RESTORE_COMPLETE2'], number_format($restore['eintraege_ready'], 0, ',', '.'));
+        $aus[] = '<p class="small">'.zeit_format($restore['xtime']).', '.$restore['aufruf'].' '.$lang['L_PAGE_REFRESHS'].' </p>';
+        if ($restore['errors'] > 0) {
+            $aus[] = $lang['L_ERRORS'].': '.$restore['errors'].'  <a href="log.php?r=3">&raquo; '.$lang['L_VIEW'].'</a><br>';
+        }
+        if ($restore['notices'] > 0) {
+            $aus[] = $lang['L_NOTICES'].': '.$restore['notices'].'  <a href="log.php?r=3">&raquo; '.$lang['L_VIEW'].'</a><br>';
+        }
+        $aus[] = '<br>&nbsp;&nbsp;&nbsp;<input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_MINISQL']."\" onclick=\"self.location.href='sql.php'\">";
+        $aus[] = '&nbsp;&nbsp;&nbsp;<input class="Formbutton" type="button" value="'.$lang['L_BACK_TO_OVERVIEW']."\" onclick=\"self.location.href='main.php?action=db&dbid=".$databases['db_selected_index']."#dbid'\">";
+        $RestoreFertig = 1;
+    } else {
+        if ($restore['fileEOF']) {
+            //Multipart-Restore
+            $restore['fileEOF'] = false;
+            $nextfile = NextPart($restore['filename'], 0, true);
+            if (!file_exists($config['paths']['backup'].$nextfile)) {
+                $done = number_format($restore['eintraege_ready'], 0, ',', '.');
+                $to_do = number_format($restore['anzahl_eintraege'], 0, ',', '.');
+                $aus = [];
+                $aus[] = '<h3>'.$lang['L_RESTORE'].'</h3>';
+                $aus[] = sprintf($lang['L_RESTORE_DB'], $databases['db_actual'], $config['dbhost']);
+                $aus[] = '<p class="error">'.$lang['L_MULTI_PART'].': '.$lang['L_FILE_MISSING'].' \''.$nextfile.'\' !</p>';
+                $aus[] = sprintf($lang['L_RESTORE_RUN1'], $done, $to_do);
+                $aus[] = sprintf($lang['L_RESTORE_RUN2'], $restore['actual_table']);
+                $aus[] = '<p class="small">'.zeit_format(time() - $restore['xtime']).', '.$restore['aufruf'].' '.$lang['L_PAGE_REFRESHS'];
+                $aus[] = ($restore['part'] > 0) ? ', '.$lang['L_FILE'].' '.$restore['part'] : '';
+                $aus[] = ($restore['errors'] > 0) ? ', <span class="error">'.$restore['errors'].' errors</span>' : '';
+                $aus[] = '</p>';
+                WriteLog('Restore unsuccessful: Cannot find Multipartfile \''.$nextfile.'\'');
+                $RestoreFertig = 1;
+            } else {
+                $restore['filename'] = $nextfile;
+                $restore['offset'] = 0;
+                ++$restore['part'];
+                WriteLog("Continue Multipart-Restore with File '".$restore['filename']."'");
+            }
+        }
+    }
+} else {
+    $aus[] = $config['paths']['backup'].$restore['filename'].' :  '.$lang['L_FILE_OPEN_ERROR'];
 }
-else
-	$aus[]=$config['paths']['backup'].$restore['filename'].' :  '.$lang['L_FILE_OPEN_ERROR'];
 
-$pagefooter=($RestoreFertig==1) ? MSDFooter() : '</div></BODY></HTML>';
+$pagefooter = (1 == $RestoreFertig) ? MODFooter() : '</div></BODY></HTML>';
 // formerly all parameters were submitted via POST; now we use a session but we need the form to do the js-selfcall
-$page_parameter='<form action="restore.php?MySQLDumper='.session_id().'" method="POST" name="restore"></form>';
-if ($RestoreFertig==1)
-{
-	$complete_page=$pageheader.(($aus!='') ? implode("\n",$aus) : '').$pagefooter;
-}
-else
-{
-	$aus[]=$page_parameter;
-	$_SESSION['restore']=$restore;
-	$selbstaufruf='<script language="javascript" type="text/javascript">setTimeout("document.restore.submit()",10);</script>';
-	$complete_page=$pageheader.(($aus!='') ? implode("\n",$aus) : '').$selbstaufruf.$pagefooter;
+$page_parameter = '<form action="restore.php?MyOOSDumperID='.session_id().'" method="POST" name="restore"></form>';
+if (1 == $RestoreFertig) {
+    $complete_page = $pageheader.(('' != $aus) ? implode("\n", $aus) : '').$pagefooter;
+} else {
+    $aus[] = $page_parameter;
+    $_SESSION['restore'] = $restore;
+    $selbstaufruf = '<script>setTimeout("document.restore.submit()",10);</script>';
+    $complete_page = $pageheader.(('' != $aus) ? implode("\n", $aus) : '').$selbstaufruf.$pagefooter;
 }
 echo $complete_page;
 ob_end_flush();
+exit();
diff --git a/msd/sql.php b/msd/sql.php
index 877fa601..ff8ae45b 100644
--- a/msd/sql.php
+++ b/msd/sql.php
@@ -4,7 +4,7 @@
    MyOOS [Dumper]
    http://www.oos-shop.de/
 
-   Copyright (c) 2016 by the MyOOS Development Team.
+   Copyright (c) 2013 - 2022 by the MyOOS Development Team.
    ----------------------------------------------------------------------
    Based on:
 
@@ -18,278 +18,315 @@
 
 define('OOS_VALID_MOD', true);
 
-if (!@ob_start("ob_gzhandler")) @ob_start();
-$download=(isset($_POST['f_export_submit'])&&(isset($_POST['f_export_sendresult'])&&$_POST['f_export_sendresult']==1));
-include ('./inc/header.php');
-include ('language/'.$config['language'].'/lang.php');
-include ('language/'.$config['language'].'/lang_sql.php');
-include ('./inc/functions_sql.php');
-include ('./'.$config['files']['parameter']);
-include ('./inc/template.php');
-include ('./inc/define_icons.php');
-$key='';
+if (!@ob_start('ob_gzhandler')) {
+    @ob_start();
+}
+
+$download = (isset($_POST['f_export_submit']) && (isset($_POST['f_export_sendresult']) && 1 == $_POST['f_export_sendresult']));
+include './inc/header.php';
+include 'language/'.$config['language'].'/lang.php';
+include 'language/'.$config['language'].'/lang_sql.php';
+include './inc/functions_sql.php';
+include './'.$config['files']['parameter'];
+include './inc/template.php';
+include './inc/define_icons.php';
+$key = '';
 // stripslashes and trimming is done in runtime.php which is included and executet above
-if (isset($_GET['rk']))
-{
-	$rk=urldecode($_GET['rk']);
-	$key=urldecode($rk);
-	if (!$rk=@unserialize($key)) $rk=$key;
+if (isset($_GET['rk'])) {
+    $rk = urldecode($_GET['rk']);
+    $key = urldecode($rk);
+    if (!$rk = @unserialize($key)) {
+        $rk = $key;
+    }
+} else {
+    $rk = '';
 }
-else
-	$rk='';
-$mode=isset($_GET['mode']) ? $_GET['mode'] : '';
+$mode = isset($_GET['mode']) ? $_GET['mode'] : '';
 
-if (isset($_GET['recordkey']))
-{
-	$recordkey=$_GET['recordkey'];
-	$key=isset($_GET['recordkey']) ? urldecode($recordkey) : $recordkey;
-	if (!$recordkey=@unserialize(urldecode($key))) $recordkey=urldecode($key);
+if (isset($_GET['recordkey'])) {
+    $recordkey = $_GET['recordkey'];
+    /*
+        $key = isset($_GET['recordkey']) ? urldecode($recordkey) : $recordkey;
+        if (!$recordkey = @unserialize(urldecode($key))) {
+            $recordkey = urldecode($key);
+        }
+        */
 }
-if (isset($_POST['recordkey'])) $recordkey=urldecode($_POST['recordkey']);
 
-$context=(!isset($_GET['context'])) ? 0 : $_GET['context'];
-$context=(!isset($_POST['context'])) ? $context : $_POST['context'];
 
-if (!$download)
-{
-	echo MSDHeader();
-	ReadSQL();
-	echo '<script language="JavaScript" type="text/javascript">
-		var auswahl = "document.getElementsByName(\"f_export_tables[]\")[0]";
-		var msg1="'.$lang['L_SQL_NOTABLESSELECTED'].'";
+if (isset($_POST['recordkey'])) {
+    //  $recordkey = urldecode($_POST['recordkey']);
+    $recordkey = $_POST['recordkey'];
+}
+
+$context = (!isset($_GET['context'])) ? 0 : $_GET['context'];
+$context = (!isset($_POST['context'])) ? $context : $_POST['context'];
+
+if (!$download) {
+    echo MODHeader();
+    ReadSQL();
+    echo '<script>
+		var auswahl  =  "document.getElementsByName(\"f_export_tables[]\")[0]";
+		var msg1 = "'.$lang['L_SQL_NOTABLESSELECTED'].'";
 		</script>';
 }
 //Variabeln
-$mysql_help_ref='http://dev.mysql.com/doc/';
-$mysqli_errorhelp_ref='http://dev.mysql.com/doc/mysql/en/error-handling.html';
-$no_order=false;
-$tdcompact=(isset($_GET['tdc'])) ? $_GET['tdc'] : $config['interface_table_compact'];
-$db=(!isset($_GET['db'])) ? $databases['db_actual'] : $_GET['db'];
-$dbid=(!isset($_GET['dbid'])) ? $databases['db_selected_index'] : $_GET['dbid'];
-$context=(!isset($_GET['context'])) ? 0 : $_GET['context'];
-$context=(!isset($_POST['context'])) ? $context : $_POST['context'];
-$tablename=(!isset($_GET['tablename'])) ? '' : $_GET['tablename'];
-$limitstart=(isset($_POST['limitstart'])) ? intval($_POST['limitstart']) : 0;
-if (isset($_GET['limitstart'])) $limitstart=intval($_GET['limitstart']);
-$orderdir=(!isset($_GET['orderdir'])) ? '' : $_GET['orderdir'];
-$order=(!isset($_GET['order'])) ? '' : $_GET['order'];
-$sqlconfig=(isset($_GET['sqlconfig'])) ? 1 : 0;
-$norder=($orderdir=="DESC") ? 'ASC' : 'DESC';
-$sql['order_statement']=($order!='') ? ' ORDER BY `'.$order.'` '.$norder : '';
-$sql['sql_statement']=(isset($_GET['sql_statement'])) ? urldecode($_GET['sql_statement']) : '';
-if (isset($_POST['sql_statement'])) $sql['sql_statement']=$_POST['sql_statement'];
-
-$showtables=(!isset($_GET['showtables'])) ? 0 : $_GET['showtables'];
-$limit=$add_sql='';
-$bb=(isset($_GET['bb'])) ? $_GET['bb'] : -1;
-if (isset($_POST['tablename'])) $tablename=$_POST['tablename'];
-$search=(isset($_GET['search'])) ? $_GET['search'] : 0;
-
-//SQL-Statement geposted
-if (isset($_POST['execsql']))
-{
-	$sql['sql_statement']=(isset($_POST['sqltextarea'])) ? $_POST['sqltextarea'] : '';
-	$db=$_POST['db'];
-	$dbid=$_POST['dbid'];
-	$tablename=$_POST['tablename'];
-	if (isset($_POST['tablecombo'])&&$_POST['tablecombo']>'')
-	{
-		$sql['sql_statement']=$_POST['tablecombo'];
-		$tablename=ExtractTablenameFromSQL($sql['sql_statement']);
-
-	}
-	if (isset($_POST['sqltextarea'])&&$_POST['sqltextarea']>'') $tablename=ExtractTablenameFromSQL($_POST['sqltextarea']);
-	if ($tablename=='') $tablename=ExtractTablenameFromSQL($sql['sql_statement']);
+$mysql_help_ref = 'http://dev.mysql.com/doc/';
+$mysqli_errorhelp_ref = 'http://dev.mysql.com/doc/mysql/en/error-handling.html';
+$no_order = false;
+$config['interface_table_compact'] = isset($config['interface_table_compact']) ? $config['interface_table_compact'] : 1;
+$tdcompact = (isset($_GET['tdc'])) ? $_GET['tdc'] : $config['interface_table_compact'];
+$db = (!isset($_GET['db'])) ? $databases['db_actual'] : $_GET['db'];
+$dbid = (!isset($_GET['dbid'])) ? $databases['db_selected_index'] : $_GET['dbid'];
+$context = (!isset($_GET['context'])) ? 0 : $_GET['context'];
+$context = (!isset($_POST['context'])) ? $context : $_POST['context'];
+$tablename = (!isset($_GET['tablename'])) ? '' : $_GET['tablename'];
+$limitstart = (isset($_POST['limitstart'])) ? intval($_POST['limitstart']) : 0;
+if (isset($_GET['limitstart'])) {
+    $limitstart = intval($_GET['limitstart']);
+}
+$orderdir = (!isset($_GET['orderdir'])) ? '' : $_GET['orderdir'];
+$order = (!isset($_GET['order'])) ? '' : $_GET['order'];
+$sqlconfig = (isset($_GET['sqlconfig'])) ? 1 : 0;
+$norder = ('DESC' == $orderdir) ? 'ASC' : 'DESC';
+$sql['order_statement'] = ('' != $order) ? ' ORDER BY `'.$order.'` '.$norder : '';
+$sql['sql_statement'] = (isset($_GET['sql_statement'])) ? urldecode($_GET['sql_statement']) : '';
+if (isset($_POST['sql_statement'])) {
+    $sql['sql_statement'] = $_POST['sql_statement'];
 }
 
-if ($sql['sql_statement']=='')
-{
-	if ($tablename!=''&&$showtables==0)
-	{
-		$sql['sql_statement']="SELECT * FROM `$tablename`";
-	}
-	else
-	{
-		$sql['sql_statement']="SHOW TABLE STATUS FROM `$db`";
-		$showtables=1;
-	}
+$showtables = (!isset($_GET['showtables'])) ? 0 : $_GET['showtables'];
+$limit = $add_sql = '';
+$bb = (isset($_GET['bb'])) ? $_GET['bb'] : -1;
+if (isset($_POST['tablename'])) {
+    $tablename = $_POST['tablename'];
+}
+$search = (isset($_GET['search'])) ? $_GET['search'] : 0;
+
+//SQL-Statement geposted
+if (isset($_POST['execsql'])) {
+    $sql['sql_statement'] = (isset($_POST['sqltextarea'])) ? $_POST['sqltextarea'] : '';
+    $db = $_POST['db'];
+    $dbid = $_POST['dbid'];
+    $tablename = $_POST['tablename'];
+    if (isset($_POST['tablecombo']) && $_POST['tablecombo'] > '') {
+        $sql['sql_statement'] = $_POST['tablecombo'];
+        $tablename = ExtractTablenameFromSQL($sql['sql_statement']);
+    }
+    if (isset($_POST['sqltextarea']) && $_POST['sqltextarea'] > '') {
+        $tablename = ExtractTablenameFromSQL($_POST['sqltextarea']);
+    }
+    if ('' == $tablename) {
+        $tablename = ExtractTablenameFromSQL($sql['sql_statement']);
+    }
+}
+
+if ('' == $sql['sql_statement']) {
+    if ('' != $tablename && 0 == $showtables) {
+        $sql['sql_statement'] = "SELECT * FROM `$tablename`";
+    } else {
+        $sql['sql_statement'] = "SHOW TABLE STATUS FROM `$db`";
+        $showtables = 1;
+    }
 }
 
 //sql-type
-$sql_to_display_data=0;
-$Anzahl_SQLs=getCountSQLStatements($sql['sql_statement']);
-$sql_to_display_data=sqlReturnsRecords($sql['sql_statement']);
-if ($Anzahl_SQLs>1) $sql_to_display_data=0;
-if ($sql_to_display_data==1)
-{
-	//nur ein SQL-Statement
-	$limitende=($limitstart+$config['sql_limit']);
+$sql_to_display_data = 0;
+$Anzahl_SQLs = getCountSQLStatements($sql['sql_statement']);
+$sql_to_display_data = sqlReturnsRecords($sql['sql_statement']);
+if ($Anzahl_SQLs > 1) {
+    $sql_to_display_data = 0;
+}
+if (1 == $sql_to_display_data) {
+    // only one SQL statement
+    $limitende = ($limitstart + $config['sql_limit']);
 
-	//Darf editiert werden?
-	$no_edit=(strtoupper(substr($sql['sql_statement'],0,6))!="SELECT"||$showtables==1||preg_match('@^((-- |#)[^\n]*\n|/\*.*?\*/)*(UNION|JOIN)@im',$sql['sql_statement']));
-	if ($no_edit) $no_order=true;
+    // Is it allowed to edit?
+    $no_edit = ('SELECT' != strtoupper(substr($sql['sql_statement'], 0, 6)) || 1 == $showtables || preg_match('@^((-- |#)[^\n]*\n|/\*.*?\*/)*(UNION|JOIN)@im', $sql['sql_statement']));
+    if ($no_edit) {
+        $no_order = true;
+    }
 
-	//Darf sortiert werden?
-	$op=strpos(strtoupper($sql['sql_statement'])," ORDER ");
-	if ($op>0)
-	{
-		//is order by last ?
-		$sql['order_statement']=substr($sql['sql_statement'],$op);
-		if (strpos($sql['order_statement'],')')>0) $sql['order_statement']='';
-		else
-			$sql['sql_statement']=substr($sql['sql_statement'],0,$op);
-	}
+    // May be sorted?
+    $op = strpos(strtoupper($sql['sql_statement']), ' ORDER ');
+    if ($op > 0) {
+        //is order by last ?
+        $sql['order_statement'] = substr($sql['sql_statement'], $op);
+        if (strpos($sql['order_statement'], ')') > 0) {
+            $sql['order_statement'] = '';
+        } else {
+            $sql['sql_statement'] = substr($sql['sql_statement'], 0, $op);
+        }
+    }
 }
 
-if (isset($_POST['tableselect'])&&$_POST['tableselect']!='1') $tablename=$_POST['tableselect'];
-MSD_mysql_connect();
+if (isset($_POST['tableselect']) && '1' != $_POST['tableselect']) {
+    $tablename = $_POST['tableselect'];
+}
+mod_mysqli_connect();
 mysqli_select_db($config['dbconnection'], $db);
 
 ///*** EDIT / UPDATES / INSERTS ***///
 ///***                          ***///
 
-
 // handle update action after submitting it
-if (isset($_POST['update'])||isset($_GET['update']))
-{
-	GetPostParams();
-	$f=explode('|',$_POST['feldnamen']);
-	$sqlu='UPDATE `'.$_POST['db'].'`.`'.$tablename.'` SET ';
-	for ($i=0; $i<count($f); $i++)
-	{
-		$index=isset($_POST[$f[$i]]) ? $f[$i] : correct_post_index($f[$i]);
-		// Check if field is set to null
-		if (isset($_POST['null_'.$index]))
-		{
-			// Yes, set it to NULL in Querystring
-			$sqlu.='`'.$f[$i].'`=NULL, ';
-		}
-		else
-			$sqlu.='`'.$f[$i].'`=\''.db_escape(convert_to_latin1($_POST[$index])).'\', ';
-	}
-	$sqlu=substr($sqlu,0,strlen($sqlu)-2).' WHERE '.$recordkey;
-	$res=MSD_query($sqlu);
-	$msg='<p class="success">'.$lang['L_SQL_RECORDUPDATED'].'</p>';
-	if (isset($mode)&&$mode=='searchedit') $search=1;
-	$sql_to_display_data=1;
+if (isset($_POST['update']) || isset($_GET['update'])) {
+    GetPostParams();
+    $f = explode('|', $_POST['feldnamen']);
+    $sqlu = 'UPDATE `'.$_POST['db'].'`.`'.$tablename.'` SET ';
+    for ($i = 0; $i < count($f); ++$i) {
+        $index = isset($_POST[$f[$i]]) ? $f[$i] : correct_post_index($f[$i]);
+        // Check if field is set to null
+        if (isset($_POST['null_'.$index])) {
+            // Yes, set it to NULL in Querystring
+            $sqlu .= '`'.$f[$i].'`=NULL, ';
+        } else {
+            $sqlu .= '`'.$f[$i].'`=\''.db_escape(convert_to_latin1($_POST[$index])).'\', ';
+        }
+    }
+    $sqlu = substr($sqlu, 0, strlen($sqlu) - 2).' WHERE '.$recordkey;
+    $res = mod_query($sqlu);
+    $msg = '<p class = "success">'.$lang['L_SQL_RECORDUPDATED'].'</p>';
+    if (isset($mode) && 'searchedit' == $mode) {
+        $search = 1;
+    }
+    $sql_to_display_data = 1;
 }
 // handle insert action after submitting it
-if (isset($_POST['insert']))
-{
-	GetPostParams();
-	$f=explode('|',$_POST['feldnamen']);
-	$sqlu='INSERT INTO `'.$tablename.'` SET ';
-	for ($i=0; $i<count($f); $i++)
-	{
-		$index=isset($_POST[$f[$i]]) ? $f[$i] : correct_post_index($f[$i]);
-		if (isset($_POST['null_'.$index]))
-		{
-			// Yes, set it to NULL in Querystring
-			$sqlu.='`'.$f[$i].'`=NULL, ';
-		}
-		else
-			$sqlu.='`'.$f[$i].'`=\''.db_escape(convert_to_latin1($_POST[$index])).'\', ';
-	}
-	$sqlu=substr($sqlu,0,strlen($sqlu)-2);
-	$res=MSD_query($sqlu);
-	$msg='<p class="success">'.$lang['L_SQL_RECORDINSERTED'].'</p>';
-	$sql_to_display_data=1;
+if (isset($_POST['insert'])) {
+    GetPostParams();
+    $f = explode('|', $_POST['feldnamen']);
+    $sqlu = 'INSERT INTO `'.$tablename.'` SET ';
+    for ($i = 0; $i < count($f); ++$i) {
+        $index = isset($_POST[$f[$i]]) ? $f[$i] : correct_post_index($f[$i]);
+        if (isset($_POST['null_'.$index])) {
+            // Yes, set it to NULL in Querystring
+            $sqlu .= '`'.$f[$i].'` = NULL, ';
+        } else {
+            $sqlu .= '`'.$f[$i].'` = \''.db_escape(convert_to_latin1($_POST[$index])).'\', ';
+        }
+    }
+    $sqlu = substr($sqlu, 0, strlen($sqlu) - 2);
+    $res = mod_query($sqlu);
+    $msg = '<p class = "success">'.$lang['L_SQL_RECORDINSERTED'].'</p>';
+    $sql_to_display_data = 1;
 }
 
-if (isset($_POST['cancel'])) GetPostParams();
+if (isset($_POST['cancel'])) {
+    GetPostParams();
+}
 
 //Tabellenansicht
-$showtables=(substr(strtoupper($sql['sql_statement']),0,10)=='SHOW TABLE') ? 1 : 0;
-$tabellenansicht=(substr(strtoupper($sql['sql_statement']),0,5)=='SHOW ') ? 1 : 0;
+$showtables = ('SHOW TABLE' == substr(strtoupper($sql['sql_statement']), 0, 10)) ? 1 : 0;
+$tabellenansicht = ('SHOW ' == substr(strtoupper($sql['sql_statement']), 0, 5)) ? 1 : 0;
 
-if (!isset($limitstart)) $limitstart=0;
-$limitende=$config['sql_limit'];
-if (strtolower(substr($sql['sql_statement'],0,6))=='select') $limit=' LIMIT '.$limitstart.', '.$limitende.';';
+if (!isset($limitstart)) {
+    $limitstart = 0;
+}
+$limitende = $config['sql_limit'];
+if ('select' == strtolower(substr($sql['sql_statement'], 0, 6))) {
+    $limit = ' LIMIT '.$limitstart.', '.$limitende.';';
+}
 
-$params="sql.php?db=".$db."&amp;tablename=".$tablename."&amp;dbid=".$dbid.'&amp;context='.$context.'&amp;sql_statement='.urlencode($sql['sql_statement']).'&amp;tdc='.$tdcompact.'&amp;showtables='.$showtables;
-if ($order!="") $params.="&amp;order=".$order."&amp;orderdir=".$orderdir.'&amp;context='.$context;
-if ($bb>-1) $params.="&amp;bb=".$bb;
+$params = 'sql.php?db='.$db.'&amp;tablename='.$tablename.'&amp;dbid='.$dbid.'&amp;context='.$context.'&amp;sql_statement='.urlencode($sql['sql_statement']).'&amp;tdc='.$tdcompact.'&amp;showtables='.$showtables;
+if ('' != $order) {
+    $params .= '&amp;order='.$order.'&amp;orderdir='.$orderdir.'&amp;context='.$context;
+}
+if ($bb > -1) {
+    $params .= '&amp;bb='.$bb;
+}
 
-$aus=headline($lang['L_SQL_BROWSER']);
+$aus = headline($lang['L_SQL_BROWSER']);
 
-if ($search==0&&!$download)
-{
-	echo $aus;
-	$aus='';
-	include ('./inc/sqlbrowser/sqlbox.php');
+if (0 == $search && !$download) {
+    echo $aus;
+    $aus = '';
+    include './inc/sqlbrowser/sqlbox.php';
 
-	if ($mode>''&&$context==0)
-	{
-		if (isset($recordkey)&&$recordkey>'') $rk=urldecode($recordkey);
-		if (isset($_GET['tablename'])) $tablename=$_GET['tablename'];
+    if ($mode > '' && 0 == $context) {
+        if (isset($recordkey) && $recordkey > '') {
+            $rk = urldecode($recordkey);
+        }
+        if (isset($_GET['tablename'])) {
+            $tablename = $_GET['tablename'];
+        }
 
-		if ($mode=='kill'||$mode=='kill_view')
-		{
-			if ($showtables==0)
-			{
-				$sqlk="DELETE FROM `$tablename` WHERE ".$rk." LIMIT 1";
-				$res=MSD_query($sqlk);
-				//echo "<br>".$sqlk;
-				$aus.='<p class="success">'.$lang['L_SQL_RECORDDELETED'].'</p>';
-			}
-			else
-			{
-				$sqlk="DROP TABLE `$rk`";
-				if ($mode=='kill_view') $sqlk='DROP VIEW `'.$rk.'`';
-				$res=MSD_query($sqlk);
-				$aus.='<p class="success">'.sprintf($lang['L_SQL_RECORDDELETED'],$rk).'</p>';
-			}
-		}
-		if ($mode=="empty")
-		{
+        if ('kill' == $mode || 'kill_view' == $mode) {
+            if (0 == $showtables) {
+                $sqlk = "DELETE FROM `$tablename` WHERE ".$rk.' LIMIT 1';
+                $res = mod_query($sqlk);
+                //echo "<br>".$sqlk;
+                $aus .= '<p class = "success">'.$lang['L_SQL_RECORDDELETED'].'</p>';
+            } else {
+                $sqlk = "DROP TABLE `$rk`";
+                if ('kill_view' == $mode) {
+                    $sqlk = 'DROP VIEW `'.$rk.'`';
+                }
+                $res = mod_query($sqlk);
+                $aus .= '<p class = "success">'.sprintf($lang['L_SQL_RECORDDELETED'], $rk).'</p>';
+            }
+        }
+        if ('empty' == $mode) {
+            if (0 != $showtables) {
+                $sqlk = "TRUNCATE `$rk`";
+                $res = mod_query($sqlk);
+                $aus .= '<p class = "success">'.sprintf($lang['L_SQL_TABLEEMPTIED'], $rk).'</p>';
+            }
+        }
+        if ('emptyk' == $mode) {
+            if (0 != $showtables) {
+                $sqlk = "TRUNCATE `$rk`;";
+                $res = mod_query($sqlk);
+                $sqlk = "ALTER TABLE `$rk` AUTO_INCREMENT = 1;";
+                $res = mod_query($sqlk);
+                $aus .= '<p class = "success">'.sprintf($lang['L_SQL_TABLEEMPTIEDKEYS'], $rk).'</p>';
+            }
+        }
 
-			if ($showtables!=0)
-			{
-				$sqlk="TRUNCATE `$rk`";
-				$res=MSD_query($sqlk);
-				$aus.='<p class="success">'.sprintf($lang['L_SQL_TABLEEMPTIED'],$rk).'</p>';
-			}
-		}
-		if ($mode=="emptyk")
-		{
-			if ($showtables!=0)
-			{
-				$sqlk="TRUNCATE `$rk`;";
-				$res=MSD_query($sqlk);
-				$sqlk="ALTER TABLE `$rk` AUTO_INCREMENT=1;";
-				$res=MSD_query($sqlk);
-				$aus.='<p class="success">'.sprintf($lang['L_SQL_TABLEEMPTIEDKEYS'],$rk).'</p>';
-			}
-		}
-
-		$javascript_switch='<script language="javascript" type="text/javascript">
+        $javascript_switch = '<script>
 function switch_area(textarea)
 {
-	var t=document.getElementById(\'area_\'+textarea);
-	var c=document.getElementById(\'null_\'+textarea);
-	if (c.checked==true) { t.className="off";t.disabled=true;  }
-	else { t.className="";t.disabled=false;  }
+	var t = document.getElementById(\'area_\'+textarea);
+	var c = document.getElementById(\'null_\'+textarea);
+	if (c.checked == true) { t.className = "off";t.disabled = true;  }
+	else { t.className = "";t.disabled = false;  }
 }
 </script>';
 
-		if ($mode=='edit'||$mode=='searchedit') include ('./inc/sqlbrowser/sql_record_update_inputmask.php');
-		if ($mode=='new') include ('./inc/sqlbrowser/sql_record_insert_inputmask.php');
-	}
-	if ($context==0) include_once ('./inc/sqlbrowser/sql_dataview.php');
-	if ($context==1) include ('./inc/sqlbrowser/sql_commands.php');
-	if ($context==2) include ('./inc/sqlbrowser/sql_tables.php');
-	if ($context==3) include ('./inc/sql_tools.php');
+        if ('edit' == $mode || 'searchedit' == $mode) {
+            include './inc/sqlbrowser/sql_record_update_inputmask.php';
+        }
+        if ('new' == $mode) {
+            include './inc/sqlbrowser/sql_record_insert_inputmask.php';
+        }
+    }
+    if (0 == $context) {
+        include_once './inc/sqlbrowser/sql_dataview.php';
+    }
+    if (1 == $context) {
+        include './inc/sqlbrowser/sql_commands.php';
+    }
+    if (2 == $context) {
+        include './inc/sqlbrowser/sql_tables.php';
+    }
+    if (3 == $context) {
+        include './inc/sql_tools.php';
+    }
 }
-if ($context==4) include ('./inc/sql_importexport.php');
-if ($search==1) include ('./inc/sqlbrowser/mysql_search.php');
-if (!$download)
-{
-	?>
-<script language="JavaScript" type="text/javascript">
+if (4 == $context) {
+    include './inc/sql_importexport.php';
+}
+if (1 == $search) {
+    include './inc/sqlbrowser/mysql_search.php';
+}
+
+if (!$download) {
+    ?>
+<script>
 function BrowseInput(el)
 {
-	var txt=document.getElementsByName('imexta')[0].value;
-	var win=window.open('about:blank','MSD_Output','resizable=1,scrollbars=yes');
+	var txt = document.getElementsByName('imexta')[0].value;
+	var win = window.open('about:blank','MOD_Output','resizable = 1,scrollbars = yes');
 	win.document.write(txt);
 	win.document.close();
 	win.focus();
@@ -297,21 +334,23 @@ function BrowseInput(el)
 </script>
 <?php
 
-	echo '<br><br><br>';
-	echo MSDFooter();
-	ob_end_flush();
+    echo '<br><br><br>';
+    echo MODFooter();
+    ob_end_flush();
+    exit();
 }
 
 function FormHiddenParams()
 {
-	global $db,$dbid,$tablename,$context,$limitstart,$order,$orderdir;
+    global $db, $dbid, $tablename, $context, $limitstart, $order, $orderdir;
 
-	$s='<input type="hidden" name="db" value="'.$db.'">';
-	$s.='<input type="hidden" name="dbid" value="'.$dbid.'">';
-	$s.='<input type="hidden" name="tablename" value="'.$tablename.'">';
-	$s.='<input type="hidden" name="context" value="'.$context.'">';
-	$s.='<input type="hidden" name="limitstart" value="'.$limitstart.'">';
-	$s.='<input type="hidden" name="order" value="'.$order.'">';
-	$s.='<input type="hidden" name="orderdir" value="'.$orderdir.'">';
-	return $s;
+    $s = '<input type = "hidden" name = "db" value = "'.$db.'">';
+    $s .= '<input type = "hidden" name = "dbid" value = "'.$dbid.'">';
+    $s .= '<input type = "hidden" name = "tablename" value = "'.$tablename.'">';
+    $s .= '<input type = "hidden" name = "context" value = "'.$context.'">';
+    $s .= '<input type = "hidden" name = "limitstart" value = "'.$limitstart.'">';
+    $s .= '<input type = "hidden" name = "order" value = "'.$order.'">';
+    $s .= '<input type = "hidden" name = "orderdir" value = "'.$orderdir.'">';
+
+    return $s;
 }
diff --git a/msd/tpl/home/home.tpl b/msd/tpl/home/home.tpl
index 9ef8ed20..0e34854e 100644
--- a/msd/tpl/home/home.tpl
+++ b/msd/tpl/home/home.tpl
@@ -1,29 +1,49 @@
 <h5>{L_STATUSINFORMATIONEN}</h5>
 <!-- BEGIN DIRECTORY_WARNINGS -->
-	{DIRECTORY_WARNINGS.MSD}
+	{DIRECTORY_WARNINGS.MSG}<br>
 <!-- END DIRECTORY_WARNINGS -->
 
+<!-- BEGIN NEW_VERSION_EXISTS -->
+	<br>
+	<span class="error">{L_NEW_MOD_VERSION_INFO}</span><br>
+	<span class="warnung"><strong>{L_UPDATED_IMPORTANT}</strong></span><br>
+	<br>
+	<a href="main.php?action=update" class="Formbutton">{L_UPDATE}</a><br>
+	<br>
+<!-- END NEW_VERSION_EXISTS -->
+
+<!-- BEGIN DIRECTORY_PROTECTION_STATUS -->
+	{DIRECTORY_PROTECTION_STATUS.MSG}<br>
+<!-- END DIRECTORY_PROTECTION_STATUS -->
+
+<!-- BEGIN DIRECTORY_PROTECTION_STATUS_ERROR -->
+	<span class="error">{DIRECTORY_PROTECTION_STATUS_ERROR.MSG}</span><br>
+<!-- END DIRECTORY_PROTECTION_STATUS_ERROR -->
+
 <!-- BEGIN HTACCESS_EXISTS -->
+	<br>
 	<a href="main.php?action=edithtaccess" class="Formbutton">{L_HTACC_EDIT}</a>&nbsp;
-	<a href="main.php?action=deletehtaccess" class="Formbutton">{L_DELETE_HTACCESS}</a><br>
+	<a href="main.php?action=deletehtaccess" class="Formbutton" onclick="if (!confirm('{L_HTACC_CONFIRM_DELETE}')) return false;">{L_DELETE_HTACCESS}</a><br>
 <!-- END HTACCESS_EXISTS -->
 
 <!-- BEGIN HTACCESS_DOESNT_EXISTS -->
-	<span class="error">{L_HTACC_PROPOSED}:</span>&nbsp;&nbsp;
+	<br>
 	<a href="main.php?action=schutz" class="Formbutton">{L_HTACC_CREATE}</a><br>
 <!-- END HTACCESS_DOESNT_EXISTS -->
 
 <h6>{L_VERSIONSINFORMATIONEN}</h6>
 <img src="css/{THEME}/pics/loveyourdata.gif" align="right" alt="love your data" title="love your data">
-{L_MSD_VERSION}: <strong>{MSD_VERSION}</strong><br>
+{L_MOD_VERSION}: <strong>{MOD_VERSION}</strong><br>
+
+<!-- BEGIN UPDATE_INFO -->
+	<span class="error">{UPDATE_INFO.MSG}</span><br>
+<!-- END UPDATE_INFO -->
+
 {L_OS}: <strong>{OS}</strong> ({OS_EXT})<br>
 {L_MYSQL_VERSION}: <strong>{MYSQL_VERSION}</strong><br>
 {L_PHP_VERSION}: <strong>{PHP_VERSION}</strong>&nbsp;&nbsp;{L_MEMORY}: <strong>{MEMORY}</strong>&nbsp;&nbsp;
 {L_MAX_EXECUTION_TIME}: <strong>{MAX_EXECUTION_TIME} {L_SECONDS}</strong>&nbsp;&nbsp;
 <a href="main.php?action=phpinfo" class="Formbutton">PHP-Info</a><br>
-<!-- BEGIN ZLIBBUG -->
-	<span class="error">{L_PHPBUG}</span><br>
-<!-- END ZLIBBUG -->
 
 <!-- BEGIN NO_FTP -->
 	<span class="error">{L_NOFTPPOSSIBLE}</span><br>
@@ -41,8 +61,8 @@
 
 <br clear="all">
 
-<h6>{L_MSD_INFO}</h6>
-{L_INFO_LOCATION} "<b>{SERVER_NAME}</b>" ({MSD_PATH})<br>
+<h6>{L_MOD_INFO}</h6>
+{L_INFO_LOCATION} "<b>{SERVER_NAME}</b>" ({MOD_PATH})<br>
 {L_INFO_ACTDB}: <strong>{DB}</strong><br>
 {L_BACKUPFILESANZAHL} <strong>{NR_OF_BACKUP_FILES}</strong>
 {L_BACKUPS} (<strong>{SIZE_BACKUPS}</strong>)<br>
diff --git a/msd/tpl/home/protection_create.tpl b/msd/tpl/home/protection_create.tpl
index 47571e81..6abde684 100644
--- a/msd/tpl/home/protection_create.tpl
+++ b/msd/tpl/home/protection_create.tpl
@@ -7,10 +7,9 @@
 	<meta http-equiv="pragma" content="no-cache">
 	<meta http-equiv="expires" content="0">
 	<meta http-equiv="cache-control" content="must-revalidate">
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 	<title>MyOOS [Dumper]</title>
 	<link rel="stylesheet" type="text/css" href="css/{THEME}/style.css">
-	<script language = "javascript" type = "text/javascript">
+	<script>
 		
 
 			function checkPasswords()
@@ -20,7 +19,7 @@
 					alert('{PASSWORDS_UNEQUAL}');
 					return false;
 				}
-				else return confirm('{HTACC_CONFIRM_DELETE}');
+				else return confirm('{HTACC_CONFIRM_CREATE}');
 			}	
 		</script>
 		<style type="text/css">
@@ -39,7 +38,7 @@
 
 <!-- BEGIN INPUT -->
 <form method="post" action="main.php?action=schutz" onSubmit="return checkPasswords();">
-<table style="width:600px;" border="0">
+<table style="width:700px;" border="0">
 <tr>
 	<td>{L_USERNAME}:</td>
 	<td colspan="2"><input type="text" name="username" id="username" size="50" value="{INPUT.USERNAME}" class="Formtext"></td>
@@ -64,43 +63,52 @@
 	</td>
 </tr>
 -->
+<tr><td>&nbsp;</td><td></td></tr>
 <tr>
 	<td>{L_ENCRYPTION_TYPE}:</td>
 	<td>
-	<table>
-		<tr>
-			<td>
-				<input class="radio" type="radio" name="type" id="type0" value="0"{INPUT.TYPE0_CHECKED}>
-			</td>
-			<td>
-				<label for="type0">{L_HTACC_CRYPT}</label>
-			</td>
-		</tr>
-		<tr>
-			<td>
-				<input class="radio" type="radio" name="type" id="type1" value="1"{INPUT.TYPE1_CHECKED}>
-			</td>
-			<td>
-				<label for="type1">{L_HTACC_MD5}</label>
-			</td>
-		</tr>
-		<tr>
-			<td>
-				<input class="radio" type="radio" name="type" id="type3" value="3"{INPUT.TYPE3_CHECKED}>
-			</td>
-			<td>
-				<label for="type3">{L_HTACC_SHA1}</label>
-			</td>
-		</tr>
-		<tr>
-			<td>
-				<input class="radio" type="radio" name="type" id="type2" value="2"{INPUT.TYPE2_CHECKED}>
-			</td>
-			<td>
-				<label for="type2">{L_HTACC_NO_ENCRYPTION}</label>
-			</td>
-		</tr>
-	</table>
+		<table>
+			<tr>
+				<td>
+					<input class="radio" type="radio" name="type" id="type4" value="4"{INPUT.TYPE4_CHECKED}>
+				</td>
+				<td>
+					<label for="type4">{L_HTACC_BCRYPT}</label>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<input class="radio" type="radio" name="type" id="type1" value="1"{INPUT.TYPE1_CHECKED}>
+				</td>
+				<td>
+					<label for="type1">{L_HTACC_MD5}</label>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<input class="radio" type="radio" name="type" id="type3" value="3"{INPUT.TYPE3_CHECKED}>
+				</td>
+				<td>
+					<label for="type3">{L_HTACC_SHA1}</label>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<input class="radio" type="radio" name="type" id="type0" value="0"{INPUT.TYPE0_CHECKED}>
+				</td>
+				<td>
+					<label for="type0">{L_HTACC_CRYPT}</label>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<input class="radio" type="radio" name="type" id="type2" value="2"{INPUT.TYPE2_CHECKED}>
+				</td>
+				<td>
+					<label for="type2">{L_HTACC_NO_ENCRYPTION}</label>
+				</td>
+			</tr>
+		</table>
 	</td>
 </tr>
 <tr>
@@ -116,10 +124,10 @@
 
 <!-- BEGIN CREATE_SUCCESS -->
 	<strong>{L_HTACC_CONTENT} .htaccess:</strong><br><br>
-	{CREATE_SUCCESS.HTACCESS}
+	<pre>{CREATE_SUCCESS.HTACCESS}</pre>
 
 	<br><br><strong>{L_HTACC_CONTENT} .htpasswd:</strong><br><br>
-	{CREATE_SUCCESS.HTPASSWD}
+	<pre>{CREATE_SUCCESS.HTPASSWD}</pre>
 	<br><br>
 	<a href="main.php" class="Formbutton">{L_HOME}</a>
 <!-- END CREATE_SUCCESS -->
diff --git a/msd/tpl/menu/footer.tpl b/msd/tpl/menu/footer.tpl
index 42d1b738..0795a1c9 100644
--- a/msd/tpl/menu/footer.tpl
+++ b/msd/tpl/menu/footer.tpl
@@ -1,9 +1,9 @@
 <!-- BEGIN DB_NAME_TRUE -->
-<script language="javascript" type="text/javascript">setMenuActive('m2');parent.MyOOS_Dumper_content.location.href='./config_overview.php';</script>
+<script>setMenuActive('m2');parent.MyOOS_Dumper_content.location.href='./config_overview.php';</script>
 <!-- END DB_NAME_TRUE -->
 
 <!-- BEGIN DB_NAME_FALSE -->
-<script language="javascript" type="text/javascript">setactiveMenuFromContent();</script>
+<script>setactiveMenuFromContent();</script>
 <!-- END DB_NAME_FALSE -->
 
 </body>
diff --git a/msd/tpl/menu/header.tpl b/msd/tpl/menu/header.tpl
index af993a24..36a62757 100644
--- a/msd/tpl/menu/header.tpl
+++ b/msd/tpl/menu/header.tpl
@@ -1,11 +1,11 @@
-{MSD_HEADER}
-{MSD_HEADLINE}
+{MOD_HEADER}
+{MOD_HEADLINE}
 <!-- BEGIN CONFIG_REFRESH_TRUE -->
 	{CONFIG_REFRESH}
 <!-- END CONFIG_REFRESH_TRUE -->
 
 <!-- BEGIN DB_REFRESH -->
-	<script language="JavaScript" type="text/javascript">
+	<script>
 	var curl=parent.MyOOS_Dumper_content.location.href.split("/");
 	var cdatei=curl.pop();
 	var ca=cdatei.split(".");
@@ -21,12 +21,12 @@
 <!-- END DB_REFRESH -->
 
 <!-- BEGIN CHANGED_LANGUAGE -->
-	<script language="JavaScript" type="text/javascript">self.location.href='menu.php';</script>
+	<script>self.location.href='menu.php';</script>
 <!-- END CHANGED_LANGUAGE -->
-<a href="http://www.mysqldumper.net" target="_blank" title="{L_VISIT_HOMEPAGE} {CONFIG_HOMEPAGE}"><img src="css/{CONFIG_THEME}/pics/h1_logo.gif" alt="MySQLDumper - Homepage"></a>
+<a href="{CONFIG_HOMEPAGE}" target="_blank" title="{L_VISIT_HOMEPAGE} {CONFIG_HOMEPAGE}"><img src="css/{CONFIG_THEME}/pics/h1_logo.gif" alt="MyOOS [Dumper] - Homepage"></a>
 <div id="version">
 	<a href="main.php" title="{L_HOME}" target="MyOOS_Dumper_content" style="text-decoration: none">
-		<span class="version-line">Version {MSD_VERSION}</span>
+		<span class="version-line">Version {MOD_VERSION}</span>
 		<img src="css/{CONFIG_THEME}/pics/navi_bg.jpg" alt="">
 	</a>
 </div>
diff --git a/msd/tpl/restore_select_tables.tpl b/msd/tpl/restore_select_tables.tpl
index 5180f5e7..433237f1 100644
--- a/msd/tpl/restore_select_tables.tpl
+++ b/msd/tpl/restore_select_tables.tpl
@@ -19,11 +19,11 @@
 		<th>{L_LAST_UPDATE}</th>
 		<th>{L_TABLE_TYPE}</th>
 	</tr>
-	<!-- BEGIN NO_MSD_BACKUP -->
+	<!-- BEGIN NO_MOD_BACKUP -->
 	<tr>
-		<td colspan="7">{L_NO_MSD_BACKUP}</td>
+		<td colspan="7">{L_NO_MOD_BACKUP}</td>
 	</tr>
-	<!-- END NO_MSD_BACKUP -->
+	<!-- END NO_MOD_BACKUP -->
 	
 	<!-- BEGIN ROW -->
 	<tr class="{ROW.CLASS}">
diff --git a/msd/tpl/sqlbrowser/mysql_search.tpl b/msd/tpl/sqlbrowser/mysql_search.tpl
index ee9b0950..94c8916b 100644
--- a/msd/tpl/sqlbrowser/mysql_search.tpl
+++ b/msd/tpl/sqlbrowser/mysql_search.tpl
@@ -70,4 +70,4 @@
 <!-- END NO_ENTRIES -->
 </div>
 
-<script type="text/javascript">document.suche.suchbegriffe.focus();</script>
+<script>document.suche.suchbegriffe.focus();</script>
diff --git a/msd/tpl/sqlbrowser/sql_record_insert_inputmask.tpl b/msd/tpl/sqlbrowser/sql_record_insert_inputmask.tpl
index 6da74516..b2ad620f 100644
--- a/msd/tpl/sqlbrowser/sql_record_insert_inputmask.tpl
+++ b/msd/tpl/sqlbrowser/sql_record_insert_inputmask.tpl
@@ -1,4 +1,4 @@
-<script language="javascript" type="text/javascript">
+<script>
 function switch_area(textarea)
 {
 	var t=document.getElementById('area_'+textarea);
diff --git a/msd/tpl/sqlbrowser/sql_record_update_inputmask.tpl b/msd/tpl/sqlbrowser/sql_record_update_inputmask.tpl
index 13bac061..35ab97fc 100644
--- a/msd/tpl/sqlbrowser/sql_record_update_inputmask.tpl
+++ b/msd/tpl/sqlbrowser/sql_record_update_inputmask.tpl
@@ -1,4 +1,4 @@
-<script language="javascript" type="text/javascript">
+<script>
 function switch_area(textarea)
 {
 	var t=document.getElementById('area_'+textarea);
diff --git a/msd/vendor/autoload.php b/msd/vendor/autoload.php
new file mode 100644
index 00000000..50e99eb6
--- /dev/null
+++ b/msd/vendor/autoload.php
@@ -0,0 +1,25 @@
+<?php
+
+// autoload.php @generated by Composer
+
+if (PHP_VERSION_ID < 50600) {
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, $err);
+        } elseif (!headers_sent()) {
+            echo $err;
+        }
+    }
+    trigger_error(
+        $err,
+        E_USER_ERROR
+    );
+}
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInit2352399418895b7bd82ed699298d379a::getLoader();
diff --git a/msd/vendor/composer/ClassLoader.php b/msd/vendor/composer/ClassLoader.php
new file mode 100644
index 00000000..fd56bd7d
--- /dev/null
+++ b/msd/vendor/composer/ClassLoader.php
@@ -0,0 +1,581 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ *     $loader = new \Composer\Autoload\ClassLoader();
+ *
+ *     // register classes with namespaces
+ *     $loader->add('Symfony\Component', __DIR__.'/component');
+ *     $loader->add('Symfony',           __DIR__.'/framework');
+ *
+ *     // activate the autoloader
+ *     $loader->register();
+ *
+ *     // to enable searching the include path (eg. for PEAR packages)
+ *     $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @see    https://www.php-fig.org/psr/psr-0/
+ * @see    https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+    /** @var \Closure(string):void */
+    private static $includeFile;
+
+    /** @var ?string */
+    private $vendorDir;
+
+    // PSR-4
+    /**
+     * @var array[]
+     * @psalm-var array<string, array<string, int>>
+     */
+    private $prefixLengthsPsr4 = array();
+    /**
+     * @var array[]
+     * @psalm-var array<string, array<int, string>>
+     */
+    private $prefixDirsPsr4 = array();
+    /**
+     * @var array[]
+     * @psalm-var array<string, string>
+     */
+    private $fallbackDirsPsr4 = array();
+
+    // PSR-0
+    /**
+     * @var array[]
+     * @psalm-var array<string, array<string, string[]>>
+     */
+    private $prefixesPsr0 = array();
+    /**
+     * @var array[]
+     * @psalm-var array<string, string>
+     */
+    private $fallbackDirsPsr0 = array();
+
+    /** @var bool */
+    private $useIncludePath = false;
+
+    /**
+     * @var string[]
+     * @psalm-var array<string, string>
+     */
+    private $classMap = array();
+
+    /** @var bool */
+    private $classMapAuthoritative = false;
+
+    /**
+     * @var bool[]
+     * @psalm-var array<string, bool>
+     */
+    private $missingClasses = array();
+
+    /** @var ?string */
+    private $apcuPrefix;
+
+    /**
+     * @var self[]
+     */
+    private static $registeredLoaders = array();
+
+    /**
+     * @param ?string $vendorDir
+     */
+    public function __construct($vendorDir = null)
+    {
+        $this->vendorDir = $vendorDir;
+        self::initializeIncludeClosure();
+    }
+
+    /**
+     * @return string[]
+     */
+    public function getPrefixes()
+    {
+        if (!empty($this->prefixesPsr0)) {
+            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+        }
+
+        return array();
+    }
+
+    /**
+     * @return array[]
+     * @psalm-return array<string, array<int, string>>
+     */
+    public function getPrefixesPsr4()
+    {
+        return $this->prefixDirsPsr4;
+    }
+
+    /**
+     * @return array[]
+     * @psalm-return array<string, string>
+     */
+    public function getFallbackDirs()
+    {
+        return $this->fallbackDirsPsr0;
+    }
+
+    /**
+     * @return array[]
+     * @psalm-return array<string, string>
+     */
+    public function getFallbackDirsPsr4()
+    {
+        return $this->fallbackDirsPsr4;
+    }
+
+    /**
+     * @return string[] Array of classname => path
+     * @psalm-return array<string, string>
+     */
+    public function getClassMap()
+    {
+        return $this->classMap;
+    }
+
+    /**
+     * @param string[] $classMap Class to filename map
+     * @psalm-param array<string, string> $classMap
+     *
+     * @return void
+     */
+    public function addClassMap(array $classMap)
+    {
+        if ($this->classMap) {
+            $this->classMap = array_merge($this->classMap, $classMap);
+        } else {
+            $this->classMap = $classMap;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix, either
+     * appending or prepending to the ones previously set for this prefix.
+     *
+     * @param string          $prefix  The prefix
+     * @param string[]|string $paths   The PSR-0 root directories
+     * @param bool            $prepend Whether to prepend the directories
+     *
+     * @return void
+     */
+    public function add($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            if ($prepend) {
+                $this->fallbackDirsPsr0 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr0
+                );
+            } else {
+                $this->fallbackDirsPsr0 = array_merge(
+                    $this->fallbackDirsPsr0,
+                    (array) $paths
+                );
+            }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset($this->prefixesPsr0[$first][$prefix])) {
+            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                $this->prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace, either
+     * appending or prepending to the ones previously set for this namespace.
+     *
+     * @param string          $prefix  The prefix/namespace, with trailing '\\'
+     * @param string[]|string $paths   The PSR-4 base directories
+     * @param bool            $prepend Whether to prepend the directories
+     *
+     * @throws \InvalidArgumentException
+     *
+     * @return void
+     */
+    public function addPsr4($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            // Register directories for the root namespace.
+            if ($prepend) {
+                $this->fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr4
+                );
+            } else {
+                $this->fallbackDirsPsr4 = array_merge(
+                    $this->fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
+        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+            // Register directories for a new namespace.
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        } elseif ($prepend) {
+            // Prepend directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixDirsPsr4[$prefix]
+            );
+        } else {
+            // Append directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                $this->prefixDirsPsr4[$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix,
+     * replacing any others previously set for this prefix.
+     *
+     * @param string          $prefix The prefix
+     * @param string[]|string $paths  The PSR-0 base directories
+     *
+     * @return void
+     */
+    public function set($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr0 = (array) $paths;
+        } else {
+            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace,
+     * replacing any others previously set for this namespace.
+     *
+     * @param string          $prefix The prefix/namespace, with trailing '\\'
+     * @param string[]|string $paths  The PSR-4 base directories
+     *
+     * @throws \InvalidArgumentException
+     *
+     * @return void
+     */
+    public function setPsr4($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr4 = (array) $paths;
+        } else {
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Turns on searching the include path for class files.
+     *
+     * @param bool $useIncludePath
+     *
+     * @return void
+     */
+    public function setUseIncludePath($useIncludePath)
+    {
+        $this->useIncludePath = $useIncludePath;
+    }
+
+    /**
+     * Can be used to check if the autoloader uses the include path to check
+     * for classes.
+     *
+     * @return bool
+     */
+    public function getUseIncludePath()
+    {
+        return $this->useIncludePath;
+    }
+
+    /**
+     * Turns off searching the prefix and fallback directories for classes
+     * that have not been registered with the class map.
+     *
+     * @param bool $classMapAuthoritative
+     *
+     * @return void
+     */
+    public function setClassMapAuthoritative($classMapAuthoritative)
+    {
+        $this->classMapAuthoritative = $classMapAuthoritative;
+    }
+
+    /**
+     * Should class lookup fail if not found in the current class map?
+     *
+     * @return bool
+     */
+    public function isClassMapAuthoritative()
+    {
+        return $this->classMapAuthoritative;
+    }
+
+    /**
+     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+     *
+     * @param string|null $apcuPrefix
+     *
+     * @return void
+     */
+    public function setApcuPrefix($apcuPrefix)
+    {
+        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+    }
+
+    /**
+     * The APCu prefix in use, or null if APCu caching is not enabled.
+     *
+     * @return string|null
+     */
+    public function getApcuPrefix()
+    {
+        return $this->apcuPrefix;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param bool $prepend Whether to prepend the autoloader or not
+     *
+     * @return void
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+        if (null === $this->vendorDir) {
+            return;
+        }
+
+        if ($prepend) {
+            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+        } else {
+            unset(self::$registeredLoaders[$this->vendorDir]);
+            self::$registeredLoaders[$this->vendorDir] = $this;
+        }
+    }
+
+    /**
+     * Unregisters this instance as an autoloader.
+     *
+     * @return void
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+
+        if (null !== $this->vendorDir) {
+            unset(self::$registeredLoaders[$this->vendorDir]);
+        }
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param  string    $class The name of the class
+     * @return true|null True if loaded, null otherwise
+     */
+    public function loadClass($class)
+    {
+        if ($file = $this->findFile($class)) {
+            (self::$includeFile)($file);
+
+            return true;
+        }
+
+        return null;
+    }
+
+    /**
+     * Finds the path to the file where the class is defined.
+     *
+     * @param string $class The name of the class
+     *
+     * @return string|false The path if found, false otherwise
+     */
+    public function findFile($class)
+    {
+        // class map lookup
+        if (isset($this->classMap[$class])) {
+            return $this->classMap[$class];
+        }
+        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+            return false;
+        }
+        if (null !== $this->apcuPrefix) {
+            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+            if ($hit) {
+                return $file;
+            }
+        }
+
+        $file = $this->findFileWithExtension($class, '.php');
+
+        // Search for Hack files if we are running on HHVM
+        if (false === $file && defined('HHVM_VERSION')) {
+            $file = $this->findFileWithExtension($class, '.hh');
+        }
+
+        if (null !== $this->apcuPrefix) {
+            apcu_add($this->apcuPrefix.$class, $file);
+        }
+
+        if (false === $file) {
+            // Remember that this class does not exist.
+            $this->missingClasses[$class] = true;
+        }
+
+        return $file;
+    }
+
+    /**
+     * Returns the currently registered loaders indexed by their corresponding vendor directories.
+     *
+     * @return self[]
+     */
+    public static function getRegisteredLoaders()
+    {
+        return self::$registeredLoaders;
+    }
+
+    /**
+     * @param  string       $class
+     * @param  string       $ext
+     * @return string|false
+     */
+    private function findFileWithExtension($class, $ext)
+    {
+        // PSR-4 lookup
+        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+        $first = $class[0];
+        if (isset($this->prefixLengthsPsr4[$first])) {
+            $subPath = $class;
+            while (false !== $lastPos = strrpos($subPath, '\\')) {
+                $subPath = substr($subPath, 0, $lastPos);
+                $search = $subPath . '\\';
+                if (isset($this->prefixDirsPsr4[$search])) {
+                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
+                        if (file_exists($file = $dir . $pathEnd)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-4 fallback dirs
+        foreach ($this->fallbackDirsPsr4 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 lookup
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+        } else {
+            // PEAR-like class name
+            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+        }
+
+        if (isset($this->prefixesPsr0[$first])) {
+            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($dirs as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-0 fallback dirs
+        foreach ($this->fallbackDirsPsr0 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 include paths.
+        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+            return $file;
+        }
+
+        return false;
+    }
+
+    private static function initializeIncludeClosure(): void
+    {
+        if (self::$includeFile !== null) {
+            return;
+        }
+
+        /**
+         * Scope isolated include.
+         *
+         * Prevents access to $this/self from included files.
+         *
+         * @param  string $file
+         * @return void
+         */
+        self::$includeFile = static function($file) {
+            include $file;
+        };
+    }
+}
diff --git a/msd/vendor/composer/InstalledVersions.php b/msd/vendor/composer/InstalledVersions.php
new file mode 100644
index 00000000..c6b54af7
--- /dev/null
+++ b/msd/vendor/composer/InstalledVersions.php
@@ -0,0 +1,352 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer;
+
+use Composer\Autoload\ClassLoader;
+use Composer\Semver\VersionParser;
+
+/**
+ * This class is copied in every Composer installed project and available to all
+ *
+ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
+ *
+ * To require its presence, you can require `composer-runtime-api ^2.0`
+ *
+ * @final
+ */
+class InstalledVersions
+{
+    /**
+     * @var mixed[]|null
+     * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
+     */
+    private static $installed;
+
+    /**
+     * @var bool|null
+     */
+    private static $canGetVendors;
+
+    /**
+     * @var array[]
+     * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+     */
+    private static $installedByVendor = array();
+
+    /**
+     * Returns a list of all package names which are present, either by being installed, replaced or provided
+     *
+     * @return string[]
+     * @psalm-return list<string>
+     */
+    public static function getInstalledPackages()
+    {
+        $packages = array();
+        foreach (self::getInstalled() as $installed) {
+            $packages[] = array_keys($installed['versions']);
+        }
+
+        if (1 === \count($packages)) {
+            return $packages[0];
+        }
+
+        return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+    }
+
+    /**
+     * Returns a list of all package names with a specific type e.g. 'library'
+     *
+     * @param  string   $type
+     * @return string[]
+     * @psalm-return list<string>
+     */
+    public static function getInstalledPackagesByType($type)
+    {
+        $packagesByType = array();
+
+        foreach (self::getInstalled() as $installed) {
+            foreach ($installed['versions'] as $name => $package) {
+                if (isset($package['type']) && $package['type'] === $type) {
+                    $packagesByType[] = $name;
+                }
+            }
+        }
+
+        return $packagesByType;
+    }
+
+    /**
+     * Checks whether the given package is installed
+     *
+     * This also returns true if the package name is provided or replaced by another package
+     *
+     * @param  string $packageName
+     * @param  bool   $includeDevRequirements
+     * @return bool
+     */
+    public static function isInstalled($packageName, $includeDevRequirements = true)
+    {
+        foreach (self::getInstalled() as $installed) {
+            if (isset($installed['versions'][$packageName])) {
+                return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks whether the given package satisfies a version constraint
+     *
+     * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
+     *
+     *   Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
+     *
+     * @param  VersionParser $parser      Install composer/semver to have access to this class and functionality
+     * @param  string        $packageName
+     * @param  string|null   $constraint  A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
+     * @return bool
+     */
+    public static function satisfies(VersionParser $parser, $packageName, $constraint)
+    {
+        $constraint = $parser->parseConstraints($constraint);
+        $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+        return $provided->matches($constraint);
+    }
+
+    /**
+     * Returns a version constraint representing all the range(s) which are installed for a given package
+     *
+     * It is easier to use this via isInstalled() with the $constraint argument if you need to check
+     * whether a given version of a package is installed, and not just whether it exists
+     *
+     * @param  string $packageName
+     * @return string Version constraint usable with composer/semver
+     */
+    public static function getVersionRanges($packageName)
+    {
+        foreach (self::getInstalled() as $installed) {
+            if (!isset($installed['versions'][$packageName])) {
+                continue;
+            }
+
+            $ranges = array();
+            if (isset($installed['versions'][$packageName]['pretty_version'])) {
+                $ranges[] = $installed['versions'][$packageName]['pretty_version'];
+            }
+            if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+                $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+            }
+            if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+                $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+            }
+            if (array_key_exists('provided', $installed['versions'][$packageName])) {
+                $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+            }
+
+            return implode(' || ', $ranges);
+        }
+
+        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+    }
+
+    /**
+     * @param  string      $packageName
+     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+     */
+    public static function getVersion($packageName)
+    {
+        foreach (self::getInstalled() as $installed) {
+            if (!isset($installed['versions'][$packageName])) {
+                continue;
+            }
+
+            if (!isset($installed['versions'][$packageName]['version'])) {
+                return null;
+            }
+
+            return $installed['versions'][$packageName]['version'];
+        }
+
+        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+    }
+
+    /**
+     * @param  string      $packageName
+     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
+     */
+    public static function getPrettyVersion($packageName)
+    {
+        foreach (self::getInstalled() as $installed) {
+            if (!isset($installed['versions'][$packageName])) {
+                continue;
+            }
+
+            if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+                return null;
+            }
+
+            return $installed['versions'][$packageName]['pretty_version'];
+        }
+
+        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+    }
+
+    /**
+     * @param  string      $packageName
+     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
+     */
+    public static function getReference($packageName)
+    {
+        foreach (self::getInstalled() as $installed) {
+            if (!isset($installed['versions'][$packageName])) {
+                continue;
+            }
+
+            if (!isset($installed['versions'][$packageName]['reference'])) {
+                return null;
+            }
+
+            return $installed['versions'][$packageName]['reference'];
+        }
+
+        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+    }
+
+    /**
+     * @param  string      $packageName
+     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
+     */
+    public static function getInstallPath($packageName)
+    {
+        foreach (self::getInstalled() as $installed) {
+            if (!isset($installed['versions'][$packageName])) {
+                continue;
+            }
+
+            return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
+        }
+
+        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+    }
+
+    /**
+     * @return array
+     * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
+     */
+    public static function getRootPackage()
+    {
+        $installed = self::getInstalled();
+
+        return $installed[0]['root'];
+    }
+
+    /**
+     * Returns the raw installed.php data for custom implementations
+     *
+     * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
+     * @return array[]
+     * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
+     */
+    public static function getRawData()
+    {
+        @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
+
+        if (null === self::$installed) {
+            // only require the installed.php file if this file is loaded from its dumped location,
+            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+            if (substr(__DIR__, -8, 1) !== 'C') {
+                self::$installed = include __DIR__ . '/installed.php';
+            } else {
+                self::$installed = array();
+            }
+        }
+
+        return self::$installed;
+    }
+
+    /**
+     * Returns the raw data of all installed.php which are currently loaded for custom implementations
+     *
+     * @return array[]
+     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+     */
+    public static function getAllRawData()
+    {
+        return self::getInstalled();
+    }
+
+    /**
+     * Lets you reload the static array from another file
+     *
+     * This is only useful for complex integrations in which a project needs to use
+     * this class but then also needs to execute another project's autoloader in process,
+     * and wants to ensure both projects have access to their version of installed.php.
+     *
+     * A typical case would be PHPUnit, where it would need to make sure it reads all
+     * the data it needs from this class, then call reload() with
+     * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
+     * the project in which it runs can then also use this class safely, without
+     * interference between PHPUnit's dependencies and the project's dependencies.
+     *
+     * @param  array[] $data A vendor/composer/installed.php data set
+     * @return void
+     *
+     * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
+     */
+    public static function reload($data)
+    {
+        self::$installed = $data;
+        self::$installedByVendor = array();
+    }
+
+    /**
+     * @return array[]
+     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
+     */
+    private static function getInstalled()
+    {
+        if (null === self::$canGetVendors) {
+            self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+        }
+
+        $installed = array();
+
+        if (self::$canGetVendors) {
+            foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+                if (isset(self::$installedByVendor[$vendorDir])) {
+                    $installed[] = self::$installedByVendor[$vendorDir];
+                } elseif (is_file($vendorDir.'/composer/installed.php')) {
+                    $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
+                    if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
+                        self::$installed = $installed[count($installed) - 1];
+                    }
+                }
+            }
+        }
+
+        if (null === self::$installed) {
+            // only require the installed.php file if this file is loaded from its dumped location,
+            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
+            if (substr(__DIR__, -8, 1) !== 'C') {
+                self::$installed = require __DIR__ . '/installed.php';
+            } else {
+                self::$installed = array();
+            }
+        }
+        $installed[] = self::$installed;
+
+        return $installed;
+    }
+}
diff --git a/msd/vendor/composer/LICENSE b/msd/vendor/composer/LICENSE
new file mode 100644
index 00000000..f27399a0
--- /dev/null
+++ b/msd/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/msd/vendor/composer/autoload_classmap.php b/msd/vendor/composer/autoload_classmap.php
new file mode 100644
index 00000000..0fb0a2c1
--- /dev/null
+++ b/msd/vendor/composer/autoload_classmap.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = dirname($vendorDir);
+
+return array(
+    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+);
diff --git a/msd/vendor/composer/autoload_files.php b/msd/vendor/composer/autoload_files.php
new file mode 100644
index 00000000..eec29ec9
--- /dev/null
+++ b/msd/vendor/composer/autoload_files.php
@@ -0,0 +1,10 @@
+<?php
+
+// autoload_files.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = dirname($vendorDir);
+
+return array(
+    'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
+);
diff --git a/msd/vendor/composer/autoload_namespaces.php b/msd/vendor/composer/autoload_namespaces.php
new file mode 100644
index 00000000..15a2ff3a
--- /dev/null
+++ b/msd/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = dirname($vendorDir);
+
+return array(
+);
diff --git a/msd/vendor/composer/autoload_psr4.php b/msd/vendor/composer/autoload_psr4.php
new file mode 100644
index 00000000..840860ea
--- /dev/null
+++ b/msd/vendor/composer/autoload_psr4.php
@@ -0,0 +1,19 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(__DIR__);
+$baseDir = dirname($vendorDir);
+
+return array(
+    'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
+    'VisualAppeal\\' => array($vendorDir . '/visualappeal/php-auto-update/src'),
+    'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
+    'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
+    'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
+    'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
+    'League\\Flysystem\\PhpseclibV2\\' => array($vendorDir . '/league/flysystem-sftp'),
+    'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
+    'Desarrolla2\\Cache\\' => array($vendorDir . '/desarrolla2/cache/src'),
+    'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
+);
diff --git a/msd/vendor/composer/autoload_real.php b/msd/vendor/composer/autoload_real.php
new file mode 100644
index 00000000..0691abd8
--- /dev/null
+++ b/msd/vendor/composer/autoload_real.php
@@ -0,0 +1,50 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInit2352399418895b7bd82ed699298d379a
+{
+    private static $loader;
+
+    public static function loadClassLoader($class)
+    {
+        if ('Composer\Autoload\ClassLoader' === $class) {
+            require __DIR__ . '/ClassLoader.php';
+        }
+    }
+
+    /**
+     * @return \Composer\Autoload\ClassLoader
+     */
+    public static function getLoader()
+    {
+        if (null !== self::$loader) {
+            return self::$loader;
+        }
+
+        require __DIR__ . '/platform_check.php';
+
+        spl_autoload_register(array('ComposerAutoloaderInit2352399418895b7bd82ed699298d379a', 'loadClassLoader'), true, true);
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
+        spl_autoload_unregister(array('ComposerAutoloaderInit2352399418895b7bd82ed699298d379a', 'loadClassLoader'));
+
+        require __DIR__ . '/autoload_static.php';
+        call_user_func(\Composer\Autoload\ComposerStaticInit2352399418895b7bd82ed699298d379a::getInitializer($loader));
+
+        $loader->register(true);
+
+        $filesToLoad = \Composer\Autoload\ComposerStaticInit2352399418895b7bd82ed699298d379a::$files;
+        $requireFile = static function ($fileIdentifier, $file) {
+            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+                $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+
+                require $file;
+            }
+        };
+        foreach ($filesToLoad as $fileIdentifier => $file) {
+            ($requireFile)($fileIdentifier, $file);
+        }
+
+        return $loader;
+    }
+}
diff --git a/msd/vendor/composer/autoload_static.php b/msd/vendor/composer/autoload_static.php
new file mode 100644
index 00000000..28c5c787
--- /dev/null
+++ b/msd/vendor/composer/autoload_static.php
@@ -0,0 +1,103 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInit2352399418895b7bd82ed699298d379a
+{
+    public static $files = array (
+        'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
+    );
+
+    public static $prefixLengthsPsr4 = array (
+        'p' => 
+        array (
+            'phpseclib\\' => 10,
+        ),
+        'V' => 
+        array (
+            'VisualAppeal\\' => 13,
+        ),
+        'P' => 
+        array (
+            'Psr\\SimpleCache\\' => 16,
+            'Psr\\Log\\' => 8,
+        ),
+        'M' => 
+        array (
+            'Monolog\\' => 8,
+        ),
+        'L' => 
+        array (
+            'League\\MimeTypeDetection\\' => 25,
+            'League\\Flysystem\\PhpseclibV2\\' => 29,
+            'League\\Flysystem\\' => 17,
+        ),
+        'D' => 
+        array (
+            'Desarrolla2\\Cache\\' => 18,
+        ),
+        'C' => 
+        array (
+            'Composer\\Semver\\' => 16,
+        ),
+    );
+
+    public static $prefixDirsPsr4 = array (
+        'phpseclib\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib',
+        ),
+        'VisualAppeal\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/visualappeal/php-auto-update/src',
+        ),
+        'Psr\\SimpleCache\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/simple-cache/src',
+        ),
+        'Psr\\Log\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
+        ),
+        'Monolog\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog',
+        ),
+        'League\\MimeTypeDetection\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/league/mime-type-detection/src',
+        ),
+        'League\\Flysystem\\PhpseclibV2\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/league/flysystem-sftp',
+        ),
+        'League\\Flysystem\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/league/flysystem/src',
+        ),
+        'Desarrolla2\\Cache\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/desarrolla2/cache/src',
+        ),
+        'Composer\\Semver\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/composer/semver/src',
+        ),
+    );
+
+    public static $classMap = array (
+        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+    );
+
+    public static function getInitializer(ClassLoader $loader)
+    {
+        return \Closure::bind(function () use ($loader) {
+            $loader->prefixLengthsPsr4 = ComposerStaticInit2352399418895b7bd82ed699298d379a::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInit2352399418895b7bd82ed699298d379a::$prefixDirsPsr4;
+            $loader->classMap = ComposerStaticInit2352399418895b7bd82ed699298d379a::$classMap;
+
+        }, null, ClassLoader::class);
+    }
+}
diff --git a/msd/vendor/composer/installed.json b/msd/vendor/composer/installed.json
new file mode 100644
index 00000000..81f260f3
--- /dev/null
+++ b/msd/vendor/composer/installed.json
@@ -0,0 +1,763 @@
+{
+    "packages": [
+        {
+            "name": "composer/semver",
+            "version": "3.3.2",
+            "version_normalized": "3.3.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/semver.git",
+                "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
+                "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^1.4",
+                "symfony/phpunit-bridge": "^4.2 || ^5"
+            },
+            "time": "2022-04-01T19:23:25+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "3.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Semver\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "Semver library that offers utilities, version constraint parsing and validation.",
+            "keywords": [
+                "semantic",
+                "semver",
+                "validation",
+                "versioning"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/semver/issues",
+                "source": "https://github.com/composer/semver/tree/3.3.2"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "./semver"
+        },
+        {
+            "name": "desarrolla2/cache",
+            "version": "v3.0.2",
+            "version_normalized": "3.0.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/desarrolla2/Cache.git",
+                "reference": "0b8f985d09abfc04a2c1535943f6f07b7206161a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/desarrolla2/Cache/zipball/0b8f985d09abfc04a2c1535943f6f07b7206161a",
+                "reference": "0b8f985d09abfc04a2c1535943f6f07b7206161a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.0",
+                "psr/simple-cache": "^1.0"
+            },
+            "provide": {
+                "psr/simple-cache-implementation": "1.0"
+            },
+            "require-dev": {
+                "cache/integration-tests": "dev-master",
+                "ext-apcu": "*",
+                "ext-json": "*",
+                "ext-memcached": "*",
+                "ext-mysqli": "*",
+                "mikey179/vfsstream": "v1.6.8",
+                "mongodb/mongodb": "^1.3",
+                "phpstan/phpstan": "^0.12.29",
+                "phpunit/phpunit": "^8.3 || ^9.0",
+                "predis/predis": "~1.0.0",
+                "symfony/phpunit-bridge": "^5.2"
+            },
+            "time": "2022-03-27T23:04:06+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Desarrolla2\\Cache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Daniel González",
+                    "homepage": "http://desarrolla2.com/"
+                },
+                {
+                    "name": "Arnold Daniels",
+                    "homepage": "https://jasny.net/"
+                }
+            ],
+            "description": "Provides an cache interface for several adapters Apc, Apcu, File, Mongo, Memcache, Memcached, Mysql, Mongo, Redis is supported.",
+            "homepage": "https://github.com/desarrolla2/Cache/",
+            "keywords": [
+                "apc",
+                "apcu",
+                "cache",
+                "file",
+                "memcache",
+                "memcached",
+                "mongo",
+                "mysql",
+                "psr-16",
+                "redis",
+                "simple-cache"
+            ],
+            "support": {
+                "issues": "https://github.com/desarrolla2/Cache/issues",
+                "source": "https://github.com/desarrolla2/Cache/tree/v3.0.2"
+            },
+            "install-path": "../desarrolla2/cache"
+        },
+        {
+            "name": "league/flysystem",
+            "version": "2.5.0",
+            "version_normalized": "2.5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem.git",
+                "reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8aaffb653c5777781b0f7f69a5d937baf7ab6cdb",
+                "reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "league/mime-type-detection": "^1.0.0",
+                "php": "^7.2 || ^8.0"
+            },
+            "conflict": {
+                "guzzlehttp/ringphp": "<1.1.1"
+            },
+            "require-dev": {
+                "async-aws/s3": "^1.5",
+                "async-aws/simple-s3": "^1.0",
+                "aws/aws-sdk-php": "^3.132.4",
+                "composer/semver": "^3.0",
+                "ext-fileinfo": "*",
+                "ext-ftp": "*",
+                "friendsofphp/php-cs-fixer": "^3.2",
+                "google/cloud-storage": "^1.23",
+                "phpseclib/phpseclib": "^2.0",
+                "phpstan/phpstan": "^0.12.26",
+                "phpunit/phpunit": "^8.5 || ^9.4",
+                "sabre/dav": "^4.1"
+            },
+            "time": "2022-09-17T21:02:32+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "League\\Flysystem\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
+                }
+            ],
+            "description": "File storage abstraction for PHP",
+            "keywords": [
+                "WebDAV",
+                "aws",
+                "cloud",
+                "file",
+                "files",
+                "filesystem",
+                "filesystems",
+                "ftp",
+                "s3",
+                "sftp",
+                "storage"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/flysystem/issues",
+                "source": "https://github.com/thephpleague/flysystem/tree/2.5.0"
+            },
+            "funding": [
+                {
+                    "url": "https://ecologi.com/frankdejonge",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/frankdejonge",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../league/flysystem"
+        },
+        {
+            "name": "league/flysystem-sftp",
+            "version": "2.5.0",
+            "version_normalized": "2.5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem-sftp.git",
+                "reference": "e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-sftp/zipball/e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7",
+                "reference": "e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7",
+                "shasum": ""
+            },
+            "require": {
+                "league/flysystem": "^2.0.0",
+                "league/mime-type-detection": "^1.0.0",
+                "php": "^7.2 || ^8.0",
+                "phpseclib/phpseclib": "^2.0"
+            },
+            "time": "2022-04-27T17:27:27+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "League\\Flysystem\\PhpseclibV2\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
+                }
+            ],
+            "description": "SFTP filesystem adapter for Flysystem.",
+            "keywords": [
+                "Flysystem",
+                "file",
+                "files",
+                "filesystem",
+                "sftp"
+            ],
+            "support": {
+                "issues": "https://github.com/thephpleague/flysystem-sftp/issues",
+                "source": "https://github.com/thephpleague/flysystem-sftp/tree/2.5.0"
+            },
+            "funding": [
+                {
+                    "url": "https://ecologi.com/frankdejonge",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/frankdejonge",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+                    "type": "tidelift"
+                }
+            ],
+            "abandoned": "league/flysystem-sftp-v3",
+            "install-path": "../league/flysystem-sftp"
+        },
+        {
+            "name": "league/mime-type-detection",
+            "version": "1.11.0",
+            "version_normalized": "1.11.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/mime-type-detection.git",
+                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+                "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+                "shasum": ""
+            },
+            "require": {
+                "ext-fileinfo": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^3.2",
+                "phpstan/phpstan": "^0.12.68",
+                "phpunit/phpunit": "^8.5.8 || ^9.3"
+            },
+            "time": "2022-04-17T13:12:02+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "League\\MimeTypeDetection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Frank de Jonge",
+                    "email": "info@frankdejonge.nl"
+                }
+            ],
+            "description": "Mime-type detection for Flysystem",
+            "support": {
+                "issues": "https://github.com/thephpleague/mime-type-detection/issues",
+                "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/frankdejonge",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../league/mime-type-detection"
+        },
+        {
+            "name": "monolog/monolog",
+            "version": "2.8.0",
+            "version_normalized": "2.8.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/monolog.git",
+                "reference": "720488632c590286b88b80e62aa3d3d551ad4a50"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50",
+                "reference": "720488632c590286b88b80e62aa3d3d551ad4a50",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2",
+                "psr/log": "^1.0.1 || ^2.0 || ^3.0"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
+            },
+            "require-dev": {
+                "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+                "doctrine/couchdb": "~1.0@dev",
+                "elasticsearch/elasticsearch": "^7 || ^8",
+                "ext-json": "*",
+                "graylog2/gelf-php": "^1.4.2",
+                "guzzlehttp/guzzle": "^7.4",
+                "guzzlehttp/psr7": "^2.2",
+                "mongodb/mongodb": "^1.8",
+                "php-amqplib/php-amqplib": "~2.4 || ^3",
+                "phpspec/prophecy": "^1.15",
+                "phpstan/phpstan": "^0.12.91",
+                "phpunit/phpunit": "^8.5.14",
+                "predis/predis": "^1.1 || ^2.0",
+                "rollbar/rollbar": "^1.3 || ^2 || ^3",
+                "ruflin/elastica": "^7",
+                "swiftmailer/swiftmailer": "^5.3|^6.0",
+                "symfony/mailer": "^5.4 || ^6",
+                "symfony/mime": "^5.4 || ^6"
+            },
+            "suggest": {
+                "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+                "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+                "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+                "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+                "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+                "ext-mbstring": "Allow to work properly with unicode symbols",
+                "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+                "ext-openssl": "Required to send log messages using SSL",
+                "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+                "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+                "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+                "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+                "rollbar/rollbar": "Allow sending log messages to Rollbar",
+                "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+            },
+            "time": "2022-07-24T11:55:47+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Monolog\\": "src/Monolog"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "https://seld.be"
+                }
+            ],
+            "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+            "homepage": "https://github.com/Seldaek/monolog",
+            "keywords": [
+                "log",
+                "logging",
+                "psr-3"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/monolog/issues",
+                "source": "https://github.com/Seldaek/monolog/tree/2.8.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Seldaek",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../monolog/monolog"
+        },
+        {
+            "name": "phpseclib/phpseclib",
+            "version": "2.0.41",
+            "version_normalized": "2.0.41.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpseclib/phpseclib.git",
+                "reference": "7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b",
+                "reference": "7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "phing/phing": "~2.7",
+                "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
+                "squizlabs/php_codesniffer": "~2.0"
+            },
+            "suggest": {
+                "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+                "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+                "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+                "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
+                "ext-xml": "Install the XML extension to load XML formatted public keys."
+            },
+            "time": "2022-12-23T16:44:18+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "phpseclib/bootstrap.php"
+                ],
+                "psr-4": {
+                    "phpseclib\\": "phpseclib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jim Wigginton",
+                    "email": "terrafrost@php.net",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Patrick Monnerat",
+                    "email": "pm@datasphere.ch",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Andreas Fischer",
+                    "email": "bantu@phpbb.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Hans-Jürgen Petrich",
+                    "email": "petrich@tronic-media.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "graham@alt-three.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+            "homepage": "http://phpseclib.sourceforge.net",
+            "keywords": [
+                "BigInteger",
+                "aes",
+                "asn.1",
+                "asn1",
+                "blowfish",
+                "crypto",
+                "cryptography",
+                "encryption",
+                "rsa",
+                "security",
+                "sftp",
+                "signature",
+                "signing",
+                "ssh",
+                "twofish",
+                "x.509",
+                "x509"
+            ],
+            "support": {
+                "issues": "https://github.com/phpseclib/phpseclib/issues",
+                "source": "https://github.com/phpseclib/phpseclib/tree/2.0.41"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/terrafrost",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/phpseclib",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../phpseclib/phpseclib"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.1.4",
+            "version_normalized": "1.1.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2021-05-03T11:20:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/log/tree/1.1.4"
+            },
+            "install-path": "../psr/log"
+        },
+        {
+            "name": "psr/simple-cache",
+            "version": "1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/simple-cache.git",
+                "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+                "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2017-10-23T01:57:42+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\SimpleCache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interfaces for simple caching",
+            "keywords": [
+                "cache",
+                "caching",
+                "psr",
+                "psr-16",
+                "simple-cache"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/simple-cache/tree/master"
+            },
+            "install-path": "../psr/simple-cache"
+        },
+        {
+            "name": "visualappeal/php-auto-update",
+            "version": "1.0.2",
+            "version_normalized": "1.0.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/VisualAppeal/PHP-Auto-Update.git",
+                "reference": "4454361a0fa346c7fb179deef11585c79715b645"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/VisualAppeal/PHP-Auto-Update/zipball/4454361a0fa346c7fb179deef11585c79715b645",
+                "reference": "4454361a0fa346c7fb179deef11585c79715b645",
+                "shasum": ""
+            },
+            "require": {
+                "composer/semver": "^3.0",
+                "desarrolla2/cache": "^3.0",
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-zip": "*",
+                "monolog/monolog": "^2.1",
+                "php": ">=7.2.0",
+                "psr/log": "1.1.4"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5",
+                "roave/security-advisories": "dev-master"
+            },
+            "time": "2021-11-27T22:39:05+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "VisualAppeal\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Tim Helfensdörfer",
+                    "email": "tim@visualappeal.de"
+                }
+            ],
+            "description": "Autoupdater for PHP",
+            "support": {
+                "issues": "https://github.com/VisualAppeal/PHP-Auto-Update/issues",
+                "source": "https://github.com/VisualAppeal/PHP-Auto-Update/tree/1.0.2"
+            },
+            "install-path": "../visualappeal/php-auto-update"
+        }
+    ],
+    "dev": true,
+    "dev-package-names": []
+}
diff --git a/msd/vendor/composer/installed.php b/msd/vendor/composer/installed.php
new file mode 100644
index 00000000..3b185fb2
--- /dev/null
+++ b/msd/vendor/composer/installed.php
@@ -0,0 +1,125 @@
+<?php return array(
+    'root' => array(
+        'name' => '__root__',
+        'pretty_version' => 'dev-master',
+        'version' => 'dev-master',
+        'reference' => '36584e64258f869722dd8bc34b66b083a03b2369',
+        'type' => 'library',
+        'install_path' => __DIR__ . '/../../',
+        'aliases' => array(),
+        'dev' => true,
+    ),
+    'versions' => array(
+        '__root__' => array(
+            'pretty_version' => 'dev-master',
+            'version' => 'dev-master',
+            'reference' => '36584e64258f869722dd8bc34b66b083a03b2369',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../../',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'composer/semver' => array(
+            'pretty_version' => '3.3.2',
+            'version' => '3.3.2.0',
+            'reference' => '3953f23262f2bff1919fc82183ad9acb13ff62c9',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/./semver',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'desarrolla2/cache' => array(
+            'pretty_version' => 'v3.0.2',
+            'version' => '3.0.2.0',
+            'reference' => '0b8f985d09abfc04a2c1535943f6f07b7206161a',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../desarrolla2/cache',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'league/flysystem' => array(
+            'pretty_version' => '2.5.0',
+            'version' => '2.5.0.0',
+            'reference' => '8aaffb653c5777781b0f7f69a5d937baf7ab6cdb',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../league/flysystem',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'league/flysystem-sftp' => array(
+            'pretty_version' => '2.5.0',
+            'version' => '2.5.0.0',
+            'reference' => 'e30acbc9be024bb7df6ee4b159f2c8db3efcb6a7',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../league/flysystem-sftp',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'league/mime-type-detection' => array(
+            'pretty_version' => '1.11.0',
+            'version' => '1.11.0.0',
+            'reference' => 'ff6248ea87a9f116e78edd6002e39e5128a0d4dd',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../league/mime-type-detection',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'monolog/monolog' => array(
+            'pretty_version' => '2.8.0',
+            'version' => '2.8.0.0',
+            'reference' => '720488632c590286b88b80e62aa3d3d551ad4a50',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../monolog/monolog',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'phpseclib/phpseclib' => array(
+            'pretty_version' => '2.0.41',
+            'version' => '2.0.41.0',
+            'reference' => '7e763c6f97ec1fcb37c46aa8ecfc20a2c71d9c1b',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../phpseclib/phpseclib',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'psr/log' => array(
+            'pretty_version' => '1.1.4',
+            'version' => '1.1.4.0',
+            'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../psr/log',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'psr/log-implementation' => array(
+            'dev_requirement' => false,
+            'provided' => array(
+                0 => '1.0.0 || 2.0.0 || 3.0.0',
+            ),
+        ),
+        'psr/simple-cache' => array(
+            'pretty_version' => '1.0.1',
+            'version' => '1.0.1.0',
+            'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../psr/simple-cache',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'psr/simple-cache-implementation' => array(
+            'dev_requirement' => false,
+            'provided' => array(
+                0 => '1.0',
+            ),
+        ),
+        'visualappeal/php-auto-update' => array(
+            'pretty_version' => '1.0.2',
+            'version' => '1.0.2.0',
+            'reference' => '4454361a0fa346c7fb179deef11585c79715b645',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../visualappeal/php-auto-update',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+    ),
+);
diff --git a/msd/vendor/composer/platform_check.php b/msd/vendor/composer/platform_check.php
new file mode 100644
index 00000000..580fa960
--- /dev/null
+++ b/msd/vendor/composer/platform_check.php
@@ -0,0 +1,26 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70400)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+        } elseif (!headers_sent()) {
+            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+        }
+    }
+    trigger_error(
+        'Composer detected issues in your platform: ' . implode(' ', $issues),
+        E_USER_ERROR
+    );
+}
diff --git a/msd/vendor/composer/semver/CHANGELOG.md b/msd/vendor/composer/semver/CHANGELOG.md
new file mode 100644
index 00000000..c9514773
--- /dev/null
+++ b/msd/vendor/composer/semver/CHANGELOG.md
@@ -0,0 +1,209 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+This project adheres to [Semantic Versioning](http://semver.org/).
+
+### [3.3.2] 2022-04-01
+
+  * Fixed handling of non-string values (#134)
+
+### [3.3.1] 2022-03-16
+
+  * Fixed possible cache key clash in the CompilingMatcher memoization (#132)
+
+### [3.3.0] 2022-03-15
+
+  * Improved performance of CompilingMatcher by memoizing more (#131)
+  * Added CompilingMatcher::clear to clear all memoization caches
+
+### [3.2.9] 2022-02-04
+
+  * Revert #129 (Fixed MultiConstraint with MatchAllConstraint) which caused regressions
+
+### [3.2.8] 2022-02-04
+
+  * Updates to latest phpstan / CI by @Seldaek in https://github.com/composer/semver/pull/130
+  * Fixed MultiConstraint with MatchAllConstraint by @Toflar in https://github.com/composer/semver/pull/129
+
+### [3.2.7] 2022-01-04
+
+  * Fixed: typo in type definition of Intervals class causing issues with Psalm scanning vendors
+
+### [3.2.6] 2021-10-25
+
+  * Fixed: type improvements to parseStability
+
+### [3.2.5] 2021-05-24
+
+  * Fixed: issue comparing disjunctive MultiConstraints to conjunctive ones (#127)
+  * Fixed: added complete type information using phpstan annotations
+
+### [3.2.4] 2020-11-13
+
+  * Fixed: code clean-up
+
+### [3.2.3] 2020-11-12
+
+  * Fixed: constraints in the form of `X || Y, >=Y.1` and other such complex constructs were in some cases being optimized into a more restrictive constraint
+
+### [3.2.2] 2020-10-14
+
+  * Fixed: internal code cleanups
+
+### [3.2.1] 2020-09-27
+
+  * Fixed: accidental validation of broken constraints combining ^/~ and wildcards, and -dev suffix allowing weird cases
+  * Fixed: normalization of beta0 and such which was dropping the 0
+
+### [3.2.0] 2020-09-09
+
+  * Added: support for `x || @dev`, not very useful but seen in the wild and failed to validate with 1.5.2/1.6.0
+  * Added: support for `foobar-dev` being equal to `dev-foobar`, dev-foobar is the official way to write it but we need to support the other for BC and convenience
+
+### [3.1.0] 2020-09-08
+
+  * Added: support for constraints like `^2.x-dev` and `~2.x-dev`, not very useful but seen in the wild and failed to validate with 3.0.1
+  * Fixed: invalid aliases will no longer throw, unless explicitly validated by Composer in the root package
+
+### [3.0.1] 2020-09-08
+
+  * Fixed: handling of some invalid -dev versions which were seen as valid
+
+### [3.0.0] 2020-05-26
+
+  * Break: Renamed `EmptyConstraint`, replace it with `MatchAllConstraint`
+  * Break: Unlikely to affect anyone but strictly speaking a breaking change, `*.*` and such variants will not match all `dev-*` versions anymore, only `*` does
+  * Break: ConstraintInterface is now considered internal/private and not meant to be implemented by third parties anymore
+  * Added `Intervals` class to check if a constraint is a subsets of another one, and allow compacting complex MultiConstraints into simpler ones
+  * Added `CompilingMatcher` class to speed up constraint matching against simple Constraint instances
+  * Added `MatchAllConstraint` and `MatchNoneConstraint` which match everything and nothing
+  * Added more advanced optimization of contiguous constraints inside MultiConstraint
+  * Added tentative support for PHP 8
+  * Fixed ConstraintInterface::matches to be commutative in all cases
+
+### [2.0.0] 2020-04-21
+
+  * Break: `dev-master`, `dev-trunk` and `dev-default` now normalize to `dev-master`, `dev-trunk` and `dev-default` instead of `9999999-dev` in 1.x
+  * Break: Removed the deprecated `AbstractConstraint`
+  * Added `getUpperBound` and `getLowerBound` to ConstraintInterface. They return `Composer\Semver\Constraint\Bound` instances
+  * Added `MultiConstraint::create` to create the most-optimal form of ConstraintInterface from an array of constraint strings
+
+### [1.7.2] 2020-12-03
+
+  * Fixed: Allow installing on php 8
+
+### [1.7.1] 2020-09-27
+
+  * Fixed: accidental validation of broken constraints combining ^/~ and wildcards, and -dev suffix allowing weird cases
+  * Fixed: normalization of beta0 and such which was dropping the 0
+
+### [1.7.0] 2020-09-09
+
+  * Added: support for `x || @dev`, not very useful but seen in the wild and failed to validate with 1.5.2/1.6.0
+  * Added: support for `foobar-dev` being equal to `dev-foobar`, dev-foobar is the official way to write it but we need to support the other for BC and convenience
+
+### [1.6.0] 2020-09-08
+
+  * Added: support for constraints like `^2.x-dev` and `~2.x-dev`, not very useful but seen in the wild and failed to validate with 1.5.2
+  * Fixed: invalid aliases will no longer throw, unless explicitly validated by Composer in the root package
+
+### [1.5.2] 2020-09-08
+
+  * Fixed: handling of some invalid -dev versions which were seen as valid
+  * Fixed: some doctypes
+
+### [1.5.1] 2020-01-13
+
+  * Fixed: Parsing of aliased version was not validating the alias to be a valid version
+
+### [1.5.0] 2019-03-19
+
+  * Added: some support for date versions (e.g. 201903) in `~` operator
+  * Fixed: support for stabilities in `~` operator was inconsistent
+
+### [1.4.2] 2016-08-30
+
+  * Fixed: collapsing of complex constraints lead to buggy constraints
+
+### [1.4.1] 2016-06-02
+
+  * Changed: branch-like requirements no longer strip build metadata - [composer/semver#38](https://github.com/composer/semver/pull/38).
+
+### [1.4.0] 2016-03-30
+
+  * Added: getters on MultiConstraint - [composer/semver#35](https://github.com/composer/semver/pull/35).
+
+### [1.3.0] 2016-02-25
+
+  * Fixed: stability parsing - [composer/composer#1234](https://github.com/composer/composer/issues/4889).
+  * Changed: collapse contiguous constraints when possible.
+
+### [1.2.0] 2015-11-10
+
+  * Changed: allow multiple numerical identifiers in 'pre-release' version part.
+  * Changed: add more 'v' prefix support.
+
+### [1.1.0] 2015-11-03
+
+  * Changed: dropped redundant `test` namespace.
+  * Changed: minor adjustment in datetime parsing normalization.
+  * Changed: `ConstraintInterface` relaxed, setPrettyString is not required anymore.
+  * Changed: `AbstractConstraint` marked deprecated, will be removed in 2.0.
+  * Changed: `Constraint` is now extensible.
+
+### [1.0.0] 2015-09-21
+
+  * Break: `VersionConstraint` renamed to `Constraint`.
+  * Break: `SpecificConstraint` renamed to `AbstractConstraint`.
+  * Break: `LinkConstraintInterface` renamed to `ConstraintInterface`.
+  * Break: `VersionParser::parseNameVersionPairs` was removed.
+  * Changed: `VersionParser::parseConstraints` allows (but ignores) build metadata now.
+  * Changed: `VersionParser::parseConstraints` allows (but ignores) prefixing numeric versions with a 'v' now.
+  * Changed: Fixed namespace(s) of test files.
+  * Changed: `Comparator::compare` no longer throws `InvalidArgumentException`.
+  * Changed: `Constraint` now throws `InvalidArgumentException`.
+
+### [0.1.0] 2015-07-23
+
+  * Added: `Composer\Semver\Comparator`, various methods to compare versions.
+  * Added: various documents such as README.md, LICENSE, etc.
+  * Added: configuration files for Git, Travis, php-cs-fixer, phpunit.
+  * Break: the following namespaces were renamed:
+    - Namespace: `Composer\Package\Version` -> `Composer\Semver`
+    - Namespace: `Composer\Package\LinkConstraint` -> `Composer\Semver\Constraint`
+    - Namespace: `Composer\Test\Package\Version` -> `Composer\Test\Semver`
+    - Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint`
+  * Changed: code style using php-cs-fixer.
+
+[3.3.2]: https://github.com/composer/semver/compare/3.3.1...3.3.2
+[3.3.1]: https://github.com/composer/semver/compare/3.3.0...3.3.1
+[3.3.0]: https://github.com/composer/semver/compare/3.2.9...3.3.0
+[3.2.9]: https://github.com/composer/semver/compare/3.2.8...3.2.9
+[3.2.8]: https://github.com/composer/semver/compare/3.2.7...3.2.8
+[3.2.7]: https://github.com/composer/semver/compare/3.2.6...3.2.7
+[3.2.6]: https://github.com/composer/semver/compare/3.2.5...3.2.6
+[3.2.5]: https://github.com/composer/semver/compare/3.2.4...3.2.5
+[3.2.4]: https://github.com/composer/semver/compare/3.2.3...3.2.4
+[3.2.3]: https://github.com/composer/semver/compare/3.2.2...3.2.3
+[3.2.2]: https://github.com/composer/semver/compare/3.2.1...3.2.2
+[3.2.1]: https://github.com/composer/semver/compare/3.2.0...3.2.1
+[3.2.0]: https://github.com/composer/semver/compare/3.1.0...3.2.0
+[3.1.0]: https://github.com/composer/semver/compare/3.0.1...3.1.0
+[3.0.1]: https://github.com/composer/semver/compare/3.0.0...3.0.1
+[3.0.0]: https://github.com/composer/semver/compare/2.0.0...3.0.0
+[2.0.0]: https://github.com/composer/semver/compare/1.5.1...2.0.0
+[1.7.2]: https://github.com/composer/semver/compare/1.7.1...1.7.2
+[1.7.1]: https://github.com/composer/semver/compare/1.7.0...1.7.1
+[1.7.0]: https://github.com/composer/semver/compare/1.6.0...1.7.0
+[1.6.0]: https://github.com/composer/semver/compare/1.5.2...1.6.0
+[1.5.2]: https://github.com/composer/semver/compare/1.5.1...1.5.2
+[1.5.1]: https://github.com/composer/semver/compare/1.5.0...1.5.1
+[1.5.0]: https://github.com/composer/semver/compare/1.4.2...1.5.0
+[1.4.2]: https://github.com/composer/semver/compare/1.4.1...1.4.2
+[1.4.1]: https://github.com/composer/semver/compare/1.4.0...1.4.1
+[1.4.0]: https://github.com/composer/semver/compare/1.3.0...1.4.0
+[1.3.0]: https://github.com/composer/semver/compare/1.2.0...1.3.0
+[1.2.0]: https://github.com/composer/semver/compare/1.1.0...1.2.0
+[1.1.0]: https://github.com/composer/semver/compare/1.0.0...1.1.0
+[1.0.0]: https://github.com/composer/semver/compare/0.1.0...1.0.0
+[0.1.0]: https://github.com/composer/semver/compare/5e0b9a4da...0.1.0
diff --git a/msd/vendor/composer/semver/LICENSE b/msd/vendor/composer/semver/LICENSE
new file mode 100644
index 00000000..46697586
--- /dev/null
+++ b/msd/vendor/composer/semver/LICENSE
@@ -0,0 +1,19 @@
+Copyright (C) 2015 Composer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/msd/vendor/composer/semver/README.md b/msd/vendor/composer/semver/README.md
new file mode 100644
index 00000000..35db99a5
--- /dev/null
+++ b/msd/vendor/composer/semver/README.md
@@ -0,0 +1,98 @@
+composer/semver
+===============
+
+Semver (Semantic Versioning) library that offers utilities, version constraint parsing and validation.
+
+Originally written as part of [composer/composer](https://github.com/composer/composer),
+now extracted and made available as a stand-alone library.
+
+[![Continuous Integration](https://github.com/composer/semver/workflows/Continuous%20Integration/badge.svg?branch=main)](https://github.com/composer/semver/actions)
+
+
+Installation
+------------
+
+Install the latest version with:
+
+```bash
+$ composer require composer/semver
+```
+
+
+Requirements
+------------
+
+* PHP 5.3.2 is required but using the latest version of PHP is highly recommended.
+
+
+Version Comparison
+------------------
+
+For details on how versions are compared, refer to the [Versions](https://getcomposer.org/doc/articles/versions.md)
+article in the documentation section of the [getcomposer.org](https://getcomposer.org) website.
+
+
+Basic usage
+-----------
+
+### Comparator
+
+The [`Composer\Semver\Comparator`](https://github.com/composer/semver/blob/main/src/Comparator.php) class provides the following methods for comparing versions:
+
+* greaterThan($v1, $v2)
+* greaterThanOrEqualTo($v1, $v2)
+* lessThan($v1, $v2)
+* lessThanOrEqualTo($v1, $v2)
+* equalTo($v1, $v2)
+* notEqualTo($v1, $v2)
+
+Each function takes two version strings as arguments and returns a boolean. For example:
+
+```php
+use Composer\Semver\Comparator;
+
+Comparator::greaterThan('1.25.0', '1.24.0'); // 1.25.0 > 1.24.0
+```
+
+### Semver
+
+The [`Composer\Semver\Semver`](https://github.com/composer/semver/blob/main/src/Semver.php) class provides the following methods:
+
+* satisfies($version, $constraints)
+* satisfiedBy(array $versions, $constraint)
+* sort($versions)
+* rsort($versions)
+
+### Intervals
+
+The [`Composer\Semver\Intervals`](https://github.com/composer/semver/blob/main/src/Intervals.php) static class provides
+a few utilities to work with complex constraints or read version intervals from a constraint:
+
+```php
+use Composer\Semver\Intervals;
+
+// Checks whether $candidate is a subset of $constraint
+Intervals::isSubsetOf(ConstraintInterface $candidate, ConstraintInterface $constraint);
+
+// Checks whether $a and $b have any intersection, equivalent to $a->matches($b)
+Intervals::haveIntersections(ConstraintInterface $a, ConstraintInterface $b);
+
+// Optimizes a complex multi constraint by merging all intervals down to the smallest
+// possible multi constraint. The drawbacks are this is not very fast, and the resulting
+// multi constraint will have no human readable prettyConstraint configured on it
+Intervals::compactConstraint(ConstraintInterface $constraint);
+
+// Creates an array of numeric intervals and branch constraints representing a given constraint
+Intervals::get(ConstraintInterface $constraint);
+
+// Clears the memoization cache when you are done processing constraints
+Intervals::clear()
+```
+
+See the class docblocks for more details.
+
+
+License
+-------
+
+composer/semver is licensed under the MIT License, see the LICENSE file for details.
diff --git a/msd/vendor/composer/semver/composer.json b/msd/vendor/composer/semver/composer.json
new file mode 100644
index 00000000..ba78676d
--- /dev/null
+++ b/msd/vendor/composer/semver/composer.json
@@ -0,0 +1,59 @@
+{
+    "name": "composer/semver",
+    "description": "Semver library that offers utilities, version constraint parsing and validation.",
+    "type": "library",
+    "license": "MIT",
+    "keywords": [
+        "semver",
+        "semantic",
+        "versioning",
+        "validation"
+    ],
+    "authors": [
+        {
+            "name": "Nils Adermann",
+            "email": "naderman@naderman.de",
+            "homepage": "http://www.naderman.de"
+        },
+        {
+            "name": "Jordi Boggiano",
+            "email": "j.boggiano@seld.be",
+            "homepage": "http://seld.be"
+        },
+        {
+            "name": "Rob Bast",
+            "email": "rob.bast@gmail.com",
+            "homepage": "http://robbast.nl"
+        }
+    ],
+    "support": {
+        "irc": "irc://irc.freenode.org/composer",
+        "issues": "https://github.com/composer/semver/issues"
+    },
+    "require": {
+        "php": "^5.3.2 || ^7.0 || ^8.0"
+    },
+    "require-dev": {
+        "symfony/phpunit-bridge": "^4.2 || ^5",
+        "phpstan/phpstan": "^1.4"
+    },
+    "autoload": {
+        "psr-4": {
+            "Composer\\Semver\\": "src"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "Composer\\Semver\\": "tests"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-main": "3.x-dev"
+        }
+    },
+    "scripts": {
+        "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit",
+        "phpstan": "@php vendor/bin/phpstan analyse"
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Comparator.php b/msd/vendor/composer/semver/src/Comparator.php
new file mode 100644
index 00000000..38f483aa
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Comparator.php
@@ -0,0 +1,113 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver;
+
+use Composer\Semver\Constraint\Constraint;
+
+class Comparator
+{
+    /**
+     * Evaluates the expression: $version1 > $version2.
+     *
+     * @param string $version1
+     * @param string $version2
+     *
+     * @return bool
+     */
+    public static function greaterThan($version1, $version2)
+    {
+        return self::compare($version1, '>', $version2);
+    }
+
+    /**
+     * Evaluates the expression: $version1 >= $version2.
+     *
+     * @param string $version1
+     * @param string $version2
+     *
+     * @return bool
+     */
+    public static function greaterThanOrEqualTo($version1, $version2)
+    {
+        return self::compare($version1, '>=', $version2);
+    }
+
+    /**
+     * Evaluates the expression: $version1 < $version2.
+     *
+     * @param string $version1
+     * @param string $version2
+     *
+     * @return bool
+     */
+    public static function lessThan($version1, $version2)
+    {
+        return self::compare($version1, '<', $version2);
+    }
+
+    /**
+     * Evaluates the expression: $version1 <= $version2.
+     *
+     * @param string $version1
+     * @param string $version2
+     *
+     * @return bool
+     */
+    public static function lessThanOrEqualTo($version1, $version2)
+    {
+        return self::compare($version1, '<=', $version2);
+    }
+
+    /**
+     * Evaluates the expression: $version1 == $version2.
+     *
+     * @param string $version1
+     * @param string $version2
+     *
+     * @return bool
+     */
+    public static function equalTo($version1, $version2)
+    {
+        return self::compare($version1, '==', $version2);
+    }
+
+    /**
+     * Evaluates the expression: $version1 != $version2.
+     *
+     * @param string $version1
+     * @param string $version2
+     *
+     * @return bool
+     */
+    public static function notEqualTo($version1, $version2)
+    {
+        return self::compare($version1, '!=', $version2);
+    }
+
+    /**
+     * Evaluates the expression: $version1 $operator $version2.
+     *
+     * @param string $version1
+     * @param string $operator
+     * @param string $version2
+     *
+     * @return bool
+     *
+     * @phpstan-param Constraint::STR_OP_*  $operator
+     */
+    public static function compare($version1, $operator, $version2)
+    {
+        $constraint = new Constraint($operator, $version2);
+
+        return $constraint->matchSpecific(new Constraint('==', $version1), true);
+    }
+}
diff --git a/msd/vendor/composer/semver/src/CompilingMatcher.php b/msd/vendor/composer/semver/src/CompilingMatcher.php
new file mode 100644
index 00000000..45bce70a
--- /dev/null
+++ b/msd/vendor/composer/semver/src/CompilingMatcher.php
@@ -0,0 +1,94 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver;
+
+use Composer\Semver\Constraint\Constraint;
+use Composer\Semver\Constraint\ConstraintInterface;
+
+/**
+ * Helper class to evaluate constraint by compiling and reusing the code to evaluate
+ */
+class CompilingMatcher
+{
+    /**
+     * @var array
+     * @phpstan-var array<string, callable>
+     */
+    private static $compiledCheckerCache = array();
+    /**
+     * @var array
+     * @phpstan-var array<string, bool>
+     */
+    private static $resultCache = array();
+
+    /** @var bool */
+    private static $enabled;
+
+    /**
+     * @phpstan-var array<Constraint::OP_*, Constraint::STR_OP_*>
+     */
+    private static $transOpInt = array(
+        Constraint::OP_EQ => Constraint::STR_OP_EQ,
+        Constraint::OP_LT => Constraint::STR_OP_LT,
+        Constraint::OP_LE => Constraint::STR_OP_LE,
+        Constraint::OP_GT => Constraint::STR_OP_GT,
+        Constraint::OP_GE => Constraint::STR_OP_GE,
+        Constraint::OP_NE => Constraint::STR_OP_NE,
+    );
+
+    /**
+     * Clears the memoization cache once you are done
+     *
+     * @return void
+     */
+    public static function clear()
+    {
+        self::$resultCache = array();
+        self::$compiledCheckerCache = array();
+    }
+
+    /**
+     * Evaluates the expression: $constraint match $operator $version
+     *
+     * @param ConstraintInterface $constraint
+     * @param int                 $operator
+     * @phpstan-param Constraint::OP_*  $operator
+     * @param string              $version
+     *
+     * @return mixed
+     */
+    public static function match(ConstraintInterface $constraint, $operator, $version)
+    {
+        $resultCacheKey = $operator.$constraint.';'.$version;
+
+        if (isset(self::$resultCache[$resultCacheKey])) {
+            return self::$resultCache[$resultCacheKey];
+        }
+
+        if (self::$enabled === null) {
+            self::$enabled = !\in_array('eval', explode(',', (string) ini_get('disable_functions')), true);
+        }
+        if (!self::$enabled) {
+            return self::$resultCache[$resultCacheKey] = $constraint->matches(new Constraint(self::$transOpInt[$operator], $version));
+        }
+
+        $cacheKey = $operator.$constraint;
+        if (!isset(self::$compiledCheckerCache[$cacheKey])) {
+            $code = $constraint->compile($operator);
+            self::$compiledCheckerCache[$cacheKey] = $function = eval('return function($v, $b){return '.$code.';};');
+        } else {
+            $function = self::$compiledCheckerCache[$cacheKey];
+        }
+
+        return self::$resultCache[$resultCacheKey] = $function($version, strpos($version, 'dev-') === 0);
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Constraint/Bound.php b/msd/vendor/composer/semver/src/Constraint/Bound.php
new file mode 100644
index 00000000..7effb11a
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Constraint/Bound.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+class Bound
+{
+    /**
+     * @var string
+     */
+    private $version;
+
+    /**
+     * @var bool
+     */
+    private $isInclusive;
+
+    /**
+     * @param string $version
+     * @param bool   $isInclusive
+     */
+    public function __construct($version, $isInclusive)
+    {
+        $this->version = $version;
+        $this->isInclusive = $isInclusive;
+    }
+
+    /**
+     * @return string
+     */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isInclusive()
+    {
+        return $this->isInclusive;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isZero()
+    {
+        return $this->getVersion() === '0.0.0.0-dev' && $this->isInclusive();
+    }
+
+    /**
+     * @return bool
+     */
+    public function isPositiveInfinity()
+    {
+        return $this->getVersion() === PHP_INT_MAX.'.0.0.0' && !$this->isInclusive();
+    }
+
+    /**
+     * Compares a bound to another with a given operator.
+     *
+     * @param Bound  $other
+     * @param string $operator
+     *
+     * @return bool
+     */
+    public function compareTo(Bound $other, $operator)
+    {
+        if (!\in_array($operator, array('<', '>'), true)) {
+            throw new \InvalidArgumentException('Does not support any other operator other than > or <.');
+        }
+
+        // If they are the same it doesn't matter
+        if ($this == $other) {
+            return false;
+        }
+
+        $compareResult = version_compare($this->getVersion(), $other->getVersion());
+
+        // Not the same version means we don't need to check if the bounds are inclusive or not
+        if (0 !== $compareResult) {
+            return (('>' === $operator) ? 1 : -1) === $compareResult;
+        }
+
+        // Question we're answering here is "am I higher than $other?"
+        return '>' === $operator ? $other->isInclusive() : !$other->isInclusive();
+    }
+
+    public function __toString()
+    {
+        return sprintf(
+            '%s [%s]',
+            $this->getVersion(),
+            $this->isInclusive() ? 'inclusive' : 'exclusive'
+        );
+    }
+
+    /**
+     * @return self
+     */
+    public static function zero()
+    {
+        return new Bound('0.0.0.0-dev', true);
+    }
+
+    /**
+     * @return self
+     */
+    public static function positiveInfinity()
+    {
+        return new Bound(PHP_INT_MAX.'.0.0.0', false);
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Constraint/Constraint.php b/msd/vendor/composer/semver/src/Constraint/Constraint.php
new file mode 100644
index 00000000..dc394829
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Constraint/Constraint.php
@@ -0,0 +1,435 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+/**
+ * Defines a constraint.
+ */
+class Constraint implements ConstraintInterface
+{
+    /* operator integer values */
+    const OP_EQ = 0;
+    const OP_LT = 1;
+    const OP_LE = 2;
+    const OP_GT = 3;
+    const OP_GE = 4;
+    const OP_NE = 5;
+
+    /* operator string values */
+    const STR_OP_EQ = '==';
+    const STR_OP_EQ_ALT = '=';
+    const STR_OP_LT = '<';
+    const STR_OP_LE = '<=';
+    const STR_OP_GT = '>';
+    const STR_OP_GE = '>=';
+    const STR_OP_NE = '!=';
+    const STR_OP_NE_ALT = '<>';
+
+    /**
+     * Operator to integer translation table.
+     *
+     * @var array
+     * @phpstan-var array<self::STR_OP_*, self::OP_*>
+     */
+    private static $transOpStr = array(
+        '=' => self::OP_EQ,
+        '==' => self::OP_EQ,
+        '<' => self::OP_LT,
+        '<=' => self::OP_LE,
+        '>' => self::OP_GT,
+        '>=' => self::OP_GE,
+        '<>' => self::OP_NE,
+        '!=' => self::OP_NE,
+    );
+
+    /**
+     * Integer to operator translation table.
+     *
+     * @var array
+     * @phpstan-var array<self::OP_*, self::STR_OP_*>
+     */
+    private static $transOpInt = array(
+        self::OP_EQ => '==',
+        self::OP_LT => '<',
+        self::OP_LE => '<=',
+        self::OP_GT => '>',
+        self::OP_GE => '>=',
+        self::OP_NE => '!=',
+    );
+
+    /**
+     * @var int
+     * @phpstan-var self::OP_*
+     */
+    protected $operator;
+
+    /** @var string */
+    protected $version;
+
+    /** @var string|null */
+    protected $prettyString;
+
+    /** @var Bound */
+    protected $lowerBound;
+
+    /** @var Bound */
+    protected $upperBound;
+
+    /**
+     * Sets operator and version to compare with.
+     *
+     * @param string $operator
+     * @param string $version
+     *
+     * @throws \InvalidArgumentException if invalid operator is given.
+     *
+     * @phpstan-param self::STR_OP_* $operator
+     */
+    public function __construct($operator, $version)
+    {
+        if (!isset(self::$transOpStr[$operator])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid operator "%s" given, expected one of: %s',
+                $operator,
+                implode(', ', self::getSupportedOperators())
+            ));
+        }
+
+        $this->operator = self::$transOpStr[$operator];
+        $this->version = $version;
+    }
+
+    /**
+     * @return string
+     */
+    public function getVersion()
+    {
+        return $this->version;
+    }
+
+    /**
+     * @return string
+     *
+     * @phpstan-return self::STR_OP_*
+     */
+    public function getOperator()
+    {
+        return self::$transOpInt[$this->operator];
+    }
+
+    /**
+     * @param ConstraintInterface $provider
+     *
+     * @return bool
+     */
+    public function matches(ConstraintInterface $provider)
+    {
+        if ($provider instanceof self) {
+            return $this->matchSpecific($provider);
+        }
+
+        // turn matching around to find a match
+        return $provider->matches($this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setPrettyString($prettyString)
+    {
+        $this->prettyString = $prettyString;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPrettyString()
+    {
+        if ($this->prettyString) {
+            return $this->prettyString;
+        }
+
+        return $this->__toString();
+    }
+
+    /**
+     * Get all supported comparison operators.
+     *
+     * @return array
+     *
+     * @phpstan-return list<self::STR_OP_*>
+     */
+    public static function getSupportedOperators()
+    {
+        return array_keys(self::$transOpStr);
+    }
+
+    /**
+     * @param  string $operator
+     * @return int
+     *
+     * @phpstan-param  self::STR_OP_* $operator
+     * @phpstan-return self::OP_*
+     */
+    public static function getOperatorConstant($operator)
+    {
+        return self::$transOpStr[$operator];
+    }
+
+    /**
+     * @param string $a
+     * @param string $b
+     * @param string $operator
+     * @param bool   $compareBranches
+     *
+     * @throws \InvalidArgumentException if invalid operator is given.
+     *
+     * @return bool
+     *
+     * @phpstan-param self::STR_OP_* $operator
+     */
+    public function versionCompare($a, $b, $operator, $compareBranches = false)
+    {
+        if (!isset(self::$transOpStr[$operator])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Invalid operator "%s" given, expected one of: %s',
+                $operator,
+                implode(', ', self::getSupportedOperators())
+            ));
+        }
+
+        $aIsBranch = strpos($a, 'dev-') === 0;
+        $bIsBranch = strpos($b, 'dev-') === 0;
+
+        if ($operator === '!=' && ($aIsBranch || $bIsBranch)) {
+            return $a !== $b;
+        }
+
+        if ($aIsBranch && $bIsBranch) {
+            return $operator === '==' && $a === $b;
+        }
+
+        // when branches are not comparable, we make sure dev branches never match anything
+        if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
+            return false;
+        }
+
+        return \version_compare($a, $b, $operator);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function compile($otherOperator)
+    {
+        if (strpos($this->version, 'dev-') === 0) {
+            if (self::OP_EQ === $this->operator) {
+                if (self::OP_EQ === $otherOperator) {
+                    return sprintf('$b && $v === %s', \var_export($this->version, true));
+                }
+                if (self::OP_NE === $otherOperator) {
+                    return sprintf('!$b || $v !== %s', \var_export($this->version, true));
+                }
+                return 'false';
+            }
+
+            if (self::OP_NE === $this->operator) {
+                if (self::OP_EQ === $otherOperator) {
+                    return sprintf('!$b || $v !== %s', \var_export($this->version, true));
+                }
+                if (self::OP_NE === $otherOperator) {
+                    return 'true';
+                }
+                return '!$b';
+            }
+
+            return 'false';
+        }
+
+        if (self::OP_EQ === $this->operator) {
+            if (self::OP_EQ === $otherOperator) {
+                return sprintf('\version_compare($v, %s, \'==\')', \var_export($this->version, true));
+            }
+            if (self::OP_NE === $otherOperator) {
+                return sprintf('$b || \version_compare($v, %s, \'!=\')', \var_export($this->version, true));
+            }
+
+            return sprintf('!$b && \version_compare(%s, $v, \'%s\')', \var_export($this->version, true), self::$transOpInt[$otherOperator]);
+        }
+
+        if (self::OP_NE === $this->operator) {
+            if (self::OP_EQ === $otherOperator) {
+                return sprintf('$b || (!$b && \version_compare($v, %s, \'!=\'))', \var_export($this->version, true));
+            }
+
+            if (self::OP_NE === $otherOperator) {
+                return 'true';
+            }
+            return '!$b';
+        }
+
+        if (self::OP_LT === $this->operator || self::OP_LE === $this->operator) {
+            if (self::OP_LT === $otherOperator || self::OP_LE === $otherOperator) {
+                return '!$b';
+            }
+        } else { // $this->operator must be self::OP_GT || self::OP_GE here
+            if (self::OP_GT === $otherOperator || self::OP_GE === $otherOperator) {
+                return '!$b';
+            }
+        }
+
+        if (self::OP_NE === $otherOperator) {
+            return 'true';
+        }
+
+        $codeComparison = sprintf('\version_compare($v, %s, \'%s\')', \var_export($this->version, true), self::$transOpInt[$this->operator]);
+        if ($this->operator === self::OP_LE) {
+            if ($otherOperator === self::OP_GT) {
+                return sprintf('!$b && \version_compare($v, %s, \'!=\') && ', \var_export($this->version, true)) . $codeComparison;
+            }
+        } elseif ($this->operator === self::OP_GE) {
+            if ($otherOperator === self::OP_LT) {
+                return sprintf('!$b && \version_compare($v, %s, \'!=\') && ', \var_export($this->version, true)) . $codeComparison;
+            }
+        }
+
+        return sprintf('!$b && %s', $codeComparison);
+    }
+
+    /**
+     * @param Constraint $provider
+     * @param bool       $compareBranches
+     *
+     * @return bool
+     */
+    public function matchSpecific(Constraint $provider, $compareBranches = false)
+    {
+        $noEqualOp = str_replace('=', '', self::$transOpInt[$this->operator]);
+        $providerNoEqualOp = str_replace('=', '', self::$transOpInt[$provider->operator]);
+
+        $isEqualOp = self::OP_EQ === $this->operator;
+        $isNonEqualOp = self::OP_NE === $this->operator;
+        $isProviderEqualOp = self::OP_EQ === $provider->operator;
+        $isProviderNonEqualOp = self::OP_NE === $provider->operator;
+
+        // '!=' operator is match when other operator is not '==' operator or version is not match
+        // these kinds of comparisons always have a solution
+        if ($isNonEqualOp || $isProviderNonEqualOp) {
+            if ($isNonEqualOp && !$isProviderNonEqualOp && !$isProviderEqualOp && strpos($provider->version, 'dev-') === 0) {
+                return false;
+            }
+
+            if ($isProviderNonEqualOp && !$isNonEqualOp && !$isEqualOp && strpos($this->version, 'dev-') === 0) {
+                return false;
+            }
+
+            if (!$isEqualOp && !$isProviderEqualOp) {
+                return true;
+            }
+            return $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
+        }
+
+        // an example for the condition is <= 2.0 & < 1.0
+        // these kinds of comparisons always have a solution
+        if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) {
+            return !(strpos($this->version, 'dev-') === 0 || strpos($provider->version, 'dev-') === 0);
+        }
+
+        $version1 = $isEqualOp ? $this->version : $provider->version;
+        $version2 = $isEqualOp ? $provider->version : $this->version;
+        $operator = $isEqualOp ? $provider->operator : $this->operator;
+
+        if ($this->versionCompare($version1, $version2, self::$transOpInt[$operator], $compareBranches)) {
+            // special case, e.g. require >= 1.0 and provide < 1.0
+            // 1.0 >= 1.0 but 1.0 is outside of the provided interval
+
+            return !(self::$transOpInt[$provider->operator] === $providerNoEqualOp
+                && self::$transOpInt[$this->operator] !== $noEqualOp
+                && \version_compare($provider->version, $this->version, '=='));
+        }
+
+        return false;
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString()
+    {
+        return self::$transOpInt[$this->operator] . ' ' . $this->version;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getLowerBound()
+    {
+        $this->extractBounds();
+
+        return $this->lowerBound;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getUpperBound()
+    {
+        $this->extractBounds();
+
+        return $this->upperBound;
+    }
+
+    /**
+     * @return void
+     */
+    private function extractBounds()
+    {
+        if (null !== $this->lowerBound) {
+            return;
+        }
+
+        // Branches
+        if (strpos($this->version, 'dev-') === 0) {
+            $this->lowerBound = Bound::zero();
+            $this->upperBound = Bound::positiveInfinity();
+
+            return;
+        }
+
+        switch ($this->operator) {
+            case self::OP_EQ:
+                $this->lowerBound = new Bound($this->version, true);
+                $this->upperBound = new Bound($this->version, true);
+                break;
+            case self::OP_LT:
+                $this->lowerBound = Bound::zero();
+                $this->upperBound = new Bound($this->version, false);
+                break;
+            case self::OP_LE:
+                $this->lowerBound = Bound::zero();
+                $this->upperBound = new Bound($this->version, true);
+                break;
+            case self::OP_GT:
+                $this->lowerBound = new Bound($this->version, false);
+                $this->upperBound = Bound::positiveInfinity();
+                break;
+            case self::OP_GE:
+                $this->lowerBound = new Bound($this->version, true);
+                $this->upperBound = Bound::positiveInfinity();
+                break;
+            case self::OP_NE:
+                $this->lowerBound = Bound::zero();
+                $this->upperBound = Bound::positiveInfinity();
+                break;
+        }
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Constraint/ConstraintInterface.php b/msd/vendor/composer/semver/src/Constraint/ConstraintInterface.php
new file mode 100644
index 00000000..389b935b
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Constraint/ConstraintInterface.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+/**
+ * DO NOT IMPLEMENT this interface. It is only meant for usage as a type hint
+ * in libraries relying on composer/semver but creating your own constraint class
+ * that implements this interface is not a supported use case and will cause the
+ * composer/semver components to return unexpected results.
+ */
+interface ConstraintInterface
+{
+    /**
+     * Checks whether the given constraint intersects in any way with this constraint
+     *
+     * @param ConstraintInterface $provider
+     *
+     * @return bool
+     */
+    public function matches(ConstraintInterface $provider);
+
+    /**
+     * Provides a compiled version of the constraint for the given operator
+     * The compiled version must be a PHP expression.
+     * Executor of compile version must provide 2 variables:
+     * - $v = the string version to compare with
+     * - $b = whether or not the version is a non-comparable branch (starts with "dev-")
+     *
+     * @see Constraint::OP_* for the list of available operators.
+     * @example return '!$b && version_compare($v, '1.0', '>')';
+     *
+     * @param int $otherOperator one Constraint::OP_*
+     *
+     * @return string
+     *
+     * @phpstan-param Constraint::OP_* $otherOperator
+     */
+    public function compile($otherOperator);
+
+    /**
+     * @return Bound
+     */
+    public function getUpperBound();
+
+    /**
+     * @return Bound
+     */
+    public function getLowerBound();
+
+    /**
+     * @return string
+     */
+    public function getPrettyString();
+
+    /**
+     * @param string|null $prettyString
+     *
+     * @return void
+     */
+    public function setPrettyString($prettyString);
+
+    /**
+     * @return string
+     */
+    public function __toString();
+}
diff --git a/msd/vendor/composer/semver/src/Constraint/MatchAllConstraint.php b/msd/vendor/composer/semver/src/Constraint/MatchAllConstraint.php
new file mode 100644
index 00000000..5e51af95
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Constraint/MatchAllConstraint.php
@@ -0,0 +1,85 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+/**
+ * Defines the absence of a constraint.
+ *
+ * This constraint matches everything.
+ */
+class MatchAllConstraint implements ConstraintInterface
+{
+    /** @var string|null */
+    protected $prettyString;
+
+    /**
+     * @param ConstraintInterface $provider
+     *
+     * @return bool
+     */
+    public function matches(ConstraintInterface $provider)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function compile($otherOperator)
+    {
+        return 'true';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setPrettyString($prettyString)
+    {
+        $this->prettyString = $prettyString;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPrettyString()
+    {
+        if ($this->prettyString) {
+            return $this->prettyString;
+        }
+
+        return (string) $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __toString()
+    {
+        return '*';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getUpperBound()
+    {
+        return Bound::positiveInfinity();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getLowerBound()
+    {
+        return Bound::zero();
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Constraint/MatchNoneConstraint.php b/msd/vendor/composer/semver/src/Constraint/MatchNoneConstraint.php
new file mode 100644
index 00000000..dadcf622
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Constraint/MatchNoneConstraint.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+/**
+ * Blackhole of constraints, nothing escapes it
+ */
+class MatchNoneConstraint implements ConstraintInterface
+{
+    /** @var string|null */
+    protected $prettyString;
+
+    /**
+     * @param ConstraintInterface $provider
+     *
+     * @return bool
+     */
+    public function matches(ConstraintInterface $provider)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function compile($otherOperator)
+    {
+        return 'false';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setPrettyString($prettyString)
+    {
+        $this->prettyString = $prettyString;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPrettyString()
+    {
+        if ($this->prettyString) {
+            return $this->prettyString;
+        }
+
+        return (string) $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __toString()
+    {
+        return '[]';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getUpperBound()
+    {
+        return new Bound('0.0.0.0-dev', false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getLowerBound()
+    {
+        return new Bound('0.0.0.0-dev', false);
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Constraint/MultiConstraint.php b/msd/vendor/composer/semver/src/Constraint/MultiConstraint.php
new file mode 100644
index 00000000..1f4c0061
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Constraint/MultiConstraint.php
@@ -0,0 +1,325 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver\Constraint;
+
+/**
+ * Defines a conjunctive or disjunctive set of constraints.
+ */
+class MultiConstraint implements ConstraintInterface
+{
+    /**
+     * @var ConstraintInterface[]
+     * @phpstan-var non-empty-array<ConstraintInterface>
+     */
+    protected $constraints;
+
+    /** @var string|null */
+    protected $prettyString;
+
+    /** @var string|null */
+    protected $string;
+
+    /** @var bool */
+    protected $conjunctive;
+
+    /** @var Bound|null */
+    protected $lowerBound;
+
+    /** @var Bound|null */
+    protected $upperBound;
+
+    /**
+     * @param ConstraintInterface[] $constraints A set of constraints
+     * @param bool                  $conjunctive Whether the constraints should be treated as conjunctive or disjunctive
+     *
+     * @throws \InvalidArgumentException If less than 2 constraints are passed
+     */
+    public function __construct(array $constraints, $conjunctive = true)
+    {
+        if (\count($constraints) < 2) {
+            throw new \InvalidArgumentException(
+                'Must provide at least two constraints for a MultiConstraint. Use '.
+                'the regular Constraint class for one constraint only or MatchAllConstraint for none. You may use '.
+                'MultiConstraint::create() which optimizes and handles those cases automatically.'
+            );
+        }
+
+        $this->constraints = $constraints;
+        $this->conjunctive = $conjunctive;
+    }
+
+    /**
+     * @return ConstraintInterface[]
+     */
+    public function getConstraints()
+    {
+        return $this->constraints;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isConjunctive()
+    {
+        return $this->conjunctive;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isDisjunctive()
+    {
+        return !$this->conjunctive;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function compile($otherOperator)
+    {
+        $parts = array();
+        foreach ($this->constraints as $constraint) {
+            $code = $constraint->compile($otherOperator);
+            if ($code === 'true') {
+                if (!$this->conjunctive) {
+                    return 'true';
+                }
+            } elseif ($code === 'false') {
+                if ($this->conjunctive) {
+                    return 'false';
+                }
+            } else {
+                $parts[] = '('.$code.')';
+            }
+        }
+
+        if (!$parts) {
+            return $this->conjunctive ? 'true' : 'false';
+        }
+
+        return $this->conjunctive ? implode('&&', $parts) : implode('||', $parts);
+    }
+
+    /**
+     * @param ConstraintInterface $provider
+     *
+     * @return bool
+     */
+    public function matches(ConstraintInterface $provider)
+    {
+        if (false === $this->conjunctive) {
+            foreach ($this->constraints as $constraint) {
+                if ($provider->matches($constraint)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        // when matching a conjunctive and a disjunctive multi constraint we have to iterate over the disjunctive one
+        // otherwise we'd return true if different parts of the disjunctive constraint match the conjunctive one
+        // which would lead to incorrect results, e.g. [>1 and <2] would match [<1 or >2] although they do not intersect
+        if ($provider instanceof MultiConstraint && $provider->isDisjunctive()) {
+            return $provider->matches($this);
+        }
+
+        foreach ($this->constraints as $constraint) {
+            if (!$provider->matches($constraint)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setPrettyString($prettyString)
+    {
+        $this->prettyString = $prettyString;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPrettyString()
+    {
+        if ($this->prettyString) {
+            return $this->prettyString;
+        }
+
+        return (string) $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __toString()
+    {
+        if ($this->string !== null) {
+            return $this->string;
+        }
+
+        $constraints = array();
+        foreach ($this->constraints as $constraint) {
+            $constraints[] = (string) $constraint;
+        }
+
+        return $this->string = '[' . implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getLowerBound()
+    {
+        $this->extractBounds();
+
+        if (null === $this->lowerBound) {
+            throw new \LogicException('extractBounds should have populated the lowerBound property');
+        }
+
+        return $this->lowerBound;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getUpperBound()
+    {
+        $this->extractBounds();
+
+        if (null === $this->upperBound) {
+            throw new \LogicException('extractBounds should have populated the upperBound property');
+        }
+
+        return $this->upperBound;
+    }
+
+    /**
+     * Tries to optimize the constraints as much as possible, meaning
+     * reducing/collapsing congruent constraints etc.
+     * Does not necessarily return a MultiConstraint instance if
+     * things can be reduced to a simple constraint
+     *
+     * @param ConstraintInterface[] $constraints A set of constraints
+     * @param bool                  $conjunctive Whether the constraints should be treated as conjunctive or disjunctive
+     *
+     * @return ConstraintInterface
+     */
+    public static function create(array $constraints, $conjunctive = true)
+    {
+        if (0 === \count($constraints)) {
+            return new MatchAllConstraint();
+        }
+
+        if (1 === \count($constraints)) {
+            return $constraints[0];
+        }
+
+        $optimized = self::optimizeConstraints($constraints, $conjunctive);
+        if ($optimized !== null) {
+            list($constraints, $conjunctive) = $optimized;
+            if (\count($constraints) === 1) {
+                return $constraints[0];
+            }
+        }
+
+        return new self($constraints, $conjunctive);
+    }
+
+    /**
+     * @param  ConstraintInterface[] $constraints
+     * @param  bool                  $conjunctive
+     * @return ?array
+     *
+     * @phpstan-return array{0: list<ConstraintInterface>, 1: bool}|null
+     */
+    private static function optimizeConstraints(array $constraints, $conjunctive)
+    {
+        // parse the two OR groups and if they are contiguous we collapse
+        // them into one constraint
+        // [>= 1 < 2] || [>= 2 < 3] || [>= 3 < 4] => [>= 1 < 4]
+        if (!$conjunctive) {
+            $left = $constraints[0];
+            $mergedConstraints = array();
+            $optimized = false;
+            for ($i = 1, $l = \count($constraints); $i < $l; $i++) {
+                $right = $constraints[$i];
+                if (
+                    $left instanceof self
+                    && $left->conjunctive
+                    && $right instanceof self
+                    && $right->conjunctive
+                    && \count($left->constraints) === 2
+                    && \count($right->constraints) === 2
+                    && ($left0 = (string) $left->constraints[0])
+                    && $left0[0] === '>' && $left0[1] === '='
+                    && ($left1 = (string) $left->constraints[1])
+                    && $left1[0] === '<'
+                    && ($right0 = (string) $right->constraints[0])
+                    && $right0[0] === '>' && $right0[1] === '='
+                    && ($right1 = (string) $right->constraints[1])
+                    && $right1[0] === '<'
+                    && substr($left1, 2) === substr($right0, 3)
+                ) {
+                    $optimized = true;
+                    $left = new MultiConstraint(
+                        array(
+                            $left->constraints[0],
+                            $right->constraints[1],
+                        ),
+                        true);
+                } else {
+                    $mergedConstraints[] = $left;
+                    $left = $right;
+                }
+            }
+            if ($optimized) {
+                $mergedConstraints[] = $left;
+                return array($mergedConstraints, false);
+            }
+        }
+
+        // TODO: Here's the place to put more optimizations
+
+        return null;
+    }
+
+    /**
+     * @return void
+     */
+    private function extractBounds()
+    {
+        if (null !== $this->lowerBound) {
+            return;
+        }
+
+        foreach ($this->constraints as $constraint) {
+            if (null === $this->lowerBound || null === $this->upperBound) {
+                $this->lowerBound = $constraint->getLowerBound();
+                $this->upperBound = $constraint->getUpperBound();
+                continue;
+            }
+
+            if ($constraint->getLowerBound()->compareTo($this->lowerBound, $this->isConjunctive() ? '>' : '<')) {
+                $this->lowerBound = $constraint->getLowerBound();
+            }
+
+            if ($constraint->getUpperBound()->compareTo($this->upperBound, $this->isConjunctive() ? '<' : '>')) {
+                $this->upperBound = $constraint->getUpperBound();
+            }
+        }
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Interval.php b/msd/vendor/composer/semver/src/Interval.php
new file mode 100644
index 00000000..43d5a4f5
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Interval.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver;
+
+use Composer\Semver\Constraint\Constraint;
+
+class Interval
+{
+    /** @var Constraint */
+    private $start;
+    /** @var Constraint */
+    private $end;
+
+    public function __construct(Constraint $start, Constraint $end)
+    {
+        $this->start = $start;
+        $this->end = $end;
+    }
+
+    /**
+     * @return Constraint
+     */
+    public function getStart()
+    {
+        return $this->start;
+    }
+
+    /**
+     * @return Constraint
+     */
+    public function getEnd()
+    {
+        return $this->end;
+    }
+
+    /**
+     * @return Constraint
+     */
+    public static function fromZero()
+    {
+        static $zero;
+
+        if (null === $zero) {
+            $zero = new Constraint('>=', '0.0.0.0-dev');
+        }
+
+        return $zero;
+    }
+
+    /**
+     * @return Constraint
+     */
+    public static function untilPositiveInfinity()
+    {
+        static $positiveInfinity;
+
+        if (null === $positiveInfinity) {
+            $positiveInfinity = new Constraint('<', PHP_INT_MAX.'.0.0.0');
+        }
+
+        return $positiveInfinity;
+    }
+
+    /**
+     * @return self
+     */
+    public static function any()
+    {
+        return new self(self::fromZero(), self::untilPositiveInfinity());
+    }
+
+    /**
+     * @return array{'names': string[], 'exclude': bool}
+     */
+    public static function anyDev()
+    {
+        // any == exclude nothing
+        return array('names' => array(), 'exclude' => true);
+    }
+
+    /**
+     * @return array{'names': string[], 'exclude': bool}
+     */
+    public static function noDev()
+    {
+        // nothing == no names included
+        return array('names' => array(), 'exclude' => false);
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Intervals.php b/msd/vendor/composer/semver/src/Intervals.php
new file mode 100644
index 00000000..d889d0ad
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Intervals.php
@@ -0,0 +1,478 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver;
+
+use Composer\Semver\Constraint\Constraint;
+use Composer\Semver\Constraint\ConstraintInterface;
+use Composer\Semver\Constraint\MatchAllConstraint;
+use Composer\Semver\Constraint\MatchNoneConstraint;
+use Composer\Semver\Constraint\MultiConstraint;
+
+/**
+ * Helper class generating intervals from constraints
+ *
+ * This contains utilities for:
+ *
+ *  - compacting an existing constraint which can be used to combine several into one
+ * by creating a MultiConstraint out of the many constraints you have.
+ *
+ *  - checking whether one subset is a subset of another.
+ *
+ * Note: You should call clear to free memoization memory  usage when you are done using this class
+ */
+class Intervals
+{
+    /**
+     * @phpstan-var array<string, array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}>
+     */
+    private static $intervalsCache = array();
+
+    /**
+     * @phpstan-var array<string, int>
+     */
+    private static $opSortOrder = array(
+        '>=' => -3,
+        '<' => -2,
+        '>' => 2,
+        '<=' => 3,
+    );
+
+    /**
+     * Clears the memoization cache once you are done
+     *
+     * @return void
+     */
+    public static function clear()
+    {
+        self::$intervalsCache = array();
+    }
+
+    /**
+     * Checks whether $candidate is a subset of $constraint
+     *
+     * @return bool
+     */
+    public static function isSubsetOf(ConstraintInterface $candidate, ConstraintInterface $constraint)
+    {
+        if ($constraint instanceof MatchAllConstraint) {
+            return true;
+        }
+
+        if ($candidate instanceof MatchNoneConstraint || $constraint instanceof MatchNoneConstraint) {
+            return false;
+        }
+
+        $intersectionIntervals = self::get(new MultiConstraint(array($candidate, $constraint), true));
+        $candidateIntervals = self::get($candidate);
+        if (\count($intersectionIntervals['numeric']) !== \count($candidateIntervals['numeric'])) {
+            return false;
+        }
+
+        foreach ($intersectionIntervals['numeric'] as $index => $interval) {
+            if (!isset($candidateIntervals['numeric'][$index])) {
+                return false;
+            }
+
+            if ((string) $candidateIntervals['numeric'][$index]->getStart() !== (string) $interval->getStart()) {
+                return false;
+            }
+
+            if ((string) $candidateIntervals['numeric'][$index]->getEnd() !== (string) $interval->getEnd()) {
+                return false;
+            }
+        }
+
+        if ($intersectionIntervals['branches']['exclude'] !== $candidateIntervals['branches']['exclude']) {
+            return false;
+        }
+        if (\count($intersectionIntervals['branches']['names']) !== \count($candidateIntervals['branches']['names'])) {
+            return false;
+        }
+        foreach ($intersectionIntervals['branches']['names'] as $index => $name) {
+            if ($name !== $candidateIntervals['branches']['names'][$index]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks whether $a and $b have any intersection, equivalent to $a->matches($b)
+     *
+     * @return bool
+     */
+    public static function haveIntersections(ConstraintInterface $a, ConstraintInterface $b)
+    {
+        if ($a instanceof MatchAllConstraint || $b instanceof MatchAllConstraint) {
+            return true;
+        }
+
+        if ($a instanceof MatchNoneConstraint || $b instanceof MatchNoneConstraint) {
+            return false;
+        }
+
+        $intersectionIntervals = self::generateIntervals(new MultiConstraint(array($a, $b), true), true);
+
+        return \count($intersectionIntervals['numeric']) > 0 || $intersectionIntervals['branches']['exclude'] || \count($intersectionIntervals['branches']['names']) > 0;
+    }
+
+    /**
+     * Attempts to optimize a MultiConstraint
+     *
+     * When merging MultiConstraints together they can get very large, this will
+     * compact it by looking at the real intervals covered by all the constraints
+     * and then creates a new constraint containing only the smallest amount of rules
+     * to match the same intervals.
+     *
+     * @return ConstraintInterface
+     */
+    public static function compactConstraint(ConstraintInterface $constraint)
+    {
+        if (!$constraint instanceof MultiConstraint) {
+            return $constraint;
+        }
+
+        $intervals = self::generateIntervals($constraint);
+        $constraints = array();
+        $hasNumericMatchAll = false;
+
+        if (\count($intervals['numeric']) === 1 && (string) $intervals['numeric'][0]->getStart() === (string) Interval::fromZero() && (string) $intervals['numeric'][0]->getEnd() === (string) Interval::untilPositiveInfinity()) {
+            $constraints[] = $intervals['numeric'][0]->getStart();
+            $hasNumericMatchAll = true;
+        } else {
+            $unEqualConstraints = array();
+            for ($i = 0, $count = \count($intervals['numeric']); $i < $count; $i++) {
+                $interval = $intervals['numeric'][$i];
+
+                // if current interval ends with < N and next interval begins with > N we can swap this out for != N
+                // but this needs to happen as a conjunctive expression together with the start of the current interval
+                // and end of next interval, so [>=M, <N] || [>N, <P] => [>=M, !=N, <P] but M/P can be skipped if
+                // they are zero/+inf
+                if ($interval->getEnd()->getOperator() === '<' && $i+1 < $count) {
+                    $nextInterval = $intervals['numeric'][$i+1];
+                    if ($interval->getEnd()->getVersion() === $nextInterval->getStart()->getVersion() && $nextInterval->getStart()->getOperator() === '>') {
+                        // only add a start if we didn't already do so, can be skipped if we're looking at second
+                        // interval in [>=M, <N] || [>N, <P] || [>P, <Q] where unEqualConstraints currently contains
+                        // [>=M, !=N] already and we only want to add !=P right now
+                        if (\count($unEqualConstraints) === 0 && (string) $interval->getStart() !== (string) Interval::fromZero()) {
+                            $unEqualConstraints[] = $interval->getStart();
+                        }
+                        $unEqualConstraints[] = new Constraint('!=', $interval->getEnd()->getVersion());
+                        continue;
+                    }
+                }
+
+                if (\count($unEqualConstraints) > 0) {
+                    // this is where the end of the following interval of a != constraint is added as explained above
+                    if ((string) $interval->getEnd() !== (string) Interval::untilPositiveInfinity()) {
+                        $unEqualConstraints[] = $interval->getEnd();
+                    }
+
+                    // count is 1 if entire constraint is just one != expression
+                    if (\count($unEqualConstraints) > 1) {
+                        $constraints[] = new MultiConstraint($unEqualConstraints, true);
+                    } else {
+                        $constraints[] = $unEqualConstraints[0];
+                    }
+
+                    $unEqualConstraints = array();
+                    continue;
+                }
+
+                // convert back >= x - <= x intervals to == x
+                if ($interval->getStart()->getVersion() === $interval->getEnd()->getVersion() && $interval->getStart()->getOperator() === '>=' && $interval->getEnd()->getOperator() === '<=') {
+                    $constraints[] = new Constraint('==', $interval->getStart()->getVersion());
+                    continue;
+                }
+
+                if ((string) $interval->getStart() === (string) Interval::fromZero()) {
+                    $constraints[] = $interval->getEnd();
+                } elseif ((string) $interval->getEnd() === (string) Interval::untilPositiveInfinity()) {
+                    $constraints[] = $interval->getStart();
+                } else {
+                    $constraints[] = new MultiConstraint(array($interval->getStart(), $interval->getEnd()), true);
+                }
+            }
+        }
+
+        $devConstraints = array();
+
+        if (0 === \count($intervals['branches']['names'])) {
+            if ($intervals['branches']['exclude']) {
+                if ($hasNumericMatchAll) {
+                    return new MatchAllConstraint;
+                }
+                // otherwise constraint should contain a != operator and already cover this
+            }
+        } else {
+            foreach ($intervals['branches']['names'] as $branchName) {
+                if ($intervals['branches']['exclude']) {
+                    $devConstraints[] = new Constraint('!=', $branchName);
+                } else {
+                    $devConstraints[] = new Constraint('==', $branchName);
+                }
+            }
+
+            // excluded branches, e.g. != dev-foo are conjunctive with the interval, so
+            // > 2.0 != dev-foo must return a conjunctive constraint
+            if ($intervals['branches']['exclude']) {
+                if (\count($constraints) > 1) {
+                    return new MultiConstraint(array_merge(
+                        array(new MultiConstraint($constraints, false)),
+                        $devConstraints
+                    ), true);
+                }
+
+                if (\count($constraints) === 1 && (string)$constraints[0] === (string)Interval::fromZero()) {
+                    if (\count($devConstraints) > 1) {
+                        return new MultiConstraint($devConstraints, true);
+                    }
+                    return $devConstraints[0];
+                }
+
+                return new MultiConstraint(array_merge($constraints, $devConstraints), true);
+            }
+
+            // otherwise devConstraints contains a list of == operators for branches which are disjunctive with the
+            // rest of the constraint
+            $constraints = array_merge($constraints, $devConstraints);
+        }
+
+        if (\count($constraints) > 1) {
+            return new MultiConstraint($constraints, false);
+        }
+
+        if (\count($constraints) === 1) {
+            return $constraints[0];
+        }
+
+        return new MatchNoneConstraint;
+    }
+
+    /**
+     * Creates an array of numeric intervals and branch constraints representing a given constraint
+     *
+     * if the returned numeric array is empty it means the constraint matches nothing in the numeric range (0 - +inf)
+     * if the returned branches array is empty it means no dev-* versions are matched
+     * if a constraint matches all possible dev-* versions, branches will contain Interval::anyDev()
+     *
+     * @return array
+     * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
+     */
+    public static function get(ConstraintInterface $constraint)
+    {
+        $key = (string) $constraint;
+
+        if (!isset(self::$intervalsCache[$key])) {
+            self::$intervalsCache[$key] = self::generateIntervals($constraint);
+        }
+
+        return self::$intervalsCache[$key];
+    }
+
+    /**
+     * @param bool $stopOnFirstValidInterval
+     *
+     * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
+     */
+    private static function generateIntervals(ConstraintInterface $constraint, $stopOnFirstValidInterval = false)
+    {
+        if ($constraint instanceof MatchAllConstraint) {
+            return array('numeric' => array(new Interval(Interval::fromZero(), Interval::untilPositiveInfinity())), 'branches' => Interval::anyDev());
+        }
+
+        if ($constraint instanceof MatchNoneConstraint) {
+            return array('numeric' => array(), 'branches' => array('names' => array(), 'exclude' => false));
+        }
+
+        if ($constraint instanceof Constraint) {
+            return self::generateSingleConstraintIntervals($constraint);
+        }
+
+        if (!$constraint instanceof MultiConstraint) {
+            throw new \UnexpectedValueException('The constraint passed in should be an MatchAllConstraint, Constraint or MultiConstraint instance, got '.\get_class($constraint).'.');
+        }
+
+        $constraints = $constraint->getConstraints();
+
+        $numericGroups = array();
+        $constraintBranches = array();
+        foreach ($constraints as $c) {
+            $res = self::get($c);
+            $numericGroups[] = $res['numeric'];
+            $constraintBranches[] = $res['branches'];
+        }
+
+        if ($constraint->isDisjunctive()) {
+            $branches = Interval::noDev();
+            foreach ($constraintBranches as $b) {
+                if ($b['exclude']) {
+                    if ($branches['exclude']) {
+                        // disjunctive constraint, so only exclude what's excluded in all constraints
+                        // !=a,!=b || !=b,!=c => !=b
+                        $branches['names'] = array_intersect($branches['names'], $b['names']);
+                    } else {
+                        // disjunctive constraint so exclude all names which are not explicitly included in the alternative
+                        // (==b || ==c) || !=a,!=b => !=a
+                        $branches['exclude'] = true;
+                        $branches['names'] = array_diff($b['names'], $branches['names']);
+                    }
+                } else {
+                    if ($branches['exclude']) {
+                        // disjunctive constraint so exclude all names which are not explicitly included in the alternative
+                        // !=a,!=b || (==b || ==c) => !=a
+                        $branches['names'] = array_diff($branches['names'], $b['names']);
+                    } else {
+                        // disjunctive constraint, so just add all the other branches
+                        // (==a || ==b) || ==c => ==a || ==b || ==c
+                        $branches['names'] = array_merge($branches['names'], $b['names']);
+                    }
+                }
+            }
+        } else {
+            $branches = Interval::anyDev();
+            foreach ($constraintBranches as $b) {
+                if ($b['exclude']) {
+                    if ($branches['exclude']) {
+                        // conjunctive, so just add all branch names to be excluded
+                        // !=a && !=b => !=a,!=b
+                        $branches['names'] = array_merge($branches['names'], $b['names']);
+                    } else {
+                        // conjunctive, so only keep included names which are not excluded
+                        // (==a||==c) && !=a,!=b => ==c
+                        $branches['names'] = array_diff($branches['names'], $b['names']);
+                    }
+                } else {
+                    if ($branches['exclude']) {
+                        // conjunctive, so only keep included names which are not excluded
+                        // !=a,!=b && (==a||==c) => ==c
+                        $branches['names'] = array_diff($b['names'], $branches['names']);
+                        $branches['exclude'] = false;
+                    } else {
+                        // conjunctive, so only keep names that are included in both
+                        // (==a||==b) && (==a||==c) => ==a
+                        $branches['names'] = array_intersect($branches['names'], $b['names']);
+                    }
+                }
+            }
+        }
+
+        $branches['names'] = array_unique($branches['names']);
+
+        if (\count($numericGroups) === 1) {
+            return array('numeric' => $numericGroups[0], 'branches' => $branches);
+        }
+
+        $borders = array();
+        foreach ($numericGroups as $group) {
+            foreach ($group as $interval) {
+                $borders[] = array('version' => $interval->getStart()->getVersion(), 'operator' => $interval->getStart()->getOperator(), 'side' => 'start');
+                $borders[] = array('version' => $interval->getEnd()->getVersion(), 'operator' => $interval->getEnd()->getOperator(), 'side' => 'end');
+            }
+        }
+
+        $opSortOrder = self::$opSortOrder;
+        usort($borders, function ($a, $b) use ($opSortOrder) {
+            $order = version_compare($a['version'], $b['version']);
+            if ($order === 0) {
+                return $opSortOrder[$a['operator']] - $opSortOrder[$b['operator']];
+            }
+
+            return $order;
+        });
+
+        $activeIntervals = 0;
+        $intervals = array();
+        $index = 0;
+        $activationThreshold = $constraint->isConjunctive() ? \count($numericGroups) : 1;
+        $start = null;
+        foreach ($borders as $border) {
+            if ($border['side'] === 'start') {
+                $activeIntervals++;
+            } else {
+                $activeIntervals--;
+            }
+            if (!$start && $activeIntervals >= $activationThreshold) {
+                $start = new Constraint($border['operator'], $border['version']);
+            } elseif ($start && $activeIntervals < $activationThreshold) {
+                // filter out invalid intervals like > x - <= x, or >= x - < x
+                if (
+                    version_compare($start->getVersion(), $border['version'], '=')
+                    && (
+                        ($start->getOperator() === '>' && $border['operator'] === '<=')
+                        || ($start->getOperator() === '>=' && $border['operator'] === '<')
+                    )
+                ) {
+                    unset($intervals[$index]);
+                } else {
+                    $intervals[$index] = new Interval($start, new Constraint($border['operator'], $border['version']));
+                    $index++;
+
+                    if ($stopOnFirstValidInterval) {
+                        break;
+                    }
+                }
+
+                $start = null;
+            }
+        }
+
+        return array('numeric' => $intervals, 'branches' => $branches);
+    }
+
+    /**
+     * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
+     */
+    private static function generateSingleConstraintIntervals(Constraint $constraint)
+    {
+        $op = $constraint->getOperator();
+
+        // handle branch constraints first
+        if (strpos($constraint->getVersion(), 'dev-') === 0) {
+            $intervals = array();
+            $branches = array('names' => array(), 'exclude' => false);
+
+            // != dev-foo means any numeric version may match, we treat >/< like != they are not really defined for branches
+            if ($op === '!=') {
+                $intervals[] = new Interval(Interval::fromZero(), Interval::untilPositiveInfinity());
+                $branches = array('names' => array($constraint->getVersion()), 'exclude' => true);
+            } elseif ($op === '==') {
+                $branches['names'][] = $constraint->getVersion();
+            }
+
+            return array(
+                'numeric' => $intervals,
+                'branches' => $branches,
+            );
+        }
+
+        if ($op[0] === '>') { // > & >=
+            return array('numeric' => array(new Interval($constraint, Interval::untilPositiveInfinity())), 'branches' => Interval::noDev());
+        }
+        if ($op[0] === '<') { // < & <=
+            return array('numeric' => array(new Interval(Interval::fromZero(), $constraint)), 'branches' => Interval::noDev());
+        }
+        if ($op === '!=') {
+            // convert !=x to intervals of 0 - <x && >x - +inf + dev*
+            return array('numeric' => array(
+                new Interval(Interval::fromZero(), new Constraint('<', $constraint->getVersion())),
+                new Interval(new Constraint('>', $constraint->getVersion()), Interval::untilPositiveInfinity()),
+            ), 'branches' => Interval::anyDev());
+        }
+
+        // convert ==x to an interval of >=x - <=x
+        return array('numeric' => array(
+            new Interval(new Constraint('>=', $constraint->getVersion()), new Constraint('<=', $constraint->getVersion())),
+        ), 'branches' => Interval::noDev());
+    }
+}
diff --git a/msd/vendor/composer/semver/src/Semver.php b/msd/vendor/composer/semver/src/Semver.php
new file mode 100644
index 00000000..4d6de3c2
--- /dev/null
+++ b/msd/vendor/composer/semver/src/Semver.php
@@ -0,0 +1,129 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver;
+
+use Composer\Semver\Constraint\Constraint;
+
+class Semver
+{
+    const SORT_ASC = 1;
+    const SORT_DESC = -1;
+
+    /** @var VersionParser */
+    private static $versionParser;
+
+    /**
+     * Determine if given version satisfies given constraints.
+     *
+     * @param string $version
+     * @param string $constraints
+     *
+     * @return bool
+     */
+    public static function satisfies($version, $constraints)
+    {
+        if (null === self::$versionParser) {
+            self::$versionParser = new VersionParser();
+        }
+
+        $versionParser = self::$versionParser;
+        $provider = new Constraint('==', $versionParser->normalize($version));
+        $parsedConstraints = $versionParser->parseConstraints($constraints);
+
+        return $parsedConstraints->matches($provider);
+    }
+
+    /**
+     * Return all versions that satisfy given constraints.
+     *
+     * @param string[] $versions
+     * @param string   $constraints
+     *
+     * @return string[]
+     */
+    public static function satisfiedBy(array $versions, $constraints)
+    {
+        $versions = array_filter($versions, function ($version) use ($constraints) {
+            return Semver::satisfies($version, $constraints);
+        });
+
+        return array_values($versions);
+    }
+
+    /**
+     * Sort given array of versions.
+     *
+     * @param string[] $versions
+     *
+     * @return string[]
+     */
+    public static function sort(array $versions)
+    {
+        return self::usort($versions, self::SORT_ASC);
+    }
+
+    /**
+     * Sort given array of versions in reverse.
+     *
+     * @param string[] $versions
+     *
+     * @return string[]
+     */
+    public static function rsort(array $versions)
+    {
+        return self::usort($versions, self::SORT_DESC);
+    }
+
+    /**
+     * @param string[] $versions
+     * @param int      $direction
+     *
+     * @return string[]
+     */
+    private static function usort(array $versions, $direction)
+    {
+        if (null === self::$versionParser) {
+            self::$versionParser = new VersionParser();
+        }
+
+        $versionParser = self::$versionParser;
+        $normalized = array();
+
+        // Normalize outside of usort() scope for minor performance increase.
+        // Creates an array of arrays: [[normalized, key], ...]
+        foreach ($versions as $key => $version) {
+            $normalizedVersion = $versionParser->normalize($version);
+            $normalizedVersion = $versionParser->normalizeDefaultBranch($normalizedVersion);
+            $normalized[] = array($normalizedVersion, $key);
+        }
+
+        usort($normalized, function (array $left, array $right) use ($direction) {
+            if ($left[0] === $right[0]) {
+                return 0;
+            }
+
+            if (Comparator::lessThan($left[0], $right[0])) {
+                return -$direction;
+            }
+
+            return $direction;
+        });
+
+        // Recreate input array, using the original indexes which are now in sorted order.
+        $sorted = array();
+        foreach ($normalized as $item) {
+            $sorted[] = $versions[$item[1]];
+        }
+
+        return $sorted;
+    }
+}
diff --git a/msd/vendor/composer/semver/src/VersionParser.php b/msd/vendor/composer/semver/src/VersionParser.php
new file mode 100644
index 00000000..202ce247
--- /dev/null
+++ b/msd/vendor/composer/semver/src/VersionParser.php
@@ -0,0 +1,586 @@
+<?php
+
+/*
+ * This file is part of composer/semver.
+ *
+ * (c) Composer <https://github.com/composer>
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
+namespace Composer\Semver;
+
+use Composer\Semver\Constraint\ConstraintInterface;
+use Composer\Semver\Constraint\MatchAllConstraint;
+use Composer\Semver\Constraint\MultiConstraint;
+use Composer\Semver\Constraint\Constraint;
+
+/**
+ * Version parser.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class VersionParser
+{
+    /**
+     * Regex to match pre-release data (sort of).
+     *
+     * Due to backwards compatibility:
+     *   - Instead of enforcing hyphen, an underscore, dot or nothing at all are also accepted.
+     *   - Only stabilities as recognized by Composer are allowed to precede a numerical identifier.
+     *   - Numerical-only pre-release identifiers are not supported, see tests.
+     *
+     *                        |--------------|
+     * [major].[minor].[patch] -[pre-release] +[build-metadata]
+     *
+     * @var string
+     */
+    private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*+)?)?([.-]?dev)?';
+
+    /** @var string */
+    private static $stabilitiesRegex = 'stable|RC|beta|alpha|dev';
+
+    /**
+     * Returns the stability of a version.
+     *
+     * @param string $version
+     *
+     * @return string
+     * @phpstan-return 'stable'|'RC'|'beta'|'alpha'|'dev'
+     */
+    public static function parseStability($version)
+    {
+        $version = (string) preg_replace('{#.+$}', '', (string) $version);
+
+        if (strpos($version, 'dev-') === 0 || '-dev' === substr($version, -4)) {
+            return 'dev';
+        }
+
+        preg_match('{' . self::$modifierRegex . '(?:\+.*)?$}i', strtolower($version), $match);
+
+        if (!empty($match[3])) {
+            return 'dev';
+        }
+
+        if (!empty($match[1])) {
+            if ('beta' === $match[1] || 'b' === $match[1]) {
+                return 'beta';
+            }
+            if ('alpha' === $match[1] || 'a' === $match[1]) {
+                return 'alpha';
+            }
+            if ('rc' === $match[1]) {
+                return 'RC';
+            }
+        }
+
+        return 'stable';
+    }
+
+    /**
+     * @param string $stability
+     *
+     * @return string
+     */
+    public static function normalizeStability($stability)
+    {
+        $stability = strtolower((string) $stability);
+
+        return $stability === 'rc' ? 'RC' : $stability;
+    }
+
+    /**
+     * Normalizes a version string to be able to perform comparisons on it.
+     *
+     * @param string $version
+     * @param ?string $fullVersion optional complete version string to give more context
+     *
+     * @throws \UnexpectedValueException
+     *
+     * @return string
+     */
+    public function normalize($version, $fullVersion = null)
+    {
+        $version = trim((string) $version);
+        $origVersion = $version;
+        if (null === $fullVersion) {
+            $fullVersion = $version;
+        }
+
+        // strip off aliasing
+        if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $version, $match)) {
+            $version = $match[1];
+        }
+
+        // strip off stability flag
+        if (preg_match('{@(?:' . self::$stabilitiesRegex . ')$}i', $version, $match)) {
+            $version = substr($version, 0, strlen($version) - strlen($match[0]));
+        }
+
+        // normalize master/trunk/default branches to dev-name for BC with 1.x as these used to be valid constraints
+        if (\in_array($version, array('master', 'trunk', 'default'), true)) {
+            $version = 'dev-' . $version;
+        }
+
+        // if requirement is branch-like, use full name
+        if (stripos($version, 'dev-') === 0) {
+            return 'dev-' . substr($version, 4);
+        }
+
+        // strip off build metadata
+        if (preg_match('{^([^,\s+]++)\+[^\s]++$}', $version, $match)) {
+            $version = $match[1];
+        }
+
+        // match classical versioning
+        if (preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
+            $version = $matches[1]
+                . (!empty($matches[2]) ? $matches[2] : '.0')
+                . (!empty($matches[3]) ? $matches[3] : '.0')
+                . (!empty($matches[4]) ? $matches[4] : '.0');
+            $index = 5;
+        // match date(time) based versioning
+        } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
+            $version = preg_replace('{\D}', '.', $matches[1]);
+            $index = 2;
+        }
+
+        // add version modifiers if a version was matched
+        if (isset($index)) {
+            if (!empty($matches[$index])) {
+                if ('stable' === $matches[$index]) {
+                    return $version;
+                }
+                $version .= '-' . $this->expandStability($matches[$index]) . (isset($matches[$index + 1]) && '' !== $matches[$index + 1] ? ltrim($matches[$index + 1], '.-') : '');
+            }
+
+            if (!empty($matches[$index + 2])) {
+                $version .= '-dev';
+            }
+
+            return $version;
+        }
+
+        // match dev branches
+        if (preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
+            try {
+                $normalized = $this->normalizeBranch($match[1]);
+                // a branch ending with -dev is only valid if it is numeric
+                // if it gets prefixed with dev- it means the branch name should
+                // have had a dev- prefix already when passed to normalize
+                if (strpos($normalized, 'dev-') === false) {
+                    return $normalized;
+                }
+            } catch (\Exception $e) {
+            }
+        }
+
+        $extraMessage = '';
+        if (preg_match('{ +as +' . preg_quote($version) . '(?:@(?:'.self::$stabilitiesRegex.'))?$}', $fullVersion)) {
+            $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version';
+        } elseif (preg_match('{^' . preg_quote($version) . '(?:@(?:'.self::$stabilitiesRegex.'))? +as +}', $fullVersion)) {
+            $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
+        }
+
+        throw new \UnexpectedValueException('Invalid version string "' . $origVersion . '"' . $extraMessage);
+    }
+
+    /**
+     * Extract numeric prefix from alias, if it is in numeric format, suitable for version comparison.
+     *
+     * @param string $branch Branch name (e.g. 2.1.x-dev)
+     *
+     * @return string|false Numeric prefix if present (e.g. 2.1.) or false
+     */
+    public function parseNumericAliasPrefix($branch)
+    {
+        if (preg_match('{^(?P<version>(\d++\\.)*\d++)(?:\.x)?-dev$}i', (string) $branch, $matches)) {
+            return $matches['version'] . '.';
+        }
+
+        return false;
+    }
+
+    /**
+     * Normalizes a branch name to be able to perform comparisons on it.
+     *
+     * @param string $name
+     *
+     * @return string
+     */
+    public function normalizeBranch($name)
+    {
+        $name = trim((string) $name);
+
+        if (preg_match('{^v?(\d++)(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?$}i', $name, $matches)) {
+            $version = '';
+            for ($i = 1; $i < 5; ++$i) {
+                $version .= isset($matches[$i]) ? str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
+            }
+
+            return str_replace('x', '9999999', $version) . '-dev';
+        }
+
+        return 'dev-' . $name;
+    }
+
+    /**
+     * Normalizes a default branch name (i.e. master on git) to 9999999-dev.
+     *
+     * @param string $name
+     *
+     * @return string
+     *
+     * @deprecated No need to use this anymore in theory, Composer 2 does not normalize any branch names to 9999999-dev anymore
+     */
+    public function normalizeDefaultBranch($name)
+    {
+        if ($name === 'dev-master' || $name === 'dev-default' || $name === 'dev-trunk') {
+            return '9999999-dev';
+        }
+
+        return (string) $name;
+    }
+
+    /**
+     * Parses a constraint string into MultiConstraint and/or Constraint objects.
+     *
+     * @param string $constraints
+     *
+     * @return ConstraintInterface
+     */
+    public function parseConstraints($constraints)
+    {
+        $prettyConstraint = (string) $constraints;
+
+        $orConstraints = preg_split('{\s*\|\|?\s*}', trim((string) $constraints));
+        if (false === $orConstraints) {
+            throw new \RuntimeException('Failed to preg_split string: '.$constraints);
+        }
+        $orGroups = array();
+
+        foreach ($orConstraints as $constraints) {
+            $andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
+            if (false === $andConstraints) {
+                throw new \RuntimeException('Failed to preg_split string: '.$constraints);
+            }
+            if (\count($andConstraints) > 1) {
+                $constraintObjects = array();
+                foreach ($andConstraints as $constraint) {
+                    foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
+                        $constraintObjects[] = $parsedConstraint;
+                    }
+                }
+            } else {
+                $constraintObjects = $this->parseConstraint($andConstraints[0]);
+            }
+
+            if (1 === \count($constraintObjects)) {
+                $constraint = $constraintObjects[0];
+            } else {
+                $constraint = new MultiConstraint($constraintObjects);
+            }
+
+            $orGroups[] = $constraint;
+        }
+
+        $constraint = MultiConstraint::create($orGroups, false);
+
+        $constraint->setPrettyString($prettyConstraint);
+
+        return $constraint;
+    }
+
+    /**
+     * @param string $constraint
+     *
+     * @throws \UnexpectedValueException
+     *
+     * @return array
+     *
+     * @phpstan-return non-empty-array<ConstraintInterface>
+     */
+    private function parseConstraint($constraint)
+    {
+        // strip off aliasing
+        if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $constraint, $match)) {
+            $constraint = $match[1];
+        }
+
+        // strip @stability flags, and keep it for later use
+        if (preg_match('{^([^,\s]*?)@(' . self::$stabilitiesRegex . ')$}i', $constraint, $match)) {
+            $constraint = '' !== $match[1] ? $match[1] : '*';
+            if ($match[2] !== 'stable') {
+                $stabilityModifier = $match[2];
+            }
+        }
+
+        // get rid of #refs as those are used by composer only
+        if (preg_match('{^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#.+$}i', $constraint, $match)) {
+            $constraint = $match[1];
+        }
+
+        if (preg_match('{^(v)?[xX*](\.[xX*])*$}i', $constraint, $match)) {
+            if (!empty($match[1]) || !empty($match[2])) {
+                return array(new Constraint('>=', '0.0.0.0-dev'));
+            }
+
+            return array(new MatchAllConstraint());
+        }
+
+        $versionRegex = 'v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.(\d++))?(?:' . self::$modifierRegex . '|\.([xX*][.-]?dev))(?:\+[^\s]+)?';
+
+        // Tilde Range
+        //
+        // Like wildcard constraints, unsuffixed tilde constraints say that they must be greater than the previous
+        // version, to ensure that unstable instances of the current version are allowed. However, if a stability
+        // suffix is added to the constraint, then a >= match on the current version is used instead.
+        if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
+            if (strpos($constraint, '~>') === 0) {
+                throw new \UnexpectedValueException(
+                    'Could not parse version constraint ' . $constraint . ': ' .
+                    'Invalid operator "~>", you probably meant to use the "~" operator'
+                );
+            }
+
+            // Work out which position in the version we are operating at
+            if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
+                $position = 4;
+            } elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
+                $position = 3;
+            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
+                $position = 2;
+            } else {
+                $position = 1;
+            }
+
+            // when matching 2.x-dev or 3.0.x-dev we have to shift the second or third number, despite no second/third number matching above
+            if (!empty($matches[8])) {
+                $position++;
+            }
+
+            // Calculate the stability suffix
+            $stabilitySuffix = '';
+            if (empty($matches[5]) && empty($matches[7]) && empty($matches[8])) {
+                $stabilitySuffix .= '-dev';
+            }
+
+            $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
+            $lowerBound = new Constraint('>=', $lowVersion);
+
+            // For upper bound, we increment the position of one more significance,
+            // but highPosition = 0 would be illegal
+            $highPosition = max(1, $position - 1);
+            $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
+            $upperBound = new Constraint('<', $highVersion);
+
+            return array(
+                $lowerBound,
+                $upperBound,
+            );
+        }
+
+        // Caret Range
+        //
+        // Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple.
+        // In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for
+        // versions 0.X >=0.1.0, and no updates for versions 0.0.X
+        if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) {
+            // Work out which position in the version we are operating at
+            if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
+                $position = 1;
+            } elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
+                $position = 2;
+            } else {
+                $position = 3;
+            }
+
+            // Calculate the stability suffix
+            $stabilitySuffix = '';
+            if (empty($matches[5]) && empty($matches[7]) && empty($matches[8])) {
+                $stabilitySuffix .= '-dev';
+            }
+
+            $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
+            $lowerBound = new Constraint('>=', $lowVersion);
+
+            // For upper bound, we increment the position of one more significance,
+            // but highPosition = 0 would be illegal
+            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
+            $upperBound = new Constraint('<', $highVersion);
+
+            return array(
+                $lowerBound,
+                $upperBound,
+            );
+        }
+
+        // X Range
+        //
+        // Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple.
+        // A partial version range is treated as an X-Range, so the special character is in fact optional.
+        if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) {
+            if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
+                $position = 3;
+            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
+                $position = 2;
+            } else {
+                $position = 1;
+            }
+
+            $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
+            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
+
+            if ($lowVersion === '0.0.0.0-dev') {
+                return array(new Constraint('<', $highVersion));
+            }
+
+            return array(
+                new Constraint('>=', $lowVersion),
+                new Constraint('<', $highVersion),
+            );
+        }
+
+        // Hyphen Range
+        //
+        // Specifies an inclusive set. If a partial version is provided as the first version in the inclusive range,
+        // then the missing pieces are replaced with zeroes. If a partial version is provided as the second version in
+        // the inclusive range, then all versions that start with the supplied parts of the tuple are accepted, but
+        // nothing that would be greater than the provided tuple parts.
+        if (preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
+            // Calculate the stability suffix
+            $lowStabilitySuffix = '';
+            if (empty($matches[6]) && empty($matches[8]) && empty($matches[9])) {
+                $lowStabilitySuffix = '-dev';
+            }
+
+            $lowVersion = $this->normalize($matches['from']);
+            $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);
+
+            $empty = function ($x) {
+                return ($x === 0 || $x === '0') ? false : empty($x);
+            };
+
+            if ((!$empty($matches[12]) && !$empty($matches[13])) || !empty($matches[15]) || !empty($matches[17]) || !empty($matches[18])) {
+                $highVersion = $this->normalize($matches['to']);
+                $upperBound = new Constraint('<=', $highVersion);
+            } else {
+                $highMatch = array('', $matches[11], $matches[12], $matches[13], $matches[14]);
+
+                // validate to version
+                $this->normalize($matches['to']);
+
+                $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[12]) ? 1 : 2, 1) . '-dev';
+                $upperBound = new Constraint('<', $highVersion);
+            }
+
+            return array(
+                $lowerBound,
+                $upperBound,
+            );
+        }
+
+        // Basic Comparators
+        if (preg_match('{^(<>|!=|>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) {
+            try {
+                try {
+                    $version = $this->normalize($matches[2]);
+                } catch (\UnexpectedValueException $e) {
+                    // recover from an invalid constraint like foobar-dev which should be dev-foobar
+                    // except if the constraint uses a known operator, in which case it must be a parse error
+                    if (substr($matches[2], -4) === '-dev' && preg_match('{^[0-9a-zA-Z-./]+$}', $matches[2])) {
+                        $version = $this->normalize('dev-'.substr($matches[2], 0, -4));
+                    } else {
+                        throw $e;
+                    }
+                }
+
+                $op = $matches[1] ?: '=';
+
+                if ($op !== '==' && $op !== '=' && !empty($stabilityModifier) && self::parseStability($version) === 'stable') {
+                    $version .= '-' . $stabilityModifier;
+                } elseif ('<' === $op || '>=' === $op) {
+                    if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
+                        if (strpos($matches[2], 'dev-') !== 0) {
+                            $version .= '-dev';
+                        }
+                    }
+                }
+
+                return array(new Constraint($matches[1] ?: '=', $version));
+            } catch (\Exception $e) {
+            }
+        }
+
+        $message = 'Could not parse version constraint ' . $constraint;
+        if (isset($e)) {
+            $message .= ': ' . $e->getMessage();
+        }
+
+        throw new \UnexpectedValueException($message);
+    }
+
+    /**
+     * Increment, decrement, or simply pad a version number.
+     *
+     * Support function for {@link parseConstraint()}
+     *
+     * @param array  $matches   Array with version parts in array indexes 1,2,3,4
+     * @param int    $position  1,2,3,4 - which segment of the version to increment/decrement
+     * @param int    $increment
+     * @param string $pad       The string to pad version parts after $position
+     *
+     * @return string|null The new version
+     *
+     * @phpstan-param string[] $matches
+     */
+    private function manipulateVersionString(array $matches, $position, $increment = 0, $pad = '0')
+    {
+        for ($i = 4; $i > 0; --$i) {
+            if ($i > $position) {
+                $matches[$i] = $pad;
+            } elseif ($i === $position && $increment) {
+                $matches[$i] += $increment;
+                // If $matches[$i] was 0, carry the decrement
+                if ($matches[$i] < 0) {
+                    $matches[$i] = $pad;
+                    --$position;
+
+                    // Return null on a carry overflow
+                    if ($i === 1) {
+                        return null;
+                    }
+                }
+            }
+        }
+
+        return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
+    }
+
+    /**
+     * Expand shorthand stability string to long version.
+     *
+     * @param string $stability
+     *
+     * @return string
+     */
+    private function expandStability($stability)
+    {
+        $stability = strtolower($stability);
+
+        switch ($stability) {
+            case 'a':
+                return 'alpha';
+            case 'b':
+                return 'beta';
+            case 'p':
+            case 'pl':
+                return 'patch';
+            case 'rc':
+                return 'RC';
+            default:
+                return $stability;
+        }
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/.formatter.yml b/msd/vendor/desarrolla2/cache/.formatter.yml
new file mode 100644
index 00000000..3225af2e
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/.formatter.yml
@@ -0,0 +1,18 @@
+use-sort:
+    group:
+        - _main
+    group-type: each
+    sort-type: alph
+    sort-direction: asc
+
+header: |
+    /*
+     * This file is part of the Cache package.
+     *
+     * Copyright (c) Daniel González
+     *
+     * For the full copyright and license information, please view the LICENSE
+     * file that was distributed with this source code.
+     *
+     * @author Daniel González <daniel@desarrolla2.com>
+     */
diff --git a/msd/vendor/desarrolla2/cache/.github/workflows/php.yml b/msd/vendor/desarrolla2/cache/.github/workflows/php.yml
new file mode 100644
index 00000000..a411fa9e
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/.github/workflows/php.yml
@@ -0,0 +1,73 @@
+name: PHP
+
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+jobs:
+  run:
+    runs-on: ubuntu-latest
+    services:
+      mysql:
+        image: mysql:5.7
+        ports:
+          - 3306:3306
+        env:
+          MYSQL_ALLOW_EMPTY_PASSWORD: yes
+      redis:
+        image: redis:6.0
+        ports:
+          - 6379:6379
+      mongo:
+        image: mongo:4.2-bionic
+        ports:
+          - 27017:27017
+      memcached:
+        image: memcached:1.6
+        ports:
+          - 11211:11211
+
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - php: 7.2
+            composer: '--prefer-lowest'
+            desc: "Lowest versions"
+          - php: 7.4
+            composer: '--prefer-lowest'
+            desc: "Lowest versions"
+          - php: 7.2
+          - php: 7.3
+          - php: 7.4
+            coverage: '--coverage-clover /tmp/clover.xml'
+          - php: 8.0
+    name: PHP ${{ matrix.php }} ${{ matrix.desc }}
+
+    steps:
+    - uses: actions/checkout@v2
+
+    - name: Setup PHP
+      uses: shivammathur/setup-php@v2
+      with:
+        php-version: ${{ matrix.php }}
+        coverage: xdebug
+        extensions: apcu, mongodb, memcached
+        ini-values: apc.enable_cli=1,mysqli.default_host=127.0.0.1,mysqli.default_port=3306,mysqli.default_user=root
+
+    - name: Validate composer.json and composer.lock
+      run: composer validate
+
+    - name: Install dependencies
+      run: composer update --prefer-dist --no-progress ${{ matrix.composer }}
+
+    - name: Run PHPUnit
+      run: vendor/bin/phpunit ${{ matrix.coverage }}
+
+    - name: Upload coverage to Scrutinizer
+      if: ${{ matrix.coverage }}
+      run: >
+        wget https://scrutinizer-ci.com/ocular.phar -O "/tmp/ocular.phar" &&
+        php "/tmp/ocular.phar" code-coverage:upload --format=php-clover /tmp/clover.xml
diff --git a/msd/vendor/desarrolla2/cache/.gitignore b/msd/vendor/desarrolla2/cache/.gitignore
new file mode 100644
index 00000000..e35f5efa
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/.gitignore
@@ -0,0 +1,9 @@
+/build
+/composer.lock
+/tests/config.json
+/vendor
+/.idea
+/TODO.md
+*~
+*.swp
+/.phpunit.result.cache
\ No newline at end of file
diff --git a/msd/vendor/desarrolla2/cache/.scrutinizer.yml b/msd/vendor/desarrolla2/cache/.scrutinizer.yml
new file mode 100644
index 00000000..e13f6974
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/.scrutinizer.yml
@@ -0,0 +1,31 @@
+#language: php
+checks:
+  php: true
+filter:
+  excluded_paths:
+    - tests
+build:
+  nodes:
+    analysis:
+      environment:
+        php: 
+          version: 7.4
+          pecl_extensions:
+            - apcu
+            - mongodb
+            - memcached
+        mysql: false
+        postgresql: false
+        redis: false
+        mongodb: false
+      tests:
+        override:
+            - phpcs-run src
+            -
+                command: vendor/bin/phpstan analyze --error-format=checkstyle | sed '/^\s*$/d' > phpstan-checkstyle.xml
+                analysis:
+                    file: phpstan-checkstyle.xml
+                    format: 'general-checkstyle'
+            - php-scrutinizer-run
+tools:
+    external_code_coverage: true
diff --git a/msd/vendor/desarrolla2/cache/LICENSE b/msd/vendor/desarrolla2/cache/LICENSE
new file mode 100644
index 00000000..2dd6c18d
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012-2013 Desarrolla2 - http://desarrolla2.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/msd/vendor/desarrolla2/cache/README.md b/msd/vendor/desarrolla2/cache/README.md
new file mode 100644
index 00000000..b71bfafd
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/README.md
@@ -0,0 +1,174 @@
+# Desarolla2 Cache
+
+A **simple cache** library, implementing the [PSR-16](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) standard using **immutable** objects.
+
+![life-is-hard-cache-is](https://user-images.githubusercontent.com/100821/41566888-ecd60cde-735d-11e8-893f-da42b2cd65e7.jpg)
+
+Caching is typically used throughout an applicatiton. Immutability ensure that modifying the cache behaviour in one
+location doesn't result in unexpected behaviour due to changes in unrelated code.
+
+_Desarolla2 Cache aims to be the most complete, correct and best performing PSR-16 implementation available._
+
+[![Latest version][ico-version]][link-packagist]
+[![Latest version][ico-pre-release]][link-packagist]
+[![Software License][ico-license]][link-license]
+[![Build Status][ico-github-actions]][link-github-actions]
+[![Coverage Status][ico-coverage]][link-scrutinizer]
+[![Quality Score][ico-code-quality]][link-scrutinizer]
+[![Total Downloads][ico-downloads]][link-downloads]
+[![Today Downloads][ico-today-downloads]][link-downloads]
+[![Gitter][ico-gitter]][link-gitter]
+
+
+## Installation
+
+```
+composer require desarrolla2/cache
+```
+
+## Usage
+
+
+``` php
+use Desarrolla2\Cache\Memory as Cache;
+
+$cache = new Cache();
+
+$value = $cache->get('key');
+
+if (!isset($value)) {
+    $value = do_something(); 
+    $cache->set('key', $value, 3600);
+}
+
+echo $value;
+```
+
+## Adapters
+
+* [Apcu](docs/implementations/apcu.md)
+* [File](docs/implementations/file.md)
+* [Memcached](docs/implementations/memcached.md)
+* [Memory](docs/implementations/memory.md)
+* [MongoDB](docs/implementations/mongodb.md)
+* [Mysqli](docs/implementations/mysqli.md)
+* [NotCache](docs/implementations/notcache.md)
+* [PhpFile](docs/implementations/phpfile.md)
+* [Predis](docs/implementations/predis.md)
+
+The following implementation allows you to combine cache adapters.
+
+* [Chain](docs/implementations/chain.md)
+
+[Other implementations][todo-implementations] are planned. Please vote or
+provide a PR to speed up the process of adding the to this library.
+
+[todo-implementations]: https://github.com/desarrolla2/Cache/issues?q=is%3Aissue+is%3Aopen+label%3Aadapter
+
+### Options
+
+You can set options for cache using the `withOption` or `withOptions` method.
+Note that all cache objects are immutable, setting an option creates a new
+object.
+
+#### TTL
+
+All cache implementations support the `ttl` option. This sets the default
+time (in seconds) that cache will survive. It defaults to one hour (3600
+seconds).
+
+Setting the TTL to 0 or a negative number, means the cache should live forever.
+
+## Methods
+
+Each cache implementation has the following `Psr\SimpleCache\CacheInterface`
+methods:
+
+##### `get(string $key [, mixed $default])`
+Retrieve the value corresponding to a provided key
+
+##### `has(string $key)`
+Retrieve the if value corresponding to a provided key exist
+
+##### `set(string $key, mixed $value [, int $ttl])`
+Add a value to the cache under a unique key
+
+##### `delete(string $key)`
+Delete a value from the cache
+
+##### `clear()`
+Clear all cache
+
+##### `getMultiple(array $keys)`
+Obtains multiple cache items by their unique keys
+
+##### `setMultiple(array $values [, int $ttl])`
+Persists a set of key => value pairs in the cache
+
+##### `deleteMultiple(array $keys)`
+Deletes multiple cache items in a single operation
+
+.
+
+The `Desarrolla2\Cache\CacheInterface` also has the following methods:
+
+##### `withOption(string $key, string $value)`
+Set option for implementation. Creates a new instance.
+
+##### `withOptions(array $options)`
+Set multiple options for implementation. Creates a new instance.
+
+##### `getOption(string $key)`
+Get option for implementation.
+
+
+## Packers
+
+Cache objects typically hold a `Desarrolla2\Cache\Packer\PackerInterface`
+object. By default, packing is done using `serialize` and `unserialize`.
+
+Available packers are:
+
+* `SerializePacker` using `serialize` and `unserialize`
+* `JsonPacker` using `json_encode` and `json_decode`
+* `NopPacker` does no packing
+* `MongoDBBinaryPacker` using `serialize` and `unserialize` to store as [BSON Binary](http://php.net/manual/en/class.mongodb-bson-binary.php)
+
+#### PSR-16 incompatible packers
+
+The `JsonPacker` does not fully comply with PSR-16, as packing and
+unpacking an object will probably not result in an object of the same class.
+
+The `NopPacker` is intended when caching string data only (like HTML output) or
+if the caching backend supports structured data. Using it when storing objects
+will might give unexpected results.
+
+## Contributors
+
+[![Daniel González](https://avatars1.githubusercontent.com/u/661529?v=3&s=80)](https://github.com/desarrolla2)
+Twitter: [@desarrolla2](https://twitter.com/desarrolla2)\
+[![Arnold Daniels](https://avatars3.githubusercontent.com/u/100821?v=3&s=80)](https://github.com/jasny)
+Twitter: [@ArnoldDaniels](https://twitter.com/ArnoldDaniels)
+
+[ico-version]: https://img.shields.io/packagist/v/desarrolla2/Cache.svg?style=flat-square
+[ico-pre-release]: https://img.shields.io/packagist/vpre/desarrolla2/Cache.svg?style=flat-square
+[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square
+[ico-travis]: https://img.shields.io/travis/desarrolla2/Cache/master.svg?style=flat-square
+[ico-coveralls]: https://img.shields.io/coveralls/desarrolla2/Cache/master.svg?style=flat-square
+[ico-code-quality]: https://img.shields.io/scrutinizer/g/desarrolla2/cache.svg?style=flat-square
+[ico-coverage]: https://scrutinizer-ci.com/g/desarrolla2/Cache/badges/coverage.png?b=master
+[ico-sensiolabs]: https://img.shields.io/sensiolabs/i/5f139261-1ac1-4559-846a-723e09319a88.svg?style=flat-square
+[ico-downloads]: https://img.shields.io/packagist/dt/desarrolla2/cache.svg?style=flat-square
+[ico-today-downloads]: https://img.shields.io/packagist/dd/desarrolla2/cache.svg?style=flat-square
+[ico-gitter]: https://img.shields.io/badge/GITTER-JOIN%20CHAT%20%E2%86%92-brightgreen.svg?style=flat-square
+[ico-github-actions]: https://github.com/desarrolla2/Cache/workflows/PHP/badge.svg
+
+[link-packagist]: https://packagist.org/packages/desarrolla2/cache
+[link-license]: http://hassankhan.mit-license.org
+[link-travis]: https://travis-ci.org/desarrolla2/Cache
+[link-github-actions]: https://github.com/desarrolla2/Cache/actions
+[link-coveralls]: https://coveralls.io/github/desarrolla2/Cache
+[link-scrutinizer]: https://scrutinizer-ci.com/g/desarrolla2/cache
+[link-sensiolabs]: https://insight.sensiolabs.com/projects/5f139261-1ac1-4559-846a-723e09319a88
+[link-downloads]: https://packagist.org/packages/desarrolla2/cache
+[link-gitter]: https://gitter.im/desarrolla2/Cache?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
diff --git a/msd/vendor/desarrolla2/cache/build.xml b/msd/vendor/desarrolla2/cache/build.xml
new file mode 100644
index 00000000..4a5ff014
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/build.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="Cache" default="build">
+
+    <target name="install" depends="composer"
+            description="Prepare for execution"/>
+
+    <target name="build" depends="install, init"
+            description="Run all tests and build everything"/>
+
+    <target name="metrics" depends="build, phpunit, phpdoc, pdepend, phpcs, phpmd"
+            description="Generate Metrics"/>
+
+    <target name="clean"
+            description="Cleanup build artifacts">
+        <delete dir="cache"/>
+        <delete dir="build"/>
+    </target>
+
+    <target name="init" depends="clean"
+            description="Prepare for build">
+        <mkdir dir="cache/htmlpurifier"/>
+        <mkdir dir="build/api"/>
+        <mkdir dir="build/coverage"/>
+        <mkdir dir="build/pdepend"/>
+        <mkdir dir="build/phpcs"/>
+        <mkdir dir="build/phpmd"/>
+    </target>
+
+    <target name="composer"
+            description="Composer install">
+        <exec executable="composer">
+            <arg value="install"/>
+        </exec>
+    </target>
+
+    <target name="phpdoc"
+            description="Generate API documentation using PHPDocumentor">
+        <exec executable="phpdoc">
+            <arg value="-d"/>
+            <arg value="src"/>
+            <arg value="-t"/>
+            <arg value="build/api/"/>
+        </exec>
+    </target>
+
+    <target name="phpunit"
+            description="Run unit tests using PHPUnit">
+        <exec executable="phpunit">
+            <arg value="-c"/>
+            <arg value="phpunit.xml"/>
+        </exec>
+    </target>
+
+    <target name="pdepend"
+            description="Generate software metrics charts using PHP_Depend">
+        <exec executable="pdepend">
+            <arg value="--jdepend-chart=build/pdepend/dependencies.svg"/>
+            <arg value="--overview-pyramid=build/pdepend/overview-pyramid.svg"/>
+            <arg value="src"/>
+        </exec>
+    </target>
+
+    <target name="phpcs"
+            description="Generate coding standard metrics using PHPCS">
+        <exec executable="phpcs">
+            <arg value="--standard=PSR2"/>
+            <arg value="--report-full=build/phpcs/full.txt"/>
+            <arg value="--report-summary=build/phpcs/sumary.txt"/>
+            <arg value="src"/>
+            <arg value="tests"/>
+        </exec>
+    </target>
+
+    <target name="phpmd"
+            description="Generate coding metrics for mess code using PHPMD">
+        <exec executable="phpmd">
+            <arg value="src"/>
+            <arg value="text"/>
+            <arg value="codesize,unusedcode,naming,design,controversial"/>
+            <arg value="--reportfile"/>
+            <arg value="build/phpmd/report.txt"/>
+        </exec>
+
+    </target>
+
+    <target name="cs" description="">
+        <parallel>
+            <exec executable="php-cs-fixer">
+                <arg line="fix src"/>
+            </exec>
+            <exec executable="php-formatter">
+                <arg line="formatter:header:fix src"/>
+            </exec>
+            <exec executable="php-formatter">
+                <arg line="formatter:use:sort src"/>
+            </exec>
+        </parallel>
+    </target>
+</project>
diff --git a/msd/vendor/desarrolla2/cache/composer.json b/msd/vendor/desarrolla2/cache/composer.json
new file mode 100644
index 00000000..71b858f5
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/composer.json
@@ -0,0 +1,67 @@
+{
+    "name": "desarrolla2/cache",
+    "description": "Provides an cache interface for several adapters Apc, Apcu, File, Mongo, Memcache, Memcached, Mysql, Mongo, Redis is supported.",
+    "keywords": [
+        "cache",
+        "simple-cache",
+        "psr-16",
+        "apc",
+        "apcu",
+        "file",
+        "memcached",
+        "memcache",
+        "mysql",
+        "mongo",
+        "redis"
+    ],
+    "type": "library",
+    "license": "MIT",
+    "homepage": "https://github.com/desarrolla2/Cache/",
+    "authors": [
+        {
+            "name": "Daniel González",
+            "homepage": "http://desarrolla2.com/"
+        },
+        {
+            "name": "Arnold Daniels",
+            "homepage": "https://jasny.net/"
+        }
+    ],
+    "provide": {
+        "psr/simple-cache-implementation": "1.0"
+    },    
+    "require": {
+        "php": ">=7.2.0",
+        "psr/simple-cache": "^1.0"
+    },
+    "require-dev": {
+        "ext-apcu": "*",
+        "ext-json": "*",
+        "ext-mysqli": "*",
+        "ext-memcached": "*",
+        "predis/predis": "~1.0.0",
+        "mongodb/mongodb": "^1.3",
+        "cache/integration-tests": "dev-master",
+        "phpunit/phpunit": "^8.3 || ^9.0",
+        "phpstan/phpstan": "^0.12.29",
+        "symfony/phpunit-bridge": "^5.2",
+        "mikey179/vfsstream": "v1.6.8"
+    },
+    "autoload": {
+        "psr-4": {
+            "Desarrolla2\\Cache\\": "src/"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "Desarrolla2\\Test\\Cache\\": "tests/"
+        }
+    },
+    "scripts": {
+        "test": [
+            "phpstan analyse",
+            "phpunit --colors=always",
+            "phpcs -p src"
+        ]
+    }   
+}
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/apcu.md b/msd/vendor/desarrolla2/cache/docs/implementations/apcu.md
new file mode 100644
index 00000000..711f42d1
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/apcu.md
@@ -0,0 +1,25 @@
+# Apcu
+
+Use [APCu cache](http://php.net/manual/en/book.apcu.php) to cache to shared
+memory.
+
+``` php
+use Desarrolla2\Cache\Apcu as ApcuCache;
+
+$cache = new ApcuCache();
+```
+
+_Note: by default APCu uses the time at the beginning of a request for ttl. In
+some cases, like with a long running script, this can be a problem. You can
+change this behaviour `ini_set('apc.use_request_time', false)`._
+
+### Options
+
+| name      | type      | default |                                       |
+| --------- | ----      | ------- | ------------------------------------- |
+| ttl       | int       | null    | Maximum time to live in seconds       |
+| prefix    | string    | ""      | Key prefix                            |
+
+### Packer
+
+By default the [`NopPacker`](../packers/nop.md) is used.
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/chain.md b/msd/vendor/desarrolla2/cache/docs/implementations/chain.md
new file mode 100644
index 00000000..4aa5c110
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/chain.md
@@ -0,0 +1,37 @@
+# Chain
+
+The Cache chain allows you to use multiple implementations to store cache. For
+instance, you can use both fast volatile (in-memory) storage and slower
+non-volatile (disk) storage. Alternatively you can have a local storage
+as well as a shared storage service. 
+
+``` php
+use Desarrolla2\Cache\Chain as CacheChain;
+use Desarrolla2\Cache\Memory as MemoryCache;
+use Desarrolla2\Cache\Predis as PredisCache;
+
+$cache = new CacheChain([
+    (new MemoryCache())->withOption('ttl', 3600),
+    (new PredisCache())->withOption('ttl', 10800)
+]);
+```
+
+The Chain cache implementation doesn't use any option. It uses the `Nop` packer
+by default.
+
+Typically it's useful to specify a maximum `ttl` for each implementation. This
+means that the volatile memory only holds items that are used often.
+
+The following actions propogate to all cache adapters in the chain
+
+* `set`
+* `setMultiple`
+* `delete`
+* `deleteMultiple`
+* `clear`
+
+For the following actions all nodes are tried in sequence
+
+* `has`
+* `get`
+* `getMultiple`
\ No newline at end of file
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/file.md b/msd/vendor/desarrolla2/cache/docs/implementations/file.md
new file mode 100644
index 00000000..1902f231
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/file.md
@@ -0,0 +1,82 @@
+# File
+
+Save the cache as file to on the filesystem.
+
+You must pass a cache directory to the constructor.
+
+``` php
+use Desarrolla2\Cache\File as FileCache;
+
+$cache = new FileCache(sys_get_temp_dir() . '/cache');
+```
+
+### Options
+
+| name         | type                              | default        |                                       |
+| ------------ | --------------------------------- | -------------- | ------------------------------------- |
+| ttl          | int                               | null           | Maximum time to live in seconds       |
+| ttl-strategy | string ('embed', 'file', 'mtime') | "embed"        | Strategy to store the TTL             |
+| prefix       | string                            | ""             | Key prefix                            |
+| filename     | string or callable                | "%s.php.cache" | Filename as sprintf format            |
+
+#### TTL strategy option
+
+The ttl strategy determines how the TTL is stored. Typical filesystems don't
+allow custom file properties, so we'll have to use one of these strategies:
+
+| strategy |                                                 |
+| -------- | ----------------------------------------------- |
+| embed    | Embed the TTL as first line of the file         |
+| file     | Create a TTL file in addition to the cache file |
+| mtime    | Use [mtime][] + max ttl                         |
+
+The 'mtime' strategy is not PSR-16 compliant, as the TTL passed to the `set()`
+method is ignored. Only the `ttl` option for is used on `get()` and `has()`.
+
+[mtime]: https://www.unixtutorial.org/2008/04/atime-ctime-mtime-in-unix-filesystems/
+
+#### Filename option
+
+The `filename` will be parsed using `sprintf` where '%s' is substituted with
+the key. The default extension is automatically determined based on the
+packer.
+
+Instead of a string, `filename` may also be set to a callable, like a callable
+object or closure. In that case the callable will be called to create a
+filename as
+
+    $filename = $callable($key);
+
+##### BasicFilename
+
+The library comes with invokable object as callable for the filename. The
+`BasicFilename` object works as described above.
+
+##### TrieFilename
+
+The `TrieFilename` object will create a prefix tree directory structure. This
+is useful where a lot of cache files would cause to many files in a directory.
+
+Specify the `sprintf` format and the directory level to the constructor when
+creating a `TrieFilename` object.
+
+``` php
+use Desarrolla2\Cache\File as FileCache;
+use Desarrolla2\Cache\File\TrieFilename;
+
+$callback = new TrieFilename('%s.php.cache', 2);
+
+$cache = (new FileCache(sys_get_temp_dir() . '/cache'))
+    ->withOption('filename', $callback);
+```
+
+In this case, adding an item with key `foobar` would be create a file at
+
+    /tmp/cache/f/fo/foobar.php.cache
+
+### Packer
+
+By default the [`SerializePacker`](../packers/serialize.md) is used. The
+[`NopPacker`](../packers/nop.md) can be used if the values are strings.
+Other packers, like the [`JsonPacker`](../packers/json.md) are also
+useful with file cache. 
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/memcached.md b/msd/vendor/desarrolla2/cache/docs/implementations/memcached.md
new file mode 100644
index 00000000..8e00eb08
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/memcached.md
@@ -0,0 +1,28 @@
+# Memcached
+
+Store cache to [Memcached](https://memcached.org/). Memcached is a high
+performance distributed caching system.
+
+``` php
+use Desarrolla2\Cache\Memcached as MemcachedCache;
+use Memcached;
+
+$server = new Memcached();
+// configure it here
+
+$cache = new MemcachedCache($server);
+```
+
+This implementation uses the [memcached](https://php.net/memcached) php
+extension. The (alternative) memcache extension is not supported.
+
+### Options
+
+| name      | type      | default |                                       |
+| --------- | ----      | ------- | ------------------------------------- |
+| ttl       | int       | null    | Maximum time to live in seconds       |
+| prefix    | string    | ""      | Key prefix                            |
+
+### Packer
+
+By default the [`NopPacker`](../packers/nop.md) is used.
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/memory.md b/msd/vendor/desarrolla2/cache/docs/implementations/memory.md
new file mode 100644
index 00000000..03d12623
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/memory.md
@@ -0,0 +1,23 @@
+# Memory
+
+Store the cache in process memory _(in other words in an array)_. Cache Memory
+is removed when the PHP process exist. Also it is not shared between different
+processes.
+
+``` php
+use Desarrolla2\Cache\Memory as MemoryCache;
+
+$cache = new MemoryCache();
+```
+
+### Options
+
+| name      | type      | default |                                       |
+| --------- | ----      | ------- | ------------------------------------- |
+| ttl       | int       | null    | Maximum time to live in seconds       |
+| limit     | int       | null    | Maximum items in cache                |
+| prefix    | string    | ""      | Key prefix                            |
+
+### Packer
+
+By default the [`SerializePacker`](../packers/serialize.md) is used.
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/mongodb.md b/msd/vendor/desarrolla2/cache/docs/implementations/mongodb.md
new file mode 100644
index 00000000..3bad03d2
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/mongodb.md
@@ -0,0 +1,45 @@
+# Mongo
+
+Use it to store the cache in a Mongo database. Requires the mongodb extension
+and the [mongodb/mongodb](https://github.com/mongodb/mongo-php-library)
+library.
+
+You must pass a `MongoDB\Collection` object to the cache constructor.
+
+``` php
+<?php
+
+use Desarrolla2\Cache\Mongo as MongoCache;
+use MongoDB\Client;
+
+$client = new Client('mongodb://localhost:27017');
+$database = $client->selectDatabase('mycache');
+$collection = $database->selectCollection('cache');
+
+$cache = new MongoCache($collection);
+```
+
+MonoDB will always automatically create the database and collection if needed. 
+
+### Options
+
+| name       | type      | default |                                       |
+| ---------  | ----      | ------- | ------------------------------------- |
+| initialize | bool      | true    | Enable auto-initialize                |
+| ttl        | int       | null    | Maximum time to live in seconds       |
+| prefix     | string    | ""      | Key prefix                            |
+
+#### Initialize option
+
+If `initialize` is enabled, the cache implementation will automatically create
+a [ttl index](https://docs.mongodb.com/manual/core/index-ttl/). In production
+it's better to disable auto-initialization and create the ttl index explicitly
+when setting up the database. This prevents a `createIndex()` call on each
+request. 
+
+### Packer
+
+By default the [`MongoDBBinaryPacker`](../packers/mongodbbinary.md) is used. It
+serializes the data and stores it in a [Binary BSON variable](http://php.net/manual/en/class.mongodb-bson-binary.php). 
+If the data is a UTF-8 string of simple array or stdClass object, it may be
+useful to use the [`NopPacker`](../packers/nop.md) instead.
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/mysqli.md b/msd/vendor/desarrolla2/cache/docs/implementations/mysqli.md
new file mode 100644
index 00000000..df676e31
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/mysqli.md
@@ -0,0 +1,47 @@
+# Mysqli
+
+Cache to a [MySQL database](https://www.mysql.com/) using the
+[mysqli](http://php.net/manual/en/book.mysqli.php) PHP extension.
+
+You must pass a `mysqli` connection object to the constructor.
+
+``` php
+<?php
+    
+use Desarrolla2\Cache\Mysqli as MysqliCache;
+
+$db = new mysqli('localhost');
+$cache = new MysqliCache($db);
+```
+
+### Options
+
+| name       | type      | default |                                       |
+| ---------  | ----      | ------- | ------------------------------------- |
+| initialize | bool      | true    | Enable auto-initialize                |
+| ttl        | int       | null    | Maximum time to live in seconds       |
+| prefix     | string    | ""      | Key prefix                            |
+
+#### Initialize option
+
+If `initialize` is enabled, the cache implementation will automatically create
+a [scheduled event](https://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html).
+
+```
+DELIMITER ;;
+
+CREATE TABLE IF NOT EXISTS `cache` (`key` VARCHAR(255), `value` TEXT, `ttl` INT UNSIGNED, PRIMARY KEY (`key`));;
+
+CREATE EVENT `apply_ttl_cache` ON SCHEDULE 1 HOUR 
+DO BEGIN
+    DELETE FROM `cache` WHERE `ttl` < NOW();
+END;;
+```
+
+In production it's better to disable auto-initialization and create the event
+explicitly when setting up the database. This prevents a `CREATE TABLE` and
+`CREATE EVENT` query on each request. 
+
+### Packer
+
+By default the [`SerializePacker`](../packers/serialize.md) is used.
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/notcache.md b/msd/vendor/desarrolla2/cache/docs/implementations/notcache.md
new file mode 100644
index 00000000..5654b999
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/notcache.md
@@ -0,0 +1,13 @@
+# NotCache
+
+A [Null object](https://sourcemaking.com/design_patterns/null_object) that
+correctly implements the PSR-16 interface, but does not actually cache
+anything.
+
+``` php
+use Desarrolla2\Cache\NotCache;
+
+$cache = new NotCache();
+```
+
+It doesn't use any options or packers.
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/phpfile.md b/msd/vendor/desarrolla2/cache/docs/implementations/phpfile.md
new file mode 100644
index 00000000..8fc991e3
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/phpfile.md
@@ -0,0 +1,74 @@
+# PhpFile
+
+Save the cache as PHP script to on the filesystem using 
+[`var_export`](http://php.net/manual/en/function.var-export.php) when storing
+cache and [`include`](http://php.net/manual/en/function.include.php) when
+loading cache.
+
+The implementation leverages the PHP engine’s in-memory file caching (opcache)
+to cache application data in addition to code. This method is particularly fast
+in PHP7.2+ due to opcode cache optimizations.
+
+PHP file caching should primarily be used for arrays and objects. There is no
+performance benefit over APCu for storing strings.
+
+[read more][]
+
+``` php
+use Desarrolla2\Cache\PhpFile as PhpFileCache;
+
+$cache = new PhpFileCache();
+```
+
+### Options
+
+| name      | type               | default        |                                       |
+| --------- | ------------------ | -------------- | ------------------------------------- |
+| ttl       | int                | null           | Maximum time to live in seconds       |
+| prefix    | string             | ""             | Key prefix                            |
+| filename  | string or callable | "%s.php"       | Filename as sprintf format            |
+
+#### Filename option
+
+The `filename` will be parsed using `sprintf` where '%s' is substituted with
+the key.
+
+Instead of a string, `filename` may also be set to a callable, like a callable
+object or closure. In that case the callable will be called to create a
+filename as
+
+    $filename = $callable($key);
+
+##### BasicFilename
+
+The library comes with invokable object as callable for the filename. The
+`BasicFilename` object works as described above.
+
+##### TrieFilename
+
+The `TrieFilename` object will create a prefix tree directory structure. This
+is useful where a lot of cache files would cause to many files in a directory.
+
+Specify the `sprintf` format and the directory level to the constructor when
+creating a `TrieFilename` object.
+
+``` php
+use Desarrolla2\Cache\File as FileCache;
+use Desarrolla2\Cache\File\TrieFilename;
+
+$callback = new TrieFilename('%s.php', 2);
+
+$cache = (new FileCache(sys_get_temp_dir() . '/cache'))
+    ->withOption('filename', $callback);
+```
+
+In this case, adding an item with key `foobar` would be create a file at
+
+    /tmp/cache/f/fo/foobar.php
+
+### Packer
+
+By default the [`NopPacker`](../packers/nop.md) is used. Other packers should
+not be used.
+
+[read more]: https://medium.com/@dylanwenzlau/500x-faster-caching-than-redis-memcache-apc-in-php-hhvm-dcd26e8447ad
diff --git a/msd/vendor/desarrolla2/cache/docs/implementations/predis.md b/msd/vendor/desarrolla2/cache/docs/implementations/predis.md
new file mode 100644
index 00000000..d29fa968
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/implementations/predis.md
@@ -0,0 +1,31 @@
+# Predis
+
+Cache using a [redis server](https://redis.io/). Redis is an open source,
+in-memory data structure store, used as a database, cache and message broker.  
+
+You must provide a `Predis\Client` object to the constructor.
+
+```php
+use Desarrolla2\Cache\Predis as PredisCache;
+use Predis\Client as PredisClient;
+
+$client = new PredisClient('tcp://localhost:6379');
+$cache = new PredisCache($client);
+```
+
+### Installation
+
+Requires the [`predis`](https://github.com/nrk/predis/wiki) library.
+
+    composer require predis/predis
+
+### Options
+
+| name      | type      | default |                                       |
+| --------- | ----      | ------- | ------------------------------------- |
+| ttl       | int       | null    | Maximum time to live in seconds       |
+| prefix    | string    | ""      | Key prefix                            |
+
+### Packer
+
+By default the [`SerializePacker`](../packers/serialize.md) is used.
diff --git a/msd/vendor/desarrolla2/cache/docs/performance.md b/msd/vendor/desarrolla2/cache/docs/performance.md
new file mode 100644
index 00000000..4b01b2e7
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/docs/performance.md
@@ -0,0 +1,40 @@
+# Performance test
+
+Here are my performance tests, you can view the results ordered from faster to slower.
+
+| Adapter         | 10.000 set    | 10.000 has    | 10.000 get |
+| :-------------- | -----------:  | -----------:  | ---------: | 
+| NoCache         | 0.0637        | 0.0482        | 0.0488     | 
+| Apcu             | 0.0961        | 0.0556        | 0.0770     |
+| File            | 0.6881        | 0.3426        | 0.3107     | 
+| Mongo           | 13.8144       | 30.0203       | 24.4214    | 
+
+
+## how i run the test? 
+
+The test its the same for all Adapters and look like this.
+
+``` php
+    <?php
+
+    $timer = new Timer();
+    for ($i = 1; $i <= 10000; $i++) {
+        $cache->set(md5($i), md5($i), 3600);
+    }
+    $timer->mark('10.000 set');
+    for ($i = 1; $i <= 10000; $i++) {
+        $cache->has(md5($i));
+    }
+    $timer->mark('10.000 has');
+    for ($i = 1; $i <= 10000; $i++) {
+        $cache->get(md5($i));
+    }
+    $timer->mark('10.000 get');
+
+```
+
+ if you want run the tests them execute.
+
+``` sh
+    php test/performance/AdapterName.php
+```
\ No newline at end of file
diff --git a/msd/vendor/desarrolla2/cache/phpcs.xml b/msd/vendor/desarrolla2/cache/phpcs.xml
new file mode 100644
index 00000000..b5585bf4
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/phpcs.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<ruleset name="PSR">
+    <!-- Include the whole PSR-1 standard -->
+    <rule ref="PSR1"/>
+    <!-- Include the whole PSR-2 standard -->
+    <rule ref="PSR2"/>
+</ruleset>
+
diff --git a/msd/vendor/desarrolla2/cache/phpstan.neon b/msd/vendor/desarrolla2/cache/phpstan.neon
new file mode 100644
index 00000000..b38d1262
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/phpstan.neon
@@ -0,0 +1,8 @@
+parameters:
+    level: 3
+    paths:
+        - src
+    reportUnmatchedIgnoredErrors: false
+    ignoreErrors:
+        - /^Variable property access/
+
diff --git a/msd/vendor/desarrolla2/cache/phpunit.xml.dist b/msd/vendor/desarrolla2/cache/phpunit.xml.dist
new file mode 100644
index 00000000..c49dbde6
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/phpunit.xml.dist
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit
+  bootstrap="./vendor/autoload.php"
+  convertWarningsToExceptions="true"
+  convertNoticesToExceptions="true"
+  convertErrorsToExceptions="true"
+  backupStaticAttributes="false"
+  processIsolation="false"
+  stopOnFailure="false"
+  backupGlobals="false"
+  colors="true"
+>
+    <testsuites>
+        <testsuite name="Desarrolla2 Cache test suite">
+            <directory suffix="Test.php">./tests</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./src</directory>
+        </whitelist>
+    </filter>
+
+    <php>
+        <!--ini name="mysqli.default_host" value="localhost" /-->
+        <!--ini name="mysqli.default_user" value="root" /-->
+        <!--ini name="mysqli.default_pw" value=""/-->
+        <const name="CACHE_TESTS_MYSQLI_DATABASE" value="cache_tests" />
+
+        <const name="CACHE_TESTS_MONGO_DSN" value="mongodb://localhost:27017" />
+        <const name="CACHE_TESTS_MONGO_DATABASE" value="cache_tests" />
+
+        <const name="CACHE_TESTS_MEMCACHED_SERVER" value="localhost:11211" />
+
+        <const name="CACHE_TESTS_PREDIS_DSN" value="tcp://localhost:6379" />
+    </php>
+</phpunit>
diff --git a/msd/vendor/desarrolla2/cache/src/AbstractCache.php b/msd/vendor/desarrolla2/cache/src/AbstractCache.php
new file mode 100644
index 00000000..b0fcb455
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/AbstractCache.php
@@ -0,0 +1,296 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Option\PrefixTrait as PrefixOption;
+use Desarrolla2\Cache\Option\TtlTrait as TtlOption;
+use Desarrolla2\Cache\Packer\PackingTrait as Packing;
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+use DateTimeImmutable;
+use DateInterval;
+use Traversable;
+
+/**
+ * AbstractAdapter
+ */
+abstract class AbstractCache implements CacheInterface
+{
+    use PrefixOption;
+    use TtlOption;
+    use Packing;
+
+    /**
+     * Make a clone of this object.
+     *
+     * @return static
+     */
+    protected function cloneSelf(): self
+    {
+        return clone $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withOption(string $key, $value): self
+    {
+        return $this->withOptions([$key => $value]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function withOptions(array $options): self
+    {
+        $cache = $this->cloneSelf();
+
+        foreach ($options as $key => $value) {
+            $method = "set" . str_replace('-', '', $key) . "Option";
+
+            if (empty($key) || !method_exists($cache, $method)) {
+                throw new InvalidArgumentException("unknown option '$key'");
+            }
+
+            $cache->$method($value);
+        }
+
+        return $cache;
+    }
+    
+    /**
+     * {@inheritdoc}
+     */
+    public function getOption($key)
+    {
+        $method = "get" . str_replace('-', '', $key) . "Option";
+        
+        if (empty($key) || !method_exists($this, $method)) {
+            throw new InvalidArgumentException("unknown option '$key'");
+        }
+        
+        return $this->$method();
+    }
+
+
+    /**
+     * Validate the key
+     *
+     * @param string $key
+     * @return void
+     * @throws InvalidArgumentException
+     */
+    protected function assertKey($key): void
+    {
+        if (!is_string($key)) {
+            $type = (is_object($key) ? get_class($key) . ' ' : '') . gettype($key);
+            throw new InvalidArgumentException("Expected key to be a string, not $type");
+        }
+
+        if ($key === '' || preg_match('~[{}()/\\\\@:]~', $key)) {
+            throw new InvalidArgumentException("Invalid key '$key'");
+        }
+    }
+
+    /**
+     * Assert that the keys are an array or traversable
+     * 
+     * @param iterable $subject
+     * @param string   $msg
+     * @return void
+     * @throws InvalidArgumentException if subject are not iterable
+     */
+    protected function assertIterable($subject, $msg): void
+    {
+        $iterable = function_exists('is_iterable')
+            ? is_iterable($subject)
+            : is_array($subject) || $subject instanceof Traversable;
+        
+        if (!$iterable) {
+            throw new InvalidArgumentException($msg);
+        }
+    }
+
+    /**
+     * Turn the key into a cache identifier
+     *
+     * @param string $key
+     * @return string
+     * @throws InvalidArgumentException
+     */
+    protected function keyToId($key): string
+    {
+        $this->assertKey($key);
+
+        return sprintf('%s%s', $this->prefix, $key);
+    }
+
+    /**
+     * Create a map with keys and ids
+     *
+     * @param iterable $keys
+     * @return array
+     * @throws InvalidArgumentException
+     */
+    protected function mapKeysToIds($keys): array
+    {
+        $this->assertIterable($keys, 'keys not iterable');
+
+        $map = [];
+
+        foreach ($keys as $key) {
+            $id = $this->keyToId($key);
+            $map[$id] = $key;
+        }
+
+        return $map;
+    }
+
+
+    /**
+     * Pack all values and turn keys into ids
+     *
+     * @param iterable $values
+     * @return array
+     */
+    protected function packValues(iterable $values): array
+    {
+        $packed = [];
+
+        foreach ($values as $key => $value) {
+            $id = $this->keyToId(is_int($key) ? (string)$key : $key);
+            $packed[$id] = $this->pack($value);
+        }
+
+        return $packed;
+    }
+
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        $this->assertIterable($keys, 'keys not iterable');
+        
+        $result = [];
+        
+        foreach ($keys as $key) {
+            $result[$key] = $this->get($key, $default);
+        }
+        
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        $this->assertIterable($values, 'values not iterable');
+
+        $success = true;
+        
+        foreach ($values as $key => $value) {
+            $success = $this->set(is_int($key) ? (string)$key : $key, $value, $ttl) && $success;
+        }
+        
+        return $success;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMultiple($keys)
+    {
+        $this->assertIterable($keys, 'keys not iterable');
+
+        $success = true;
+
+        foreach ($keys as $key) {
+            $success = $this->delete($key) && $success;
+        }
+
+        return $success;
+    }
+
+
+    /**
+     * Get the current time.
+     *
+     * @return int
+     */
+    protected function currentTimestamp(): int
+    {
+        return time();
+    }
+
+    /**
+     * Convert TTL to seconds from now
+     *
+     * @param null|int|DateInterval $ttl
+     * @return int|null
+     * @throws InvalidArgumentException
+     */
+    protected function ttlToSeconds($ttl): ?int
+    {
+        if (!isset($ttl)) {
+            return $this->ttl;
+        }
+
+        if ($ttl instanceof DateInterval) {
+            $reference = new DateTimeImmutable();
+            $endTime = $reference->add($ttl);
+
+            $ttl = $endTime->getTimestamp() - $reference->getTimestamp();
+        }
+
+        if (!is_int($ttl)) {
+            $type = (is_object($ttl) ? get_class($ttl) . ' ' : '') . gettype($ttl);
+            throw new InvalidArgumentException("ttl should be of type int or DateInterval, not $type");
+        }
+
+        return isset($this->ttl) ? min($ttl, $this->ttl) : $ttl;
+    }
+
+    /**
+     * Convert TTL to epoch timestamp
+     *
+     * @param null|int|DateInterval $ttl
+     * @return int|null
+     * @throws InvalidArgumentException
+     */
+    protected function ttlToTimestamp($ttl): ?int
+    {
+        if (!isset($ttl)) {
+            return isset($this->ttl) ? time() + $this->ttl : null;
+        }
+
+        if (is_int($ttl)) {
+            return time() + (isset($this->ttl) ? min($ttl, $this->ttl) : $ttl);
+        }
+
+        if ($ttl instanceof DateInterval) {
+            $timestamp = (new DateTimeImmutable())->add($ttl)->getTimestamp();
+
+            return isset($this->ttl) ? min($timestamp, time() + $this->ttl) : $timestamp;
+        }
+
+        $type = (is_object($ttl) ? get_class($ttl) . ' ' : '') . gettype($ttl);
+        throw new InvalidArgumentException("ttl should be of type int or DateInterval, not $type");
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/AbstractFile.php b/msd/vendor/desarrolla2/cache/src/AbstractFile.php
new file mode 100644
index 00000000..c98a22c2
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/AbstractFile.php
@@ -0,0 +1,216 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+use Desarrolla2\Cache\Option\FilenameTrait as FilenameOption;
+
+/**
+ * Abstract class for using files as cache.
+ *
+ * @package Desarrolla2\Cache
+ */
+abstract class AbstractFile extends AbstractCache
+{
+    use FilenameOption;
+
+    /**
+     * @var string
+     */
+    protected $cacheDir;
+
+
+    /**
+     * Class constructor
+     *
+     * @param string|null $cacheDir
+     */
+    public function __construct(?string $cacheDir = null)
+    {
+        if (!$cacheDir) {
+            $cacheDir = realpath(sys_get_temp_dir()) . DIRECTORY_SEPARATOR . 'cache';
+            if(!is_dir($cacheDir)) {
+                mkdir($cacheDir, 0777, true);
+            }
+        }
+
+        $this->cacheDir = rtrim($cacheDir, '/');
+    }
+
+    /**
+     * Validate the key
+     *
+     * @param string $key
+     * @return void
+     * @throws InvalidArgumentException
+     */
+    protected function assertKey($key): void
+    {
+        parent::assertKey($key);
+
+        if (strpos($key, '*')) {
+            throw new InvalidArgumentException("Key may not contain the character '*'");
+        }
+    }
+
+
+    /**
+     * Get the contents of the cache file.
+     *
+     * @param string $cacheFile
+     * @return string
+     */
+    protected function readFile(string $cacheFile): string
+    {
+        return file_get_contents($cacheFile);
+    }
+
+    /**
+     * Read the first line of the cache file.
+     *
+     * @param string $cacheFile
+     * @return string
+     */
+    protected function readLine(string $cacheFile): string
+    {
+        $fp = fopen($cacheFile, 'r');
+        $line = fgets($fp);
+        fclose($fp);
+
+        return $line;
+    }
+
+    /**
+     * Create a cache file
+     *
+     * @param string $cacheFile
+     * @param string $contents
+     * @return bool
+     */
+    protected function writeFile(string $cacheFile, string $contents): bool
+    {
+        $dir = dirname($cacheFile);
+
+        if ($dir !== $this->cacheDir && !is_dir($dir)) {
+            mkdir($dir, 0775, true);
+        }
+
+        return (bool)file_put_contents($cacheFile, $contents);
+    }
+
+    /**
+     * Delete a cache file
+     *
+     * @param string $file
+     * @return bool
+     */
+    protected function deleteFile(string $file): bool
+    {
+        return !is_file($file) || unlink($file);
+    }
+
+    /**
+     * Remove all files from a directory.
+     */
+    protected function removeFiles(string $dir): bool
+    {
+        $success = true;
+
+        $generator = $this->getFilenameOption();
+        $objects = $this->streamSafeGlob($dir, $generator('*'));
+
+        foreach ($objects as $object) {
+            $success = $this->deleteFile($object) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * Recursive delete an empty directory.
+     *
+     * @param string $dir
+     */
+    protected function removeRecursively(string $dir): bool
+    {
+        $success = $this->removeFiles($dir);
+
+        $objects = $this->streamSafeGlob($dir, '*');
+
+        foreach ($objects as $object) {
+            if (!is_dir($object)) {
+                continue;
+            }
+
+            if (is_link($object)) {
+                unlink($object);
+            } else {
+                $success = $this->removeRecursively($object) && $success;
+                rmdir($object);
+            }
+        }
+
+        return $success;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $cacheFile = $this->getFilename($key);
+
+        return $this->deleteFile($cacheFile);
+    }
+
+    /**
+     * Delete cache directory.
+     *
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        $this->removeRecursively($this->cacheDir);
+
+        return true;
+    }
+
+    /**
+     * Glob that is safe with streams (vfs for example)
+     *
+     * @param string $directory
+     * @param string $filePattern
+     * @return array
+     */
+    protected function streamSafeGlob(string $directory, string $filePattern): array
+    {
+        $filePattern = basename($filePattern);
+        $files = scandir($directory);
+        $found = [];
+
+        foreach ($files as $filename) {
+            if (in_array($filename, ['.', '..'])) {
+                continue;
+            }
+
+            if (fnmatch($filePattern, $filename) || fnmatch($filePattern . '.ttl', $filename)) {
+                $found[] = "{$directory}/{$filename}";
+            }
+        }
+
+        return $found;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Apcu.php b/msd/vendor/desarrolla2/cache/src/Apcu.php
new file mode 100644
index 00000000..9cdfab5a
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Apcu.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Exception\CacheException;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\NopPacker;
+
+/**
+ * Apcu
+ */
+class Apcu extends AbstractCache
+{
+    /**
+     * Create the default packer for this cache implementation
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new NopPacker();
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $ttlSeconds = $this->ttlToSeconds($ttl);
+
+        if (isset($ttlSeconds) && $ttlSeconds <= 0) {
+            return $this->delete($key);
+        }
+
+        return apcu_store($this->keyToId($key), $this->pack($value), $ttlSeconds ?? 0);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        $packed = apcu_fetch($this->keyToId($key), $success);
+
+        return $success ? $this->unpack($packed) : $default;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        return apcu_exists($this->keyToId($key));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $id = $this->keyToId($key);
+
+        return apcu_delete($id) || !apcu_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        return apcu_clear_cache();
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/CacheInterface.php b/msd/vendor/desarrolla2/cache/src/CacheInterface.php
new file mode 100644
index 00000000..00d5d469
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/CacheInterface.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+namespace Desarrolla2\Cache;
+
+use Psr\SimpleCache\CacheInterface as PsrCacheInterface;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\KeyMaker\KeyMakerInterface;
+
+/**
+ * CacheInterface
+ */
+interface CacheInterface extends PsrCacheInterface
+{
+    /**
+     * Set option for cache
+     *
+     * @param string $key
+     * @param mixed $value
+     * @return static
+     */
+    public function withOption(string $key, $value);
+
+    /**
+     * Set multiple options for cache
+     *
+     * @param array $options
+     * @return static
+     */
+    public function withOptions(array $options);
+
+    /**
+     * Get option for cache
+     *
+     * @param string $key
+     * @return mixed
+     */
+    public function getOption($key);
+
+    /**
+     * Set the packer
+     *
+     * @param PackerInterface $packer
+     * @return static
+     */
+    public function withPacker(PackerInterface $packer);
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Chain.php b/msd/vendor/desarrolla2/cache/src/Chain.php
new file mode 100644
index 00000000..bb5f1959
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Chain.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Packer\NopPacker;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+
+/**
+ * Use multiple cache adapters.
+ */
+class Chain extends AbstractCache
+{
+    /**
+     * @var CacheInterface[]
+     */
+    protected $adapters;
+
+    /**
+     * Create the default packer for this cache implementation
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new NopPacker();
+    }
+
+
+    /**
+     * Chain constructor.
+     *
+     * @param CacheInterface[] $adapters  Fastest to slowest
+     */
+    public function __construct(array $adapters)
+    {
+        foreach ($adapters as $adapter) {
+            if (!$adapter instanceof CacheInterface) {
+                throw new InvalidArgumentException("All adapters should be a cache implementation");
+            }
+        }
+
+        $this->adapters = $adapters;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $success = true;
+
+        foreach ($this->adapters as $adapter) {
+            $success = $adapter->set($key, $value, $ttl) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        $success = true;
+
+        foreach ($this->adapters as $adapter) {
+            $success = $adapter->setMultiple($values, $ttl) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        foreach ($this->adapters as $adapter) {
+            $result = $adapter->get($key); // Not using $default as we want to get null if the adapter doesn't have it
+
+            if (isset($result)) {
+                return $result;
+            }
+        }
+
+        return $default;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        $this->assertIterable($keys, 'keys are not iterable');
+
+        $missing = [];
+        $values = [];
+
+        foreach ($keys as $key) {
+            $this->assertKey($key);
+
+            $missing[] = $key;
+            $values[$key] = $default;
+        }
+
+        foreach ($this->adapters as $adapter) {
+            if (empty($missing)) {
+                break;
+            }
+
+            $found = [];
+            foreach ($adapter->getMultiple($missing) as $key => $value) {
+                if (isset($value)) {
+                    $found[$key] = $value;
+                }
+            }
+
+            $values = array_merge($values, $found);
+            $missing = array_values(array_diff($missing, array_keys($found)));
+        }
+
+        return $values;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        foreach ($this->adapters as $adapter) {
+            if ($adapter->has($key)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $success = true;
+
+        foreach ($this->adapters as $adapter) {
+            $success = $adapter->delete($key) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMultiple($keys)
+    {
+        $success = true;
+
+        foreach ($this->adapters as $adapter) {
+            $success = $adapter->deleteMultiple($keys) && $success;
+        }
+
+        return $success;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        $success = true;
+
+        foreach ($this->adapters as $adapter) {
+            $success = $adapter->clear() && $success;
+        }
+
+        return $success;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Exception/BadMethodCallException.php b/msd/vendor/desarrolla2/cache/src/Exception/BadMethodCallException.php
new file mode 100644
index 00000000..079f2c1a
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Exception/BadMethodCallException.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Exception;
+
+use Psr\SimpleCache\CacheException as PsrCacheException;
+
+/**
+ * Exception bad method calls
+ */
+class BadMethodCallException extends \BadMethodCallException implements PsrCacheException
+{
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Exception/CacheException.php b/msd/vendor/desarrolla2/cache/src/Exception/CacheException.php
new file mode 100644
index 00000000..079df456
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Exception/CacheException.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Exception;
+
+use Psr\SimpleCache\CacheException as PsrCacheException;
+
+/**
+ * Interface used for all types of exceptions thrown by the implementing library.
+ */
+class CacheException extends \RuntimeException implements PsrCacheException
+{
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Exception/InvalidArgumentException.php b/msd/vendor/desarrolla2/cache/src/Exception/InvalidArgumentException.php
new file mode 100644
index 00000000..fd155e53
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Exception/InvalidArgumentException.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Exception;
+
+use Psr\SimpleCache\InvalidArgumentException as PsrInvalidArgumentException;
+
+/**
+ * Exception for invalid cache arguments.
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements PsrInvalidArgumentException
+{
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Exception/UnexpectedValueException.php b/msd/vendor/desarrolla2/cache/src/Exception/UnexpectedValueException.php
new file mode 100644
index 00000000..2c05cc40
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Exception/UnexpectedValueException.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Exception;
+
+use Psr\SimpleCache\CacheException as PsrCacheException;
+
+/**
+ * Exception for unexpected values when reading from cache.
+ */
+class UnexpectedValueException extends \UnexpectedValueException implements PsrCacheException
+{
+}
diff --git a/msd/vendor/desarrolla2/cache/src/File.php b/msd/vendor/desarrolla2/cache/src/File.php
new file mode 100644
index 00000000..fce35b66
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/File.php
@@ -0,0 +1,175 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+use Desarrolla2\Cache\Exception\UnexpectedValueException;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\SerializePacker;
+
+/**
+ * Cache file.
+ */
+class File extends AbstractFile
+{
+    /**
+     * @var string  'embed', 'file', 'mtime'
+     */
+    protected $ttlStrategy = 'embed';
+
+    /**
+     * Create the default packer for this cache implementation
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new SerializePacker();
+    }
+
+    /**
+     * Set TTL strategy
+     *
+     * @param string $strategy
+     */
+    protected function setTtlStrategyOption($strategy)
+    {
+        if (!in_array($strategy, ['embed', 'file', 'mtime'])) {
+            throw new InvalidArgumentException("Unknown strategy '$strategy', should be 'embed', 'file' or 'mtime'");
+        }
+
+        $this->ttlStrategy = $strategy;
+    }
+
+    /**
+     * Get TTL strategy
+     *
+     * @return string
+     */
+    protected function getTtlStrategyOption(): string
+    {
+        return $this->ttlStrategy;
+    }
+
+
+    /**
+     * Get the TTL using one of the strategies
+     *
+     * @param string $cacheFile
+     * @return int
+     */
+    protected function getTtl(string $cacheFile)
+    {
+        switch ($this->ttlStrategy) {
+            case 'embed':
+                return (int)$this->readLine($cacheFile);
+            case 'file':
+                return file_exists("$cacheFile.ttl")
+                    ? (int)file_get_contents("$cacheFile.ttl")
+                    : PHP_INT_MAX;
+            case 'mtime':
+                return $this->getTtl($cacheFile) > 0 ? filemtime($cacheFile) + $this->ttl : PHP_INT_MAX;
+        }
+
+        throw new \InvalidArgumentException("Invalid TTL strategy '{$this->ttlStrategy}'");
+    }
+
+    /**
+     * Set the TTL using one of the strategies
+     *
+     * @param int|null $expiration
+     * @param string   $contents
+     * @param string   $cacheFile
+     * @return string  The (modified) contents
+     */
+    protected function setTtl($expiration, $contents, $cacheFile)
+    {
+        switch ($this->ttlStrategy) {
+            case 'embed':
+                $contents = ($expiration ?? PHP_INT_MAX) . "\n" . $contents;
+                break;
+            case 'file':
+                if ($expiration !== null) {
+                    file_put_contents("$cacheFile.ttl", $expiration);
+                }
+                break;
+            case 'mtime':
+                // nothing
+                break;
+        }
+
+        return $contents;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        if (!$this->has($key)) {
+            return $default;
+        }
+
+        $cacheFile = $this->getFilename($key);
+        $packed = $this->readFile($cacheFile);
+
+        if ($this->ttlStrategy === 'embed') {
+            $packed = substr($packed, strpos($packed, "\n") + 1);
+        }
+        
+        return $this->unpack($packed);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        $cacheFile = $this->getFilename($key);
+
+        if (!file_exists($cacheFile)) {
+            return false;
+        }
+
+        $ttl = $this->getTtl($cacheFile);
+
+        if ($ttl <= time()) {
+            $this->deleteFile($cacheFile);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $cacheFile = $this->getFilename($key);
+        $packed = $this->pack($value);
+
+        if (!is_string($packed)) {
+            throw new UnexpectedValueException("Packer must create a string for the data to be cached to file");
+        }
+
+        $contents = $this->setTtl($this->ttlToTimestamp($ttl), $packed, $cacheFile);
+
+        return $this->writeFile($cacheFile, $contents);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/File/BasicFilename.php b/msd/vendor/desarrolla2/cache/src/File/BasicFilename.php
new file mode 100644
index 00000000..1c7130c0
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/File/BasicFilename.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\File;
+
+/**
+ * Create a path for a key
+ */
+class BasicFilename
+{
+    /**
+     * @var string
+     */
+    protected $format;
+
+    /**
+     * BasicFilename constructor.
+     *
+     * @param string $format
+     */
+    public function __construct(string $format)
+    {
+        $this->format = $format;
+    }
+
+    /**
+     * Get the format
+     *
+     * @return string
+     */
+    public function getFormat(): string
+    {
+        return $this->format;
+    }
+
+    /**
+     * Create the path for a key
+     *
+     * @param string $key
+     * @return string
+     */
+    public function __invoke(string $key): string
+    {
+        return sprintf($this->format, $key ?: '*');
+    }
+
+    /**
+     * Cast to string
+     *
+     * @return string
+     */
+    public function __toString(): string
+    {
+        return $this->getFormat();
+    }
+}
\ No newline at end of file
diff --git a/msd/vendor/desarrolla2/cache/src/File/TrieFilename.php b/msd/vendor/desarrolla2/cache/src/File/TrieFilename.php
new file mode 100644
index 00000000..62190094
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/File/TrieFilename.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\File;
+
+/**
+ * Create a path for a key as prefix tree directory structure.
+ *
+ * @see https://en.wikipedia.org/wiki/Trie
+ */
+class TrieFilename
+{
+    /**
+     * @var string
+     */
+    protected $format;
+
+    /**
+     * @var int
+     */
+    protected $levels;
+
+    /**
+     * @var bool
+     */
+    protected $hash;
+
+
+    /**
+     * TrieFilename constructor.
+     *
+     * @param string $format
+     * @param int    $levels  The depth of the structure
+     * @param bool   $hash    MD5 hash the key to get a better spread
+     */
+    public function __construct(string $format, int $levels = 1, bool $hash = false)
+    {
+        $this->format = $format;
+        $this->levels = $levels;
+        $this->hash = $hash;
+    }
+
+    /**
+     * Get the format
+     *
+     * @return string
+     */
+    public function getFormat(): string
+    {
+        return $this->format;
+    }
+
+    /**
+     * Get the depth of the structure
+     *
+     * @return int
+     */
+    public function getLevels(): int
+    {
+        return $this->levels;
+    }
+
+    /**
+     * Will the key be hashed to create the trie.
+     *
+     * @return bool
+     */
+    public function isHashed(): bool
+    {
+        return $this->hash;
+    }
+
+
+    /**
+     * Create the path for a key
+     *
+     * @param string $key
+     * @return string
+     */
+    public function __invoke(string $key): string
+    {
+        if (empty($key)) {
+            return $this->wildcardPath();
+        }
+
+        $dirname = $this->hash ? base_convert(md5($key), 16, 36) : $key;
+        $filename = sprintf($this->format, $key);
+
+        $path = '';
+
+        for ($length = 1; $length <= $this->levels; $length++) {
+            $path .= substr($dirname, 0, $length) . DIRECTORY_SEPARATOR;
+        }
+
+        return $path . $filename;
+    }
+
+    /**
+     * Get a path for all files (using glob)
+     *
+     * @return string
+     */
+    protected function wildcardPath(): string
+    {
+        $filename = sprintf($this->format, '*');
+
+        return str_repeat('*' . DIRECTORY_SEPARATOR, $this->levels) . $filename;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Memcached.php b/msd/vendor/desarrolla2/cache/src/Memcached.php
new file mode 100644
index 00000000..c8d8d4e4
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Memcached.php
@@ -0,0 +1,218 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\NopPacker;
+use Memcached as MemcachedServer;
+
+/**
+ * Memcached
+ */
+class Memcached extends AbstractCache
+{
+    /**
+     * @var MemcachedServer
+     */
+    protected $server;
+
+    /**
+     * @param MemcachedServer $server
+     */
+    public function __construct(MemcachedServer $server)
+    {
+        $this->server = $server;
+    }
+
+
+    /**
+     * Create the default packer for this cache implementation
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new NopPacker();
+    }
+
+    /**
+     * Validate the key
+     *
+     * @param string $key
+     * @return void
+     * @throws InvalidArgumentException
+     */
+    protected function assertKey($key): void
+    {
+        parent::assertKey($key);
+
+        if (strlen($key) > 250) {
+            throw new InvalidArgumentException("Key to long, max 250 characters");
+        }
+    }
+
+    /**
+     * Pack all values and turn keys into ids
+     *
+     * @param iterable $values
+     * @return array
+     */
+    protected function packValues(iterable $values): array
+    {
+        $packed = [];
+
+        foreach ($values as $key => $value) {
+            $this->assertKey(is_int($key) ? (string)$key : $key);
+            $packed[$key] = $this->pack($value);
+        }
+
+        return $packed;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        $this->assertKey($key);
+
+        $data = $this->server->get($key);
+
+        if ($this->server->getResultCode() !== MemcachedServer::RES_SUCCESS) {
+            return $default;
+        }
+
+        return $this->unpack($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        $this->assertKey($key);
+        $this->server->get($key);
+
+        $result = $this->server->getResultCode();
+
+        return $result === MemcachedServer::RES_SUCCESS;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $this->assertKey($key);
+
+        $packed = $this->pack($value);
+        $ttlTime = $this->ttlToMemcachedTime($ttl);
+
+        if ($ttlTime === false) {
+            return $this->delete($key);
+        }
+
+        $success = $this->server->set($key, $packed, $ttlTime);
+
+        return $success;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $this->server->delete($this->keyToId($key));
+
+        $result = $this->server->getResultCode();
+
+        return $result === MemcachedServer::RES_SUCCESS || $result === MemcachedServer::RES_NOTFOUND;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        $this->assertIterable($keys, 'keys not iterable');
+        $keysArr = is_array($keys) ? $keys : iterator_to_array($keys, false);
+        array_walk($keysArr, [$this, 'assertKey']);
+
+        $result = $this->server->getMulti($keysArr);
+
+        if ($result === false) {
+            return false;
+        }
+
+        $items = array_fill_keys($keysArr, $default);
+
+        foreach ($result as $key => $value) {
+            $items[$key] = $this->unpack($value);
+        }
+
+        return $items;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        $this->assertIterable($values, 'values not iterable');
+
+        $packed = $this->packValues($values);
+        $ttlTime = $this->ttlToMemcachedTime($ttl);
+
+        if ($ttlTime === false) {
+            return $this->server->deleteMulti(array_keys($packed));
+        }
+
+        return $this->server->setMulti($packed, $ttlTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+       return $this->server->flush();
+    }
+
+
+    /**
+     * Convert ttl to timestamp or seconds.
+     *
+     * @see http://php.net/manual/en/memcached.expiration.php
+     *
+     * @param null|int|\DateInterval $ttl
+     * @return int|null
+     * @throws InvalidArgumentException
+     */
+    protected function ttlToMemcachedTime($ttl)
+    {
+        $seconds = $this->ttlToSeconds($ttl);
+
+        if ($seconds <= 0) {
+            return isset($seconds) ? false : 0;
+        }
+
+        /* 2592000 seconds = 30 days */
+        return $seconds <= 2592000 ? $seconds : $this->ttlToTimestamp($ttl);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Memory.php b/msd/vendor/desarrolla2/cache/src/Memory.php
new file mode 100644
index 00000000..899cc797
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Memory.php
@@ -0,0 +1,165 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\SerializePacker;
+
+/**
+ * Memory
+ */
+class Memory extends AbstractCache
+{
+    /**
+     * Limit the amount of entries
+     * @var int
+     */
+    protected $limit = PHP_INT_MAX;
+
+
+    /**
+     * @var array
+     */
+    protected $cache = [];
+
+    /**
+     * @var array
+     */
+    protected $cacheTtl = [];
+
+
+    /**
+     * Create the default packer for this cache implementation.
+     * {@internal NopPacker might fail PSR-16, as cached objects would change}
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new SerializePacker();
+    }
+
+    /**
+     * Make a clone of this object.
+     * Set by cache reference, thus using the same pool.
+     *
+     * @return static
+     */
+    protected function cloneSelf(): AbstractCache
+    {
+        $clone = clone $this;
+
+        $clone->cache =& $this->cache;
+        $clone->cacheTtl =& $this->cacheTtl;
+
+        return $clone;
+    }
+
+    /**
+     * Set the max number of items
+     *
+     * @param int $limit
+     */
+    protected function setLimitOption($limit)
+    {
+        $this->limit = (int)$limit ?: PHP_INT_MAX;
+    }
+
+    /**
+     * Get the max number of items
+     *
+     * @return int
+     */
+    protected function getLimitOption()
+    {
+        return $this->limit;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        if (!$this->has($key)) {
+            return $default;
+        }
+
+        $id = $this->keyToId($key);
+
+        return $this->unpack($this->cache[$id]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        $id = $this->keyToId($key);
+
+        if (!isset($this->cacheTtl[$id])) {
+            return false;
+        }
+
+        if ($this->cacheTtl[$id] <= time()) {
+            unset($this->cache[$id], $this->cacheTtl[$id]);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        if (count($this->cache) >= $this->limit) {
+            $deleteKey = key($this->cache);
+            unset($this->cache[$deleteKey], $this->cacheTtl[$deleteKey]);
+        }
+
+        $id = $this->keyToId($key);
+
+        $this->cache[$id] = $this->pack($value);
+        $this->cacheTtl[$id] = $this->ttlToTimestamp($ttl) ?? PHP_INT_MAX;
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $id = $this->keyToId($key);
+        unset($this->cache[$id], $this->cacheTtl[$id]);
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        $this->cache = [];
+        $this->cacheTtl = [];
+
+        return true;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/MongoDB.php b/msd/vendor/desarrolla2/cache/src/MongoDB.php
new file mode 100644
index 00000000..95cc3315
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/MongoDB.php
@@ -0,0 +1,273 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\MongoDBBinaryPacker;
+use Desarrolla2\Cache\Option\InitializeTrait as InitializeOption;
+use MongoDB\Collection;
+use MongoDB\BSON\UTCDatetime as BSONUTCDateTime;
+use MongoDB\Driver\Exception\RuntimeException as MongoDBRuntimeException;
+
+/**
+ * MongoDB cache implementation
+ */
+class MongoDB extends AbstractCache
+{
+    use InitializeOption;
+
+    /**
+     * @var Collection
+     */
+    protected $collection;
+
+    /**
+     * Class constructor
+     *
+     * @param Collection $collection
+     */
+    public function __construct(Collection $collection)
+    {
+        $this->collection = $collection;
+    }
+
+    /**
+     * Initialize the DB collection.
+     * Set TTL index.
+     */
+    protected function initialize(): void
+    {
+        $this->collection->createIndex(['ttl' => 1], ['expireAfterSeconds' => 0]);
+    }
+
+
+    /**
+     * Create the default packer for this cache implementation.
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new MongoDBBinaryPacker();
+    }
+
+    /**
+     * Get filter for key and ttl.
+     *
+     * @param string|iterable $key
+     * @return array
+     */
+    protected function filter($key)
+    {
+        if (is_array($key)) {
+            $key = ['$in' => $key];
+        }
+
+        return [
+            '_id' => $key,
+            '$or' => [
+                ['ttl' => ['$gt' => new BSONUTCDateTime($this->currentTimestamp() * 1000)]],
+                ['ttl' => null]
+            ]
+        ];
+    }
+
+    /**
+     * {@inheritdoc }
+     */
+    public function get($key, $default = null)
+    {
+        $filter = $this->filter($this->keyToId($key));
+
+        try {
+            $data = $this->collection->findOne($filter);
+        } catch (MongoDBRuntimeException $e) {
+            return $default;
+        }
+
+        return isset($data) ? $this->unpack($data['value']) : $default;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        $idKeyPairs = $this->mapKeysToIds($keys);
+
+        if (empty($idKeyPairs)) {
+            return [];
+        }
+
+        $filter = $this->filter(array_keys($idKeyPairs));
+        $items = array_fill_keys(array_values($idKeyPairs), $default);
+
+        try {
+            $rows = $this->collection->find($filter);
+        } catch (MongoDBRuntimeException $e) {
+            return $items;
+        }
+
+        foreach ($rows as $row) {
+            $id = $row['_id'];
+            $key = $idKeyPairs[$id];
+
+            $items[$key] = $this->unpack($row['value']);
+        }
+
+        return $items;
+    }
+
+    /**
+     * {@inheritdoc }
+     */
+    public function has($key)
+    {
+        $filter = $this->filter($this->keyToId($key));
+
+        try {
+            $count = $this->collection->count($filter);
+        } catch (MongoDBRuntimeException $e) {
+            return false;
+        }
+
+        return $count  > 0;
+    }
+
+    /**
+     * {@inheritdoc }
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $id = $this->keyToId($key);
+
+        $item = [
+            '_id' => $id,
+            'ttl' => $this->getTtlBSON($ttl),
+            'value' => $this->pack($value)
+        ];
+
+        try {
+            $this->collection->replaceOne(['_id' => $id], $item, ['upsert' => true]);
+        } catch (MongoDBRuntimeException $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        $this->assertIterable($values, 'values not iterable');
+
+        if (empty($values)) {
+            return true;
+        }
+
+        $bsonTtl = $this->getTtlBSON($ttl);
+        $items = [];
+
+        foreach ($values as $key => $value) {
+            $id = $this->keyToId(is_int($key) ? (string)$key : $key);
+
+            $items[] = [
+                'replaceOne' => [
+                    ['_id' => $id],
+                    [
+                        '_id' => $id,
+                        'ttl' => $bsonTtl,
+                        'value' => $this->pack($value)
+                    ],
+                    [ 'upsert' => true ]
+                ]
+            ];
+        }
+
+        try {
+            $this->collection->bulkWrite($items);
+        } catch (MongoDBRuntimeException $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $id = $this->keyToId($key);
+
+        try {
+            $this->collection->deleteOne(['_id' => $id]);
+        } catch (MongoDBRuntimeException $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMultiple($keys)
+    {
+        $idKeyPairs = $this->mapKeysToIds($keys);
+
+        try {
+            if (!empty($idKeyPairs)) {
+                $this->collection->deleteMany(['_id' => ['$in' => array_keys($idKeyPairs)]]);
+            }
+        } catch (MongoDBRuntimeException $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        try {
+            $this->collection->drop();
+        } catch (MongoDBRuntimeException $e) {
+            return false;
+        }
+
+        $this->requireInitialization();
+
+        return true;
+    }
+
+
+    /**
+     * Get TTL as Date type BSON object
+     *
+     * @param null|int|\DateInterval $ttl
+     * @return BSONUTCDatetime|null
+     */
+    protected function getTtlBSON($ttl): ?BSONUTCDatetime
+    {
+        return isset($ttl) ? new BSONUTCDateTime($this->ttlToTimestamp($ttl) * 1000) : null;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Mysqli.php b/msd/vendor/desarrolla2/cache/src/Mysqli.php
new file mode 100644
index 00000000..3f44969c
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Mysqli.php
@@ -0,0 +1,312 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\Option\InitializeTrait;
+use mysqli as Server;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\SerializePacker;
+
+/**
+ * Mysqli cache adapter.
+ *
+ * Errors are silently ignored but exceptions are **not** caught. Beware when using `mysqli_report()` to throw a
+ * `mysqli_sql_exception` on error.
+ */
+class Mysqli extends AbstractCache
+{
+    use InitializeTrait;
+
+    /**
+     * @var Server
+     */
+    protected $server;
+
+    /**
+     * @var string
+     */
+    protected $table  = 'cache';
+
+
+    /**
+     * Class constructor
+     *
+     * @param Server $server
+     */
+    public function __construct(Server $server)
+    {
+        $this->server = $server;
+    }
+
+
+    /**
+     * Initialize table.
+     * Automatically delete old cache.
+     */
+    protected function initialize(): void
+    {
+        if ($this->initialized !== false) {
+            return;
+        }
+
+        $this->query(
+            "CREATE TABLE IF NOT EXISTS `{table}` "
+            . "( `key` VARCHAR(255), `value` BLOB, `ttl` BIGINT UNSIGNED, PRIMARY KEY (`key`) )"
+        );
+
+        $this->query(
+            "CREATE EVENT IF NOT EXISTS `apply_ttl_{$this->table}` ON SCHEDULE EVERY 1 HOUR DO BEGIN"
+            . " DELETE FROM {table} WHERE `ttl` < UNIX_TIMESTAMP();"
+            . " END"
+        );
+
+        $this->initialized = true;
+    }
+
+    /**
+     * Create the default packer for this cache implementation.
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new SerializePacker();
+    }
+
+
+    /**
+     * Set the table name
+     *
+     * @param string $table
+     */
+    public function setTableOption(string $table)
+    {
+        $this->table = $table;
+        $this->requireInitialization();
+    }
+
+    /**
+     * Get the table name
+     *
+     * @return string
+     */
+    public function getTableOption(): string
+    {
+        return $this->table;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        $this->initialize();
+
+        $result = $this->query(
+            'SELECT `value` FROM {table} WHERE `key` = ? AND (`ttl` > ? OR `ttl` IS NULL) LIMIT 1',
+            'si',
+            $this->keyToId($key),
+            $this->currentTimestamp()
+        );
+
+        $row = $result !== false ? $result->fetch_row() : null;
+
+        return $row ? $this->unpack($row[0]) : $default;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        $idKeyPairs = $this->mapKeysToIds($keys);
+
+        if (empty($idKeyPairs)) {
+            return [];
+        }
+
+        $this->initialize();
+
+        $values = array_fill_keys(array_values($idKeyPairs), $default);
+
+        $placeholders = rtrim(str_repeat('?, ', count($idKeyPairs)), ', ');
+        $paramTypes = str_repeat('s', count($idKeyPairs)) . 'i';
+        $params = array_keys($idKeyPairs);
+        $params[] = $this->currentTimestamp();
+
+        $result = $this->query(
+            "SELECT `key`, `value` FROM {table} WHERE `key` IN ($placeholders) AND (`ttl` > ? OR `ttl` IS NULL)",
+            $paramTypes,
+            ...$params
+        );
+
+        while (([$id, $value] = $result->fetch_row())) {
+            $key = $idKeyPairs[$id];
+            $values[$key] = $this->unpack($value);
+        }
+
+        return $values;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        $this->initialize();
+
+        $result = $this->query(
+            'SELECT COUNT(`key`) FROM {table} WHERE `key` = ? AND (`ttl` > ? OR `ttl` IS NULL) LIMIT 1',
+            'si',
+            $this->keyToId($key),
+            $this->currentTimestamp()
+        );
+
+        [$count] = $result ? $result->fetch_row() : [null];
+
+        return isset($count) && $count > 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $this->initialize();
+
+        $result = $this->query(
+            'REPLACE INTO {table} (`key`, `value`, `ttl`) VALUES (?, ?, ?)',
+            'ssi',
+            $this->keyToId($key),
+            $this->pack($value),
+            $this->ttlToTimestamp($ttl)
+        );
+
+        return $result !== false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        $this->assertIterable($values, 'values not iterable');
+
+        if (empty($values)) {
+            return true;
+        }
+
+        $this->initialize();
+
+        $count = 0;
+        $params = [];
+        $timeTtl = $this->ttlToTimestamp($ttl);
+
+        foreach ($values as $key => $value) {
+            $count++;
+            $params[] = $this->keyToId(is_int($key) ? (string)$key : $key);
+            $params[] = $this->pack($value);
+            $params[] = $timeTtl;
+        }
+
+        $query = 'REPLACE INTO {table} (`key`, `value`, `ttl`) VALUES '
+            . rtrim(str_repeat('(?, ?, ?), ', $count), ', ');
+
+        return (bool)$this->query($query, str_repeat('ssi', $count), ...$params);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $this->initialize();
+
+        return (bool)$this->query(
+            'DELETE FROM {table} WHERE `key` = ?',
+            's',
+            $this->keyToId($key)
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMultiple($keys)
+    {
+        $idKeyPairs = $this->mapKeysToIds($keys);
+
+        if (empty($idKeyPairs)) {
+            return true;
+        }
+
+        $this->initialize();
+
+        $placeholders = rtrim(str_repeat('?, ', count($idKeyPairs)), ', ');
+        $paramTypes = str_repeat('s', count($idKeyPairs));
+
+        return (bool)$this->query(
+            "DELETE FROM {table} WHERE `key` IN ($placeholders)",
+            $paramTypes,
+            ...array_keys($idKeyPairs)
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        $this->initialize();
+        return (bool)$this->query('TRUNCATE {table}');
+    }
+
+
+    /**
+     * Query the MySQL server
+     *
+     * @param string  $query
+     * @param string  $types
+     * @param mixed[] $params
+     * @return \mysqli_result|bool
+     */
+    protected function query($query, $types = '', ...$params)
+    {
+        $sql = str_replace('{table}', $this->table, $query);
+
+        if ($params === []) {
+            $ret = $this->server->query($sql);
+        } else {
+            $statement = $this->server->prepare($sql);
+
+            if ($statement !== false) {
+                $statement->bind_param($types, ...$params);
+
+                $ret = $statement->execute();
+                $ret = $ret ? ($statement->get_result() ?: true) : false;
+            } else {
+                $ret = false;
+            }
+        }
+
+        if ($this->server->error) {
+            trigger_error($this->server->error . " $sql", E_USER_NOTICE);
+        }
+
+        return $ret;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/NotCache.php b/msd/vendor/desarrolla2/cache/src/NotCache.php
new file mode 100644
index 00000000..1aafc7f3
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/NotCache.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\AbstractCache;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\NopPacker;
+
+/**
+ * Dummy cache handler
+ */
+class NotCache extends AbstractCache
+{
+    /**
+     * Create the default packer for this cache implementation.
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new NopPacker();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        return true;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Option/FilenameTrait.php b/msd/vendor/desarrolla2/cache/src/Option/FilenameTrait.php
new file mode 100644
index 00000000..345607c6
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Option/FilenameTrait.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Option;
+
+use TypeError;
+use Desarrolla2\Cache\File\BasicFilename;
+
+/**
+ * Use filename generator
+ */
+trait FilenameTrait
+{
+    /**
+     * @var callable
+     */
+    protected $filename;
+
+
+    /**
+     * Filename format or callable.
+     * The filename format will be applied using sprintf, replacing `%s` with the key.
+     *
+     * @param string|callable $filename
+     * @return void
+     */
+    protected function setFilenameOption($filename): void
+    {
+        if (is_string($filename)) {
+            $filename = new BasicFilename($filename);
+        }
+
+        if (!is_callable($filename)) {
+            throw new TypeError("Filename should be a string or callable");
+        }
+
+        $this->filename = $filename;
+    }
+
+    /**
+     * Get the filename callable
+     *
+     * @return callable
+     */
+    protected function getFilenameOption(): callable
+    {
+        if (!isset($this->filename)) {
+            $this->filename = new BasicFilename('%s.' . $this->getPacker()->getType());
+        }
+
+        return $this->filename;
+    }
+
+    /**
+     * Create a filename based on the key
+     *
+     * @param string|mixed $key
+     * @return string
+     */
+    protected function getFilename($key): string
+    {
+        $id = $this->keyToId($key);
+        $generator = $this->getFilenameOption();
+
+        return $this->cacheDir . DIRECTORY_SEPARATOR . $generator($id);
+    }
+
+    /**
+     * Get a wildcard for all files
+     *
+     * @return string
+     */
+    protected function getWildcard(): string
+    {
+        $generator = $this->getFilenameOption();
+
+        return $this->cacheDir . DIRECTORY_SEPARATOR . $generator('');
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Option/InitializeTrait.php b/msd/vendor/desarrolla2/cache/src/Option/InitializeTrait.php
new file mode 100644
index 00000000..680d507c
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Option/InitializeTrait.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Option;
+
+/**
+ * Auto initialize the cache
+ */
+trait InitializeTrait
+{
+    /**
+     * Is cache initialized
+     * @var bool|null
+     */
+    protected $initialized = false;
+
+
+    /**
+     * Enable/disable initialization
+     *
+     * @param bool $enabled
+     */
+    public function setInitializeOption(bool $enabled)
+    {
+        $this->initialized = $enabled ? (bool)$this->initialized : null;
+    }
+
+    /**
+     * Should initialize
+     *
+     * @return bool
+     */
+    protected function getInitializeOption(): bool
+    {
+        return $this->initialized !== null;
+    }
+
+    /**
+     * Mark as initialization required (if enabled)
+     */
+    protected function requireInitialization()
+    {
+        $this->initialized = isset($this->initialized) ? false : null;
+    }
+
+
+    /**
+     * Initialize
+     *
+     * @return void
+     */
+    abstract protected function initialize(): void;
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Option/PrefixTrait.php b/msd/vendor/desarrolla2/cache/src/Option/PrefixTrait.php
new file mode 100644
index 00000000..2befaf4b
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Option/PrefixTrait.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Option;
+
+/**
+ * Prefix option
+ */
+trait PrefixTrait
+{
+    /**
+     * @var string
+     */
+    protected $prefix = '';
+
+
+    /**
+     * Set the key prefix
+     *
+     * @param string $prefix
+     * @return void
+     */
+    protected function setPrefixOption(string $prefix): void
+    {
+        $this->prefix = $prefix;
+    }
+
+    /**
+     * Get the key prefix
+     *
+     * @return string
+     */
+    protected function getPrefixOption(): string
+    {
+        return $this->prefix;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Option/TtlTrait.php b/msd/vendor/desarrolla2/cache/src/Option/TtlTrait.php
new file mode 100644
index 00000000..330aa154
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Option/TtlTrait.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Option;
+
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+
+/**
+ * TTL option
+ */
+trait TtlTrait
+{
+    /**
+     * @var int|null
+     */
+    protected $ttl = null;
+
+    /**
+     * Set the maximum time to live (ttl)
+     *
+     * @param int|null $value  Seconds or null to live forever
+     * @throws InvalidArgumentException
+     */
+    protected function setTtlOption(?int $value): void
+    {
+        if (isset($value) && $value < 1) {
+            throw new InvalidArgumentException('ttl cant be lower than 1');
+        }
+
+        $this->ttl = $value;
+    }
+
+    /**
+     * Get the maximum time to live (ttl)
+     *
+     * @return int|null
+     */
+    protected function getTtlOption(): ?int
+    {
+        return $this->ttl;
+    }
+}
\ No newline at end of file
diff --git a/msd/vendor/desarrolla2/cache/src/Packer/JsonPacker.php b/msd/vendor/desarrolla2/cache/src/Packer/JsonPacker.php
new file mode 100644
index 00000000..80fb649c
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Packer/JsonPacker.php
@@ -0,0 +1,69 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Packer;
+
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+
+/**
+ * Pack value through serialization
+ */
+class JsonPacker implements PackerInterface
+{
+    /**
+     * Get cache type (might be used as file extension)
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return 'json';
+    }
+
+    /**
+     * Pack the value
+     * 
+     * @param mixed $value
+     * @return string
+     */
+    public function pack($value)
+    {
+        return json_encode($value);
+    }
+    
+    /**
+     * Unpack the value
+     * 
+     * @param string $packed
+     * @return mixed
+     * @throws InvalidArgumentException
+     */
+    public function unpack($packed)
+    {
+        if (!is_string($packed)) {
+            throw new InvalidArgumentException("packed value should be a string");
+        }
+
+        $ret = json_decode($packed);
+
+        if (!isset($ret) && json_last_error()) {
+            throw new \UnexpectedValueException("packed value is not a valid JSON string");
+        }
+
+        return $ret;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Packer/MongoDBBinaryPacker.php b/msd/vendor/desarrolla2/cache/src/Packer/MongoDBBinaryPacker.php
new file mode 100644
index 00000000..562c7109
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Packer/MongoDBBinaryPacker.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+namespace Desarrolla2\Cache\Packer;
+
+use Desarrolla2\Cache\Packer\PackerInterface;
+use MongoDB\BSON\Binary;
+
+/**
+ * Pack as BSON binary
+ *
+ * @todo Don't use serialize when packer chain is here.
+ */
+class MongoDBBinaryPacker implements PackerInterface
+{
+    /**
+     * @var array
+     */
+    protected $options;
+
+    /**
+     * SerializePacker constructor
+     *
+     * @param array $options  Any options to be provided to unserialize()
+     */
+    public function __construct(array $options = ['allowed_classes' => true])
+    {
+        $this->options = $options;
+    }
+
+    /**
+     * Get cache type (might be used as file extension)
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return 'bson';
+    }
+
+    /**
+     * Pack the value
+     *
+     * @param mixed $value
+     * @return string
+     */
+    public function pack($value)
+    {
+        return new Binary(serialize($value), Binary::TYPE_GENERIC);
+    }
+
+    /**
+     * Unpack the value
+     *
+     * @param string $packed
+     * @return string
+     * @throws \UnexpectedValueException if he value can't be unpacked
+     */
+    public function unpack($packed)
+    {
+        if (!$packed instanceof Binary) {
+            throw new \InvalidArgumentException("packed value should be BSON binary");
+        }
+
+        return unserialize((string)$packed, $this->options);
+    }
+}
\ No newline at end of file
diff --git a/msd/vendor/desarrolla2/cache/src/Packer/NopPacker.php b/msd/vendor/desarrolla2/cache/src/Packer/NopPacker.php
new file mode 100644
index 00000000..3e1bd44d
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Packer/NopPacker.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Packer;
+
+use Desarrolla2\Cache\Packer\PackerInterface;
+
+/**
+ * Don't pack, just straight passthrough
+ */
+class NopPacker implements PackerInterface
+{
+    /**
+     * Get cache type (might be used as file extension)
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return 'data';
+    }
+
+    /**
+     * Pack the value
+     * 
+     * @param mixed $value
+     * @return mixed
+     */
+    public function pack($value)
+    {
+        return $value;
+    }
+    
+    /**
+     * Unpack the value
+     * 
+     * @param mixed $packed
+     * @return mixed
+     */
+    public function unpack($packed)
+    {
+        return $packed;
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Packer/PackerInterface.php b/msd/vendor/desarrolla2/cache/src/Packer/PackerInterface.php
new file mode 100644
index 00000000..1c1539ee
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Packer/PackerInterface.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Packer;
+
+/**
+ * Interface for packer / unpacker
+ */
+interface PackerInterface
+{
+    /**
+     * Get cache type (might be used as file extension)
+     *
+     * @return string
+     */
+    public function getType();
+
+    /**
+     * Pack the value
+     * 
+     * @param mixed $value
+     * @return string|mixed
+     */
+    public function pack($value);
+    
+    /**
+     * Unpack the value
+     * 
+     * @param string|mixed $packed
+     * @return string
+     * @throws \UnexpectedValueException if the value can't be unpacked
+     */
+    public function unpack($packed);
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Packer/PackingTrait.php b/msd/vendor/desarrolla2/cache/src/Packer/PackingTrait.php
new file mode 100644
index 00000000..4d786c73
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Packer/PackingTrait.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Packer;
+
+/**
+ * Support packing for Caching adapter
+ */
+trait PackingTrait
+{
+    /**
+     * @var PackerInterface
+     */
+    protected $packer;
+
+
+    /**
+     * Create the default packer for this cache implementation
+     *
+     * @return PackerInterface
+     */
+    abstract protected static function createDefaultPacker(): PackerInterface;
+
+    /**
+     * Set a packer to pack (serialialize) and unpack (unserialize) the data.
+     *
+     * @param PackerInterface $packer
+     * @return static
+     */
+    public function withPacker(PackerInterface $packer)
+    {
+        $cache = $this->cloneSelf();
+        $cache->packer = $packer;
+
+        return $cache;
+    }
+
+    /**
+     * Get the packer
+     *
+     * @return PackerInterface
+     */
+    protected function getPacker(): PackerInterface
+    {
+        if (!isset($this->packer)) {
+            $this->packer = static::createDefaultPacker();
+        }
+
+        return $this->packer;
+    }
+
+    /**
+     * Pack the value
+     *
+     * @param mixed $value
+     * @return string|mixed
+     */
+    protected function pack($value)
+    {
+        return $this->getPacker()->pack($value);
+    }
+
+    /**
+     * Unpack the data to retrieve the value
+     *
+     * @param string|mixed $packed
+     * @return mixed
+     * @throws \UnexpectedValueException
+     */
+    protected function unpack($packed)
+    {
+        return $this->getPacker()->unpack($packed);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Packer/SerializePacker.php b/msd/vendor/desarrolla2/cache/src/Packer/SerializePacker.php
new file mode 100644
index 00000000..8df68fd3
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Packer/SerializePacker.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache\Packer;
+
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+
+/**
+ * Pack value through serialization
+ */
+class SerializePacker implements PackerInterface
+{
+    /**
+     * @var array
+     */
+    protected $options;
+
+    /**
+     * SerializePacker constructor
+     *
+     * @param array $options  Any options to be provided to unserialize()
+     */
+    public function __construct(array $options = ['allowed_classes' => true])
+    {
+        $this->options = $options;
+    }
+
+    /**
+     * Get cache type (might be used as file extension)
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return 'php.cache';
+    }
+
+    /**
+     * Pack the value
+     * 
+     * @param mixed $value
+     * @return string
+     */
+    public function pack($value)
+    {
+        return serialize($value);
+    }
+    
+    /**
+     * Unpack the value
+     * 
+     * @param string $packed
+     * @return string
+     * @throws \UnexpectedValueException if he value can't be unpacked
+     */
+    public function unpack($packed)
+    {
+        if (!is_string($packed)) {
+            throw new InvalidArgumentException("packed value should be a string");
+        }
+
+        return unserialize($packed, $this->options);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/PhpFile.php b/msd/vendor/desarrolla2/cache/src/PhpFile.php
new file mode 100644
index 00000000..a8774e39
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/PhpFile.php
@@ -0,0 +1,111 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\AbstractFile;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\SerializePacker;
+use Desarrolla2\Cache\File\BasicFilename;
+
+/**
+ * Cache file as PHP script.
+ */
+class PhpFile extends AbstractFile
+{
+    /**
+     * Create the default packer for this cache implementation.
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new SerializePacker();
+    }
+
+    /**
+     * Get the filename callable
+     *
+     * @return callable
+     */
+    protected function getFilenameOption(): callable
+    {
+        if (!isset($this->filename)) {
+            $this->filename = new BasicFilename('%s.php');
+        }
+
+        return $this->filename;
+    }
+
+    /**
+     * Create a PHP script returning the cached value
+     *
+     * @param mixed    $value
+     * @param int|null $ttl
+     * @return string
+     */
+    public function createScript($value, ?int $ttl): string
+    {
+        $macro = var_export($value, true);
+
+        if (strpos($macro, 'stdClass::__set_state') !== false) {
+            $macro = preg_replace_callback("/('([^'\\\\]++|''\\.)')|stdClass::__set_state/", $macro, function($match) {
+                return empty($match[1]) ? '(object)' : $match[1];
+            });
+        }
+
+        return $ttl !== null
+            ? "<?php return time() < {$ttl} ? {$macro} : false;"
+            : "<?php return {$macro};";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        $cacheFile = $this->getFilename($key);
+
+        if (!file_exists($cacheFile)) {
+            return $default;
+        }
+
+        $packed = include $cacheFile;
+
+        return $packed === false ? $default : $this->unpack($packed);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        return $this->get($key) !== null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $cacheFile = $this->getFilename($key);
+
+        $packed = $this->pack($value);
+        $script = $this->createScript($packed, $this->ttlToTimestamp($ttl));
+
+        return $this->writeFile($cacheFile, $script);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/src/Predis.php b/msd/vendor/desarrolla2/cache/src/Predis.php
new file mode 100644
index 00000000..73d11180
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/src/Predis.php
@@ -0,0 +1,245 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+declare(strict_types=1);
+
+namespace Desarrolla2\Cache;
+
+use Desarrolla2\Cache\AbstractCache;
+use Desarrolla2\Cache\Exception\UnexpectedValueException;
+use Desarrolla2\Cache\Packer\PackerInterface;
+use Desarrolla2\Cache\Packer\SerializePacker;
+use Predis\Client;
+use Predis\Response\ServerException;
+use Predis\Response\Status;
+use Predis\Response\ErrorInterface;
+
+/**
+ * Predis cache adapter.
+ *
+ * Errors are silently ignored but ServerExceptions are **not** caught. To PSR-16 compliant disable the `exception`
+ * option.
+ */
+class Predis extends AbstractCache
+{
+    /**
+     * @var Client
+     */
+    protected $predis;
+
+    /**
+     * Class constructor
+     * @see predis documentation about how know your configuration https://github.com/nrk/predis
+     *
+     * @param Client $client
+     */
+    public function __construct(Client $client)
+    {
+        $this->predis = $client;
+    }
+
+    /**
+     * Create the default packer for this cache implementation.
+     *
+     * @return PackerInterface
+     */
+    protected static function createDefaultPacker(): PackerInterface
+    {
+        return new SerializePacker();
+    }
+
+
+    /**
+     * Run a predis command.
+     *
+     * @param string $cmd
+     * @param mixed ...$args
+     * @return mixed|bool
+     */
+    protected function execCommand(string $cmd, ...$args)
+    {
+        $command = $this->predis->createCommand($cmd, $args);
+        $response = $this->predis->executeCommand($command);
+
+        if ($response instanceof ErrorInterface) {
+            return false;
+        }
+
+        if ($response instanceof Status) {
+            return $response->getPayload() === 'OK';
+        }
+
+        return $response;
+    }
+
+    /**
+     * Set multiple (mset) with expire
+     *
+     * @param array    $dictionary
+     * @param int|null $ttlSeconds
+     * @return bool
+     */
+    protected function msetExpire(array $dictionary, ?int $ttlSeconds): bool
+    {
+        if (empty($dictionary)) {
+            return true;
+        }
+
+        if (!isset($ttlSeconds)) {
+            return $this->execCommand('MSET', $dictionary);
+        }
+
+        $transaction = $this->predis->transaction();
+
+        foreach ($dictionary as $key => $value) {
+            $transaction->set($key, $value, 'EX', $ttlSeconds);
+        }
+
+        try {
+            $responses = $transaction->execute();
+        } catch (ServerException $e) {
+            return false;
+        }
+
+        $ok = array_reduce($responses, function($ok, $response) {
+            return $ok && $response instanceof Status && $response->getPayload() === 'OK';
+        }, true);
+
+        return $ok;
+    }
+
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        $id = $this->keyToId($key);
+        $response = $this->execCommand('GET', $id);
+
+        return !empty($response) ? $this->unpack($response) : $default;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMultiple($keys, $default = null)
+    {
+        $idKeyPairs = $this->mapKeysToIds($keys);
+        $ids = array_keys($idKeyPairs);
+
+        $response = $this->execCommand('MGET', $ids);
+
+        if ($response === false) {
+            return false;
+        }
+
+        $items = [];
+        $packedItems = array_combine(array_values($idKeyPairs), $response);
+
+        foreach ($packedItems as $key => $packed) {
+            $items[$key] = isset($packed) ? $this->unpack($packed) : $default;
+        }
+
+        return $items;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        return $this->execCommand('EXISTS', $this->keyToId($key));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value, $ttl = null)
+    {
+        $id = $this->keyToId($key);
+        $packed = $this->pack($value);
+
+        if (!is_string($packed)) {
+            throw new UnexpectedValueException("Packer must create a string for the data");
+        }
+
+        $ttlSeconds = $this->ttlToSeconds($ttl);
+
+        if (isset($ttlSeconds) && $ttlSeconds <= 0) {
+            return $this->execCommand('DEL', [$id]);
+        }
+
+        return !isset($ttlSeconds)
+            ? $this->execCommand('SET', $id, $packed)
+            : $this->execCommand('SETEX', $id, $ttlSeconds, $packed);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMultiple($values, $ttl = null)
+    {
+        $this->assertIterable($values, 'values not iterable');
+
+        $dictionary = [];
+
+        foreach ($values as $key => $value) {
+            $id = $this->keyToId(is_int($key) ? (string)$key : $key);
+            $packed = $this->pack($value);
+
+            if (!is_string($packed)) {
+                throw new UnexpectedValueException("Packer must create a string for the data");
+            }
+
+            $dictionary[$id] = $packed;
+        }
+
+        $ttlSeconds = $this->ttlToSeconds($ttl);
+
+        if (isset($ttlSeconds) && $ttlSeconds <= 0) {
+            return $this->execCommand('DEL', array_keys($dictionary));
+        }
+
+        return $this->msetExpire($dictionary, $ttlSeconds);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($key)
+    {
+        $id = $this->keyToId($key);
+
+        return $this->execCommand('DEL', [$id]) !== false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMultiple($keys)
+    {
+        $ids = array_keys($this->mapKeysToIds($keys));
+
+        return empty($ids) || $this->execCommand('DEL', $ids) !== false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function clear()
+    {
+        return $this->execCommand('FLUSHDB');
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/AbstractCacheTest.php b/msd/vendor/desarrolla2/cache/tests/AbstractCacheTest.php
new file mode 100644
index 00000000..8c16a7a6
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/AbstractCacheTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Cache\IntegrationTests\SimpleCacheTest;
+use Desarrolla2\Cache\Exception\InvalidArgumentException;
+
+/**
+ * AbstractCacheTest
+ */
+abstract class AbstractCacheTest extends SimpleCacheTest
+{
+    /**
+     * @return array
+     */
+    public function dataProviderForOptions()
+    {
+        return [
+            ['ttl', 100],
+            ['prefix', 'test']
+        ];
+    }
+
+    /**
+     * @dataProvider dataProviderForOptions
+     *
+     * @param string $key
+     * @param mixed  $value
+     */
+    public function testWithOption($key, $value)
+    {
+        $cache = $this->cache->withOption($key, $value);
+        $this->assertEquals($value, $cache->getOption($key));
+
+        // Check immutability
+        $this->assertNotSame($this->cache, $cache);
+        $this->assertNotEquals($value, $this->cache->getOption($key));
+    }
+
+    public function testWithOptions()
+    {
+        $data = $this->dataProviderForOptions();
+        $options = array_combine(array_column($data, 0), array_column($data, 1));
+
+        $cache = $this->cache->withOptions($options);
+
+        foreach ($options as $key => $value) {
+            $this->assertEquals($value, $cache->getOption($key));
+        }
+
+        // Check immutability
+        $this->assertNotSame($this->cache, $cache);
+
+        foreach ($options as $key => $value) {
+            $this->assertNotEquals($value, $this->cache->getOption($key));
+        }
+    }
+
+
+    /**
+     * @return array
+     */
+    public function dataProviderForOptionsException()
+    {
+        return [
+            ['ttl', 0, InvalidArgumentException::class],
+            ['foo', 'bar', InvalidArgumentException::class]
+        ];
+    }
+
+    /**
+     * @dataProvider dataProviderForOptionsException
+     *
+     * @param string   $key
+     * @param mixed    $value
+     * @param string   $expectedException
+     */
+    public function testWithOptionException($key, $value, $expectedException)
+    {
+        $this->expectException($expectedException);
+        $this->createSimpleCache()->withOption($key, $value);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/ApcuCacheTest.php b/msd/vendor/desarrolla2/cache/tests/ApcuCacheTest.php
new file mode 100644
index 00000000..94cea254
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/ApcuCacheTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\Apcu as ApcuCache;
+
+/**
+ * ApcuCacheTest
+ */
+class ApcuCacheTest extends AbstractCacheTest
+{
+    public static function setUpBeforeClass(): void
+    {
+        // Required to check the TTL for new entries
+        ini_set('apc.use_request_time', false);
+    }
+
+    public function createSimpleCache()
+    {
+        if (!extension_loaded('apcu')) {
+            $this->markTestSkipped(
+                'The APCu extension is not available.'
+            );
+        }
+        if (!ini_get('apc.enable_cli')) {
+            $this->markTestSkipped(
+                'You need to enable apc.enable_cli'
+            );
+        }
+        
+        return new ApcuCache();
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/ChainTest.php b/msd/vendor/desarrolla2/cache/tests/ChainTest.php
new file mode 100644
index 00000000..e22010bb
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/ChainTest.php
@@ -0,0 +1,216 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\Chain as CacheChain;
+use Desarrolla2\Cache\Memory as MemoryCache;
+
+/**
+ * ChainTest
+ */
+class ChainTest extends AbstractCacheTest
+{
+    public function createSimpleCache()
+    {
+        $adapters = [new MemoryCache()]; // For the general PSR-16 tests, we don't need more than 1 adapter
+
+        return new CacheChain($adapters);
+    }
+
+
+    public function tearDown(): void
+    {
+        // No need to clear cache, as the adapters don't persist between tests.
+    }
+
+
+    public function testChainSet()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('set')->with("foo", "bar", 300);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('set')->with("foo", "bar", 300);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $cache->set("foo", "bar", 300);
+    }
+
+    public function testChainSetMultiple()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('setMultiple')->with(["foo" => 1, "bar" => 2], 300);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('setMultiple')->with(["foo" => 1, "bar" => 2], 300);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $cache->setMultiple(["foo" => 1, "bar" => 2], 300);
+    }
+
+
+    public function testChainGetFirst()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('get')->with("foo")->willReturn("bar");
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->never())->method('get');
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertEquals("bar", $cache->get("foo", 42));
+    }
+
+    public function testChainGetSecond()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('get')->with("foo")->willReturn(null);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('get')->with("foo")->willReturn("car");
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertEquals("car", $cache->get("foo", 42));
+    }
+
+    public function testChainGetNone()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('get')->with("foo")->willReturn(null);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('get')->with("foo")->willReturn(null);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertEquals(42, $cache->get("foo", 42));
+    }
+
+
+    public function testChainGetMultipleFirst()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('getMultiple')->with(["foo", "bar"])
+            ->willReturn(["foo" => 1, "bar" => 2]);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->never())->method('getMultiple');
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertEquals(["foo" => 1, "bar" => 2], $cache->getMultiple(["foo", "bar"]));
+    }
+
+    public function testChainGetMultipleMixed()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('getMultiple')
+            ->with($this->equalTo(["foo", "bar", "wux", "lot"]))
+            ->willReturn(["foo" => null, "bar" => 2, "wux" => null, "lot" => null]);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('getMultiple')
+            ->with($this->equalTo(["foo", "wux", "lot"]))
+            ->willReturn(["foo" => 11, "wux" => 15, "lot" => null]);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $expected = ["foo" => 11, "bar" => 2, "wux" => 15, "lot" => 42];
+        $this->assertEquals($expected, $cache->getMultiple(["foo", "bar", "wux", "lot"], 42));
+    }
+    
+
+    public function testChainHasFirst()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('has')->with("foo")->willReturn(true);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->never())->method('has');
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertTrue($cache->has("foo"));
+    }
+
+    public function testChainHasSecond()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('has')->with("foo")->willReturn(false);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('has')->with("foo")->willReturn(true);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertTrue($cache->has("foo"));
+    }
+
+    public function testChainHasNone()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('has')->with("foo")->willReturn(false);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('has')->with("foo")->willReturn(false);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $this->assertFalse($cache->has("foo"));
+    }
+
+
+    public function testChainDelete()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('delete')->with("foo");
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('delete')->with("foo");
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $cache->delete("foo");
+    }
+
+    public function testChainDeleteMultiple()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('deleteMultiple')->with(["foo", "bar"]);
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('deleteMultiple')->with(["foo", "bar"]);
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $cache->deleteMultiple(["foo", "bar"]);
+    }
+
+    public function testChainClear()
+    {
+        $adapter1 = $this->createMock(MemoryCache::class);
+        $adapter1->expects($this->once())->method('clear');
+
+        $adapter2 = $this->createMock(MemoryCache::class);
+        $adapter2->expects($this->once())->method('clear');
+
+        $cache = new CacheChain([$adapter1, $adapter2]);
+
+        $cache->clear();
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/FileTest.php b/msd/vendor/desarrolla2/cache/tests/FileTest.php
new file mode 100644
index 00000000..b03a6b4a
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/FileTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\File as FileCache;
+use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
+
+/**
+ * FileTest
+ */
+class FileTest extends AbstractCacheTest
+{
+    /**
+     * @var vfsStreamDirectory
+     */
+    private $root;
+
+    protected $skippedTests = [
+        'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
+    ];
+
+    public function createSimpleCache()
+    {
+        $this->root = vfsStream::setup('cache');
+
+        return new FileCache(vfsStream::url('cache'));
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/FileTrieTest.php b/msd/vendor/desarrolla2/cache/tests/FileTrieTest.php
new file mode 100644
index 00000000..9ff06e7c
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/FileTrieTest.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\File as FileCache;
+use Desarrolla2\Cache\File\TrieFilename;
+use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
+
+/**
+ * FileTest with Trie structure
+ */
+class FileTrieTest extends AbstractCacheTest
+{
+    /**
+     * @var vfsStreamDirectory
+     */
+    private $root;
+
+    protected $skippedTests = [
+        'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
+    ];
+
+    public function createSimpleCache()
+    {
+        $this->root = vfsStream::setup('cache');
+
+        return (new FileCache(vfsStream::url('cache')))
+            ->withOption('filename', new TrieFilename('%s.php.cache',4));
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/FileTtlFileTest.php b/msd/vendor/desarrolla2/cache/tests/FileTtlFileTest.php
new file mode 100644
index 00000000..3c05d8cf
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/FileTtlFileTest.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ * @author Arnold Daniels <arnold@jasny.net>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\File as FileCache;
+use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
+
+/**
+ * FileTest
+ */
+class FileTtlFileTest extends AbstractCacheTest
+{
+    /**
+     * @var vfsStreamDirectory
+     */
+    private $root;
+
+    protected $skippedTests = [
+        'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
+    ];
+
+    public function createSimpleCache()
+    {
+        $this->root = vfsStream::setup('cache');
+
+        return (new FileCache(vfsStream::url('cache')))
+            ->withOption('ttl-strategy', 'file');
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/MemcachedTest.php b/msd/vendor/desarrolla2/cache/tests/MemcachedTest.php
new file mode 100644
index 00000000..ba59442d
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/MemcachedTest.php
@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\Memcached as MemcachedCache;
+use Memcached;
+
+/**
+ * MemcachedTest
+ */
+class MemcachedTest extends AbstractCacheTest
+{
+    protected $skippedTests = [
+        'testBasicUsageWithLongKey' => 'Only support keys up to 250 bytes'
+    ];
+
+    public function createSimpleCache()
+    {
+        if (!extension_loaded('memcached') || !class_exists('\Memcached')) {
+            $this->markTestSkipped(
+                'The Memcached extension is not available.'
+            );
+        }
+
+        list($host, $port) = explode(':', CACHE_TESTS_MEMCACHED_SERVER) + [1 => 11211];
+
+        $adapter = new Memcached();
+        $adapter->addServer($host, (int)$port);
+
+        if (!$adapter->flush()) {
+            $this->markTestSkipped("Unable to flush Memcached; not running?");
+        }
+
+        return new MemcachedCache($adapter);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/MemoryTest.php b/msd/vendor/desarrolla2/cache/tests/MemoryTest.php
new file mode 100644
index 00000000..b3cd7cbe
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/MemoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\Memory as MemoryCache;
+
+/**
+ * MemoryTest
+ */
+class MemoryTest extends AbstractCacheTest
+{
+    public function createSimpleCache()
+    {
+        return new MemoryCache();
+    }
+
+    public function tearDown(): void
+    {
+        // No need to clear cache, as the adapters don't persist between tests.
+    }
+
+    public function testExceededLimit()
+    {
+        $cache = $this->createSimpleCache()->withOption('limit', 1);
+
+        $cache->set('foo', 1);
+        $this->assertTrue($cache->has('foo'));
+
+        $cache->set('bar', 1);
+        $this->assertFalse($cache->has('foo'));
+        $this->assertTrue($cache->has('bar'));
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/MongoDBTest.php b/msd/vendor/desarrolla2/cache/tests/MongoDBTest.php
new file mode 100644
index 00000000..ebd82c81
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/MongoDBTest.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\MongoDB as MongoDBCache;
+use MongoDB\Client;
+
+/**
+ * MongoDBTest
+ */
+class MongoDBTest extends AbstractCacheTest
+{
+    /**
+     * @var Client
+     */
+    protected static $client;
+
+    /**
+     * Use one client per test, as the MongoDB extension leaves connections open
+     */
+    public static function setUpBeforeClass(): void
+    {
+        if (!extension_loaded('mongodb')) {
+            return;
+        }
+
+        self::$client = new Client(CACHE_TESTS_MONGO_DSN);
+        self::$client->listDatabases(); // Fail if unable to connect
+    }
+
+    public function createSimpleCache()
+    {
+        if (!isset(self::$client)) {
+            $this->markTestSkipped('The mongodb extension is not available');
+        }
+
+        $collection = self::$client->selectCollection(CACHE_TESTS_MONGO_DATABASE, 'cache');
+
+        return (new MongoDBCache($collection))
+            ->withOption('initialize', false);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/MysqliTest.php b/msd/vendor/desarrolla2/cache/tests/MysqliTest.php
new file mode 100644
index 00000000..9247615f
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/MysqliTest.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\Mysqli as MysqliCache;
+
+/**
+ * MysqliTest
+ */
+class MysqliTest extends AbstractCacheTest
+{
+    /**
+     * @var \mysqli
+     */
+    protected static $mysqli;
+
+    protected $skippedTests = [
+        'testBasicUsageWithLongKey' => 'Only support keys up to 255 bytes'
+    ];
+
+    public static function setUpBeforeClass(): void
+    {
+        if (class_exists('mysqli')) {
+            static::$mysqli = new \mysqli(
+                ini_get('mysqli.default_host') ?: 'localhost',
+                ini_get('mysqli.default_user') ?: 'root'
+            );
+        }
+    }
+
+    public function init(): void
+    {
+        if (!class_exists('mysqli')) {
+            $this->markTestSkipped("mysqli extension not loaded");
+        }
+
+        try {
+            static::$mysqli->query('CREATE DATABASE IF NOT EXISTS `' . CACHE_TESTS_MYSQLI_DATABASE . '`');
+            static::$mysqli->select_db(CACHE_TESTS_MYSQLI_DATABASE);
+
+            static::$mysqli->query("CREATE TABLE IF NOT EXISTS `cache` "
+                ."( `key` VARCHAR(255), `value` BLOB, `ttl` INT UNSIGNED, PRIMARY KEY (`key`) )");
+        } catch (\Exception $e) {
+            $this->markTestSkipped("skipping mysqli test; " . $e->getMessage());
+        }
+
+        if (static::$mysqli->error) {
+            $this->markTestSkipped(static::$mysqli->error);
+        }
+    }
+
+    public function createSimpleCache()
+    {
+        $this->init();
+
+        return (new MysqliCache(static::$mysqli))
+            ->withOption('initialize', false);
+    }
+
+    public static function tearDownAfterClass(): void
+    {
+        static::$mysqli->query('DROP DATABASE IF EXISTS `' . CACHE_TESTS_MYSQLI_DATABASE . '`');
+        static::$mysqli->close();
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/NotCacheTest.php b/msd/vendor/desarrolla2/cache/tests/NotCacheTest.php
new file mode 100644
index 00000000..1b8a3ce3
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/NotCacheTest.php
@@ -0,0 +1,88 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\NotCache as NotCache;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * NotCacheTest
+ */
+class NotCacheTest extends TestCase
+{
+    /**
+     * @var \Desarrolla2\Cache\NotCache
+     */
+    protected $cache;
+
+    public function setUp(): void
+    {
+        $this->cache = new NotCache();
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProvider()
+    {
+        return array(
+            array(),
+        );
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testHas()
+    {
+        $this->cache->set('key', 'value');
+        $this->assertFalse($this->cache->has('key'));
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testGet()
+    {
+        $this->cache->set('key', 'value');
+        $this->assertFalse($this->cache->get('key', false));
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testSet()
+    {
+        $this->assertFalse($this->cache->set('key', 'value'));
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testDelete()
+    {
+        $this->assertTrue($this->cache->delete('key'));
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testWithOption()
+    {
+        $cache = $this->cache->withOption('ttl', 3600);
+        $this->assertSame(3600, $cache->getOption('ttl'));
+
+        $this->assertNotSame($this->cache, $cache);
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/PhpFileTest.php b/msd/vendor/desarrolla2/cache/tests/PhpFileTest.php
new file mode 100644
index 00000000..8adc9a6e
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/PhpFileTest.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\PhpFile as PhpFileCache;
+use org\bovigo\vfs\vfsStream;
+use org\bovigo\vfs\vfsStreamDirectory;
+
+/**
+ * FileTest with PhpPacker
+ */
+class PhpFileTest extends AbstractCacheTest
+{
+    /**
+     * @var vfsStreamDirectory
+     */
+    private $root;
+
+    protected $skippedTests = [
+        'testBasicUsageWithLongKey' => 'Only support keys up to 64 bytes'
+    ];
+
+    public function createSimpleCache()
+    {
+        $this->root = vfsStream::setup('cache');
+
+        return new PhpFileCache(vfsStream::url('cache'));
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/PredisTest.php b/msd/vendor/desarrolla2/cache/tests/PredisTest.php
new file mode 100644
index 00000000..69aa728c
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/PredisTest.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+namespace Desarrolla2\Test\Cache;
+
+use Desarrolla2\Cache\Predis as PredisCache;
+use Predis\Client;
+use Predis\Connection\ConnectionException;
+
+/**
+ * PredisTest
+ */
+class PredisTest extends AbstractCacheTest
+{
+    /**
+     * @var Client
+     */
+    protected $client;
+
+    public function createSimpleCache()
+    {
+        if (!class_exists('Predis\Client')) {
+            $this->markTestSkipped('The predis library is not available');
+        }
+
+        try {
+            $this->client = new Client(CACHE_TESTS_PREDIS_DSN, ['exceptions' => false]);
+            $this->client->connect();
+        } catch (ConnectionException $e) {
+            $this->markTestSkipped($e->getMessage());
+        }
+
+        return new PredisCache($this->client);
+    }
+
+    public function tearDown(): void
+    {
+        parent::tearDown();
+
+        $this->client->disconnect();
+    }
+}
diff --git a/msd/vendor/desarrolla2/cache/tests/performance/Apc.php b/msd/vendor/desarrolla2/cache/tests/performance/Apc.php
new file mode 100644
index 00000000..230eb6f4
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/performance/Apc.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+require_once __DIR__.'/../bootstrap.php';
+
+use Desarrolla2\Cache\Cache;
+use Desarrolla2\Cache\Adapter\Apcu;
+
+$cache = new Cache(new Apcu());
+
+require_once __DIR__.'/common.php';
diff --git a/msd/vendor/desarrolla2/cache/tests/performance/File.php b/msd/vendor/desarrolla2/cache/tests/performance/File.php
new file mode 100644
index 00000000..48dd5872
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/performance/File.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+require_once __DIR__.'/../bootstrap.php';
+
+use Desarrolla2\Cache\Cache;
+use Desarrolla2\Cache\Adapter\File;
+
+$cache = new Cache(new File('/tmp'));
+
+require_once __DIR__.'/common.php';
diff --git a/msd/vendor/desarrolla2/cache/tests/performance/Mongo.php b/msd/vendor/desarrolla2/cache/tests/performance/Mongo.php
new file mode 100644
index 00000000..d5cec313
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/performance/Mongo.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+require_once __DIR__.'/../bootstrap.php';
+
+use Desarrolla2\Cache\Cache;
+use Desarrolla2\Cache\Adapter\Mongo;
+
+$cache = new Cache(new Mongo('mongodb://localhost:27017'));
+
+require_once __DIR__.'/common.php';
diff --git a/msd/vendor/desarrolla2/cache/tests/performance/NoCache.php b/msd/vendor/desarrolla2/cache/tests/performance/NoCache.php
new file mode 100644
index 00000000..451fd309
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/performance/NoCache.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+require_once __DIR__.'/../bootstrap.php';
+
+use Desarrolla2\Cache\Cache;
+use Desarrolla2\Cache\Adapter\NotCache;
+
+$cache = new Cache(new NotCache());
+
+require_once __DIR__.'/common.php';
diff --git a/msd/vendor/desarrolla2/cache/tests/performance/common.php b/msd/vendor/desarrolla2/cache/tests/performance/common.php
new file mode 100644
index 00000000..414f7188
--- /dev/null
+++ b/msd/vendor/desarrolla2/cache/tests/performance/common.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Cache package.
+ *
+ * Copyright (c) Daniel González
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @author Daniel González <daniel@desarrolla2.com>
+ */
+
+
+//build test data outside of timing loop
+$data = [];
+for ($i = 1; $i <= 10000; $i++) {
+    $data[$i] = md5($i);
+}
+
+$timer = new \Desarrolla2\Timer\Timer(new \Desarrolla2\Timer\Formatter\Human());
+for ($i = 1; $i <= 10000; $i++) {
+    $cache->set($data[$i], $data[$i], 3600);
+}
+$timer->mark('10.000 set');
+for ($i = 1; $i <= 10000; $i++) {
+    $cache->has($data[$i]);
+}
+$timer->mark('10.000 has');
+for ($i = 1; $i <= 10000; $i++) {
+    $cache->get($data[$i]);
+}
+$timer->mark('10.000 get');
+for ($i = 1; $i <= 10000; $i++) {
+    $cache->has($data[$i]);
+    $cache->get($data[$i]);
+}
+$timer->mark('10.000 has+get combos');
+
+$benchmarks = $timer->getAll();
+foreach ($benchmarks as $benchmark) {
+    ld($benchmark);
+}
diff --git a/msd/vendor/league/flysystem-sftp/ConnectionProvider.php b/msd/vendor/league/flysystem-sftp/ConnectionProvider.php
new file mode 100644
index 00000000..0b9dd228
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/ConnectionProvider.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use phpseclib\Net\SFTP;
+
+interface ConnectionProvider
+{
+    public function provideConnection(): SFTP;
+}
diff --git a/msd/vendor/league/flysystem-sftp/ConnectivityChecker.php b/msd/vendor/league/flysystem-sftp/ConnectivityChecker.php
new file mode 100644
index 00000000..cb035e3b
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/ConnectivityChecker.php
@@ -0,0 +1,12 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use phpseclib\Net\SFTP;
+
+interface ConnectivityChecker
+{
+    public function isConnected(SFTP $connection): bool;
+}
diff --git a/msd/vendor/league/flysystem-sftp/FixatedConnectivityChecker.php b/msd/vendor/league/flysystem-sftp/FixatedConnectivityChecker.php
new file mode 100644
index 00000000..f2faedaa
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/FixatedConnectivityChecker.php
@@ -0,0 +1,36 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use phpseclib\Net\SFTP;
+
+class FixatedConnectivityChecker implements ConnectivityChecker
+{
+    /**
+     * @var int
+     */
+    private $succeedAfter;
+
+    /**
+     * @var int
+     */
+    private $numberOfTimesChecked = 0;
+
+    public function __construct(int $succeedAfter = 0)
+    {
+        $this->succeedAfter = $succeedAfter;
+    }
+
+    public function isConnected(SFTP $connection): bool
+    {
+        if ($this->numberOfTimesChecked >= $this->succeedAfter) {
+            return true;
+        }
+
+        $this->numberOfTimesChecked++;
+
+        return false;
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/README.md b/msd/vendor/league/flysystem-sftp/README.md
new file mode 100644
index 00000000..8aa043fc
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/README.md
@@ -0,0 +1,7 @@
+## Sub-split of Flysystem for SFTP using phpseclib2.
+
+```bash
+composer require league/flysystem-sftp
+```
+
+View the [documentation](https://flysystem.thephpleague.com/v2/docs/adapter/sftp/).
diff --git a/msd/vendor/league/flysystem-sftp/SftpAdapter.php b/msd/vendor/league/flysystem-sftp/SftpAdapter.php
new file mode 100644
index 00000000..a7b89ec6
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/SftpAdapter.php
@@ -0,0 +1,334 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use League\Flysystem\Config;
+use League\Flysystem\DirectoryAttributes;
+use League\Flysystem\FileAttributes;
+use League\Flysystem\FilesystemAdapter;
+use League\Flysystem\FilesystemException;
+use League\Flysystem\PathPrefixer;
+use League\Flysystem\StorageAttributes;
+use League\Flysystem\UnableToCopyFile;
+use League\Flysystem\UnableToCreateDirectory;
+use League\Flysystem\UnableToMoveFile;
+use League\Flysystem\UnableToReadFile;
+use League\Flysystem\UnableToRetrieveMetadata;
+use League\Flysystem\UnableToSetVisibility;
+use League\Flysystem\UnableToWriteFile;
+use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
+use League\Flysystem\UnixVisibility\VisibilityConverter;
+use League\MimeTypeDetection\FinfoMimeTypeDetector;
+use League\MimeTypeDetection\MimeTypeDetector;
+use phpseclib\Net\SFTP;
+use Throwable;
+
+class SftpAdapter implements FilesystemAdapter
+{
+    /**
+     * @var ConnectionProvider
+     */
+    private $connectionProvider;
+
+    /**
+     * @var VisibilityConverter
+     */
+    private $visibilityConverter;
+
+    /**
+     * @var PathPrefixer
+     */
+    private $prefixer;
+
+    /**
+     * @var MimeTypeDetector
+     */
+    private $mimeTypeDetector;
+
+    public function __construct(
+        ConnectionProvider $connectionProvider,
+        string $root,
+        VisibilityConverter $visibilityConverter = null,
+        MimeTypeDetector $mimeTypeDetector = null
+    ) {
+        $this->connectionProvider = $connectionProvider;
+        $this->prefixer = new PathPrefixer($root);
+        $this->visibilityConverter = $visibilityConverter ?: new PortableVisibilityConverter();
+        $this->mimeTypeDetector = $mimeTypeDetector ?: new FinfoMimeTypeDetector();
+    }
+
+    public function fileExists(string $path): bool
+    {
+        $location = $this->prefixer->prefixPath($path);
+
+        return $this->connectionProvider->provideConnection()->is_file($location);
+    }
+
+    /**
+     * @param string          $path
+     * @param string|resource $contents
+     * @param Config          $config
+     *
+     * @throws FilesystemException
+     */
+    private function upload(string $path, $contents, Config $config): void
+    {
+        $this->ensureParentDirectoryExists($path, $config);
+        $connection = $this->connectionProvider->provideConnection();
+        $location = $this->prefixer->prefixPath($path);
+
+        if ( ! $connection->put($location, $contents, SFTP::SOURCE_STRING)) {
+            throw UnableToWriteFile::atLocation($path, 'not able to write the file');
+        }
+
+        if ($visibility = $config->get(Config::OPTION_VISIBILITY)) {
+            $this->setVisibility($path, $visibility);
+        }
+    }
+
+    private function ensureParentDirectoryExists(string $path, Config $config): void
+    {
+        $parentDirectory = dirname($path);
+
+        if ($parentDirectory === '' || $parentDirectory === '.') {
+            return;
+        }
+
+        /** @var string $visibility */
+        $visibility = $config->get(Config::OPTION_DIRECTORY_VISIBILITY);
+        $this->makeDirectory($parentDirectory, $visibility);
+    }
+
+    private function makeDirectory(string $directory, ?string $visibility): void
+    {
+        $location = $this->prefixer->prefixPath($directory);
+        $connection = $this->connectionProvider->provideConnection();
+
+        if ($connection->is_dir($location)) {
+            return;
+        }
+
+        $mode = $visibility ? $this->visibilityConverter->forDirectory(
+            $visibility
+        ) : $this->visibilityConverter->defaultForDirectories();
+
+        if ( ! $connection->mkdir($location, $mode, true)) {
+            throw UnableToCreateDirectory::atLocation($directory);
+        }
+    }
+
+    public function write(string $path, string $contents, Config $config): void
+    {
+        try {
+            $this->upload($path, $contents, $config);
+        } catch (UnableToWriteFile $exception) {
+            throw $exception;
+        } catch (Throwable $exception) {
+            throw UnableToWriteFile::atLocation($path, '', $exception);
+        }
+    }
+
+    public function writeStream(string $path, $contents, Config $config): void
+    {
+        try {
+            $this->upload($path, $contents, $config);
+        } catch (UnableToWriteFile $exception) {
+            throw $exception;
+        } catch (Throwable $exception) {
+            throw UnableToWriteFile::atLocation($path, '', $exception);
+        }
+    }
+
+    public function read(string $path): string
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $connection = $this->connectionProvider->provideConnection();
+        $contents = $connection->get($location);
+
+        if ( ! is_string($contents)) {
+            throw UnableToReadFile::fromLocation($path);
+        }
+
+        return $contents;
+    }
+
+    public function readStream(string $path)
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $connection = $this->connectionProvider->provideConnection();
+        /** @var resource $readStream */
+        $readStream = fopen('php://temp', 'w+');
+
+        if ( ! $connection->get($location, $readStream)) {
+            fclose($readStream);
+            throw UnableToReadFile::fromLocation($path);
+        }
+
+        rewind($readStream);
+
+        return $readStream;
+    }
+
+    public function delete(string $path): void
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $connection = $this->connectionProvider->provideConnection();
+        $connection->delete($location);
+    }
+
+    public function deleteDirectory(string $path): void
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $connection = $this->connectionProvider->provideConnection();
+        $connection->delete(rtrim($location, '/') . '/');
+    }
+
+    public function createDirectory(string $path, Config $config): void
+    {
+        $this->makeDirectory($path, $config->get(Config::OPTION_DIRECTORY_VISIBILITY));
+    }
+
+    public function setVisibility(string $path, string $visibility): void
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $connection = $this->connectionProvider->provideConnection();
+        $mode = $this->visibilityConverter->forFile($visibility);
+
+        if ( ! $connection->chmod($mode, $location, false)) {
+            throw UnableToSetVisibility::atLocation($path);
+        }
+    }
+
+    private function fetchFileMetadata(string $path, string $type): FileAttributes
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $connection = $this->connectionProvider->provideConnection();
+        $stat = $connection->stat($location);
+
+        if ( ! is_array($stat)) {
+            throw UnableToRetrieveMetadata::create($path, $type);
+        }
+
+        $attributes = $this->convertListingToAttributes($path, $stat);
+
+        if ( ! $attributes instanceof FileAttributes) {
+            throw UnableToRetrieveMetadata::create($path, $type, 'path is not a file');
+        }
+
+        return $attributes;
+    }
+
+    public function mimeType(string $path): FileAttributes
+    {
+        try {
+            $contents = $this->read($path);
+            $mimetype = $this->mimeTypeDetector->detectMimeType($path, $contents);
+        } catch (Throwable $exception) {
+            throw UnableToRetrieveMetadata::mimeType($path, '', $exception);
+        }
+
+        if ($mimetype === null) {
+            throw UnableToRetrieveMetadata::mimeType($path, 'Unknown.');
+        }
+
+        return new FileAttributes($path, null, null, null, $mimetype);
+    }
+
+    public function lastModified(string $path): FileAttributes
+    {
+        return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_LAST_MODIFIED);
+    }
+
+    public function fileSize(string $path): FileAttributes
+    {
+        return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_FILE_SIZE);
+    }
+
+    public function visibility(string $path): FileAttributes
+    {
+        return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_VISIBILITY);
+    }
+
+    public function listContents(string $path, bool $deep): iterable
+    {
+        $connection = $this->connectionProvider->provideConnection();
+        $location = $this->prefixer->prefixPath(rtrim($path, '/')) . '/';
+        $listing = $connection->rawlist($location, false);
+
+        if ($listing === false) {
+            return;
+        }
+
+        foreach ($listing as $filename => $attributes) {
+            if ($filename === '.' || $filename === '..') {
+                continue;
+            }
+
+            // Ensure numeric keys are strings.
+            $filename = (string) $filename;
+            $path = $this->prefixer->stripPrefix($location . ltrim($filename, '/'));
+            $attributes = $this->convertListingToAttributes($path, $attributes);
+            yield $attributes;
+
+            if ($deep && $attributes->isDir()) {
+                foreach ($this->listContents($attributes->path(), true) as $child) {
+                    yield $child;
+                }
+            }
+        }
+    }
+
+    private function convertListingToAttributes(string $path, array $attributes): StorageAttributes
+    {
+        $permissions = $attributes['permissions'] & 0777;
+        $lastModified = $attributes['mtime'] ?? null;
+
+        if ($attributes['type'] === NET_SFTP_TYPE_DIRECTORY) {
+            return new DirectoryAttributes(
+                ltrim($path, '/'),
+                $this->visibilityConverter->inverseForDirectory($permissions),
+                $lastModified
+            );
+        }
+
+        return new FileAttributes(
+            $path,
+            $attributes['size'],
+            $this->visibilityConverter->inverseForFile($permissions),
+            $lastModified
+        );
+    }
+
+    public function move(string $source, string $destination, Config $config): void
+    {
+        $sourceLocation = $this->prefixer->prefixPath($source);
+        $destinationLocation = $this->prefixer->prefixPath($destination);
+        $connection = $this->connectionProvider->provideConnection();
+
+        try {
+            $this->ensureParentDirectoryExists($destination, $config);
+        } catch (Throwable $exception) {
+            throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
+        }
+
+        if ( ! $connection->rename($sourceLocation, $destinationLocation)) {
+            throw UnableToMoveFile::fromLocationTo($source, $destination);
+        }
+    }
+
+    public function copy(string $source, string $destination, Config $config): void
+    {
+        try {
+            $readStream = $this->readStream($source);
+            $visibility = $this->visibility($source)->visibility();
+            $this->writeStream($destination, $readStream, new Config(compact('visibility')));
+        } catch (Throwable $exception) {
+            if (isset($readStream) && is_resource($readStream)) {
+                @fclose($readStream);
+            }
+            throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
+        }
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/SftpConnectionProvider.php b/msd/vendor/league/flysystem-sftp/SftpConnectionProvider.php
new file mode 100644
index 00000000..c04a12ed
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/SftpConnectionProvider.php
@@ -0,0 +1,236 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use phpseclib\Crypt\RSA;
+use phpseclib\Net\SFTP;
+use phpseclib\System\SSH\Agent;
+use Throwable;
+
+class SftpConnectionProvider implements ConnectionProvider
+{
+    /**
+     * @var string
+     */
+    private $host;
+
+    /**
+     * @var string
+     */
+    private $username;
+
+    /**
+     * @var string|null
+     */
+    private $password;
+
+    /**
+     * @var bool
+     */
+    private $useAgent;
+
+    /**
+     * @var int
+     */
+    private $port;
+
+    /**
+     * @var int
+     */
+    private $timeout;
+
+    /**
+     * @var SFTP|null
+     */
+    private $connection;
+
+    /**
+     * @var ConnectivityChecker
+     */
+    private $connectivityChecker;
+
+    /**
+     * @var string|null
+     */
+    private $hostFingerprint;
+
+    /**
+     * @var string|null
+     */
+    private $privateKey;
+
+    /**
+     * @var string|null
+     */
+    private $passphrase;
+
+    /**
+     * @var int
+     */
+    private $maxTries;
+
+    public function __construct(
+        string $host,
+        string $username,
+        string $password = null,
+        string $privateKey = null,
+        string $passphrase = null,
+        int $port = 22,
+        bool $useAgent = false,
+        int $timeout = 10,
+        int $maxTries = 4,
+        string $hostFingerprint = null,
+        ConnectivityChecker $connectivityChecker = null
+    ) {
+        $this->host = $host;
+        $this->username = $username;
+        $this->password = $password;
+        $this->privateKey = $privateKey;
+        $this->passphrase = $passphrase;
+        $this->useAgent = $useAgent;
+        $this->port = $port;
+        $this->timeout = $timeout;
+        $this->hostFingerprint = $hostFingerprint;
+        $this->connectivityChecker = $connectivityChecker ?: new SimpleConnectivityChecker();
+        $this->maxTries = $maxTries;
+    }
+
+    public function provideConnection(): SFTP
+    {
+        $tries = 0;
+        start:
+
+        $connection = $this->connection instanceof SFTP
+            ? $this->connection
+            : $this->setupConnection();
+
+        if ( ! $this->connectivityChecker->isConnected($connection)) {
+            $connection->disconnect();
+            $this->connection = null;
+
+            if ($tries < $this->maxTries) {
+                $tries++;
+                goto start;
+            }
+
+            throw UnableToConnectToSftpHost::atHostname($this->host);
+        }
+
+        return $this->connection = $connection;
+    }
+
+    private function setupConnection(): SFTP
+    {
+        $connection = new SFTP($this->host, $this->port, $this->timeout);
+        $connection->disableStatCache();
+
+        try {
+            $this->checkFingerprint($connection);
+            $this->authenticate($connection);
+        } catch (Throwable $exception) {
+            $connection->disconnect();
+            throw $exception;
+        }
+
+        return $connection;
+    }
+
+    private function checkFingerprint(SFTP $connection): void
+    {
+        if ( ! $this->hostFingerprint) {
+            return;
+        }
+
+        $publicKey = $connection->getServerPublicHostKey();
+
+        if ($publicKey === false) {
+            throw UnableToEstablishAuthenticityOfHost::becauseTheAuthenticityCantBeEstablished($this->host);
+        }
+
+        $fingerprint = $this->getFingerprintFromPublicKey($publicKey);
+
+        if (0 !== strcasecmp($this->hostFingerprint, $fingerprint)) {
+            throw UnableToEstablishAuthenticityOfHost::becauseTheAuthenticityCantBeEstablished($this->host);
+        }
+    }
+
+    private function getFingerprintFromPublicKey(string $publicKey): string
+    {
+        $content = explode(' ', $publicKey, 3);
+
+        return implode(':', str_split(md5(base64_decode($content[1])), 2));
+    }
+
+    private function authenticate(SFTP $connection): void
+    {
+        if ($this->privateKey !== null) {
+            $this->authenticateWithPrivateKey($connection);
+        } elseif ($this->useAgent) {
+            $this->authenticateWithAgent($connection);
+        } elseif ( ! $connection->login($this->username, $this->password)) {
+            throw UnableToAuthenticate::withPassword();
+        }
+    }
+
+    public static function fromArray(array $options): SftpConnectionProvider
+    {
+        return new SftpConnectionProvider(
+            $options['host'],
+            $options['username'],
+            $options['password'] ?? null,
+            $options['privateKey'] ?? null,
+            $options['passphrase'] ?? null,
+            $options['port'] ?? 22,
+            $options['useAgent'] ?? false,
+            $options['timeout'] ?? 10,
+            $options['maxTries'] ?? 4,
+            $options['hostFingerprint'] ?? null,
+            $options['connectivityChecker'] ?? null
+        );
+    }
+
+    private function authenticateWithPrivateKey(SFTP $connection): void
+    {
+        $privateKey = $this->loadPrivateKey();
+
+        if ($connection->login($this->username, $privateKey)) {
+            return;
+        }
+
+        if ($this->password !== null && $connection->login($this->username, $this->password)) {
+            return;
+        }
+
+        throw UnableToAuthenticate::withPrivateKey();
+    }
+
+    private function loadPrivateKey(): RSA
+    {
+        if ("---" !== substr($this->privateKey, 0, 3) && is_file($this->privateKey)) {
+            $this->privateKey = file_get_contents($this->privateKey);
+        }
+
+        $key = new RSA();
+
+        if ($this->passphrase !== null) {
+            $key->setPassword($this->passphrase);
+        }
+
+        if ( ! $key->loadKey($this->privateKey)) {
+            throw new UnableToLoadPrivateKey();
+        }
+
+        return $key;
+    }
+
+    private function authenticateWithAgent(SFTP $connection): void
+    {
+        $agent = new Agent();
+
+        if ( ! $connection->login($this->username, $agent)) {
+            throw UnableToAuthenticate::withSshAgent();
+        }
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/SimpleConnectivityChecker.php b/msd/vendor/league/flysystem-sftp/SimpleConnectivityChecker.php
new file mode 100644
index 00000000..913a3936
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/SimpleConnectivityChecker.php
@@ -0,0 +1,15 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use phpseclib\Net\SFTP;
+
+class SimpleConnectivityChecker implements ConnectivityChecker
+{
+    public function isConnected(SFTP $connection): bool
+    {
+        return $connection->isConnected();
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/StubSftpConnectionProvider.php b/msd/vendor/league/flysystem-sftp/StubSftpConnectionProvider.php
new file mode 100644
index 00000000..22498ca6
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/StubSftpConnectionProvider.php
@@ -0,0 +1,59 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use phpseclib\Net\SFTP;
+
+class StubSftpConnectionProvider implements ConnectionProvider
+{
+    /**
+     * @var string
+     */
+    private $host;
+
+    /**
+     * @var string
+     */
+    private $username;
+
+    /**
+     * @var string|null
+     */
+    private $password;
+
+    /**
+     * @var int
+     */
+    private $port;
+
+    /**
+     * @var SftpStub
+     */
+    private $connection;
+
+    public function __construct(
+        string $host,
+        string $username,
+        string $password = null,
+        int $port = 22
+    ) {
+        $this->host = $host;
+        $this->username = $username;
+        $this->password = $password;
+        $this->port = $port;
+    }
+
+    public function provideConnection(): SFTP
+    {
+        if ( ! $this->connection instanceof SFTP) {
+            $connection = new SftpStub($this->host, $this->port);
+            $connection->login($this->username, $this->password);
+
+            $this->connection = $connection;
+        }
+
+        return $this->connection;
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/UnableToAuthenticate.php b/msd/vendor/league/flysystem-sftp/UnableToAuthenticate.php
new file mode 100644
index 00000000..599406e8
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/UnableToAuthenticate.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use League\Flysystem\FilesystemException;
+use RuntimeException;
+
+class UnableToAuthenticate extends RuntimeException implements FilesystemException
+{
+    public static function withPassword(): UnableToAuthenticate
+    {
+        return new UnableToAuthenticate('Unable to authenticate using a password.');
+    }
+
+    public static function withPrivateKey(): UnableToAuthenticate
+    {
+        return new UnableToAuthenticate('Unable to authenticate using a private key.');
+    }
+
+    public static function withSshAgent(): UnableToAuthenticate
+    {
+        return new UnableToAuthenticate('Unable to authenticate using an SSH agent.');
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/UnableToConnectToSftpHost.php b/msd/vendor/league/flysystem-sftp/UnableToConnectToSftpHost.php
new file mode 100644
index 00000000..ae74c69d
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/UnableToConnectToSftpHost.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use League\Flysystem\FilesystemException;
+use RuntimeException;
+
+class UnableToConnectToSftpHost extends RuntimeException implements FilesystemException
+{
+    public static function atHostname(string $host): UnableToConnectToSftpHost
+    {
+        return new UnableToConnectToSftpHost("Unable to connect to host: $host");
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/UnableToEstablishAuthenticityOfHost.php b/msd/vendor/league/flysystem-sftp/UnableToEstablishAuthenticityOfHost.php
new file mode 100644
index 00000000..75731690
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/UnableToEstablishAuthenticityOfHost.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use League\Flysystem\FilesystemException;
+use RuntimeException;
+
+class UnableToEstablishAuthenticityOfHost extends RuntimeException implements FilesystemException
+{
+    public static function becauseTheAuthenticityCantBeEstablished(string $host): UnableToEstablishAuthenticityOfHost
+    {
+        return new UnableToEstablishAuthenticityOfHost("The authenticity of host $host can't be established.");
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/UnableToLoadPrivateKey.php b/msd/vendor/league/flysystem-sftp/UnableToLoadPrivateKey.php
new file mode 100644
index 00000000..e0664214
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/UnableToLoadPrivateKey.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\PhpseclibV2;
+
+use League\Flysystem\FilesystemException;
+use RuntimeException;
+
+class UnableToLoadPrivateKey extends RuntimeException implements FilesystemException
+{
+    public function __construct(string $message = "Unable to load private key.")
+    {
+        parent::__construct($message);
+    }
+}
diff --git a/msd/vendor/league/flysystem-sftp/composer.json b/msd/vendor/league/flysystem-sftp/composer.json
new file mode 100644
index 00000000..dad201c0
--- /dev/null
+++ b/msd/vendor/league/flysystem-sftp/composer.json
@@ -0,0 +1,23 @@
+{
+    "name": "league/flysystem-sftp",
+    "description": "SFTP filesystem adapter for Flysystem.",
+    "keywords": ["flysystem", "filesystem", "sftp", "files", "file"],
+    "autoload": {
+        "psr-4": {
+                "League\\Flysystem\\PhpseclibV2\\": ""
+        }
+    },
+    "require": {
+        "php": "^7.2 || ^8.0",
+        "league/flysystem": "^2.0.0",
+        "league/mime-type-detection": "^1.0.0",
+        "phpseclib/phpseclib": "^2.0"
+    },
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Frank de Jonge",
+            "email": "info@frankdejonge.nl"
+        }
+    ]
+}
diff --git a/msd/vendor/league/flysystem/INFO.md b/msd/vendor/league/flysystem/INFO.md
new file mode 100644
index 00000000..8a44d14e
--- /dev/null
+++ b/msd/vendor/league/flysystem/INFO.md
@@ -0,0 +1,2 @@
+View the docs at: https://flysystem.thephpleague.com/v2/  
+Changelog at: https://github.com/thephpleague/flysystem/blob/2.x/CHANGELOG.md
diff --git a/msd/vendor/league/flysystem/LICENSE b/msd/vendor/league/flysystem/LICENSE
new file mode 100644
index 00000000..1f016521
--- /dev/null
+++ b/msd/vendor/league/flysystem/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013-2022 Frank de Jonge
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/msd/vendor/league/flysystem/composer.json b/msd/vendor/league/flysystem/composer.json
new file mode 100644
index 00000000..9c244f8c
--- /dev/null
+++ b/msd/vendor/league/flysystem/composer.json
@@ -0,0 +1,48 @@
+{
+    "name": "league/flysystem",
+    "description": "File storage abstraction for PHP",
+    "keywords": [
+        "filesystem", "filesystems", "files", "storage", "aws",
+        "s3", "ftp", "sftp", "webdav", "file", "cloud"
+    ],
+    "scripts": {
+        "phpstan": "vendor/bin/phpstan analyse -l 6 src"
+    },
+    "type": "library",
+    "minimum-stability": "dev",
+    "prefer-stable": true,
+    "autoload": {
+        "psr-4": {
+            "League\\Flysystem\\": "src"
+        }
+    },
+    "require": {
+        "php": "^7.2 || ^8.0",
+        "ext-json": "*",
+        "league/mime-type-detection": "^1.0.0"
+    },
+    "require-dev": {
+        "ext-fileinfo": "*",
+        "ext-ftp": "*",
+        "phpunit/phpunit": "^8.5 || ^9.4",
+        "phpstan/phpstan": "^0.12.26",
+        "phpseclib/phpseclib": "^2.0",
+        "aws/aws-sdk-php": "^3.132.4",
+        "composer/semver": "^3.0",
+        "friendsofphp/php-cs-fixer": "^3.2",
+        "google/cloud-storage": "^1.23",
+        "async-aws/s3": "^1.5",
+        "async-aws/simple-s3": "^1.0",
+        "sabre/dav": "^4.1"
+    },
+    "conflict": {
+        "guzzlehttp/ringphp": "<1.1.1"
+    },
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Frank de Jonge",
+            "email": "info@frankdejonge.nl"
+        }
+    ]
+}
diff --git a/msd/vendor/league/flysystem/config.subsplit-publish.json b/msd/vendor/league/flysystem/config.subsplit-publish.json
new file mode 100644
index 00000000..b0de91ee
--- /dev/null
+++ b/msd/vendor/league/flysystem/config.subsplit-publish.json
@@ -0,0 +1,49 @@
+{
+    "sub-splits": [
+        {
+            "name": "ftp",
+            "directory": "src/Ftp",
+            "target": "git@github.com:thephpleague/flysystem-ftp.git"
+        },
+        {
+            "name": "sftp",
+            "directory": "src/PhpseclibV2",
+            "target": "git@github.com:thephpleague/flysystem-sftp.git"
+        },
+        {
+            "name": "sftp-v3",
+            "directory": "src/PhpseclibV3",
+            "target": "git@github.com:thephpleague/flysystem-sftp-v3.git"
+        },
+        {
+            "name": "memory",
+            "directory": "src/InMemory",
+            "target": "git@github.com:thephpleague/flysystem-memory.git"
+        },
+        {
+            "name": "ziparchive",
+            "directory": "src/ZipArchive",
+            "target": "git@github.com:thephpleague/flysystem-ziparchive.git"
+        },
+        {
+            "name": "aws-s3-v3",
+            "directory": "src/AwsS3V3",
+            "target": "git@github.com:thephpleague/flysystem-aws-s3-v3.git"
+        },
+        {
+            "name": "async-aws-s3",
+            "directory": "src/AsyncAwsS3",
+            "target": "git@github.com:thephpleague/flysystem-async-aws-s3.git"
+        },
+        {
+            "name": "google-cloud-storage",
+            "directory": "src/GoogleCloudStorage",
+            "target": "git@github.com:thephpleague/flysystem-google-cloud-storage.git"
+        },
+        {
+            "name": "adapter-test-utilities",
+            "directory": "src/AdapterTestUtilities",
+            "target": "git@github.com:thephpleague/flysystem-adapter-test-utilities.git"
+        }
+    ]
+}
diff --git a/msd/vendor/league/flysystem/docker-compose.yml b/msd/vendor/league/flysystem/docker-compose.yml
new file mode 100644
index 00000000..3ab6b772
--- /dev/null
+++ b/msd/vendor/league/flysystem/docker-compose.yml
@@ -0,0 +1,58 @@
+---
+version: "3"
+services:
+  webdav:
+    image: bytemark/webdav
+    restart: always
+    ports:
+      - "80:80"
+    environment:
+      AUTH_TYPE: Digest
+      USERNAME: alice
+      PASSWORD: secret1234
+  sftp:
+    container_name: sftp
+    restart: always
+    image: atmoz/sftp
+    volumes:
+      - ./test_files/sftp/users.conf:/etc/sftp/users.conf
+      - ./test_files/sftp/ssh_host_ed25519_key:/etc/ssh/ssh_host_ed25519_key
+      - ./test_files/sftp/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key
+      - ./test_files/sftp/id_rsa.pub:/home/bar/.ssh/keys/id_rsa.pub
+    ports:
+      - "2222:22"
+  ftp:
+    container_name: ftp
+    restart: always
+    image: delfer/alpine-ftp-server
+    environment:
+      USERS: 'foo|pass|/home/foo/upload'
+      ADDRESS: 'localhost'
+    ports:
+      - "2121:21"
+      - "21000-21010:21000-21010"
+  ftpd:
+    container_name: ftpd
+    restart: always
+    environment:
+      PUBLICHOST: localhost
+      FTP_USER_NAME: foo
+      FTP_USER_PASS: pass
+      FTP_USER_HOME: /home/foo
+    image: stilliard/pure-ftpd
+    ports:
+      - "2122:21"
+      - "30000-30009:30000-30009"
+    command: "/run.sh -l puredb:/etc/pure-ftpd/pureftpd.pdb -E -j -P localhost"
+  toxiproxy:
+    container_name: toxiproxy
+    restart: unless-stopped
+    image: ghcr.io/shopify/toxiproxy
+    command: "-host 0.0.0.0 -config /opt/toxiproxy/config.json"
+    volumes:
+      - ./test_files/toxiproxy/toxiproxy.json:/opt/toxiproxy/config.json:ro
+    ports:
+      - "8474:8474" # HTTP API
+      - "8222:8222" # SFTP
+      - "8121:8121" # FTP
+      - "8122:8122" # FTPD
diff --git a/msd/vendor/league/flysystem/readme.md b/msd/vendor/league/flysystem/readme.md
new file mode 100644
index 00000000..0c0b98ea
--- /dev/null
+++ b/msd/vendor/league/flysystem/readme.md
@@ -0,0 +1,45 @@
+# League\Flysystem
+
+[![Author](https://img.shields.io/badge/author-@frankdejonge-blue.svg)](https://twitter.com/frankdejonge)
+[![Source Code](https://img.shields.io/badge/source-thephpleague/flysystem-blue.svg)](https://github.com/thephpleague/flysystem)
+[![Latest Version](https://img.shields.io/github/tag/thephpleague/flysystem.svg)](https://github.com/thephpleague/flysystem/releases)
+[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/thephpleague/flysystem/blob/master/LICENSE)
+[![Quality Assurance](https://github.com/thephpleague/flysystem/workflows/Quality%20Assurance/badge.svg?branch=2.x)](https://github.com/thephpleague/flysystem/actions?query=workflow%3A%22Quality+Assurance%22)
+[![Total Downloads](https://img.shields.io/packagist/dt/league/flysystem.svg)](https://packagist.org/packages/league/flysystem)
+![php 7.2+](https://img.shields.io/badge/php-min%207.2-red.svg)
+
+## About Flysystem
+
+Flysystem is a file storage library for PHP. It provides one interface to
+interact with many types of filesystems. When you use Flysystem, you're
+not only protected from vendor lock-in, you'll also have a consistent experience
+for which ever storage is right for you. 
+
+## Getting Started
+
+* **[New in V2](https://flysystem.thephpleague.com/v2/docs/what-is-new/)**: What it new in Flysystem V2?
+* **[Architecture](https://flysystem.thephpleague.com/v2/docs/architecture/)**: Flysystem's internal architecture
+* **[Flysystem API](https://flysystem.thephpleague.com/v2/docs/usage/filesystem-api/)**: How to interact with your Flysystem instance
+* **[Upgrade to V2](https://flysystem.thephpleague.com/v2/docs/advanced/upgrade-to-2.0.0/)**: How to upgrade your Flysystem V1 instance to V2
+
+### Commonly-Used Adapters
+
+* **[AsyncAws S3](https://flysystem.thephpleague.com/v2/docs/adapter/async-aws-s3/)**
+* **[AWS S3](https://flysystem.thephpleague.com/v2/docs/adapter/aws-s3-v3/)**
+* **[Local](https://flysystem.thephpleague.com/v2/docs/adapter/local/)**
+* **[Memory](https://flysystem.thephpleague.com/v2/docs/adapter/in-memory/)**
+
+### Third party Adapters
+
+* **[Gitlab](https://github.com/RoyVoetman/flysystem-gitlab-storage)**
+* **[Google Drive (using regular paths)](https://github.com/masbug/flysystem-google-drive-ext)**
+
+You can always [create an adapter](https://flysystem.thephpleague.com/v2/docs/advanced/creating-an-adapter/) yourself.
+
+## Security
+
+If you discover any security related issues, please email info@frankdejonge.nl instead of using the issue tracker.
+
+## Enjoy
+
+Oh, and if you've come down this far, you might as well follow me on [twitter](https://twitter.com/frankdejonge).
diff --git a/msd/vendor/league/flysystem/src/Config.php b/msd/vendor/league/flysystem/src/Config.php
new file mode 100644
index 00000000..77c3b5a1
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/Config.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use function array_merge;
+
+class Config
+{
+    public const OPTION_VISIBILITY = 'visibility';
+    public const OPTION_DIRECTORY_VISIBILITY = 'directory_visibility';
+
+    /**
+     * @var array
+     */
+    private $options;
+
+    public function __construct(array $options = [])
+    {
+        $this->options = $options;
+    }
+
+    /**
+     * @param mixed $default
+     *
+     * @return mixed
+     */
+    public function get(string $property, $default = null)
+    {
+        return $this->options[$property] ?? $default;
+    }
+
+    public function extend(array $options): Config
+    {
+        return new Config(array_merge($this->options, $options));
+    }
+
+    public function withDefaults(array $defaults): Config
+    {
+        return new Config($this->options + $defaults);
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/CorruptedPathDetected.php b/msd/vendor/league/flysystem/src/CorruptedPathDetected.php
new file mode 100644
index 00000000..70631ccc
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/CorruptedPathDetected.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+final class CorruptedPathDetected extends RuntimeException implements FilesystemException
+{
+    public static function forPath(string $path): CorruptedPathDetected
+    {
+        return new CorruptedPathDetected("Corrupted path detected: " . $path);
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/DirectoryAttributes.php b/msd/vendor/league/flysystem/src/DirectoryAttributes.php
new file mode 100644
index 00000000..94e62189
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/DirectoryAttributes.php
@@ -0,0 +1,110 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+class DirectoryAttributes implements StorageAttributes
+{
+    use ProxyArrayAccessToProperties;
+
+    /**
+     * @var string
+     */
+    private $type = StorageAttributes::TYPE_DIRECTORY;
+
+    /**
+     * @var string
+     */
+    private $path;
+
+    /**
+     * @var string|null
+     */
+    private $visibility;
+
+    /**
+     * @var int|null
+     */
+    private $lastModified;
+
+    /**
+     * @var array
+     */
+    private $extraMetadata;
+
+    public function __construct(string $path, ?string $visibility = null, ?int $lastModified = null, array $extraMetadata = [])
+    {
+        $this->path = $path;
+        $this->visibility = $visibility;
+        $this->lastModified = $lastModified;
+        $this->extraMetadata = $extraMetadata;
+    }
+
+    public function path(): string
+    {
+        return $this->path;
+    }
+
+    public function type(): string
+    {
+        return StorageAttributes::TYPE_DIRECTORY;
+    }
+
+    public function visibility(): ?string
+    {
+        return $this->visibility;
+    }
+
+    public function lastModified(): ?int
+    {
+        return $this->lastModified;
+    }
+
+    public function extraMetadata(): array
+    {
+        return $this->extraMetadata;
+    }
+
+    public function isFile(): bool
+    {
+        return false;
+    }
+
+    public function isDir(): bool
+    {
+        return true;
+    }
+
+    public function withPath(string $path): StorageAttributes
+    {
+        $clone = clone $this;
+        $clone->path = $path;
+
+        return $clone;
+    }
+
+    public static function fromArray(array $attributes): StorageAttributes
+    {
+        return new DirectoryAttributes(
+            $attributes[StorageAttributes::ATTRIBUTE_PATH],
+            $attributes[StorageAttributes::ATTRIBUTE_VISIBILITY] ?? null,
+            $attributes[StorageAttributes::ATTRIBUTE_LAST_MODIFIED] ?? null,
+            $attributes[StorageAttributes::ATTRIBUTE_EXTRA_METADATA] ?? []
+        );
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function jsonSerialize(): array
+    {
+        return [
+            StorageAttributes::ATTRIBUTE_TYPE => $this->type,
+            StorageAttributes::ATTRIBUTE_PATH => $this->path,
+            StorageAttributes::ATTRIBUTE_VISIBILITY => $this->visibility,
+            StorageAttributes::ATTRIBUTE_LAST_MODIFIED => $this->lastModified,
+            StorageAttributes::ATTRIBUTE_EXTRA_METADATA => $this->extraMetadata,
+        ];
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/DirectoryListing.php b/msd/vendor/league/flysystem/src/DirectoryListing.php
new file mode 100644
index 00000000..0f429a87
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/DirectoryListing.php
@@ -0,0 +1,84 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use ArrayIterator;
+use Generator;
+use IteratorAggregate;
+use Traversable;
+
+/**
+ * @template T
+ */
+class DirectoryListing implements IteratorAggregate
+{
+    /**
+     * @var iterable<T>
+     */
+    private $listing;
+
+    /**
+     * @param iterable<T> $listing
+     */
+    public function __construct(iterable $listing)
+    {
+        $this->listing = $listing;
+    }
+
+    public function filter(callable $filter): DirectoryListing
+    {
+        $generator = (static function (iterable $listing) use ($filter): Generator {
+            foreach ($listing as $item) {
+                if ($filter($item)) {
+                    yield $item;
+                }
+            }
+        })($this->listing);
+
+        return new DirectoryListing($generator);
+    }
+
+    public function map(callable $mapper): DirectoryListing
+    {
+        $generator = (static function (iterable $listing) use ($mapper): Generator {
+            foreach ($listing as $item) {
+                yield $mapper($item);
+            }
+        })($this->listing);
+
+        return new DirectoryListing($generator);
+    }
+
+    public function sortByPath(): DirectoryListing
+    {
+        $listing = $this->toArray();
+
+        usort($listing, function (StorageAttributes $a, StorageAttributes $b) {
+            return $a->path() <=> $b->path();
+        });
+
+        return new DirectoryListing($listing);
+    }
+
+    /**
+     * @return Traversable<T>
+     */
+    public function getIterator(): Traversable
+    {
+        return $this->listing instanceof Traversable
+            ? $this->listing
+            : new ArrayIterator($this->listing);
+    }
+
+    /**
+     * @return T[]
+     */
+    public function toArray(): array
+    {
+        return $this->listing instanceof Traversable
+            ? iterator_to_array($this->listing, false)
+            : (array) $this->listing;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/FileAttributes.php b/msd/vendor/league/flysystem/src/FileAttributes.php
new file mode 100644
index 00000000..2efd9c4d
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FileAttributes.php
@@ -0,0 +1,139 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+class FileAttributes implements StorageAttributes
+{
+    use ProxyArrayAccessToProperties;
+
+    /**
+     * @var string
+     */
+    private $type = StorageAttributes::TYPE_FILE;
+
+    /**
+     * @var string
+     */
+    private $path;
+
+    /**
+     * @var int|null
+     */
+    private $fileSize;
+
+    /**
+     * @var string|null
+     */
+    private $visibility;
+
+    /**
+     * @var int|null
+     */
+    private $lastModified;
+
+    /**
+     * @var string|null
+     */
+    private $mimeType;
+
+    /**
+     * @var array
+     */
+    private $extraMetadata;
+
+    public function __construct(
+        string $path,
+        ?int $fileSize = null,
+        ?string $visibility = null,
+        ?int $lastModified = null,
+        ?string $mimeType = null,
+        array $extraMetadata = []
+    ) {
+        $this->path = $path;
+        $this->fileSize = $fileSize;
+        $this->visibility = $visibility;
+        $this->lastModified = $lastModified;
+        $this->mimeType = $mimeType;
+        $this->extraMetadata = $extraMetadata;
+    }
+
+    public function type(): string
+    {
+        return $this->type;
+    }
+
+    public function path(): string
+    {
+        return $this->path;
+    }
+
+    public function fileSize(): ?int
+    {
+        return $this->fileSize;
+    }
+
+    public function visibility(): ?string
+    {
+        return $this->visibility;
+    }
+
+    public function lastModified(): ?int
+    {
+        return $this->lastModified;
+    }
+
+    public function mimeType(): ?string
+    {
+        return $this->mimeType;
+    }
+
+    public function extraMetadata(): array
+    {
+        return $this->extraMetadata;
+    }
+
+    public function isFile(): bool
+    {
+        return true;
+    }
+
+    public function isDir(): bool
+    {
+        return false;
+    }
+
+    public function withPath(string $path): StorageAttributes
+    {
+        $clone = clone $this;
+        $clone->path = $path;
+
+        return $clone;
+    }
+
+    public static function fromArray(array $attributes): StorageAttributes
+    {
+        return new FileAttributes(
+            $attributes[StorageAttributes::ATTRIBUTE_PATH],
+            $attributes[StorageAttributes::ATTRIBUTE_FILE_SIZE] ?? null,
+            $attributes[StorageAttributes::ATTRIBUTE_VISIBILITY] ?? null,
+            $attributes[StorageAttributes::ATTRIBUTE_LAST_MODIFIED] ?? null,
+            $attributes[StorageAttributes::ATTRIBUTE_MIME_TYPE] ?? null,
+            $attributes[StorageAttributes::ATTRIBUTE_EXTRA_METADATA] ?? []
+        );
+    }
+
+    public function jsonSerialize(): array
+    {
+        return [
+            StorageAttributes::ATTRIBUTE_TYPE => self::TYPE_FILE,
+            StorageAttributes::ATTRIBUTE_PATH => $this->path,
+            StorageAttributes::ATTRIBUTE_FILE_SIZE => $this->fileSize,
+            StorageAttributes::ATTRIBUTE_VISIBILITY => $this->visibility,
+            StorageAttributes::ATTRIBUTE_LAST_MODIFIED => $this->lastModified,
+            StorageAttributes::ATTRIBUTE_MIME_TYPE => $this->mimeType,
+            StorageAttributes::ATTRIBUTE_EXTRA_METADATA => $this->extraMetadata,
+        ];
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/Filesystem.php b/msd/vendor/league/flysystem/src/Filesystem.php
new file mode 100644
index 00000000..f66574d6
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/Filesystem.php
@@ -0,0 +1,163 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+class Filesystem implements FilesystemOperator
+{
+    /**
+     * @var FilesystemAdapter
+     */
+    private $adapter;
+
+    /**
+     * @var Config
+     */
+    private $config;
+
+    /**
+     * @var PathNormalizer
+     */
+    private $pathNormalizer;
+
+    public function __construct(
+        FilesystemAdapter $adapter,
+        array $config = [],
+        PathNormalizer $pathNormalizer = null
+    ) {
+        $this->adapter = $adapter;
+        $this->config = new Config($config);
+        $this->pathNormalizer = $pathNormalizer ?: new WhitespacePathNormalizer();
+    }
+
+    public function fileExists(string $location): bool
+    {
+        return $this->adapter->fileExists($this->pathNormalizer->normalizePath($location));
+    }
+
+    public function write(string $location, string $contents, array $config = []): void
+    {
+        $this->adapter->write(
+            $this->pathNormalizer->normalizePath($location),
+            $contents,
+            $this->config->extend($config)
+        );
+    }
+
+    public function writeStream(string $location, $contents, array $config = []): void
+    {
+        /* @var resource $contents */
+        $this->assertIsResource($contents);
+        $this->rewindStream($contents);
+        $this->adapter->writeStream(
+            $this->pathNormalizer->normalizePath($location),
+            $contents,
+            $this->config->extend($config)
+        );
+    }
+
+    public function read(string $location): string
+    {
+        return $this->adapter->read($this->pathNormalizer->normalizePath($location));
+    }
+
+    public function readStream(string $location)
+    {
+        return $this->adapter->readStream($this->pathNormalizer->normalizePath($location));
+    }
+
+    public function delete(string $location): void
+    {
+        $this->adapter->delete($this->pathNormalizer->normalizePath($location));
+    }
+
+    public function deleteDirectory(string $location): void
+    {
+        $this->adapter->deleteDirectory($this->pathNormalizer->normalizePath($location));
+    }
+
+    public function createDirectory(string $location, array $config = []): void
+    {
+        $this->adapter->createDirectory(
+            $this->pathNormalizer->normalizePath($location),
+            $this->config->extend($config)
+        );
+    }
+
+    public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing
+    {
+        $path = $this->pathNormalizer->normalizePath($location);
+
+        return new DirectoryListing($this->adapter->listContents($path, $deep));
+    }
+
+    public function move(string $source, string $destination, array $config = []): void
+    {
+        $this->adapter->move(
+            $this->pathNormalizer->normalizePath($source),
+            $this->pathNormalizer->normalizePath($destination),
+            $this->config->extend($config)
+        );
+    }
+
+    public function copy(string $source, string $destination, array $config = []): void
+    {
+        $this->adapter->copy(
+            $this->pathNormalizer->normalizePath($source),
+            $this->pathNormalizer->normalizePath($destination),
+            $this->config->extend($config)
+        );
+    }
+
+    public function lastModified(string $path): int
+    {
+        return $this->adapter->lastModified($this->pathNormalizer->normalizePath($path))->lastModified();
+    }
+
+    public function fileSize(string $path): int
+    {
+        return $this->adapter->fileSize($this->pathNormalizer->normalizePath($path))->fileSize();
+    }
+
+    public function mimeType(string $path): string
+    {
+        return $this->adapter->mimeType($this->pathNormalizer->normalizePath($path))->mimeType();
+    }
+
+    public function setVisibility(string $path, string $visibility): void
+    {
+        $this->adapter->setVisibility($this->pathNormalizer->normalizePath($path), $visibility);
+    }
+
+    public function visibility(string $path): string
+    {
+        return $this->adapter->visibility($this->pathNormalizer->normalizePath($path))->visibility();
+    }
+
+    /**
+     * @param mixed $contents
+     */
+    private function assertIsResource($contents): void
+    {
+        if (is_resource($contents) === false) {
+            throw new InvalidStreamProvided(
+                "Invalid stream provided, expected stream resource, received " . gettype($contents)
+            );
+        } elseif ($type = get_resource_type($contents) !== 'stream') {
+            throw new InvalidStreamProvided(
+                "Invalid stream provided, expected stream resource, received resource of type " . $type
+            );
+        }
+    }
+
+    /**
+     * @param resource $resource
+     */
+    private function rewindStream($resource): void
+    {
+        if (ftell($resource) !== 0 && stream_get_meta_data($resource)['seekable']) {
+            rewind($resource);
+        }
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/FilesystemAdapter.php b/msd/vendor/league/flysystem/src/FilesystemAdapter.php
new file mode 100644
index 00000000..6dcb51e4
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FilesystemAdapter.php
@@ -0,0 +1,108 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+interface FilesystemAdapter
+{
+    /**
+     * @throws FilesystemException
+     */
+    public function fileExists(string $path): bool;
+
+    /**
+     * @throws UnableToWriteFile
+     * @throws FilesystemException
+     */
+    public function write(string $path, string $contents, Config $config): void;
+
+    /**
+     * @param resource $contents
+     *
+     * @throws UnableToWriteFile
+     * @throws FilesystemException
+     */
+    public function writeStream(string $path, $contents, Config $config): void;
+
+    /**
+     * @throws UnableToReadFile
+     * @throws FilesystemException
+     */
+    public function read(string $path): string;
+
+    /**
+     * @return resource
+     *
+     * @throws UnableToReadFile
+     * @throws FilesystemException
+     */
+    public function readStream(string $path);
+
+    /**
+     * @throws UnableToDeleteFile
+     * @throws FilesystemException
+     */
+    public function delete(string $path): void;
+
+    /**
+     * @throws UnableToDeleteDirectory
+     * @throws FilesystemException
+     */
+    public function deleteDirectory(string $path): void;
+
+    /**
+     * @throws UnableToCreateDirectory
+     * @throws FilesystemException
+     */
+    public function createDirectory(string $path, Config $config): void;
+
+    /**
+     * @throws InvalidVisibilityProvided
+     * @throws FilesystemException
+     */
+    public function setVisibility(string $path, string $visibility): void;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function visibility(string $path): FileAttributes;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function mimeType(string $path): FileAttributes;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function lastModified(string $path): FileAttributes;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function fileSize(string $path): FileAttributes;
+
+    /**
+     * @return iterable<StorageAttributes>
+     *
+     * @throws FilesystemException
+     */
+    public function listContents(string $path, bool $deep): iterable;
+
+    /**
+     * @throws UnableToMoveFile
+     * @throws FilesystemException
+     */
+    public function move(string $source, string $destination, Config $config): void;
+
+    /**
+     * @throws UnableToCopyFile
+     * @throws FilesystemException
+     */
+    public function copy(string $source, string $destination, Config $config): void;
+}
diff --git a/msd/vendor/league/flysystem/src/FilesystemException.php b/msd/vendor/league/flysystem/src/FilesystemException.php
new file mode 100644
index 00000000..f9d60185
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FilesystemException.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use Throwable;
+
+interface FilesystemException extends Throwable
+{
+}
diff --git a/msd/vendor/league/flysystem/src/FilesystemOperationFailed.php b/msd/vendor/league/flysystem/src/FilesystemOperationFailed.php
new file mode 100644
index 00000000..1c0b6df7
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FilesystemOperationFailed.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+interface FilesystemOperationFailed extends FilesystemException
+{
+    public const OPERATION_WRITE = 'WRITE';
+    public const OPERATION_UPDATE = 'UPDATE';
+    public const OPERATION_FILE_EXISTS = 'FILE_EXISTS';
+    public const OPERATION_CREATE_DIRECTORY = 'CREATE_DIRECTORY';
+    public const OPERATION_DELETE = 'DELETE';
+    public const OPERATION_DELETE_DIRECTORY = 'DELETE_DIRECTORY';
+    public const OPERATION_MOVE = 'MOVE';
+    public const OPERATION_RETRIEVE_METADATA = 'RETRIEVE_METADATA';
+    public const OPERATION_COPY = 'COPY';
+    public const OPERATION_READ = 'READ';
+    public const OPERATION_SET_VISIBILITY = 'SET_VISIBILITY';
+
+    public function operation(): string;
+}
diff --git a/msd/vendor/league/flysystem/src/FilesystemOperator.php b/msd/vendor/league/flysystem/src/FilesystemOperator.php
new file mode 100644
index 00000000..b7f7bd46
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FilesystemOperator.php
@@ -0,0 +1,9 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+interface FilesystemOperator extends FilesystemReader, FilesystemWriter
+{
+}
diff --git a/msd/vendor/league/flysystem/src/FilesystemReader.php b/msd/vendor/league/flysystem/src/FilesystemReader.php
new file mode 100644
index 00000000..63145d09
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FilesystemReader.php
@@ -0,0 +1,66 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+/**
+ * This interface contains everything to read from and inspect
+ * a filesystem. All methods containing are non-destructive.
+ */
+interface FilesystemReader
+{
+    public const LIST_SHALLOW = false;
+    public const LIST_DEEP = true;
+
+    /**
+     * @throws FilesystemException
+     * @throws UnableToCheckFileExistence
+     */
+    public function fileExists(string $location): bool;
+
+    /**
+     * @throws UnableToReadFile
+     * @throws FilesystemException
+     */
+    public function read(string $location): string;
+
+    /**
+     * @return resource
+     *
+     * @throws UnableToReadFile
+     * @throws FilesystemException
+     */
+    public function readStream(string $location);
+
+    /**
+     * @return DirectoryListing<StorageAttributes>
+     *
+     * @throws FilesystemException
+     */
+    public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function lastModified(string $path): int;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function fileSize(string $path): int;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function mimeType(string $path): string;
+
+    /**
+     * @throws UnableToRetrieveMetadata
+     * @throws FilesystemException
+     */
+    public function visibility(string $path): string;
+}
diff --git a/msd/vendor/league/flysystem/src/FilesystemWriter.php b/msd/vendor/league/flysystem/src/FilesystemWriter.php
new file mode 100644
index 00000000..a24bb0fc
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/FilesystemWriter.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+interface FilesystemWriter
+{
+    /**
+     * @throws UnableToWriteFile
+     * @throws FilesystemException
+     */
+    public function write(string $location, string $contents, array $config = []): void;
+
+    /**
+     * @param mixed $contents
+     *
+     * @throws UnableToWriteFile
+     * @throws FilesystemException
+     */
+    public function writeStream(string $location, $contents, array $config = []): void;
+
+    /**
+     * @throws UnableToSetVisibility
+     * @throws FilesystemException
+     */
+    public function setVisibility(string $path, string $visibility): void;
+
+    /**
+     * @throws UnableToDeleteFile
+     * @throws FilesystemException
+     */
+    public function delete(string $location): void;
+
+    /**
+     * @throws UnableToDeleteDirectory
+     * @throws FilesystemException
+     */
+    public function deleteDirectory(string $location): void;
+
+    /**
+     * @throws UnableToCreateDirectory
+     * @throws FilesystemException
+     */
+    public function createDirectory(string $location, array $config = []): void;
+
+    /**
+     * @throws UnableToMoveFile
+     * @throws FilesystemException
+     */
+    public function move(string $source, string $destination, array $config = []): void;
+
+    /**
+     * @throws UnableToCopyFile
+     * @throws FilesystemException
+     */
+    public function copy(string $source, string $destination, array $config = []): void;
+}
diff --git a/msd/vendor/league/flysystem/src/InvalidStreamProvided.php b/msd/vendor/league/flysystem/src/InvalidStreamProvided.php
new file mode 100644
index 00000000..f57b2c74
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/InvalidStreamProvided.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use InvalidArgumentException as BaseInvalidArgumentException;
+
+class InvalidStreamProvided extends BaseInvalidArgumentException implements FilesystemException
+{
+}
diff --git a/msd/vendor/league/flysystem/src/InvalidVisibilityProvided.php b/msd/vendor/league/flysystem/src/InvalidVisibilityProvided.php
new file mode 100644
index 00000000..ddc1909d
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/InvalidVisibilityProvided.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use InvalidArgumentException;
+
+use function var_export;
+
+class InvalidVisibilityProvided extends InvalidArgumentException implements FilesystemException
+{
+    public static function withVisibility(string $visibility, string $expectedMessage): InvalidVisibilityProvided
+    {
+        $provided = var_export($visibility, true);
+        $message = "Invalid visibility provided. Expected {$expectedMessage}, received {$provided}";
+
+        throw new InvalidVisibilityProvided($message);
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/Local/LocalFilesystemAdapter.php b/msd/vendor/league/flysystem/src/Local/LocalFilesystemAdapter.php
new file mode 100644
index 00000000..83310f03
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/Local/LocalFilesystemAdapter.php
@@ -0,0 +1,419 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\Local;
+
+use function file_put_contents;
+use const DIRECTORY_SEPARATOR;
+use const LOCK_EX;
+use DirectoryIterator;
+use FilesystemIterator;
+use Generator;
+use League\Flysystem\Config;
+use League\Flysystem\DirectoryAttributes;
+use League\Flysystem\FileAttributes;
+use League\Flysystem\FilesystemAdapter;
+use League\Flysystem\PathPrefixer;
+use League\Flysystem\SymbolicLinkEncountered;
+use League\Flysystem\UnableToCopyFile;
+use League\Flysystem\UnableToCreateDirectory;
+use League\Flysystem\UnableToDeleteDirectory;
+use League\Flysystem\UnableToDeleteFile;
+use League\Flysystem\UnableToMoveFile;
+use League\Flysystem\UnableToReadFile;
+use League\Flysystem\UnableToRetrieveMetadata;
+use League\Flysystem\UnableToSetVisibility;
+use League\Flysystem\UnableToWriteFile;
+use League\Flysystem\UnixVisibility\PortableVisibilityConverter;
+use League\Flysystem\UnixVisibility\VisibilityConverter;
+use League\MimeTypeDetection\FinfoMimeTypeDetector;
+use League\MimeTypeDetection\MimeTypeDetector;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use SplFileInfo;
+use function chmod;
+use function clearstatcache;
+use function dirname;
+use function error_clear_last;
+use function error_get_last;
+use function file_exists;
+use function is_dir;
+use function is_file;
+use function mkdir;
+use function rename;
+use function stream_copy_to_stream;
+
+class LocalFilesystemAdapter implements FilesystemAdapter
+{
+    /**
+     * @var int
+     */
+    public const SKIP_LINKS = 0001;
+
+    /**
+     * @var int
+     */
+    public const DISALLOW_LINKS = 0002;
+
+    /**
+     * @var PathPrefixer
+     */
+    private $prefixer;
+
+    /**
+     * @var int
+     */
+    private $writeFlags;
+
+    /**
+     * @var int
+     */
+    private $linkHandling;
+
+    /**
+     * @var VisibilityConverter
+     */
+    private $visibility;
+
+    /**
+     * @var MimeTypeDetector
+     */
+    private $mimeTypeDetector;
+
+    public function __construct(
+        string $location,
+        VisibilityConverter $visibility = null,
+        int $writeFlags = LOCK_EX,
+        int $linkHandling = self::DISALLOW_LINKS,
+        MimeTypeDetector $mimeTypeDetector = null
+    ) {
+        $this->prefixer = new PathPrefixer($location, DIRECTORY_SEPARATOR);
+        $this->writeFlags = $writeFlags;
+        $this->linkHandling = $linkHandling;
+        $this->visibility = $visibility ?: new PortableVisibilityConverter();
+        $this->ensureDirectoryExists($location, $this->visibility->defaultForDirectories());
+        $this->mimeTypeDetector = $mimeTypeDetector ?: new FinfoMimeTypeDetector();
+    }
+
+    public function write(string $path, string $contents, Config $config): void
+    {
+        $this->writeToFile($path, $contents, $config);
+    }
+
+    public function writeStream(string $path, $contents, Config $config): void
+    {
+        $this->writeToFile($path, $contents, $config);
+    }
+
+    /**
+     * @param resource|string $contents
+     */
+    private function writeToFile(string $path, $contents, Config $config): void
+    {
+        $prefixedLocation = $this->prefixer->prefixPath($path);
+        $this->ensureDirectoryExists(
+            dirname($prefixedLocation),
+            $this->resolveDirectoryVisibility($config->get(Config::OPTION_DIRECTORY_VISIBILITY))
+        );
+        error_clear_last();
+
+        if (@file_put_contents($prefixedLocation, $contents, $this->writeFlags) === false) {
+            throw UnableToWriteFile::atLocation($path, error_get_last()['message'] ?? '');
+        }
+
+        if ($visibility = $config->get(Config::OPTION_VISIBILITY)) {
+            $this->setVisibility($path, (string) $visibility);
+        }
+    }
+
+    public function delete(string $path): void
+    {
+        $location = $this->prefixer->prefixPath($path);
+
+        if ( ! file_exists($location)) {
+            return;
+        }
+
+        error_clear_last();
+
+        if ( ! @unlink($location)) {
+            throw UnableToDeleteFile::atLocation($location, error_get_last()['message'] ?? '');
+        }
+    }
+
+    public function deleteDirectory(string $prefix): void
+    {
+        $location = $this->prefixer->prefixPath($prefix);
+
+        if ( ! is_dir($location)) {
+            return;
+        }
+
+        $contents = $this->listDirectoryRecursively($location, RecursiveIteratorIterator::CHILD_FIRST);
+
+        /** @var SplFileInfo $file */
+        foreach ($contents as $file) {
+            if ( ! $this->deleteFileInfoObject($file)) {
+                throw UnableToDeleteDirectory::atLocation($prefix, "Unable to delete file at " . $file->getPathname());
+            }
+        }
+
+        unset($contents);
+
+        if ( ! @rmdir($location)) {
+            throw UnableToDeleteDirectory::atLocation($prefix, error_get_last()['message'] ?? '');
+        }
+    }
+
+    private function listDirectoryRecursively(
+        string $path,
+        int $mode = RecursiveIteratorIterator::SELF_FIRST
+    ): Generator {
+        yield from new RecursiveIteratorIterator(
+            new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
+            $mode
+        );
+    }
+
+    protected function deleteFileInfoObject(SplFileInfo $file): bool
+    {
+        switch ($file->getType()) {
+            case 'dir':
+                return @rmdir((string) $file->getRealPath());
+            case 'link':
+                return @unlink((string) $file->getPathname());
+            default:
+                return @unlink((string) $file->getRealPath());
+        }
+    }
+
+    public function listContents(string $path, bool $deep): iterable
+    {
+        $location = $this->prefixer->prefixPath($path);
+
+        if ( ! is_dir($location)) {
+            return;
+        }
+
+        /** @var SplFileInfo[] $iterator */
+        $iterator = $deep ? $this->listDirectoryRecursively($location) : $this->listDirectory($location);
+
+        foreach ($iterator as $fileInfo) {
+            if ($fileInfo->isLink()) {
+                if ($this->linkHandling & self::SKIP_LINKS) {
+                    continue;
+                }
+                throw SymbolicLinkEncountered::atLocation($fileInfo->getPathname());
+            }
+
+            $path = $this->prefixer->stripPrefix($fileInfo->getPathname());
+            $lastModified = $fileInfo->getMTime();
+            $isDirectory = $fileInfo->isDir();
+            $permissions = octdec(substr(sprintf('%o', $fileInfo->getPerms()), -4));
+            $visibility = $isDirectory ? $this->visibility->inverseForDirectory($permissions) : $this->visibility->inverseForFile($permissions);
+
+            yield $isDirectory ? new DirectoryAttributes($path, $visibility, $lastModified) : new FileAttributes(
+                str_replace('\\', '/', $path),
+                $fileInfo->getSize(),
+                $visibility,
+                $lastModified
+            );
+        }
+    }
+
+    public function move(string $source, string $destination, Config $config): void
+    {
+        $sourcePath = $this->prefixer->prefixPath($source);
+        $destinationPath = $this->prefixer->prefixPath($destination);
+        $this->ensureDirectoryExists(
+            dirname($destinationPath),
+            $this->resolveDirectoryVisibility($config->get(Config::OPTION_DIRECTORY_VISIBILITY))
+        );
+
+        if ( ! @rename($sourcePath, $destinationPath)) {
+            throw UnableToMoveFile::fromLocationTo($sourcePath, $destinationPath);
+        }
+    }
+
+    public function copy(string $source, string $destination, Config $config): void
+    {
+        $sourcePath = $this->prefixer->prefixPath($source);
+        $destinationPath = $this->prefixer->prefixPath($destination);
+        $this->ensureDirectoryExists(
+            dirname($destinationPath),
+            $this->resolveDirectoryVisibility($config->get(Config::OPTION_DIRECTORY_VISIBILITY))
+        );
+
+        if ( ! @copy($sourcePath, $destinationPath)) {
+            throw UnableToCopyFile::fromLocationTo($sourcePath, $destinationPath);
+        }
+    }
+
+    public function read(string $path): string
+    {
+        $location = $this->prefixer->prefixPath($path);
+        error_clear_last();
+        $contents = @file_get_contents($location);
+
+        if ($contents === false) {
+            throw UnableToReadFile::fromLocation($path, error_get_last()['message'] ?? '');
+        }
+
+        return $contents;
+    }
+
+    public function readStream(string $path)
+    {
+        $location = $this->prefixer->prefixPath($path);
+        error_clear_last();
+        $contents = @fopen($location, 'rb');
+
+        if ($contents === false) {
+            throw UnableToReadFile::fromLocation($path, error_get_last()['message'] ?? '');
+        }
+
+        return $contents;
+    }
+
+    protected function ensureDirectoryExists(string $dirname, int $visibility): void
+    {
+        if (is_dir($dirname)) {
+            return;
+        }
+
+        error_clear_last();
+
+        if ( ! @mkdir($dirname, $visibility, true)) {
+            $mkdirError = error_get_last();
+        }
+
+        clearstatcache(true, $dirname);
+
+        if ( ! is_dir($dirname)) {
+            $errorMessage = isset($mkdirError['message']) ? $mkdirError['message'] : '';
+
+            throw UnableToCreateDirectory::atLocation($dirname, $errorMessage);
+        }
+    }
+
+    public function fileExists(string $location): bool
+    {
+        $location = $this->prefixer->prefixPath($location);
+
+        return is_file($location);
+    }
+
+    public function createDirectory(string $path, Config $config): void
+    {
+        $location = $this->prefixer->prefixPath($path);
+        $visibility = $config->get(Config::OPTION_VISIBILITY, $config->get(Config::OPTION_DIRECTORY_VISIBILITY));
+        $permissions = $this->resolveDirectoryVisibility($visibility);
+
+        if (is_dir($location)) {
+            $this->setPermissions($location, $permissions);
+
+            return;
+        }
+
+        error_clear_last();
+
+        if ( ! @mkdir($location, $permissions, true)) {
+            throw UnableToCreateDirectory::atLocation($path, error_get_last()['message'] ?? '');
+        }
+    }
+
+    public function setVisibility(string $path, string $visibility): void
+    {
+        $path = $this->prefixer->prefixPath($path);
+        $visibility = is_dir($path) ? $this->visibility->forDirectory($visibility) : $this->visibility->forFile(
+            $visibility
+        );
+
+        $this->setPermissions($path, $visibility);
+    }
+
+    public function visibility(string $path): FileAttributes
+    {
+        $location = $this->prefixer->prefixPath($path);
+        clearstatcache(false, $location);
+        error_clear_last();
+        $fileperms = @fileperms($location);
+
+        if ($fileperms === false) {
+            throw UnableToRetrieveMetadata::visibility($path, error_get_last()['message'] ?? '');
+        }
+
+        $permissions = $fileperms & 0777;
+        $visibility = $this->visibility->inverseForFile($permissions);
+
+        return new FileAttributes($path, null, $visibility);
+    }
+
+    private function resolveDirectoryVisibility(?string $visibility): int
+    {
+        return $visibility === null ? $this->visibility->defaultForDirectories() : $this->visibility->forDirectory(
+            $visibility
+        );
+    }
+
+    public function mimeType(string $path): FileAttributes
+    {
+        $location = $this->prefixer->prefixPath($path);
+        error_clear_last();
+        $mimeType = $this->mimeTypeDetector->detectMimeTypeFromFile($location);
+
+        if ($mimeType === null) {
+            throw UnableToRetrieveMetadata::mimeType($path, error_get_last()['message'] ?? '');
+        }
+
+        return new FileAttributes($path, null, null, null, $mimeType);
+    }
+
+    public function lastModified(string $path): FileAttributes
+    {
+        $location = $this->prefixer->prefixPath($path);
+        error_clear_last();
+        $lastModified = @filemtime($location);
+
+        if ($lastModified === false) {
+            throw UnableToRetrieveMetadata::lastModified($path, error_get_last()['message'] ?? '');
+        }
+
+        return new FileAttributes($path, null, null, $lastModified);
+    }
+
+    public function fileSize(string $path): FileAttributes
+    {
+        $location = $this->prefixer->prefixPath($path);
+        error_clear_last();
+
+        if (is_file($location) && ($fileSize = @filesize($location)) !== false) {
+            return new FileAttributes($path, $fileSize);
+        }
+
+        throw UnableToRetrieveMetadata::fileSize($path, error_get_last()['message'] ?? '');
+    }
+
+    private function listDirectory(string $location): Generator
+    {
+        $iterator = new DirectoryIterator($location);
+
+        foreach ($iterator as $item) {
+            if ($item->isDot()) {
+                continue;
+            }
+
+            yield $item;
+        }
+    }
+
+    private function setPermissions(string $location, int $visibility): void
+    {
+        error_clear_last();
+        if ( ! @chmod($location, $visibility)) {
+            $extraMessage = error_get_last()['message'] ?? '';
+            throw UnableToSetVisibility::atLocation($this->prefixer->stripPrefix($location), $extraMessage);
+        }
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/MountManager.php b/msd/vendor/league/flysystem/src/MountManager.php
new file mode 100644
index 00000000..b5a77735
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/MountManager.php
@@ -0,0 +1,334 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use function sprintf;
+
+class MountManager implements FilesystemOperator
+{
+    /**
+     * @var array<string, FilesystemOperator>
+     */
+    private $filesystems = [];
+
+    /**
+     * MountManager constructor.
+     *
+     * @param array<string,FilesystemOperator> $filesystems
+     */
+    public function __construct(array $filesystems = [])
+    {
+        $this->mountFilesystems($filesystems);
+    }
+
+    public function fileExists(string $location): bool
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->fileExists($path);
+        } catch (UnableToCheckFileExistence $exception) {
+            throw UnableToCheckFileExistence::forLocation($location, $exception);
+        }
+    }
+
+    public function read(string $location): string
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->read($path);
+        } catch (UnableToReadFile $exception) {
+            throw UnableToReadFile::fromLocation($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function readStream(string $location)
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->readStream($path);
+        } catch (UnableToReadFile $exception) {
+            throw UnableToReadFile::fromLocation($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path, $mountIdentifier] = $this->determineFilesystemAndPath($location);
+
+        return
+            $filesystem
+                ->listContents($path, $deep)
+                ->map(
+                    function (StorageAttributes $attributes) use ($mountIdentifier) {
+                        return $attributes->withPath(sprintf('%s://%s', $mountIdentifier, $attributes->path()));
+                    }
+                );
+    }
+
+    public function lastModified(string $location): int
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->lastModified($path);
+        } catch (UnableToRetrieveMetadata $exception) {
+            throw UnableToRetrieveMetadata::lastModified($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function fileSize(string $location): int
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->fileSize($path);
+        } catch (UnableToRetrieveMetadata $exception) {
+            throw UnableToRetrieveMetadata::fileSize($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function mimeType(string $location): string
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->mimeType($path);
+        } catch (UnableToRetrieveMetadata $exception) {
+            throw UnableToRetrieveMetadata::mimeType($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function visibility(string $location): string
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            return $filesystem->visibility($path);
+        } catch (UnableToRetrieveMetadata $exception) {
+            throw UnableToRetrieveMetadata::visibility($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function write(string $location, string $contents, array $config = []): void
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            $filesystem->write($path, $contents, $config);
+        } catch (UnableToWriteFile $exception) {
+            throw UnableToWriteFile::atLocation($location, $exception->reason(), $exception);
+        }
+    }
+
+    public function writeStream(string $location, $contents, array $config = []): void
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+        $filesystem->writeStream($path, $contents, $config);
+    }
+
+    public function setVisibility(string $path, string $visibility): void
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($path);
+        $filesystem->setVisibility($path, $visibility);
+    }
+
+    public function delete(string $location): void
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            $filesystem->delete($path);
+        } catch (UnableToDeleteFile $exception) {
+            throw UnableToDeleteFile::atLocation($location, '', $exception);
+        }
+    }
+
+    public function deleteDirectory(string $location): void
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            $filesystem->deleteDirectory($path);
+        } catch (UnableToDeleteDirectory $exception) {
+            throw UnableToDeleteDirectory::atLocation($location, '', $exception);
+        }
+    }
+
+    public function createDirectory(string $location, array $config = []): void
+    {
+        /** @var FilesystemOperator $filesystem */
+        [$filesystem, $path] = $this->determineFilesystemAndPath($location);
+
+        try {
+            $filesystem->createDirectory($path, $config);
+        } catch (UnableToCreateDirectory $exception) {
+            throw UnableToCreateDirectory::dueToFailure($location, $exception);
+        }
+    }
+
+    public function move(string $source, string $destination, array $config = []): void
+    {
+        /** @var FilesystemOperator $sourceFilesystem */
+        /* @var FilesystemOperator $destinationFilesystem */
+        [$sourceFilesystem, $sourcePath] = $this->determineFilesystemAndPath($source);
+        [$destinationFilesystem, $destinationPath] = $this->determineFilesystemAndPath($destination);
+
+        $sourceFilesystem === $destinationFilesystem ? $this->moveInTheSameFilesystem(
+            $sourceFilesystem,
+            $sourcePath,
+            $destinationPath,
+            $source,
+            $destination
+        ) : $this->moveAcrossFilesystems($source, $destination);
+    }
+
+    public function copy(string $source, string $destination, array $config = []): void
+    {
+        /** @var FilesystemOperator $sourceFilesystem */
+        /* @var FilesystemOperator $destinationFilesystem */
+        [$sourceFilesystem, $sourcePath] = $this->determineFilesystemAndPath($source);
+        [$destinationFilesystem, $destinationPath] = $this->determineFilesystemAndPath($destination);
+
+        $sourceFilesystem === $destinationFilesystem ? $this->copyInSameFilesystem(
+            $sourceFilesystem,
+            $sourcePath,
+            $destinationPath,
+            $source,
+            $destination
+        ) : $this->copyAcrossFilesystem(
+            $config['visibility'] ?? null,
+            $sourceFilesystem,
+            $sourcePath,
+            $destinationFilesystem,
+            $destinationPath,
+            $source,
+            $destination
+        );
+    }
+
+    private function mountFilesystems(array $filesystems): void
+    {
+        foreach ($filesystems as $key => $filesystem) {
+            $this->guardAgainstInvalidMount($key, $filesystem);
+            /* @var string $key */
+            /* @var FilesystemOperator $filesystem */
+            $this->mountFilesystem($key, $filesystem);
+        }
+    }
+
+    /**
+     * @param mixed $key
+     * @param mixed $filesystem
+     */
+    private function guardAgainstInvalidMount($key, $filesystem): void
+    {
+        if ( ! is_string($key)) {
+            throw UnableToMountFilesystem::becauseTheKeyIsNotValid($key);
+        }
+
+        if ( ! $filesystem instanceof FilesystemOperator) {
+            throw UnableToMountFilesystem::becauseTheFilesystemWasNotValid($filesystem);
+        }
+    }
+
+    private function mountFilesystem(string $key, FilesystemOperator $filesystem): void
+    {
+        $this->filesystems[$key] = $filesystem;
+    }
+
+    /**
+     * @param string $path
+     *
+     * @return array{0:FilesystemOperator, 1:string}
+     */
+    private function determineFilesystemAndPath(string $path): array
+    {
+        if (strpos($path, '://') < 1) {
+            throw UnableToResolveFilesystemMount::becauseTheSeparatorIsMissing($path);
+        }
+
+        /** @var string $mountIdentifier */
+        /** @var string $mountPath */
+        [$mountIdentifier, $mountPath] = explode('://', $path, 2);
+
+        if ( ! array_key_exists($mountIdentifier, $this->filesystems)) {
+            throw UnableToResolveFilesystemMount::becauseTheMountWasNotRegistered($mountIdentifier);
+        }
+
+        return [$this->filesystems[$mountIdentifier], $mountPath, $mountIdentifier];
+    }
+
+    private function copyInSameFilesystem(
+        FilesystemOperator $sourceFilesystem,
+        string $sourcePath,
+        string $destinationPath,
+        string $source,
+        string $destination
+    ): void {
+        try {
+            $sourceFilesystem->copy($sourcePath, $destinationPath);
+        } catch (UnableToCopyFile $exception) {
+            throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
+        }
+    }
+
+    private function copyAcrossFilesystem(
+        ?string $visibility,
+        FilesystemOperator $sourceFilesystem,
+        string $sourcePath,
+        FilesystemOperator $destinationFilesystem,
+        string $destinationPath,
+        string $source,
+        string $destination
+    ): void {
+        try {
+            $visibility = $visibility ?? $sourceFilesystem->visibility($sourcePath);
+            $stream = $sourceFilesystem->readStream($sourcePath);
+            $destinationFilesystem->writeStream($destinationPath, $stream, compact('visibility'));
+        } catch (UnableToRetrieveMetadata | UnableToReadFile | UnableToWriteFile $exception) {
+            throw UnableToCopyFile::fromLocationTo($source, $destination, $exception);
+        }
+    }
+
+    private function moveInTheSameFilesystem(
+        FilesystemOperator $sourceFilesystem,
+        string $sourcePath,
+        string $destinationPath,
+        string $source,
+        string $destination
+    ): void {
+        try {
+            $sourceFilesystem->move($sourcePath, $destinationPath);
+        } catch (UnableToMoveFile $exception) {
+            throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
+        }
+    }
+
+    private function moveAcrossFilesystems(string $source, string $destination): void
+    {
+        try {
+            $this->copy($source, $destination);
+            $this->delete($source);
+        } catch (UnableToCopyFile | UnableToDeleteFile $exception) {
+            throw UnableToMoveFile::fromLocationTo($source, $destination, $exception);
+        }
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/PathNormalizer.php b/msd/vendor/league/flysystem/src/PathNormalizer.php
new file mode 100644
index 00000000..54da201a
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/PathNormalizer.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+interface PathNormalizer
+{
+    public function normalizePath(string $path): string;
+}
diff --git a/msd/vendor/league/flysystem/src/PathPrefixer.php b/msd/vendor/league/flysystem/src/PathPrefixer.php
new file mode 100644
index 00000000..b675b8e5
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/PathPrefixer.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use function rtrim;
+use function strlen;
+use function substr;
+
+final class PathPrefixer
+{
+    /**
+     * @var string
+     */
+    private $prefix = '';
+
+    /**
+     * @var string
+     */
+    private $separator = '/';
+
+    public function __construct(string $prefix, string $separator = '/')
+    {
+        $this->prefix = rtrim($prefix, '\\/');
+
+        if ($this->prefix !== '' || $prefix === $separator) {
+            $this->prefix .= $separator;
+        }
+
+        $this->separator = $separator;
+    }
+
+    public function prefixPath(string $path): string
+    {
+        return $this->prefix . ltrim($path, '\\/');
+    }
+
+    public function stripPrefix(string $path): string
+    {
+        /* @var string */
+        return substr($path, strlen($this->prefix));
+    }
+
+    public function stripDirectoryPrefix(string $path): string
+    {
+        return rtrim($this->stripPrefix($path), '\\/');
+    }
+
+    public function prefixDirectoryPath(string $path): string
+    {
+        $prefixedPath = $this->prefixPath(rtrim($path, '\\/'));
+
+        if ((substr($prefixedPath, -1) === $this->separator) || $prefixedPath === '') {
+            return $prefixedPath;
+        }
+
+        return $prefixedPath . $this->separator;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/PathTraversalDetected.php b/msd/vendor/league/flysystem/src/PathTraversalDetected.php
new file mode 100644
index 00000000..d149997f
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/PathTraversalDetected.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+class PathTraversalDetected extends RuntimeException implements FilesystemException
+{
+    /**
+     * @var string
+     */
+    private $path;
+
+    public function path(): string
+    {
+        return $this->path;
+    }
+
+    public static function forPath(string $path): PathTraversalDetected
+    {
+        $e = new PathTraversalDetected("Path traversal detected: {$path}");
+        $e->path = $path;
+
+        return $e;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/PortableVisibilityGuard.php b/msd/vendor/league/flysystem/src/PortableVisibilityGuard.php
new file mode 100644
index 00000000..6e2498b4
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/PortableVisibilityGuard.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+final class PortableVisibilityGuard
+{
+    public static function guardAgainstInvalidInput(string $visibility): void
+    {
+        if ($visibility !== Visibility::PUBLIC && $visibility !== Visibility::PRIVATE) {
+            $className = Visibility::class;
+            throw InvalidVisibilityProvided::withVisibility(
+                $visibility,
+                "either {$className}::PUBLIC or {$className}::PRIVATE"
+            );
+        }
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/ProxyArrayAccessToProperties.php b/msd/vendor/league/flysystem/src/ProxyArrayAccessToProperties.php
new file mode 100644
index 00000000..956b3300
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/ProxyArrayAccessToProperties.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+/**
+ * @internal
+ */
+trait ProxyArrayAccessToProperties
+{
+    private function formatPropertyName(string $offset): string
+    {
+        return str_replace('_', '', lcfirst(ucwords($offset, '_')));
+    }
+
+    /**
+     * @param mixed $offset
+     *
+     * @return bool
+     */
+    public function offsetExists($offset): bool
+    {
+        $property = $this->formatPropertyName((string) $offset);
+
+        return isset($this->{$property});
+    }
+
+    /**
+     * @param mixed $offset
+     *
+     * @return mixed
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetGet($offset)
+    {
+        $property = $this->formatPropertyName((string) $offset);
+
+        return $this->{$property};
+    }
+
+    /**
+     * @param mixed $offset
+     * @param mixed $value
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetSet($offset, $value): void
+    {
+        throw new RuntimeException('Properties can not be manipulated');
+    }
+
+    /**
+     * @param mixed $offset
+     */
+    #[\ReturnTypeWillChange]
+    public function offsetUnset($offset): void
+    {
+        throw new RuntimeException('Properties can not be manipulated');
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/StorageAttributes.php b/msd/vendor/league/flysystem/src/StorageAttributes.php
new file mode 100644
index 00000000..6be6235b
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/StorageAttributes.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use ArrayAccess;
+use JsonSerializable;
+
+interface StorageAttributes extends JsonSerializable, ArrayAccess
+{
+    public const ATTRIBUTE_PATH = 'path';
+    public const ATTRIBUTE_TYPE = 'type';
+    public const ATTRIBUTE_FILE_SIZE = 'file_size';
+    public const ATTRIBUTE_VISIBILITY = 'visibility';
+    public const ATTRIBUTE_LAST_MODIFIED = 'last_modified';
+    public const ATTRIBUTE_MIME_TYPE = 'mime_type';
+    public const ATTRIBUTE_EXTRA_METADATA = 'extra_metadata';
+
+    public const TYPE_FILE = 'file';
+    public const TYPE_DIRECTORY = 'dir';
+
+    public function path(): string;
+
+    public function type(): string;
+
+    public function visibility(): ?string;
+
+    public function lastModified(): ?int;
+
+    public static function fromArray(array $attributes): StorageAttributes;
+
+    public function isFile(): bool;
+
+    public function isDir(): bool;
+
+    public function withPath(string $path): StorageAttributes;
+
+    public function extraMetadata(): array;
+}
diff --git a/msd/vendor/league/flysystem/src/SymbolicLinkEncountered.php b/msd/vendor/league/flysystem/src/SymbolicLinkEncountered.php
new file mode 100644
index 00000000..8091f590
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/SymbolicLinkEncountered.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+final class SymbolicLinkEncountered extends RuntimeException implements FilesystemException
+{
+    /**
+     * @var string
+     */
+    private $location;
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+
+    public static function atLocation(string $pathName): SymbolicLinkEncountered
+    {
+        $e = new static("Unsupported symbolic link encountered at location $pathName");
+        $e->location = $pathName;
+
+        return $e;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToCheckFileExistence.php b/msd/vendor/league/flysystem/src/UnableToCheckFileExistence.php
new file mode 100644
index 00000000..d78e4ee8
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToCheckFileExistence.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+class UnableToCheckFileExistence extends RuntimeException implements FilesystemOperationFailed
+{
+    public static function forLocation(string $path, Throwable $exception = null): UnableToCheckFileExistence
+    {
+        return new UnableToCheckFileExistence("Unable to check file existence for: ${path}", 0, $exception);
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_FILE_EXISTS;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToCopyFile.php b/msd/vendor/league/flysystem/src/UnableToCopyFile.php
new file mode 100644
index 00000000..2180c1e3
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToCopyFile.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToCopyFile extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $source;
+
+    /**
+     * @var string
+     */
+    private $destination;
+
+    public function source(): string
+    {
+        return $this->source;
+    }
+
+    public function destination(): string
+    {
+        return $this->destination;
+    }
+
+    public static function fromLocationTo(
+        string $sourcePath,
+        string $destinationPath,
+        Throwable $previous = null
+    ): UnableToCopyFile {
+        $e = new static("Unable to copy file from $sourcePath to $destinationPath", 0 , $previous);
+        $e->source = $sourcePath;
+        $e->destination = $destinationPath;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_COPY;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToCreateDirectory.php b/msd/vendor/league/flysystem/src/UnableToCreateDirectory.php
new file mode 100644
index 00000000..8298f9f8
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToCreateDirectory.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToCreateDirectory extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location;
+
+    public static function atLocation(string $dirname, string $errorMessage = ''): UnableToCreateDirectory
+    {
+        $message = "Unable to create a directory at {$dirname}. ${errorMessage}";
+        $e = new static(rtrim($message));
+        $e->location = $dirname;
+
+        return $e;
+    }
+
+    public static function dueToFailure(string $dirname, Throwable $previous): UnableToCreateDirectory
+    {
+        $message = "Unable to create a directory at {$dirname}";
+        $e = new static($message, 0, $previous);
+        $e->location = $dirname;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_CREATE_DIRECTORY;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToDeleteDirectory.php b/msd/vendor/league/flysystem/src/UnableToDeleteDirectory.php
new file mode 100644
index 00000000..eeeab24b
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToDeleteDirectory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToDeleteDirectory extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location = '';
+
+    /**
+     * @var string
+     */
+    private $reason;
+
+    public static function atLocation(
+        string $location,
+        string $reason = '',
+        Throwable $previous = null
+    ): UnableToDeleteDirectory {
+        $e = new static(rtrim("Unable to delete directory located at: {$location}. {$reason}"), 0, $previous);
+        $e->location = $location;
+        $e->reason = $reason;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_DELETE_DIRECTORY;
+    }
+
+    public function reason(): string
+    {
+        return $this->reason;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToDeleteFile.php b/msd/vendor/league/flysystem/src/UnableToDeleteFile.php
new file mode 100644
index 00000000..18f7215c
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToDeleteFile.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToDeleteFile extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location = '';
+
+    /**
+     * @var string
+     */
+    private $reason;
+
+    public static function atLocation(string $location, string $reason = '', Throwable $previous = null): UnableToDeleteFile
+    {
+        $e = new static(rtrim("Unable to delete file located at: {$location}. {$reason}"), 0, $previous);
+        $e->location = $location;
+        $e->reason = $reason;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_DELETE;
+    }
+
+    public function reason(): string
+    {
+        return $this->reason;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToMountFilesystem.php b/msd/vendor/league/flysystem/src/UnableToMountFilesystem.php
new file mode 100644
index 00000000..bd41bc98
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToMountFilesystem.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use LogicException;
+
+class UnableToMountFilesystem extends LogicException implements FilesystemException
+{
+    /**
+     * @param mixed $key
+     */
+    public static function becauseTheKeyIsNotValid($key): UnableToMountFilesystem
+    {
+        return new UnableToMountFilesystem(
+            'Unable to mount filesystem, key was invalid. String expected, received: ' . gettype($key)
+        );
+    }
+
+    /**
+     * @param mixed $filesystem
+     */
+    public static function becauseTheFilesystemWasNotValid($filesystem): UnableToMountFilesystem
+    {
+        $received = is_object($filesystem) ? get_class($filesystem) : gettype($filesystem);
+
+        return new UnableToMountFilesystem(
+            'Unable to mount filesystem, filesystem was invalid. Instance of ' . FilesystemOperator::class . ' expected, received: ' . $received
+        );
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToMoveFile.php b/msd/vendor/league/flysystem/src/UnableToMoveFile.php
new file mode 100644
index 00000000..4360d176
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToMoveFile.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToMoveFile extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $source;
+
+    /**
+     * @var string
+     */
+    private $destination;
+
+    public function source(): string
+    {
+        return $this->source;
+    }
+
+    public function destination(): string
+    {
+        return $this->destination;
+    }
+
+    public static function fromLocationTo(
+        string $sourcePath,
+        string $destinationPath,
+        Throwable $previous = null
+    ): UnableToMoveFile {
+        $e = new static("Unable to move file from $sourcePath to $destinationPath", 0, $previous);
+        $e->source = $sourcePath;
+        $e->destination = $destinationPath;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_MOVE;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToReadFile.php b/msd/vendor/league/flysystem/src/UnableToReadFile.php
new file mode 100644
index 00000000..766b5630
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToReadFile.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToReadFile extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location = '';
+
+    /**
+     * @var string
+     */
+    private $reason = '';
+
+    public static function fromLocation(string $location, string $reason = '', Throwable $previous = null): UnableToReadFile
+    {
+        $e = new static(rtrim("Unable to read file from location: {$location}. {$reason}"), 0, $previous);
+        $e->location = $location;
+        $e->reason = $reason;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_READ;
+    }
+
+    public function reason(): string
+    {
+        return $this->reason;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToResolveFilesystemMount.php b/msd/vendor/league/flysystem/src/UnableToResolveFilesystemMount.php
new file mode 100644
index 00000000..91a9ee3e
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToResolveFilesystemMount.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+class UnableToResolveFilesystemMount extends RuntimeException implements FilesystemException
+{
+    public static function becauseTheSeparatorIsMissing(string $path): UnableToResolveFilesystemMount
+    {
+        return new UnableToResolveFilesystemMount("Unable to resolve the filesystem mount because the path ($path) is missing a separator (://).");
+    }
+
+    public static function becauseTheMountWasNotRegistered(string $mountIdentifier): UnableToResolveFilesystemMount
+    {
+        return new UnableToResolveFilesystemMount("Unable to resolve the filesystem mount because the mount ($mountIdentifier) was not registered.");
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToRetrieveMetadata.php b/msd/vendor/league/flysystem/src/UnableToRetrieveMetadata.php
new file mode 100644
index 00000000..11cec7f9
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToRetrieveMetadata.php
@@ -0,0 +1,76 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToRetrieveMetadata extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location;
+
+    /**
+     * @var string
+     */
+    private $metadataType;
+
+    /**
+     * @var string
+     */
+    private $reason;
+
+    public static function lastModified(string $location, string $reason = '', Throwable $previous = null): self
+    {
+        return static::create($location, FileAttributes::ATTRIBUTE_LAST_MODIFIED, $reason, $previous);
+    }
+
+    public static function visibility(string $location, string $reason = '', Throwable $previous = null): self
+    {
+        return static::create($location, FileAttributes::ATTRIBUTE_VISIBILITY, $reason, $previous);
+    }
+
+    public static function fileSize(string $location, string $reason = '', Throwable $previous = null): self
+    {
+        return static::create($location, FileAttributes::ATTRIBUTE_FILE_SIZE, $reason, $previous);
+    }
+
+    public static function mimeType(string $location, string $reason = '', Throwable $previous = null): self
+    {
+        return static::create($location, FileAttributes::ATTRIBUTE_MIME_TYPE, $reason, $previous);
+    }
+
+    public static function create(string $location, string $type, string $reason = '', Throwable $previous = null): self
+    {
+        $e = new static("Unable to retrieve the $type for file at location: $location. {$reason}", 0, $previous);
+        $e->reason = $reason;
+        $e->location = $location;
+        $e->metadataType = $type;
+
+        return $e;
+    }
+
+    public function reason(): string
+    {
+        return $this->reason;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+
+    public function metadataType(): string
+    {
+        return $this->metadataType;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_RETRIEVE_METADATA;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToSetVisibility.php b/msd/vendor/league/flysystem/src/UnableToSetVisibility.php
new file mode 100644
index 00000000..5862d0e0
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToSetVisibility.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+use Throwable;
+
+use function rtrim;
+
+final class UnableToSetVisibility extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location;
+
+    /**
+     * @var string
+     */
+    private $reason;
+
+    public function reason(): string
+    {
+        return $this->reason;
+    }
+
+    public static function atLocation(string $filename, string $extraMessage = '', Throwable $previous = null): self
+    {
+        $message = "Unable to set visibility for file {$filename}. $extraMessage";
+        $e = new static(rtrim($message), 0, $previous);
+        $e->reason = $extraMessage;
+        $e->location = $filename;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_SET_VISIBILITY;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnableToWriteFile.php b/msd/vendor/league/flysystem/src/UnableToWriteFile.php
new file mode 100644
index 00000000..5de78665
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnableToWriteFile.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+use Throwable;
+
+final class UnableToWriteFile extends RuntimeException implements FilesystemOperationFailed
+{
+    /**
+     * @var string
+     */
+    private $location = '';
+
+    /**
+     * @var string
+     */
+    private $reason;
+
+    public static function atLocation(string $location, string $reason = '', Throwable $previous = null): UnableToWriteFile
+    {
+        $e = new static(rtrim("Unable to write file at location: {$location}. {$reason}"), 0, $previous);
+        $e->location = $location;
+        $e->reason = $reason;
+
+        return $e;
+    }
+
+    public function operation(): string
+    {
+        return FilesystemOperationFailed::OPERATION_WRITE;
+    }
+
+    public function reason(): string
+    {
+        return $this->reason;
+    }
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnixVisibility/PortableVisibilityConverter.php b/msd/vendor/league/flysystem/src/UnixVisibility/PortableVisibilityConverter.php
new file mode 100644
index 00000000..5cc1eb23
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnixVisibility/PortableVisibilityConverter.php
@@ -0,0 +1,109 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\UnixVisibility;
+
+use League\Flysystem\PortableVisibilityGuard;
+use League\Flysystem\Visibility;
+
+class PortableVisibilityConverter implements VisibilityConverter
+{
+    /**
+     * @var int
+     */
+    private $filePublic;
+
+    /**
+     * @var int
+     */
+    private $filePrivate;
+
+    /**
+     * @var int
+     */
+    private $directoryPublic;
+
+    /**
+     * @var int
+     */
+    private $directoryPrivate;
+
+    /**
+     * @var string
+     */
+    private $defaultForDirectories;
+
+    public function __construct(
+        int $filePublic = 0644,
+        int $filePrivate = 0600,
+        int $directoryPublic = 0755,
+        int $directoryPrivate = 0700,
+        string $defaultForDirectories = Visibility::PRIVATE
+    ) {
+        $this->filePublic = $filePublic;
+        $this->filePrivate = $filePrivate;
+        $this->directoryPublic = $directoryPublic;
+        $this->directoryPrivate = $directoryPrivate;
+        $this->defaultForDirectories = $defaultForDirectories;
+    }
+
+    public function forFile(string $visibility): int
+    {
+        PortableVisibilityGuard::guardAgainstInvalidInput($visibility);
+
+        return $visibility === Visibility::PUBLIC
+            ? $this->filePublic
+            : $this->filePrivate;
+    }
+
+    public function forDirectory(string $visibility): int
+    {
+        PortableVisibilityGuard::guardAgainstInvalidInput($visibility);
+
+        return $visibility === Visibility::PUBLIC
+            ? $this->directoryPublic
+            : $this->directoryPrivate;
+    }
+
+    public function inverseForFile(int $visibility): string
+    {
+        if ($visibility === $this->filePublic) {
+            return Visibility::PUBLIC;
+        } elseif ($visibility === $this->filePrivate) {
+            return Visibility::PRIVATE;
+        }
+
+        return Visibility::PUBLIC; // default
+    }
+
+    public function inverseForDirectory(int $visibility): string
+    {
+        if ($visibility === $this->directoryPublic) {
+            return Visibility::PUBLIC;
+        } elseif ($visibility === $this->directoryPrivate) {
+            return Visibility::PRIVATE;
+        }
+
+        return Visibility::PUBLIC; // default
+    }
+
+    public function defaultForDirectories(): int
+    {
+        return $this->defaultForDirectories === Visibility::PUBLIC ? $this->directoryPublic : $this->directoryPrivate;
+    }
+
+    /**
+     * @param array<mixed>  $permissionMap
+     */
+    public static function fromArray(array $permissionMap, string $defaultForDirectories = Visibility::PRIVATE): PortableVisibilityConverter
+    {
+        return new PortableVisibilityConverter(
+            $permissionMap['file']['public'] ?? 0644,
+            $permissionMap['file']['private'] ?? 0600,
+            $permissionMap['dir']['public'] ?? 0755,
+            $permissionMap['dir']['private'] ?? 0700,
+            $defaultForDirectories
+        );
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/UnixVisibility/VisibilityConverter.php b/msd/vendor/league/flysystem/src/UnixVisibility/VisibilityConverter.php
new file mode 100644
index 00000000..64af86a0
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnixVisibility/VisibilityConverter.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem\UnixVisibility;
+
+interface VisibilityConverter
+{
+    public function forFile(string $visibility): int;
+    public function forDirectory(string $visibility): int;
+    public function inverseForFile(int $visibility): string;
+    public function inverseForDirectory(int $visibility): string;
+    public function defaultForDirectories(): int;
+}
diff --git a/msd/vendor/league/flysystem/src/UnreadableFileEncountered.php b/msd/vendor/league/flysystem/src/UnreadableFileEncountered.php
new file mode 100644
index 00000000..e31952d4
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/UnreadableFileEncountered.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+use RuntimeException;
+
+final class UnreadableFileEncountered extends RuntimeException implements FilesystemException
+{
+    /**
+     * @var string
+     */
+    private $location;
+
+    public function location(): string
+    {
+        return $this->location;
+    }
+
+    public static function atLocation(string $location): UnreadableFileEncountered
+    {
+        $e = new static("Unreadable file encountered at location {$location}.");
+        $e->location = $location;
+
+        return $e;
+    }
+}
diff --git a/msd/vendor/league/flysystem/src/Visibility.php b/msd/vendor/league/flysystem/src/Visibility.php
new file mode 100644
index 00000000..071ca000
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/Visibility.php
@@ -0,0 +1,11 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+final class Visibility
+{
+    public const PUBLIC = 'public';
+    public const PRIVATE = 'private';
+}
diff --git a/msd/vendor/league/flysystem/src/WhitespacePathNormalizer.php b/msd/vendor/league/flysystem/src/WhitespacePathNormalizer.php
new file mode 100644
index 00000000..135b22a4
--- /dev/null
+++ b/msd/vendor/league/flysystem/src/WhitespacePathNormalizer.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\Flysystem;
+
+class WhitespacePathNormalizer implements PathNormalizer
+{
+    public function normalizePath(string $path): string
+    {
+        $path = str_replace('\\', '/', $path);
+        $this->rejectFunkyWhiteSpace($path);
+
+        return $this->normalizeRelativePath($path);
+    }
+
+    private function rejectFunkyWhiteSpace(string $path): void
+    {
+        if (preg_match('#\p{C}+#u', $path)) {
+            throw CorruptedPathDetected::forPath($path);
+        }
+    }
+
+    private function normalizeRelativePath(string $path): string
+    {
+        $parts = [];
+
+        foreach (explode('/', $path) as $part) {
+            switch ($part) {
+                case '':
+                case '.':
+                    break;
+
+                case '..':
+                    if (empty($parts)) {
+                        throw PathTraversalDetected::forPath($path);
+                    }
+                    array_pop($parts);
+                    break;
+
+                default:
+                    $parts[] = $part;
+                    break;
+            }
+        }
+
+        return implode('/', $parts);
+    }
+}
diff --git a/msd/vendor/league/mime-type-detection/CHANGELOG.md b/msd/vendor/league/mime-type-detection/CHANGELOG.md
new file mode 100644
index 00000000..2264f7ad
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/CHANGELOG.md
@@ -0,0 +1,31 @@
+# Changelog
+
+## 1.10.0 - 2022-04-11
+
+### Fixed
+
+- Added Flysystem v1 inconclusive mime-types and made it configurable as a constructor parameter.
+
+## 1.9.0 - 2021-11-21
+
+### Updated
+
+- Updated lookup
+
+## 1.8.0 - 2021-09-25
+
+### Added
+
+- Added the decorator `OverridingExtensionToMimeTypeMap` which allows you to override values.
+
+## 1.7.0 - 2021-01-18
+
+### Added
+
+- Added a `bufferSampleSize` parameter to the `FinfoMimeTypeDetector` class that allows you to send a reduced content sample which costs less memory.
+
+## 1.6.0 - 2021-01-18
+
+### Changes
+
+- Updated generated mime-type map
diff --git a/msd/vendor/league/mime-type-detection/LICENSE b/msd/vendor/league/mime-type-detection/LICENSE
new file mode 100644
index 00000000..1f016521
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2013-2022 Frank de Jonge
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/msd/vendor/league/mime-type-detection/composer.json b/msd/vendor/league/mime-type-detection/composer.json
new file mode 100644
index 00000000..80ca1af8
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/composer.json
@@ -0,0 +1,34 @@
+{
+    "name": "league/mime-type-detection",
+    "description": "Mime-type detection for Flysystem",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Frank de Jonge",
+            "email": "info@frankdejonge.nl"
+        }
+    ],
+    "scripts": {
+        "test": "vendor/bin/phpunit",
+        "phpstan": "vendor/bin/phpstan analyse -l 6 src"
+    },
+    "require": {
+        "php": "^7.2 || ^8.0",
+        "ext-fileinfo": "*"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^8.5.8 || ^9.3",
+        "phpstan/phpstan": "^0.12.68",
+        "friendsofphp/php-cs-fixer": "^3.2"
+    },
+    "autoload": {
+        "psr-4": {
+            "League\\MimeTypeDetection\\": "src"
+        }
+    },
+    "config": {
+        "platform": {
+            "php": "7.2.0"
+        }
+    }
+}
diff --git a/msd/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php b/msd/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php
new file mode 100644
index 00000000..fc042416
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/EmptyExtensionToMimeTypeMap.php
@@ -0,0 +1,13 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\MimeTypeDetection;
+
+class EmptyExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
+{
+    public function lookupMimeType(string $extension): ?string
+    {
+        return null;
+    }
+}
diff --git a/msd/vendor/league/mime-type-detection/src/ExtensionMimeTypeDetector.php b/msd/vendor/league/mime-type-detection/src/ExtensionMimeTypeDetector.php
new file mode 100644
index 00000000..92b6b1c6
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/ExtensionMimeTypeDetector.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\MimeTypeDetection;
+
+use const PATHINFO_EXTENSION;
+
+class ExtensionMimeTypeDetector implements MimeTypeDetector
+{
+    /**
+     * @var ExtensionToMimeTypeMap
+     */
+    private $extensions;
+
+    public function __construct(ExtensionToMimeTypeMap $extensions = null)
+    {
+        $this->extensions = $extensions ?: new GeneratedExtensionToMimeTypeMap();
+    }
+
+    public function detectMimeType(string $path, $contents): ?string
+    {
+        return $this->detectMimeTypeFromPath($path);
+    }
+
+    public function detectMimeTypeFromPath(string $path): ?string
+    {
+        $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
+
+        return $this->extensions->lookupMimeType($extension);
+    }
+
+    public function detectMimeTypeFromFile(string $path): ?string
+    {
+        return $this->detectMimeTypeFromPath($path);
+    }
+
+    public function detectMimeTypeFromBuffer(string $contents): ?string
+    {
+        return null;
+    }
+}
diff --git a/msd/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php b/msd/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php
new file mode 100644
index 00000000..1dad7bc1
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/ExtensionToMimeTypeMap.php
@@ -0,0 +1,10 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\MimeTypeDetection;
+
+interface ExtensionToMimeTypeMap
+{
+    public function lookupMimeType(string $extension): ?string;
+}
diff --git a/msd/vendor/league/mime-type-detection/src/FinfoMimeTypeDetector.php b/msd/vendor/league/mime-type-detection/src/FinfoMimeTypeDetector.php
new file mode 100644
index 00000000..ba91938f
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/FinfoMimeTypeDetector.php
@@ -0,0 +1,92 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\MimeTypeDetection;
+
+use const FILEINFO_MIME_TYPE;
+
+use const PATHINFO_EXTENSION;
+use finfo;
+
+class FinfoMimeTypeDetector implements MimeTypeDetector
+{
+    private const INCONCLUSIVE_MIME_TYPES = [
+        'application/x-empty',
+        'text/plain',
+        'text/x-asm',
+        'application/octet-stream',
+        'inode/x-empty',
+    ];
+
+    /**
+     * @var finfo
+     */
+    private $finfo;
+
+    /**
+     * @var ExtensionToMimeTypeMap
+     */
+    private $extensionMap;
+
+    /**
+     * @var int|null
+     */
+    private $bufferSampleSize;
+
+    /**
+     * @var array<string>
+     */
+    private $inconclusiveMimetypes;
+
+    public function __construct(
+        string $magicFile = '',
+        ExtensionToMimeTypeMap $extensionMap = null,
+        ?int $bufferSampleSize = null,
+        array $inconclusiveMimetypes = self::INCONCLUSIVE_MIME_TYPES
+    ) {
+        $this->finfo = new finfo(FILEINFO_MIME_TYPE, $magicFile);
+        $this->extensionMap = $extensionMap ?: new GeneratedExtensionToMimeTypeMap();
+        $this->bufferSampleSize = $bufferSampleSize;
+        $this->inconclusiveMimetypes = $inconclusiveMimetypes;
+    }
+
+    public function detectMimeType(string $path, $contents): ?string
+    {
+        $mimeType = is_string($contents)
+            ? (@$this->finfo->buffer($this->takeSample($contents)) ?: null)
+            : null;
+
+        if ($mimeType !== null && ! in_array($mimeType, $this->inconclusiveMimetypes)) {
+            return $mimeType;
+        }
+
+        return $this->detectMimeTypeFromPath($path);
+    }
+
+    public function detectMimeTypeFromPath(string $path): ?string
+    {
+        $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
+
+        return $this->extensionMap->lookupMimeType($extension);
+    }
+
+    public function detectMimeTypeFromFile(string $path): ?string
+    {
+        return @$this->finfo->file($path) ?: null;
+    }
+
+    public function detectMimeTypeFromBuffer(string $contents): ?string
+    {
+        return @$this->finfo->buffer($this->takeSample($contents)) ?: null;
+    }
+
+    private function takeSample(string $contents): string
+    {
+        if ($this->bufferSampleSize === null) {
+            return $contents;
+        }
+
+        return (string) substr($contents, 0, $this->bufferSampleSize);
+    }
+}
diff --git a/msd/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php b/msd/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php
new file mode 100644
index 00000000..f092388d
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/GeneratedExtensionToMimeTypeMap.php
@@ -0,0 +1,1227 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\MimeTypeDetection;
+
+class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
+{
+    /**
+     * @var string[]
+     *
+     * @internal
+     */
+    public const MIME_TYPES_FOR_EXTENSIONS = [
+        '1km' => 'application/vnd.1000minds.decision-model+xml',
+        '3dml' => 'text/vnd.in3d.3dml',
+        '3ds' => 'image/x-3ds',
+        '3g2' => 'video/3gpp2',
+        '3gp' => 'video/3gp',
+        '3gpp' => 'video/3gpp',
+        '3mf' => 'model/3mf',
+        '7z' => 'application/x-7z-compressed',
+        '7zip' => 'application/x-7z-compressed',
+        '123' => 'application/vnd.lotus-1-2-3',
+        'aab' => 'application/x-authorware-bin',
+        'aac' => 'audio/x-acc',
+        'aam' => 'application/x-authorware-map',
+        'aas' => 'application/x-authorware-seg',
+        'abw' => 'application/x-abiword',
+        'ac' => 'application/vnd.nokia.n-gage.ac+xml',
+        'ac3' => 'audio/ac3',
+        'acc' => 'application/vnd.americandynamics.acc',
+        'ace' => 'application/x-ace-compressed',
+        'acu' => 'application/vnd.acucobol',
+        'acutc' => 'application/vnd.acucorp',
+        'adp' => 'audio/adpcm',
+        'aep' => 'application/vnd.audiograph',
+        'afm' => 'application/x-font-type1',
+        'afp' => 'application/vnd.ibm.modcap',
+        'age' => 'application/vnd.age',
+        'ahead' => 'application/vnd.ahead.space',
+        'ai' => 'application/pdf',
+        'aif' => 'audio/x-aiff',
+        'aifc' => 'audio/x-aiff',
+        'aiff' => 'audio/x-aiff',
+        'air' => 'application/vnd.adobe.air-application-installer-package+zip',
+        'ait' => 'application/vnd.dvb.ait',
+        'ami' => 'application/vnd.amiga.ami',
+        'amr' => 'audio/amr',
+        'apk' => 'application/vnd.android.package-archive',
+        'apng' => 'image/apng',
+        'appcache' => 'text/cache-manifest',
+        'application' => 'application/x-ms-application',
+        'apr' => 'application/vnd.lotus-approach',
+        'arc' => 'application/x-freearc',
+        'arj' => 'application/x-arj',
+        'asc' => 'application/pgp-signature',
+        'asf' => 'video/x-ms-asf',
+        'asm' => 'text/x-asm',
+        'aso' => 'application/vnd.accpac.simply.aso',
+        'asx' => 'video/x-ms-asf',
+        'atc' => 'application/vnd.acucorp',
+        'atom' => 'application/atom+xml',
+        'atomcat' => 'application/atomcat+xml',
+        'atomdeleted' => 'application/atomdeleted+xml',
+        'atomsvc' => 'application/atomsvc+xml',
+        'atx' => 'application/vnd.antix.game-component',
+        'au' => 'audio/x-au',
+        'avci' => 'image/avci',
+        'avcs' => 'image/avcs',
+        'avi' => 'video/x-msvideo',
+        'avif' => 'image/avif',
+        'aw' => 'application/applixware',
+        'azf' => 'application/vnd.airzip.filesecure.azf',
+        'azs' => 'application/vnd.airzip.filesecure.azs',
+        'azv' => 'image/vnd.airzip.accelerator.azv',
+        'azw' => 'application/vnd.amazon.ebook',
+        'b16' => 'image/vnd.pco.b16',
+        'bat' => 'application/x-msdownload',
+        'bcpio' => 'application/x-bcpio',
+        'bdf' => 'application/x-font-bdf',
+        'bdm' => 'application/vnd.syncml.dm+wbxml',
+        'bdoc' => 'application/x-bdoc',
+        'bed' => 'application/vnd.realvnc.bed',
+        'bh2' => 'application/vnd.fujitsu.oasysprs',
+        'bin' => 'application/octet-stream',
+        'blb' => 'application/x-blorb',
+        'blorb' => 'application/x-blorb',
+        'bmi' => 'application/vnd.bmi',
+        'bmml' => 'application/vnd.balsamiq.bmml+xml',
+        'bmp' => 'image/bmp',
+        'book' => 'application/vnd.framemaker',
+        'box' => 'application/vnd.previewsystems.box',
+        'boz' => 'application/x-bzip2',
+        'bpk' => 'application/octet-stream',
+        'bpmn' => 'application/octet-stream',
+        'bsp' => 'model/vnd.valve.source.compiled-map',
+        'btif' => 'image/prs.btif',
+        'buffer' => 'application/octet-stream',
+        'bz' => 'application/x-bzip',
+        'bz2' => 'application/x-bzip2',
+        'c' => 'text/x-c',
+        'c4d' => 'application/vnd.clonk.c4group',
+        'c4f' => 'application/vnd.clonk.c4group',
+        'c4g' => 'application/vnd.clonk.c4group',
+        'c4p' => 'application/vnd.clonk.c4group',
+        'c4u' => 'application/vnd.clonk.c4group',
+        'c11amc' => 'application/vnd.cluetrust.cartomobile-config',
+        'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg',
+        'cab' => 'application/vnd.ms-cab-compressed',
+        'caf' => 'audio/x-caf',
+        'cap' => 'application/vnd.tcpdump.pcap',
+        'car' => 'application/vnd.curl.car',
+        'cat' => 'application/vnd.ms-pki.seccat',
+        'cb7' => 'application/x-cbr',
+        'cba' => 'application/x-cbr',
+        'cbr' => 'application/x-cbr',
+        'cbt' => 'application/x-cbr',
+        'cbz' => 'application/x-cbr',
+        'cc' => 'text/x-c',
+        'cco' => 'application/x-cocoa',
+        'cct' => 'application/x-director',
+        'ccxml' => 'application/ccxml+xml',
+        'cdbcmsg' => 'application/vnd.contact.cmsg',
+        'cdf' => 'application/x-netcdf',
+        'cdfx' => 'application/cdfx+xml',
+        'cdkey' => 'application/vnd.mediastation.cdkey',
+        'cdmia' => 'application/cdmi-capability',
+        'cdmic' => 'application/cdmi-container',
+        'cdmid' => 'application/cdmi-domain',
+        'cdmio' => 'application/cdmi-object',
+        'cdmiq' => 'application/cdmi-queue',
+        'cdr' => 'application/cdr',
+        'cdx' => 'chemical/x-cdx',
+        'cdxml' => 'application/vnd.chemdraw+xml',
+        'cdy' => 'application/vnd.cinderella',
+        'cer' => 'application/pkix-cert',
+        'cfs' => 'application/x-cfs-compressed',
+        'cgm' => 'image/cgm',
+        'chat' => 'application/x-chat',
+        'chm' => 'application/vnd.ms-htmlhelp',
+        'chrt' => 'application/vnd.kde.kchart',
+        'cif' => 'chemical/x-cif',
+        'cii' => 'application/vnd.anser-web-certificate-issue-initiation',
+        'cil' => 'application/vnd.ms-artgalry',
+        'cjs' => 'application/node',
+        'cla' => 'application/vnd.claymore',
+        'class' => 'application/octet-stream',
+        'clkk' => 'application/vnd.crick.clicker.keyboard',
+        'clkp' => 'application/vnd.crick.clicker.palette',
+        'clkt' => 'application/vnd.crick.clicker.template',
+        'clkw' => 'application/vnd.crick.clicker.wordbank',
+        'clkx' => 'application/vnd.crick.clicker',
+        'clp' => 'application/x-msclip',
+        'cmc' => 'application/vnd.cosmocaller',
+        'cmdf' => 'chemical/x-cmdf',
+        'cml' => 'chemical/x-cml',
+        'cmp' => 'application/vnd.yellowriver-custom-menu',
+        'cmx' => 'image/x-cmx',
+        'cod' => 'application/vnd.rim.cod',
+        'coffee' => 'text/coffeescript',
+        'com' => 'application/x-msdownload',
+        'conf' => 'text/plain',
+        'cpio' => 'application/x-cpio',
+        'cpl' => 'application/cpl+xml',
+        'cpp' => 'text/x-c',
+        'cpt' => 'application/mac-compactpro',
+        'crd' => 'application/x-mscardfile',
+        'crl' => 'application/pkix-crl',
+        'crt' => 'application/x-x509-ca-cert',
+        'crx' => 'application/x-chrome-extension',
+        'cryptonote' => 'application/vnd.rig.cryptonote',
+        'csh' => 'application/x-csh',
+        'csl' => 'application/vnd.citationstyles.style+xml',
+        'csml' => 'chemical/x-csml',
+        'csp' => 'application/vnd.commonspace',
+        'csr' => 'application/octet-stream',
+        'css' => 'text/css',
+        'cst' => 'application/x-director',
+        'csv' => 'text/csv',
+        'cu' => 'application/cu-seeme',
+        'curl' => 'text/vnd.curl',
+        'cww' => 'application/prs.cww',
+        'cxt' => 'application/x-director',
+        'cxx' => 'text/x-c',
+        'dae' => 'model/vnd.collada+xml',
+        'daf' => 'application/vnd.mobius.daf',
+        'dart' => 'application/vnd.dart',
+        'dataless' => 'application/vnd.fdsn.seed',
+        'davmount' => 'application/davmount+xml',
+        'dbf' => 'application/vnd.dbf',
+        'dbk' => 'application/docbook+xml',
+        'dcr' => 'application/x-director',
+        'dcurl' => 'text/vnd.curl.dcurl',
+        'dd2' => 'application/vnd.oma.dd2+xml',
+        'ddd' => 'application/vnd.fujixerox.ddd',
+        'ddf' => 'application/vnd.syncml.dmddf+xml',
+        'dds' => 'image/vnd.ms-dds',
+        'deb' => 'application/x-debian-package',
+        'def' => 'text/plain',
+        'deploy' => 'application/octet-stream',
+        'der' => 'application/x-x509-ca-cert',
+        'dfac' => 'application/vnd.dreamfactory',
+        'dgc' => 'application/x-dgc-compressed',
+        'dic' => 'text/x-c',
+        'dir' => 'application/x-director',
+        'dis' => 'application/vnd.mobius.dis',
+        'disposition-notification' => 'message/disposition-notification',
+        'dist' => 'application/octet-stream',
+        'distz' => 'application/octet-stream',
+        'djv' => 'image/vnd.djvu',
+        'djvu' => 'image/vnd.djvu',
+        'dll' => 'application/octet-stream',
+        'dmg' => 'application/x-apple-diskimage',
+        'dmn' => 'application/octet-stream',
+        'dmp' => 'application/vnd.tcpdump.pcap',
+        'dms' => 'application/octet-stream',
+        'dna' => 'application/vnd.dna',
+        'doc' => 'application/msword',
+        'docm' => 'application/vnd.ms-word.template.macroEnabled.12',
+        'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+        'dot' => 'application/msword',
+        'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
+        'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+        'dp' => 'application/vnd.osgi.dp',
+        'dpg' => 'application/vnd.dpgraph',
+        'dra' => 'audio/vnd.dra',
+        'drle' => 'image/dicom-rle',
+        'dsc' => 'text/prs.lines.tag',
+        'dssc' => 'application/dssc+der',
+        'dtb' => 'application/x-dtbook+xml',
+        'dtd' => 'application/xml-dtd',
+        'dts' => 'audio/vnd.dts',
+        'dtshd' => 'audio/vnd.dts.hd',
+        'dump' => 'application/octet-stream',
+        'dvb' => 'video/vnd.dvb.file',
+        'dvi' => 'application/x-dvi',
+        'dwd' => 'application/atsc-dwd+xml',
+        'dwf' => 'model/vnd.dwf',
+        'dwg' => 'image/vnd.dwg',
+        'dxf' => 'image/vnd.dxf',
+        'dxp' => 'application/vnd.spotfire.dxp',
+        'dxr' => 'application/x-director',
+        'ear' => 'application/java-archive',
+        'ecelp4800' => 'audio/vnd.nuera.ecelp4800',
+        'ecelp7470' => 'audio/vnd.nuera.ecelp7470',
+        'ecelp9600' => 'audio/vnd.nuera.ecelp9600',
+        'ecma' => 'application/ecmascript',
+        'edm' => 'application/vnd.novadigm.edm',
+        'edx' => 'application/vnd.novadigm.edx',
+        'efif' => 'application/vnd.picsel',
+        'ei6' => 'application/vnd.pg.osasli',
+        'elc' => 'application/octet-stream',
+        'emf' => 'image/emf',
+        'eml' => 'message/rfc822',
+        'emma' => 'application/emma+xml',
+        'emotionml' => 'application/emotionml+xml',
+        'emz' => 'application/x-msmetafile',
+        'eol' => 'audio/vnd.digital-winds',
+        'eot' => 'application/vnd.ms-fontobject',
+        'eps' => 'application/postscript',
+        'epub' => 'application/epub+zip',
+        'es' => 'application/ecmascript',
+        'es3' => 'application/vnd.eszigno3+xml',
+        'esa' => 'application/vnd.osgi.subsystem',
+        'esf' => 'application/vnd.epson.esf',
+        'et3' => 'application/vnd.eszigno3+xml',
+        'etx' => 'text/x-setext',
+        'eva' => 'application/x-eva',
+        'evy' => 'application/x-envoy',
+        'exe' => 'application/octet-stream',
+        'exi' => 'application/exi',
+        'exp' => 'application/express',
+        'exr' => 'image/aces',
+        'ext' => 'application/vnd.novadigm.ext',
+        'ez' => 'application/andrew-inset',
+        'ez2' => 'application/vnd.ezpix-album',
+        'ez3' => 'application/vnd.ezpix-package',
+        'f' => 'text/x-fortran',
+        'f4v' => 'video/mp4',
+        'f77' => 'text/x-fortran',
+        'f90' => 'text/x-fortran',
+        'fbs' => 'image/vnd.fastbidsheet',
+        'fcdt' => 'application/vnd.adobe.formscentral.fcdt',
+        'fcs' => 'application/vnd.isac.fcs',
+        'fdf' => 'application/vnd.fdf',
+        'fdt' => 'application/fdt+xml',
+        'fe_launch' => 'application/vnd.denovo.fcselayout-link',
+        'fg5' => 'application/vnd.fujitsu.oasysgp',
+        'fgd' => 'application/x-director',
+        'fh' => 'image/x-freehand',
+        'fh4' => 'image/x-freehand',
+        'fh5' => 'image/x-freehand',
+        'fh7' => 'image/x-freehand',
+        'fhc' => 'image/x-freehand',
+        'fig' => 'application/x-xfig',
+        'fits' => 'image/fits',
+        'flac' => 'audio/x-flac',
+        'fli' => 'video/x-fli',
+        'flo' => 'application/vnd.micrografx.flo',
+        'flv' => 'video/x-flv',
+        'flw' => 'application/vnd.kde.kivio',
+        'flx' => 'text/vnd.fmi.flexstor',
+        'fly' => 'text/vnd.fly',
+        'fm' => 'application/vnd.framemaker',
+        'fnc' => 'application/vnd.frogans.fnc',
+        'fo' => 'application/vnd.software602.filler.form+xml',
+        'for' => 'text/x-fortran',
+        'fpx' => 'image/vnd.fpx',
+        'frame' => 'application/vnd.framemaker',
+        'fsc' => 'application/vnd.fsc.weblaunch',
+        'fst' => 'image/vnd.fst',
+        'ftc' => 'application/vnd.fluxtime.clip',
+        'fti' => 'application/vnd.anser-web-funds-transfer-initiation',
+        'fvt' => 'video/vnd.fvt',
+        'fxp' => 'application/vnd.adobe.fxp',
+        'fxpl' => 'application/vnd.adobe.fxp',
+        'fzs' => 'application/vnd.fuzzysheet',
+        'g2w' => 'application/vnd.geoplan',
+        'g3' => 'image/g3fax',
+        'g3w' => 'application/vnd.geospace',
+        'gac' => 'application/vnd.groove-account',
+        'gam' => 'application/x-tads',
+        'gbr' => 'application/rpki-ghostbusters',
+        'gca' => 'application/x-gca-compressed',
+        'gdl' => 'model/vnd.gdl',
+        'gdoc' => 'application/vnd.google-apps.document',
+        'ged' => 'text/vnd.familysearch.gedcom',
+        'geo' => 'application/vnd.dynageo',
+        'geojson' => 'application/geo+json',
+        'gex' => 'application/vnd.geometry-explorer',
+        'ggb' => 'application/vnd.geogebra.file',
+        'ggt' => 'application/vnd.geogebra.tool',
+        'ghf' => 'application/vnd.groove-help',
+        'gif' => 'image/gif',
+        'gim' => 'application/vnd.groove-identity-message',
+        'glb' => 'model/gltf-binary',
+        'gltf' => 'model/gltf+json',
+        'gml' => 'application/gml+xml',
+        'gmx' => 'application/vnd.gmx',
+        'gnumeric' => 'application/x-gnumeric',
+        'gpg' => 'application/gpg-keys',
+        'gph' => 'application/vnd.flographit',
+        'gpx' => 'application/gpx+xml',
+        'gqf' => 'application/vnd.grafeq',
+        'gqs' => 'application/vnd.grafeq',
+        'gram' => 'application/srgs',
+        'gramps' => 'application/x-gramps-xml',
+        'gre' => 'application/vnd.geometry-explorer',
+        'grv' => 'application/vnd.groove-injector',
+        'grxml' => 'application/srgs+xml',
+        'gsf' => 'application/x-font-ghostscript',
+        'gsheet' => 'application/vnd.google-apps.spreadsheet',
+        'gslides' => 'application/vnd.google-apps.presentation',
+        'gtar' => 'application/x-gtar',
+        'gtm' => 'application/vnd.groove-tool-message',
+        'gtw' => 'model/vnd.gtw',
+        'gv' => 'text/vnd.graphviz',
+        'gxf' => 'application/gxf',
+        'gxt' => 'application/vnd.geonext',
+        'gz' => 'application/gzip',
+        'gzip' => 'application/gzip',
+        'h' => 'text/x-c',
+        'h261' => 'video/h261',
+        'h263' => 'video/h263',
+        'h264' => 'video/h264',
+        'hal' => 'application/vnd.hal+xml',
+        'hbci' => 'application/vnd.hbci',
+        'hbs' => 'text/x-handlebars-template',
+        'hdd' => 'application/x-virtualbox-hdd',
+        'hdf' => 'application/x-hdf',
+        'heic' => 'image/heic',
+        'heics' => 'image/heic-sequence',
+        'heif' => 'image/heif',
+        'heifs' => 'image/heif-sequence',
+        'hej2' => 'image/hej2k',
+        'held' => 'application/atsc-held+xml',
+        'hh' => 'text/x-c',
+        'hjson' => 'application/hjson',
+        'hlp' => 'application/winhlp',
+        'hpgl' => 'application/vnd.hp-hpgl',
+        'hpid' => 'application/vnd.hp-hpid',
+        'hps' => 'application/vnd.hp-hps',
+        'hqx' => 'application/mac-binhex40',
+        'hsj2' => 'image/hsj2',
+        'htc' => 'text/x-component',
+        'htke' => 'application/vnd.kenameaapp',
+        'htm' => 'text/html',
+        'html' => 'text/html',
+        'hvd' => 'application/vnd.yamaha.hv-dic',
+        'hvp' => 'application/vnd.yamaha.hv-voice',
+        'hvs' => 'application/vnd.yamaha.hv-script',
+        'i2g' => 'application/vnd.intergeo',
+        'icc' => 'application/vnd.iccprofile',
+        'ice' => 'x-conference/x-cooltalk',
+        'icm' => 'application/vnd.iccprofile',
+        'ico' => 'image/x-icon',
+        'ics' => 'text/calendar',
+        'ief' => 'image/ief',
+        'ifb' => 'text/calendar',
+        'ifm' => 'application/vnd.shana.informed.formdata',
+        'iges' => 'model/iges',
+        'igl' => 'application/vnd.igloader',
+        'igm' => 'application/vnd.insors.igm',
+        'igs' => 'model/iges',
+        'igx' => 'application/vnd.micrografx.igx',
+        'iif' => 'application/vnd.shana.informed.interchange',
+        'img' => 'application/octet-stream',
+        'imp' => 'application/vnd.accpac.simply.imp',
+        'ims' => 'application/vnd.ms-ims',
+        'in' => 'text/plain',
+        'ini' => 'text/plain',
+        'ink' => 'application/inkml+xml',
+        'inkml' => 'application/inkml+xml',
+        'install' => 'application/x-install-instructions',
+        'iota' => 'application/vnd.astraea-software.iota',
+        'ipfix' => 'application/ipfix',
+        'ipk' => 'application/vnd.shana.informed.package',
+        'irm' => 'application/vnd.ibm.rights-management',
+        'irp' => 'application/vnd.irepository.package+xml',
+        'iso' => 'application/x-iso9660-image',
+        'itp' => 'application/vnd.shana.informed.formtemplate',
+        'its' => 'application/its+xml',
+        'ivp' => 'application/vnd.immervision-ivp',
+        'ivu' => 'application/vnd.immervision-ivu',
+        'jad' => 'text/vnd.sun.j2me.app-descriptor',
+        'jade' => 'text/jade',
+        'jam' => 'application/vnd.jam',
+        'jar' => 'application/java-archive',
+        'jardiff' => 'application/x-java-archive-diff',
+        'java' => 'text/x-java-source',
+        'jhc' => 'image/jphc',
+        'jisp' => 'application/vnd.jisp',
+        'jls' => 'image/jls',
+        'jlt' => 'application/vnd.hp-jlyt',
+        'jng' => 'image/x-jng',
+        'jnlp' => 'application/x-java-jnlp-file',
+        'joda' => 'application/vnd.joost.joda-archive',
+        'jp2' => 'image/jp2',
+        'jpe' => 'image/jpeg',
+        'jpeg' => 'image/jpeg',
+        'jpf' => 'image/jpx',
+        'jpg' => 'image/jpeg',
+        'jpg2' => 'image/jp2',
+        'jpgm' => 'video/jpm',
+        'jpgv' => 'video/jpeg',
+        'jph' => 'image/jph',
+        'jpm' => 'video/jpm',
+        'jpx' => 'image/jpx',
+        'js' => 'application/javascript',
+        'json' => 'application/json',
+        'json5' => 'application/json5',
+        'jsonld' => 'application/ld+json',
+        'jsonml' => 'application/jsonml+json',
+        'jsx' => 'text/jsx',
+        'jxr' => 'image/jxr',
+        'jxra' => 'image/jxra',
+        'jxrs' => 'image/jxrs',
+        'jxs' => 'image/jxs',
+        'jxsc' => 'image/jxsc',
+        'jxsi' => 'image/jxsi',
+        'jxss' => 'image/jxss',
+        'kar' => 'audio/midi',
+        'karbon' => 'application/vnd.kde.karbon',
+        'kdb' => 'application/octet-stream',
+        'kdbx' => 'application/x-keepass2',
+        'key' => 'application/x-iwork-keynote-sffkey',
+        'kfo' => 'application/vnd.kde.kformula',
+        'kia' => 'application/vnd.kidspiration',
+        'kml' => 'application/vnd.google-earth.kml+xml',
+        'kmz' => 'application/vnd.google-earth.kmz',
+        'kne' => 'application/vnd.kinar',
+        'knp' => 'application/vnd.kinar',
+        'kon' => 'application/vnd.kde.kontour',
+        'kpr' => 'application/vnd.kde.kpresenter',
+        'kpt' => 'application/vnd.kde.kpresenter',
+        'kpxx' => 'application/vnd.ds-keypoint',
+        'ksp' => 'application/vnd.kde.kspread',
+        'ktr' => 'application/vnd.kahootz',
+        'ktx' => 'image/ktx',
+        'ktx2' => 'image/ktx2',
+        'ktz' => 'application/vnd.kahootz',
+        'kwd' => 'application/vnd.kde.kword',
+        'kwt' => 'application/vnd.kde.kword',
+        'lasxml' => 'application/vnd.las.las+xml',
+        'latex' => 'application/x-latex',
+        'lbd' => 'application/vnd.llamagraphics.life-balance.desktop',
+        'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml',
+        'les' => 'application/vnd.hhe.lesson-player',
+        'less' => 'text/less',
+        'lgr' => 'application/lgr+xml',
+        'lha' => 'application/octet-stream',
+        'link66' => 'application/vnd.route66.link66+xml',
+        'list' => 'text/plain',
+        'list3820' => 'application/vnd.ibm.modcap',
+        'listafp' => 'application/vnd.ibm.modcap',
+        'litcoffee' => 'text/coffeescript',
+        'lnk' => 'application/x-ms-shortcut',
+        'log' => 'text/plain',
+        'lostxml' => 'application/lost+xml',
+        'lrf' => 'application/octet-stream',
+        'lrm' => 'application/vnd.ms-lrm',
+        'ltf' => 'application/vnd.frogans.ltf',
+        'lua' => 'text/x-lua',
+        'luac' => 'application/x-lua-bytecode',
+        'lvp' => 'audio/vnd.lucent.voice',
+        'lwp' => 'application/vnd.lotus-wordpro',
+        'lzh' => 'application/octet-stream',
+        'm1v' => 'video/mpeg',
+        'm2a' => 'audio/mpeg',
+        'm2v' => 'video/mpeg',
+        'm3a' => 'audio/mpeg',
+        'm3u' => 'text/plain',
+        'm3u8' => 'application/vnd.apple.mpegurl',
+        'm4a' => 'audio/x-m4a',
+        'm4p' => 'application/mp4',
+        'm4s' => 'video/iso.segment',
+        'm4u' => 'application/vnd.mpegurl',
+        'm4v' => 'video/x-m4v',
+        'm13' => 'application/x-msmediaview',
+        'm14' => 'application/x-msmediaview',
+        'm21' => 'application/mp21',
+        'ma' => 'application/mathematica',
+        'mads' => 'application/mads+xml',
+        'maei' => 'application/mmt-aei+xml',
+        'mag' => 'application/vnd.ecowin.chart',
+        'maker' => 'application/vnd.framemaker',
+        'man' => 'text/troff',
+        'manifest' => 'text/cache-manifest',
+        'map' => 'application/json',
+        'mar' => 'application/octet-stream',
+        'markdown' => 'text/markdown',
+        'mathml' => 'application/mathml+xml',
+        'mb' => 'application/mathematica',
+        'mbk' => 'application/vnd.mobius.mbk',
+        'mbox' => 'application/mbox',
+        'mc1' => 'application/vnd.medcalcdata',
+        'mcd' => 'application/vnd.mcd',
+        'mcurl' => 'text/vnd.curl.mcurl',
+        'md' => 'text/markdown',
+        'mdb' => 'application/x-msaccess',
+        'mdi' => 'image/vnd.ms-modi',
+        'mdx' => 'text/mdx',
+        'me' => 'text/troff',
+        'mesh' => 'model/mesh',
+        'meta4' => 'application/metalink4+xml',
+        'metalink' => 'application/metalink+xml',
+        'mets' => 'application/mets+xml',
+        'mfm' => 'application/vnd.mfmp',
+        'mft' => 'application/rpki-manifest',
+        'mgp' => 'application/vnd.osgeo.mapguide.package',
+        'mgz' => 'application/vnd.proteus.magazine',
+        'mid' => 'audio/midi',
+        'midi' => 'audio/midi',
+        'mie' => 'application/x-mie',
+        'mif' => 'application/vnd.mif',
+        'mime' => 'message/rfc822',
+        'mj2' => 'video/mj2',
+        'mjp2' => 'video/mj2',
+        'mjs' => 'application/javascript',
+        'mk3d' => 'video/x-matroska',
+        'mka' => 'audio/x-matroska',
+        'mkd' => 'text/x-markdown',
+        'mks' => 'video/x-matroska',
+        'mkv' => 'video/x-matroska',
+        'mlp' => 'application/vnd.dolby.mlp',
+        'mmd' => 'application/vnd.chipnuts.karaoke-mmd',
+        'mmf' => 'application/vnd.smaf',
+        'mml' => 'text/mathml',
+        'mmr' => 'image/vnd.fujixerox.edmics-mmr',
+        'mng' => 'video/x-mng',
+        'mny' => 'application/x-msmoney',
+        'mobi' => 'application/x-mobipocket-ebook',
+        'mods' => 'application/mods+xml',
+        'mov' => 'video/quicktime',
+        'movie' => 'video/x-sgi-movie',
+        'mp2' => 'audio/mpeg',
+        'mp2a' => 'audio/mpeg',
+        'mp3' => 'audio/mpeg',
+        'mp4' => 'video/mp4',
+        'mp4a' => 'audio/mp4',
+        'mp4s' => 'application/mp4',
+        'mp4v' => 'video/mp4',
+        'mp21' => 'application/mp21',
+        'mpc' => 'application/vnd.mophun.certificate',
+        'mpd' => 'application/dash+xml',
+        'mpe' => 'video/mpeg',
+        'mpeg' => 'video/mpeg',
+        'mpf' => 'application/media-policy-dataset+xml',
+        'mpg' => 'video/mpeg',
+        'mpg4' => 'video/mp4',
+        'mpga' => 'audio/mpeg',
+        'mpkg' => 'application/vnd.apple.installer+xml',
+        'mpm' => 'application/vnd.blueice.multipass',
+        'mpn' => 'application/vnd.mophun.application',
+        'mpp' => 'application/vnd.ms-project',
+        'mpt' => 'application/vnd.ms-project',
+        'mpy' => 'application/vnd.ibm.minipay',
+        'mqy' => 'application/vnd.mobius.mqy',
+        'mrc' => 'application/marc',
+        'mrcx' => 'application/marcxml+xml',
+        'ms' => 'text/troff',
+        'mscml' => 'application/mediaservercontrol+xml',
+        'mseed' => 'application/vnd.fdsn.mseed',
+        'mseq' => 'application/vnd.mseq',
+        'msf' => 'application/vnd.epson.msf',
+        'msg' => 'application/vnd.ms-outlook',
+        'msh' => 'model/mesh',
+        'msi' => 'application/x-msdownload',
+        'msl' => 'application/vnd.mobius.msl',
+        'msm' => 'application/octet-stream',
+        'msp' => 'application/octet-stream',
+        'msty' => 'application/vnd.muvee.style',
+        'mtl' => 'model/mtl',
+        'mts' => 'model/vnd.mts',
+        'mus' => 'application/vnd.musician',
+        'musd' => 'application/mmt-usd+xml',
+        'musicxml' => 'application/vnd.recordare.musicxml+xml',
+        'mvb' => 'application/x-msmediaview',
+        'mvt' => 'application/vnd.mapbox-vector-tile',
+        'mwf' => 'application/vnd.mfer',
+        'mxf' => 'application/mxf',
+        'mxl' => 'application/vnd.recordare.musicxml',
+        'mxmf' => 'audio/mobile-xmf',
+        'mxml' => 'application/xv+xml',
+        'mxs' => 'application/vnd.triscape.mxs',
+        'mxu' => 'video/vnd.mpegurl',
+        'n-gage' => 'application/vnd.nokia.n-gage.symbian.install',
+        'n3' => 'text/n3',
+        'nb' => 'application/mathematica',
+        'nbp' => 'application/vnd.wolfram.player',
+        'nc' => 'application/x-netcdf',
+        'ncx' => 'application/x-dtbncx+xml',
+        'nfo' => 'text/x-nfo',
+        'ngdat' => 'application/vnd.nokia.n-gage.data',
+        'nitf' => 'application/vnd.nitf',
+        'nlu' => 'application/vnd.neurolanguage.nlu',
+        'nml' => 'application/vnd.enliven',
+        'nnd' => 'application/vnd.noblenet-directory',
+        'nns' => 'application/vnd.noblenet-sealer',
+        'nnw' => 'application/vnd.noblenet-web',
+        'npx' => 'image/vnd.net-fpx',
+        'nq' => 'application/n-quads',
+        'nsc' => 'application/x-conference',
+        'nsf' => 'application/vnd.lotus-notes',
+        'nt' => 'application/n-triples',
+        'ntf' => 'application/vnd.nitf',
+        'numbers' => 'application/x-iwork-numbers-sffnumbers',
+        'nzb' => 'application/x-nzb',
+        'oa2' => 'application/vnd.fujitsu.oasys2',
+        'oa3' => 'application/vnd.fujitsu.oasys3',
+        'oas' => 'application/vnd.fujitsu.oasys',
+        'obd' => 'application/x-msbinder',
+        'obgx' => 'application/vnd.openblox.game+xml',
+        'obj' => 'model/obj',
+        'oda' => 'application/oda',
+        'odb' => 'application/vnd.oasis.opendocument.database',
+        'odc' => 'application/vnd.oasis.opendocument.chart',
+        'odf' => 'application/vnd.oasis.opendocument.formula',
+        'odft' => 'application/vnd.oasis.opendocument.formula-template',
+        'odg' => 'application/vnd.oasis.opendocument.graphics',
+        'odi' => 'application/vnd.oasis.opendocument.image',
+        'odm' => 'application/vnd.oasis.opendocument.text-master',
+        'odp' => 'application/vnd.oasis.opendocument.presentation',
+        'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
+        'odt' => 'application/vnd.oasis.opendocument.text',
+        'oga' => 'audio/ogg',
+        'ogex' => 'model/vnd.opengex',
+        'ogg' => 'audio/ogg',
+        'ogv' => 'video/ogg',
+        'ogx' => 'application/ogg',
+        'omdoc' => 'application/omdoc+xml',
+        'onepkg' => 'application/onenote',
+        'onetmp' => 'application/onenote',
+        'onetoc' => 'application/onenote',
+        'onetoc2' => 'application/onenote',
+        'opf' => 'application/oebps-package+xml',
+        'opml' => 'text/x-opml',
+        'oprc' => 'application/vnd.palm',
+        'opus' => 'audio/ogg',
+        'org' => 'text/x-org',
+        'osf' => 'application/vnd.yamaha.openscoreformat',
+        'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml',
+        'osm' => 'application/vnd.openstreetmap.data+xml',
+        'otc' => 'application/vnd.oasis.opendocument.chart-template',
+        'otf' => 'font/otf',
+        'otg' => 'application/vnd.oasis.opendocument.graphics-template',
+        'oth' => 'application/vnd.oasis.opendocument.text-web',
+        'oti' => 'application/vnd.oasis.opendocument.image-template',
+        'otp' => 'application/vnd.oasis.opendocument.presentation-template',
+        'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
+        'ott' => 'application/vnd.oasis.opendocument.text-template',
+        'ova' => 'application/x-virtualbox-ova',
+        'ovf' => 'application/x-virtualbox-ovf',
+        'owl' => 'application/rdf+xml',
+        'oxps' => 'application/oxps',
+        'oxt' => 'application/vnd.openofficeorg.extension',
+        'p' => 'text/x-pascal',
+        'p7a' => 'application/x-pkcs7-signature',
+        'p7b' => 'application/x-pkcs7-certificates',
+        'p7c' => 'application/pkcs7-mime',
+        'p7m' => 'application/pkcs7-mime',
+        'p7r' => 'application/x-pkcs7-certreqresp',
+        'p7s' => 'application/pkcs7-signature',
+        'p8' => 'application/pkcs8',
+        'p10' => 'application/x-pkcs10',
+        'p12' => 'application/x-pkcs12',
+        'pac' => 'application/x-ns-proxy-autoconfig',
+        'pages' => 'application/x-iwork-pages-sffpages',
+        'pas' => 'text/x-pascal',
+        'paw' => 'application/vnd.pawaafile',
+        'pbd' => 'application/vnd.powerbuilder6',
+        'pbm' => 'image/x-portable-bitmap',
+        'pcap' => 'application/vnd.tcpdump.pcap',
+        'pcf' => 'application/x-font-pcf',
+        'pcl' => 'application/vnd.hp-pcl',
+        'pclxl' => 'application/vnd.hp-pclxl',
+        'pct' => 'image/x-pict',
+        'pcurl' => 'application/vnd.curl.pcurl',
+        'pcx' => 'image/x-pcx',
+        'pdb' => 'application/x-pilot',
+        'pde' => 'text/x-processing',
+        'pdf' => 'application/pdf',
+        'pem' => 'application/x-x509-user-cert',
+        'pfa' => 'application/x-font-type1',
+        'pfb' => 'application/x-font-type1',
+        'pfm' => 'application/x-font-type1',
+        'pfr' => 'application/font-tdpfr',
+        'pfx' => 'application/x-pkcs12',
+        'pgm' => 'image/x-portable-graymap',
+        'pgn' => 'application/x-chess-pgn',
+        'pgp' => 'application/pgp',
+        'phar' => 'application/octet-stream',
+        'php' => 'application/x-httpd-php',
+        'php3' => 'application/x-httpd-php',
+        'php4' => 'application/x-httpd-php',
+        'phps' => 'application/x-httpd-php-source',
+        'phtml' => 'application/x-httpd-php',
+        'pic' => 'image/x-pict',
+        'pkg' => 'application/octet-stream',
+        'pki' => 'application/pkixcmp',
+        'pkipath' => 'application/pkix-pkipath',
+        'pkpass' => 'application/vnd.apple.pkpass',
+        'pl' => 'application/x-perl',
+        'plb' => 'application/vnd.3gpp.pic-bw-large',
+        'plc' => 'application/vnd.mobius.plc',
+        'plf' => 'application/vnd.pocketlearn',
+        'pls' => 'application/pls+xml',
+        'pm' => 'application/x-perl',
+        'pml' => 'application/vnd.ctc-posml',
+        'png' => 'image/png',
+        'pnm' => 'image/x-portable-anymap',
+        'portpkg' => 'application/vnd.macports.portpkg',
+        'pot' => 'application/vnd.ms-powerpoint',
+        'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
+        'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
+        'ppa' => 'application/vnd.ms-powerpoint',
+        'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
+        'ppd' => 'application/vnd.cups-ppd',
+        'ppm' => 'image/x-portable-pixmap',
+        'pps' => 'application/vnd.ms-powerpoint',
+        'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
+        'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
+        'ppt' => 'application/powerpoint',
+        'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
+        'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+        'pqa' => 'application/vnd.palm',
+        'prc' => 'model/prc',
+        'pre' => 'application/vnd.lotus-freelance',
+        'prf' => 'application/pics-rules',
+        'provx' => 'application/provenance+xml',
+        'ps' => 'application/postscript',
+        'psb' => 'application/vnd.3gpp.pic-bw-small',
+        'psd' => 'application/x-photoshop',
+        'psf' => 'application/x-font-linux-psf',
+        'pskcxml' => 'application/pskc+xml',
+        'pti' => 'image/prs.pti',
+        'ptid' => 'application/vnd.pvi.ptid1',
+        'pub' => 'application/x-mspublisher',
+        'pvb' => 'application/vnd.3gpp.pic-bw-var',
+        'pwn' => 'application/vnd.3m.post-it-notes',
+        'pya' => 'audio/vnd.ms-playready.media.pya',
+        'pyv' => 'video/vnd.ms-playready.media.pyv',
+        'qam' => 'application/vnd.epson.quickanime',
+        'qbo' => 'application/vnd.intu.qbo',
+        'qfx' => 'application/vnd.intu.qfx',
+        'qps' => 'application/vnd.publishare-delta-tree',
+        'qt' => 'video/quicktime',
+        'qwd' => 'application/vnd.quark.quarkxpress',
+        'qwt' => 'application/vnd.quark.quarkxpress',
+        'qxb' => 'application/vnd.quark.quarkxpress',
+        'qxd' => 'application/vnd.quark.quarkxpress',
+        'qxl' => 'application/vnd.quark.quarkxpress',
+        'qxt' => 'application/vnd.quark.quarkxpress',
+        'ra' => 'audio/x-realaudio',
+        'ram' => 'audio/x-pn-realaudio',
+        'raml' => 'application/raml+yaml',
+        'rapd' => 'application/route-apd+xml',
+        'rar' => 'application/x-rar',
+        'ras' => 'image/x-cmu-raster',
+        'rcprofile' => 'application/vnd.ipunplugged.rcprofile',
+        'rdf' => 'application/rdf+xml',
+        'rdz' => 'application/vnd.data-vision.rdz',
+        'relo' => 'application/p2p-overlay+xml',
+        'rep' => 'application/vnd.businessobjects',
+        'res' => 'application/x-dtbresource+xml',
+        'rgb' => 'image/x-rgb',
+        'rif' => 'application/reginfo+xml',
+        'rip' => 'audio/vnd.rip',
+        'ris' => 'application/x-research-info-systems',
+        'rl' => 'application/resource-lists+xml',
+        'rlc' => 'image/vnd.fujixerox.edmics-rlc',
+        'rld' => 'application/resource-lists-diff+xml',
+        'rm' => 'audio/x-pn-realaudio',
+        'rmi' => 'audio/midi',
+        'rmp' => 'audio/x-pn-realaudio-plugin',
+        'rms' => 'application/vnd.jcp.javame.midlet-rms',
+        'rmvb' => 'application/vnd.rn-realmedia-vbr',
+        'rnc' => 'application/relax-ng-compact-syntax',
+        'rng' => 'application/xml',
+        'roa' => 'application/rpki-roa',
+        'roff' => 'text/troff',
+        'rp9' => 'application/vnd.cloanto.rp9',
+        'rpm' => 'audio/x-pn-realaudio-plugin',
+        'rpss' => 'application/vnd.nokia.radio-presets',
+        'rpst' => 'application/vnd.nokia.radio-preset',
+        'rq' => 'application/sparql-query',
+        'rs' => 'application/rls-services+xml',
+        'rsa' => 'application/x-pkcs7',
+        'rsat' => 'application/atsc-rsat+xml',
+        'rsd' => 'application/rsd+xml',
+        'rsheet' => 'application/urc-ressheet+xml',
+        'rss' => 'application/rss+xml',
+        'rtf' => 'text/rtf',
+        'rtx' => 'text/richtext',
+        'run' => 'application/x-makeself',
+        'rusd' => 'application/route-usd+xml',
+        'rv' => 'video/vnd.rn-realvideo',
+        's' => 'text/x-asm',
+        's3m' => 'audio/s3m',
+        'saf' => 'application/vnd.yamaha.smaf-audio',
+        'sass' => 'text/x-sass',
+        'sbml' => 'application/sbml+xml',
+        'sc' => 'application/vnd.ibm.secure-container',
+        'scd' => 'application/x-msschedule',
+        'scm' => 'application/vnd.lotus-screencam',
+        'scq' => 'application/scvp-cv-request',
+        'scs' => 'application/scvp-cv-response',
+        'scss' => 'text/x-scss',
+        'scurl' => 'text/vnd.curl.scurl',
+        'sda' => 'application/vnd.stardivision.draw',
+        'sdc' => 'application/vnd.stardivision.calc',
+        'sdd' => 'application/vnd.stardivision.impress',
+        'sdkd' => 'application/vnd.solent.sdkm+xml',
+        'sdkm' => 'application/vnd.solent.sdkm+xml',
+        'sdp' => 'application/sdp',
+        'sdw' => 'application/vnd.stardivision.writer',
+        'sea' => 'application/octet-stream',
+        'see' => 'application/vnd.seemail',
+        'seed' => 'application/vnd.fdsn.seed',
+        'sema' => 'application/vnd.sema',
+        'semd' => 'application/vnd.semd',
+        'semf' => 'application/vnd.semf',
+        'senmlx' => 'application/senml+xml',
+        'sensmlx' => 'application/sensml+xml',
+        'ser' => 'application/java-serialized-object',
+        'setpay' => 'application/set-payment-initiation',
+        'setreg' => 'application/set-registration-initiation',
+        'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data',
+        'sfs' => 'application/vnd.spotfire.sfs',
+        'sfv' => 'text/x-sfv',
+        'sgi' => 'image/sgi',
+        'sgl' => 'application/vnd.stardivision.writer-global',
+        'sgm' => 'text/sgml',
+        'sgml' => 'text/sgml',
+        'sh' => 'application/x-sh',
+        'shar' => 'application/x-shar',
+        'shex' => 'text/shex',
+        'shf' => 'application/shf+xml',
+        'shtml' => 'text/html',
+        'sid' => 'image/x-mrsid-image',
+        'sieve' => 'application/sieve',
+        'sig' => 'application/pgp-signature',
+        'sil' => 'audio/silk',
+        'silo' => 'model/mesh',
+        'sis' => 'application/vnd.symbian.install',
+        'sisx' => 'application/vnd.symbian.install',
+        'sit' => 'application/x-stuffit',
+        'sitx' => 'application/x-stuffitx',
+        'siv' => 'application/sieve',
+        'skd' => 'application/vnd.koan',
+        'skm' => 'application/vnd.koan',
+        'skp' => 'application/vnd.koan',
+        'skt' => 'application/vnd.koan',
+        'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12',
+        'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
+        'slim' => 'text/slim',
+        'slm' => 'text/slim',
+        'sls' => 'application/route-s-tsid+xml',
+        'slt' => 'application/vnd.epson.salt',
+        'sm' => 'application/vnd.stepmania.stepchart',
+        'smf' => 'application/vnd.stardivision.math',
+        'smi' => 'application/smil',
+        'smil' => 'application/smil',
+        'smv' => 'video/x-smv',
+        'smzip' => 'application/vnd.stepmania.package',
+        'snd' => 'audio/basic',
+        'snf' => 'application/x-font-snf',
+        'so' => 'application/octet-stream',
+        'spc' => 'application/x-pkcs7-certificates',
+        'spdx' => 'text/spdx',
+        'spf' => 'application/vnd.yamaha.smaf-phrase',
+        'spl' => 'application/x-futuresplash',
+        'spot' => 'text/vnd.in3d.spot',
+        'spp' => 'application/scvp-vp-response',
+        'spq' => 'application/scvp-vp-request',
+        'spx' => 'audio/ogg',
+        'sql' => 'application/x-sql',
+        'src' => 'application/x-wais-source',
+        'srt' => 'application/x-subrip',
+        'sru' => 'application/sru+xml',
+        'srx' => 'application/sparql-results+xml',
+        'ssdl' => 'application/ssdl+xml',
+        'sse' => 'application/vnd.kodak-descriptor',
+        'ssf' => 'application/vnd.epson.ssf',
+        'ssml' => 'application/ssml+xml',
+        'sst' => 'application/octet-stream',
+        'st' => 'application/vnd.sailingtracker.track',
+        'stc' => 'application/vnd.sun.xml.calc.template',
+        'std' => 'application/vnd.sun.xml.draw.template',
+        'stf' => 'application/vnd.wt.stf',
+        'sti' => 'application/vnd.sun.xml.impress.template',
+        'stk' => 'application/hyperstudio',
+        'stl' => 'model/stl',
+        'stpx' => 'model/step+xml',
+        'stpxz' => 'model/step-xml+zip',
+        'stpz' => 'model/step+zip',
+        'str' => 'application/vnd.pg.format',
+        'stw' => 'application/vnd.sun.xml.writer.template',
+        'styl' => 'text/stylus',
+        'stylus' => 'text/stylus',
+        'sub' => 'text/vnd.dvb.subtitle',
+        'sus' => 'application/vnd.sus-calendar',
+        'susp' => 'application/vnd.sus-calendar',
+        'sv4cpio' => 'application/x-sv4cpio',
+        'sv4crc' => 'application/x-sv4crc',
+        'svc' => 'application/vnd.dvb.service',
+        'svd' => 'application/vnd.svd',
+        'svg' => 'image/svg+xml',
+        'svgz' => 'image/svg+xml',
+        'swa' => 'application/x-director',
+        'swf' => 'application/x-shockwave-flash',
+        'swi' => 'application/vnd.aristanetworks.swi',
+        'swidtag' => 'application/swid+xml',
+        'sxc' => 'application/vnd.sun.xml.calc',
+        'sxd' => 'application/vnd.sun.xml.draw',
+        'sxg' => 'application/vnd.sun.xml.writer.global',
+        'sxi' => 'application/vnd.sun.xml.impress',
+        'sxm' => 'application/vnd.sun.xml.math',
+        'sxw' => 'application/vnd.sun.xml.writer',
+        't' => 'text/troff',
+        't3' => 'application/x-t3vm-image',
+        't38' => 'image/t38',
+        'taglet' => 'application/vnd.mynfc',
+        'tao' => 'application/vnd.tao.intent-module-archive',
+        'tap' => 'image/vnd.tencent.tap',
+        'tar' => 'application/x-tar',
+        'tcap' => 'application/vnd.3gpp2.tcap',
+        'tcl' => 'application/x-tcl',
+        'td' => 'application/urc-targetdesc+xml',
+        'teacher' => 'application/vnd.smart.teacher',
+        'tei' => 'application/tei+xml',
+        'teicorpus' => 'application/tei+xml',
+        'tex' => 'application/x-tex',
+        'texi' => 'application/x-texinfo',
+        'texinfo' => 'application/x-texinfo',
+        'text' => 'text/plain',
+        'tfi' => 'application/thraud+xml',
+        'tfm' => 'application/x-tex-tfm',
+        'tfx' => 'image/tiff-fx',
+        'tga' => 'image/x-tga',
+        'tgz' => 'application/x-tar',
+        'thmx' => 'application/vnd.ms-officetheme',
+        'tif' => 'image/tiff',
+        'tiff' => 'image/tiff',
+        'tk' => 'application/x-tcl',
+        'tmo' => 'application/vnd.tmobile-livetv',
+        'toml' => 'application/toml',
+        'torrent' => 'application/x-bittorrent',
+        'tpl' => 'application/vnd.groove-tool-template',
+        'tpt' => 'application/vnd.trid.tpt',
+        'tr' => 'text/troff',
+        'tra' => 'application/vnd.trueapp',
+        'trig' => 'application/trig',
+        'trm' => 'application/x-msterminal',
+        'ts' => 'video/mp2t',
+        'tsd' => 'application/timestamped-data',
+        'tsv' => 'text/tab-separated-values',
+        'ttc' => 'font/collection',
+        'ttf' => 'font/ttf',
+        'ttl' => 'text/turtle',
+        'ttml' => 'application/ttml+xml',
+        'twd' => 'application/vnd.simtech-mindmapper',
+        'twds' => 'application/vnd.simtech-mindmapper',
+        'txd' => 'application/vnd.genomatix.tuxedo',
+        'txf' => 'application/vnd.mobius.txf',
+        'txt' => 'text/plain',
+        'u3d' => 'model/u3d',
+        'u8dsn' => 'message/global-delivery-status',
+        'u8hdr' => 'message/global-headers',
+        'u8mdn' => 'message/global-disposition-notification',
+        'u8msg' => 'message/global',
+        'u32' => 'application/x-authorware-bin',
+        'ubj' => 'application/ubjson',
+        'udeb' => 'application/x-debian-package',
+        'ufd' => 'application/vnd.ufdl',
+        'ufdl' => 'application/vnd.ufdl',
+        'ulx' => 'application/x-glulx',
+        'umj' => 'application/vnd.umajin',
+        'unityweb' => 'application/vnd.unity',
+        'uoml' => 'application/vnd.uoml+xml',
+        'uri' => 'text/uri-list',
+        'uris' => 'text/uri-list',
+        'urls' => 'text/uri-list',
+        'usdz' => 'model/vnd.usdz+zip',
+        'ustar' => 'application/x-ustar',
+        'utz' => 'application/vnd.uiq.theme',
+        'uu' => 'text/x-uuencode',
+        'uva' => 'audio/vnd.dece.audio',
+        'uvd' => 'application/vnd.dece.data',
+        'uvf' => 'application/vnd.dece.data',
+        'uvg' => 'image/vnd.dece.graphic',
+        'uvh' => 'video/vnd.dece.hd',
+        'uvi' => 'image/vnd.dece.graphic',
+        'uvm' => 'video/vnd.dece.mobile',
+        'uvp' => 'video/vnd.dece.pd',
+        'uvs' => 'video/vnd.dece.sd',
+        'uvt' => 'application/vnd.dece.ttml+xml',
+        'uvu' => 'video/vnd.uvvu.mp4',
+        'uvv' => 'video/vnd.dece.video',
+        'uvva' => 'audio/vnd.dece.audio',
+        'uvvd' => 'application/vnd.dece.data',
+        'uvvf' => 'application/vnd.dece.data',
+        'uvvg' => 'image/vnd.dece.graphic',
+        'uvvh' => 'video/vnd.dece.hd',
+        'uvvi' => 'image/vnd.dece.graphic',
+        'uvvm' => 'video/vnd.dece.mobile',
+        'uvvp' => 'video/vnd.dece.pd',
+        'uvvs' => 'video/vnd.dece.sd',
+        'uvvt' => 'application/vnd.dece.ttml+xml',
+        'uvvu' => 'video/vnd.uvvu.mp4',
+        'uvvv' => 'video/vnd.dece.video',
+        'uvvx' => 'application/vnd.dece.unspecified',
+        'uvvz' => 'application/vnd.dece.zip',
+        'uvx' => 'application/vnd.dece.unspecified',
+        'uvz' => 'application/vnd.dece.zip',
+        'vbox' => 'application/x-virtualbox-vbox',
+        'vbox-extpack' => 'application/x-virtualbox-vbox-extpack',
+        'vcard' => 'text/vcard',
+        'vcd' => 'application/x-cdlink',
+        'vcf' => 'text/x-vcard',
+        'vcg' => 'application/vnd.groove-vcard',
+        'vcs' => 'text/x-vcalendar',
+        'vcx' => 'application/vnd.vcx',
+        'vdi' => 'application/x-virtualbox-vdi',
+        'vds' => 'model/vnd.sap.vds',
+        'vhd' => 'application/x-virtualbox-vhd',
+        'vis' => 'application/vnd.visionary',
+        'viv' => 'video/vnd.vivo',
+        'vlc' => 'application/videolan',
+        'vmdk' => 'application/x-virtualbox-vmdk',
+        'vob' => 'video/x-ms-vob',
+        'vor' => 'application/vnd.stardivision.writer',
+        'vox' => 'application/x-authorware-bin',
+        'vrml' => 'model/vrml',
+        'vsd' => 'application/vnd.visio',
+        'vsf' => 'application/vnd.vsf',
+        'vss' => 'application/vnd.visio',
+        'vst' => 'application/vnd.visio',
+        'vsw' => 'application/vnd.visio',
+        'vtf' => 'image/vnd.valve.source.texture',
+        'vtt' => 'text/vtt',
+        'vtu' => 'model/vnd.vtu',
+        'vxml' => 'application/voicexml+xml',
+        'w3d' => 'application/x-director',
+        'wad' => 'application/x-doom',
+        'wadl' => 'application/vnd.sun.wadl+xml',
+        'war' => 'application/java-archive',
+        'wasm' => 'application/wasm',
+        'wav' => 'audio/x-wav',
+        'wax' => 'audio/x-ms-wax',
+        'wbmp' => 'image/vnd.wap.wbmp',
+        'wbs' => 'application/vnd.criticaltools.wbs+xml',
+        'wbxml' => 'application/wbxml',
+        'wcm' => 'application/vnd.ms-works',
+        'wdb' => 'application/vnd.ms-works',
+        'wdp' => 'image/vnd.ms-photo',
+        'weba' => 'audio/webm',
+        'webapp' => 'application/x-web-app-manifest+json',
+        'webm' => 'video/webm',
+        'webmanifest' => 'application/manifest+json',
+        'webp' => 'image/webp',
+        'wg' => 'application/vnd.pmi.widget',
+        'wgt' => 'application/widget',
+        'wif' => 'application/watcherinfo+xml',
+        'wks' => 'application/vnd.ms-works',
+        'wm' => 'video/x-ms-wm',
+        'wma' => 'audio/x-ms-wma',
+        'wmd' => 'application/x-ms-wmd',
+        'wmf' => 'image/wmf',
+        'wml' => 'text/vnd.wap.wml',
+        'wmlc' => 'application/wmlc',
+        'wmls' => 'text/vnd.wap.wmlscript',
+        'wmlsc' => 'application/vnd.wap.wmlscriptc',
+        'wmv' => 'video/x-ms-wmv',
+        'wmx' => 'video/x-ms-wmx',
+        'wmz' => 'application/x-msmetafile',
+        'woff' => 'font/woff',
+        'woff2' => 'font/woff2',
+        'word' => 'application/msword',
+        'wpd' => 'application/vnd.wordperfect',
+        'wpl' => 'application/vnd.ms-wpl',
+        'wps' => 'application/vnd.ms-works',
+        'wqd' => 'application/vnd.wqd',
+        'wri' => 'application/x-mswrite',
+        'wrl' => 'model/vrml',
+        'wsc' => 'message/vnd.wfa.wsc',
+        'wsdl' => 'application/wsdl+xml',
+        'wspolicy' => 'application/wspolicy+xml',
+        'wtb' => 'application/vnd.webturbo',
+        'wvx' => 'video/x-ms-wvx',
+        'x3d' => 'model/x3d+xml',
+        'x3db' => 'model/x3d+fastinfoset',
+        'x3dbz' => 'model/x3d+binary',
+        'x3dv' => 'model/x3d-vrml',
+        'x3dvz' => 'model/x3d+vrml',
+        'x3dz' => 'model/x3d+xml',
+        'x32' => 'application/x-authorware-bin',
+        'x_b' => 'model/vnd.parasolid.transmit.binary',
+        'x_t' => 'model/vnd.parasolid.transmit.text',
+        'xaml' => 'application/xaml+xml',
+        'xap' => 'application/x-silverlight-app',
+        'xar' => 'application/vnd.xara',
+        'xav' => 'application/xcap-att+xml',
+        'xbap' => 'application/x-ms-xbap',
+        'xbd' => 'application/vnd.fujixerox.docuworks.binder',
+        'xbm' => 'image/x-xbitmap',
+        'xca' => 'application/xcap-caps+xml',
+        'xcs' => 'application/calendar+xml',
+        'xdf' => 'application/xcap-diff+xml',
+        'xdm' => 'application/vnd.syncml.dm+xml',
+        'xdp' => 'application/vnd.adobe.xdp+xml',
+        'xdssc' => 'application/dssc+xml',
+        'xdw' => 'application/vnd.fujixerox.docuworks',
+        'xel' => 'application/xcap-el+xml',
+        'xenc' => 'application/xenc+xml',
+        'xer' => 'application/patch-ops-error+xml',
+        'xfdf' => 'application/vnd.adobe.xfdf',
+        'xfdl' => 'application/vnd.xfdl',
+        'xht' => 'application/xhtml+xml',
+        'xhtml' => 'application/xhtml+xml',
+        'xhvml' => 'application/xv+xml',
+        'xif' => 'image/vnd.xiff',
+        'xl' => 'application/excel',
+        'xla' => 'application/vnd.ms-excel',
+        'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
+        'xlc' => 'application/vnd.ms-excel',
+        'xlf' => 'application/xliff+xml',
+        'xlm' => 'application/vnd.ms-excel',
+        'xls' => 'application/vnd.ms-excel',
+        'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
+        'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
+        'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+        'xlt' => 'application/vnd.ms-excel',
+        'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
+        'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
+        'xlw' => 'application/vnd.ms-excel',
+        'xm' => 'audio/xm',
+        'xml' => 'application/xml',
+        'xns' => 'application/xcap-ns+xml',
+        'xo' => 'application/vnd.olpc-sugar',
+        'xop' => 'application/xop+xml',
+        'xpi' => 'application/x-xpinstall',
+        'xpl' => 'application/xproc+xml',
+        'xpm' => 'image/x-xpixmap',
+        'xpr' => 'application/vnd.is-xpr',
+        'xps' => 'application/vnd.ms-xpsdocument',
+        'xpw' => 'application/vnd.intercon.formnet',
+        'xpx' => 'application/vnd.intercon.formnet',
+        'xsd' => 'application/xml',
+        'xsl' => 'application/xml',
+        'xslt' => 'application/xslt+xml',
+        'xsm' => 'application/vnd.syncml+xml',
+        'xspf' => 'application/xspf+xml',
+        'xul' => 'application/vnd.mozilla.xul+xml',
+        'xvm' => 'application/xv+xml',
+        'xvml' => 'application/xv+xml',
+        'xwd' => 'image/x-xwindowdump',
+        'xyz' => 'chemical/x-xyz',
+        'xz' => 'application/x-xz',
+        'yaml' => 'text/yaml',
+        'yang' => 'application/yang',
+        'yin' => 'application/yin+xml',
+        'yml' => 'text/yaml',
+        'ymp' => 'text/x-suse-ymp',
+        'z' => 'application/x-compress',
+        'z1' => 'application/x-zmachine',
+        'z2' => 'application/x-zmachine',
+        'z3' => 'application/x-zmachine',
+        'z4' => 'application/x-zmachine',
+        'z5' => 'application/x-zmachine',
+        'z6' => 'application/x-zmachine',
+        'z7' => 'application/x-zmachine',
+        'z8' => 'application/x-zmachine',
+        'zaz' => 'application/vnd.zzazz.deck+xml',
+        'zip' => 'application/zip',
+        'zir' => 'application/vnd.zul',
+        'zirz' => 'application/vnd.zul',
+        'zmm' => 'application/vnd.handheld-entertainment+xml',
+        'zsh' => 'text/x-scriptzsh',
+    ];
+
+    public function lookupMimeType(string $extension): ?string
+    {
+        return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null;
+    }
+}
diff --git a/msd/vendor/league/mime-type-detection/src/MimeTypeDetector.php b/msd/vendor/league/mime-type-detection/src/MimeTypeDetector.php
new file mode 100644
index 00000000..5d799d2a
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/MimeTypeDetector.php
@@ -0,0 +1,19 @@
+<?php
+
+declare(strict_types=1);
+
+namespace League\MimeTypeDetection;
+
+interface MimeTypeDetector
+{
+    /**
+     * @param string|resource $contents
+     */
+    public function detectMimeType(string $path, $contents): ?string;
+
+    public function detectMimeTypeFromBuffer(string $contents): ?string;
+
+    public function detectMimeTypeFromPath(string $path): ?string;
+
+    public function detectMimeTypeFromFile(string $path): ?string;
+}
diff --git a/msd/vendor/league/mime-type-detection/src/OverridingExtensionToMimeTypeMap.php b/msd/vendor/league/mime-type-detection/src/OverridingExtensionToMimeTypeMap.php
new file mode 100644
index 00000000..0c71e4d5
--- /dev/null
+++ b/msd/vendor/league/mime-type-detection/src/OverridingExtensionToMimeTypeMap.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace League\MimeTypeDetection;
+
+class OverridingExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
+{
+    /**
+     * @var ExtensionToMimeTypeMap
+     */
+    private $innerMap;
+
+    /**
+     * @var string[]
+     */
+    private $overrides;
+
+    /**
+     * @param array<string, string>  $overrides
+     */
+    public function __construct(ExtensionToMimeTypeMap $innerMap, array $overrides)
+    {
+        $this->innerMap = $innerMap;
+        $this->overrides = $overrides;
+    }
+
+    public function lookupMimeType(string $extension): ?string
+    {
+        return $this->overrides[$extension] ?? $this->innerMap->lookupMimeType($extension);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/CHANGELOG.md b/msd/vendor/monolog/monolog/CHANGELOG.md
new file mode 100644
index 00000000..7f9db2b0
--- /dev/null
+++ b/msd/vendor/monolog/monolog/CHANGELOG.md
@@ -0,0 +1,608 @@
+### 2.8.0 (2022-07-24)
+
+  * Deprecated `CubeHandler` and `PHPConsoleHandler` as both projects are abandoned and those should not be used anymore (#1734)
+  * Added RFC 5424 level (`7` to `0`) support to `Logger::log` and `Logger::addRecord` to increase interoperability (#1723)
+  * Added support for `__toString` for objects which are not json serializable in `JsonFormatter` (#1733)
+  * Added `GoogleCloudLoggingFormatter` (#1719)
+  * Added support for Predis 2.x (#1732)
+  * Added `AmqpHandler->setExtraAttributes` to allow configuring attributes when using an AMQPExchange (#1724)
+  * Fixed serialization/unserialization of handlers to make sure private properties are included (#1727)
+  * Fixed allowInlineLineBreaks in LineFormatter causing issues with windows paths containing `\n` or `\r` sequences (#1720)
+  * Fixed max normalization depth not being taken into account when formatting exceptions with a deep chain of previous exceptions (#1726)
+  * Fixed PHP 8.2 deprecation warnings (#1722)
+  * Fixed rare race condition or filesystem issue where StreamHandler is unable to create the directory the log should go into yet it exists already (#1678)
+
+### 2.7.0 (2022-06-09)
+
+  * Added `$datetime` parameter to `Logger::addRecord` as low level API to allow logging into the past or future (#1682)
+  * Added `Logger::useLoggingLoopDetection` to allow disabling cyclic logging detection in concurrent frameworks (#1681)
+  * Fixed handling of fatal errors if callPrevious is disabled in ErrorHandler (#1670)
+  * Marked the reusable `Monolog\Test\TestCase` class as `@internal` to make sure PHPStorm does not show it above PHPUnit, you may still use it to test your own handlers/etc though (#1677)
+  * Fixed RotatingFileHandler issue when the date format contained slashes (#1671)
+
+### 2.6.0 (2022-05-10)
+
+  * Deprecated `SwiftMailerHandler`, use `SymfonyMailerHandler` instead
+  * Added `SymfonyMailerHandler` (#1663)
+  * Added ElasticSearch 8.x support to the ElasticsearchHandler (#1662)
+  * Added a way to filter/modify stack traces in LineFormatter (#1665)
+  * Fixed UdpSocket not being able to reopen/reconnect after close()
+  * Fixed infinite loops if a Handler is triggering logging while handling log records
+
+### 2.5.0 (2022-04-08)
+
+  * Added `callType` to IntrospectionProcessor (#1612)
+  * Fixed AsMonologProcessor syntax to be compatible with PHP 7.2 (#1651)
+
+### 2.4.0 (2022-03-14)
+
+  * Added [`Monolog\LogRecord`](src/Monolog/LogRecord.php) interface that can be used to type-hint records like `array|\Monolog\LogRecord $record` to be forward compatible with the upcoming Monolog 3 changes
+  * Added `includeStacktraces` constructor params to LineFormatter & JsonFormatter (#1603)
+  * Added `persistent`, `timeout`, `writingTimeout`, `connectionTimeout`, `chunkSize` constructor params to SocketHandler and derivatives (#1600)
+  * Added `AsMonologProcessor` PHP attribute which can help autowiring / autoconfiguration of processors if frameworks / integrations decide to make use of it. This is useless when used purely with Monolog (#1637)
+  * Added support for keeping native BSON types as is in MongoDBFormatter (#1620)
+  * Added support for a `user_agent` key in WebProcessor, disabled by default but you can use it by configuring the $extraFields you want (#1613)
+  * Added support for username/userIcon in SlackWebhookHandler (#1617)
+  * Added extension points to BrowserConsoleHandler (#1593)
+  * Added record message/context/extra info to exceptions thrown when a StreamHandler cannot open its stream to avoid completely losing the data logged (#1630)
+  * Fixed error handler signature to accept a null $context which happens with internal PHP errors (#1614)
+  * Fixed a few setter methods not returning `self` (#1609)
+  * Fixed handling of records going over the max Telegram message length (#1616)
+
+### 2.3.5 (2021-10-01)
+
+  * Fixed regression in StreamHandler since 2.3.3 on systems with the memory_limit set to >=20GB (#1592)
+
+### 2.3.4 (2021-09-15)
+
+  * Fixed support for psr/log 3.x (#1589)
+
+### 2.3.3 (2021-09-14)
+
+  * Fixed memory usage when using StreamHandler and calling stream_get_contents on the resource you passed to it (#1578, #1577)
+  * Fixed support for psr/log 2.x (#1587)
+  * Fixed some type annotations
+
+### 2.3.2 (2021-07-23)
+
+  * Fixed compatibility with PHP 7.2 - 7.4 when experiencing PCRE errors (#1568)
+
+### 2.3.1 (2021-07-14)
+
+  * Fixed Utils::getClass handling of anonymous classes not being fully compatible with PHP 8 (#1563)
+  * Fixed some `@inheritDoc` annotations having the wrong case
+
+### 2.3.0 (2021-07-05)
+
+  * Added a ton of PHPStan type annotations as well as type aliases on Monolog\Logger for Record, Level and LevelName that you can import (#1557)
+  * Added ability to customize date format when using JsonFormatter (#1561)
+  * Fixed FilterHandler not calling reset on its internal handler when reset() is called on it (#1531)
+  * Fixed SyslogUdpHandler not setting the timezone correctly on DateTimeImmutable instances (#1540)
+  * Fixed StreamHandler thread safety - chunk size set to 2GB now to avoid interlacing when doing concurrent writes (#1553)
+
+### 2.2.0 (2020-12-14)
+
+  * Added JSON_PARTIAL_OUTPUT_ON_ERROR to default json encoding flags, to avoid dropping entire context data or even records due to an invalid subset of it somewhere
+  * Added setDateFormat to NormalizerFormatter (and Line/Json formatters by extension) to allow changing this after object creation
+  * Added RedisPubSubHandler to log records to a Redis channel using PUBLISH
+  * Added support for Elastica 7, and deprecated the $type argument of ElasticaFormatter which is not in use anymore as of Elastica 7
+  * Added support for millisecond write timeouts in SocketHandler, you can now pass floats to setWritingTimeout, e.g. 0.2 is 200ms
+  * Added support for unix sockets in SyslogUdpHandler (set $port to 0 to make the $host a unix socket)
+  * Added handleBatch support for TelegramBotHandler
+  * Added RFC5424e extended date format including milliseconds to SyslogUdpHandler
+  * Added support for configuring handlers with numeric level values in strings (coming from e.g. env vars)
+  * Fixed Wildfire/FirePHP/ChromePHP handling of unicode characters
+  * Fixed PHP 8 issues in SyslogUdpHandler
+  * Fixed internal type error when mbstring is missing
+
+### 2.1.1 (2020-07-23)
+
+  * Fixed removing of json encoding options
+  * Fixed type hint of $level not accepting strings in SendGridHandler and OverflowHandler
+  * Fixed SwiftMailerHandler not accepting email templates with an empty subject
+  * Fixed array access on null in RavenHandler
+  * Fixed unique_id in WebProcessor not being disableable
+
+### 2.1.0 (2020-05-22)
+
+  * Added `JSON_INVALID_UTF8_SUBSTITUTE` to default json flags, so that invalid UTF8 characters now get converted to [�](https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character) instead of being converted from ISO-8859-15 to UTF8 as it was before, which was hardly a comprehensive solution
+  * Added `$ignoreEmptyContextAndExtra` option to JsonFormatter to skip empty context/extra entirely from the output
+  * Added `$parseMode`, `$disableWebPagePreview` and `$disableNotification` options to TelegramBotHandler
+  * Added tentative support for PHP 8
+  * NormalizerFormatter::addJsonEncodeOption and removeJsonEncodeOption are now public to allow modifying default json flags
+  * Fixed GitProcessor type error when there is no git repo present
+  * Fixed normalization of SoapFault objects containing deeply nested objects as "detail"
+  * Fixed support for relative paths in RotatingFileHandler
+
+### 2.0.2 (2019-12-20)
+
+  * Fixed ElasticsearchHandler swallowing exceptions details when failing to index log records
+  * Fixed normalization of SoapFault objects containing non-strings as "detail" in LineFormatter
+  * Fixed formatting of resources in JsonFormatter
+  * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services)
+  * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it
+  * Fixed Turkish locale messing up the conversion of level names to their constant values
+
+### 2.0.1 (2019-11-13)
+
+  * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable
+  * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler, OverflowHandler and SamplingHandler
+  * Fixed BrowserConsoleHandler formatting when using multiple styles
+  * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings
+  * Fixed normalization of SoapFault objects containing non-strings as "detail"
+  * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding
+  * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB).
+  * Fixed type error in BrowserConsoleHandler when the context array of log records was not associative.
+
+### 2.0.0 (2019-08-30)
+
+  * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release
+  * BC Break: Logger methods log/debug/info/notice/warning/error/critical/alert/emergency now have explicit void return types
+  * Added FallbackGroupHandler which works like the WhatFailureGroupHandler but stops dispatching log records as soon as one handler accepted it
+  * Fixed support for UTF-8 when cutting strings to avoid cutting a multibyte-character in half
+  * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases
+  * Fixed date timezone handling in SyslogUdpHandler
+
+### 2.0.0-beta2 (2019-07-06)
+
+  * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release
+  * BC Break: PHP 7.2 is now the minimum required PHP version.
+  * BC Break: Removed SlackbotHandler, RavenHandler and HipChatHandler, see [UPGRADE.md](UPGRADE.md) for details
+  * Added OverflowHandler which will only flush log records to its nested handler when reaching a certain amount of logs (i.e. only pass through when things go really bad)
+  * Added TelegramBotHandler to log records to a [Telegram](https://core.telegram.org/bots/api) bot account
+  * Added support for JsonSerializable when normalizing exceptions
+  * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler
+  * Added SoapFault details to formatted exceptions
+  * Fixed DeduplicationHandler silently failing to start when file could not be opened
+  * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records
+  * Fixed GelfFormatter losing some data when one attachment was too long
+  * Fixed issue in SignalHandler restarting syscalls functionality
+  * Improved performance of LogglyHandler when sending multiple logs in a single request
+
+### 2.0.0-beta1 (2018-12-08)
+
+  * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release
+  * BC Break: PHP 7.1 is now the minimum required PHP version.
+  * BC Break: Quite a few interface changes, only relevant if you implemented your own handlers/processors/formatters
+  * BC Break: Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`) methods as well as `emerg`, `crit`, `err` and `warn`
+  * BC Break: The record timezone is now set per Logger instance and not statically anymore
+  * BC Break: There is no more default handler configured on empty Logger instances
+  * BC Break: ElasticSearchHandler renamed to ElasticaHandler
+  * BC Break: Various handler-specific breaks, see [UPGRADE.md](UPGRADE.md) for details
+  * Added scalar type hints and return hints in all the places it was possible. Switched strict_types on for more reliability.
+  * Added DateTimeImmutable support, all record datetime are now immutable, and will toString/json serialize with the correct date format, including microseconds (unless disabled)
+  * Added timezone and microseconds to the default date format
+  * Added SendGridHandler to use the SendGrid API to send emails
+  * Added LogmaticHandler to use the Logmatic.io API to store log records
+  * Added SqsHandler to send log records to an AWS SQS queue
+  * Added ElasticsearchHandler to send records via the official ES library. Elastica users should now use ElasticaHandler instead of ElasticSearchHandler
+  * Added NoopHandler which is similar to the NullHandle but does not prevent the bubbling of log records to handlers further down the configuration, useful for temporarily disabling a handler in configuration files
+  * Added ProcessHandler to write log output to the STDIN of a given process
+  * Added HostnameProcessor that adds the machine's hostname to log records
+  * Added a `$dateFormat` option to the PsrLogMessageProcessor which lets you format DateTime instances nicely
+  * Added support for the PHP 7.x `mongodb` extension in the MongoDBHandler
+  * Fixed many minor issues in various handlers, and probably added a few regressions too
+
+### 1.26.1 (2021-05-28)
+
+  * Fixed PHP 8.1 deprecation warning
+
+### 1.26.0 (2020-12-14)
+
+  * Added $dateFormat and $removeUsedContextFields arguments to PsrLogMessageProcessor (backport from 2.x)
+
+### 1.25.5 (2020-07-23)
+
+  * Fixed array access on null in RavenHandler
+  * Fixed unique_id in WebProcessor not being disableable
+
+### 1.25.4 (2020-05-22)
+
+  * Fixed GitProcessor type error when there is no git repo present
+  * Fixed normalization of SoapFault objects containing deeply nested objects as "detail"
+  * Fixed support for relative paths in RotatingFileHandler
+
+### 1.25.3 (2019-12-20)
+
+  * Fixed formatting of resources in JsonFormatter
+  * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services)
+  * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it
+  * Fixed Turkish locale messing up the conversion of level names to their constant values
+
+### 1.25.2 (2019-11-13)
+
+  * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable
+  * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler and SamplingHandler
+  * Fixed BrowserConsoleHandler formatting when using multiple styles
+  * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings
+  * Fixed normalization of SoapFault objects containing non-strings as "detail"
+  * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding
+
+### 1.25.1 (2019-09-06)
+
+  * Fixed forward-compatible interfaces to be compatible with Monolog 1.x too.
+
+### 1.25.0 (2019-09-06)
+
+  * Deprecated SlackbotHandler, use SlackWebhookHandler or SlackHandler instead
+  * Deprecated RavenHandler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead
+  * Deprecated HipChatHandler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead
+  * Added forward-compatible interfaces and traits FormattableHandlerInterface, FormattableHandlerTrait, ProcessableHandlerInterface, ProcessableHandlerTrait. If you use modern PHP and want to make code compatible with Monolog 1 and 2 this can help. You will have to require at least Monolog 1.25 though.
+  * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler
+  * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records
+  * Fixed issue in SignalHandler restarting syscalls functionality
+  * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases
+  * Fixed ZendMonitorHandler to work with the latest Zend Server versions
+  * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB).
+
+### 1.24.0 (2018-11-05)
+
+  * BC Notice: If you are extending any of the Monolog's Formatters' `normalize` method, make sure you add the new `$depth = 0` argument to your function signature to avoid strict PHP warnings.
+  * Added a `ResettableInterface` in order to reset/reset/clear/flush handlers and processors
+  * Added a `ProcessorInterface` as an optional way to label a class as being a processor (mostly useful for autowiring dependency containers)
+  * Added a way to log signals being received using Monolog\SignalHandler
+  * Added ability to customize error handling at the Logger level using Logger::setExceptionHandler
+  * Added InsightOpsHandler to migrate users of the LogEntriesHandler
+  * Added protection to NormalizerFormatter against circular and very deep structures, it now stops normalizing at a depth of 9
+  * Added capture of stack traces to ErrorHandler when logging PHP errors
+  * Added RavenHandler support for a `contexts` context or extra key to forward that to Sentry's contexts
+  * Added forwarding of context info to FluentdFormatter
+  * Added SocketHandler::setChunkSize to override the default chunk size in case you must send large log lines to rsyslog for example
+  * Added ability to extend/override BrowserConsoleHandler
+  * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility
+  * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility
+  * Dropped official support for HHVM in test builds
+  * Fixed normalization of exception traces when call_user_func is used to avoid serializing objects and the data they contain
+  * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases
+  * Fixed HipChatHandler bug where slack dropped messages randomly
+  * Fixed normalization of objects in Slack handlers
+  * Fixed support for PHP7's Throwable in NewRelicHandler
+  * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory
+  * Fixed table row styling issues in HtmlFormatter
+  * Fixed RavenHandler dropping the message when logging exception
+  * Fixed WhatFailureGroupHandler skipping processors when using handleBatch
+    and implement it where possible
+  * Fixed display of anonymous class names
+
+### 1.23.0 (2017-06-19)
+
+  * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument
+  * Fixed GelfHandler truncation to be per field and not per message
+  * Fixed compatibility issue with PHP <5.3.6
+  * Fixed support for headless Chrome in ChromePHPHandler
+  * Fixed support for latest Aws SDK in DynamoDbHandler
+  * Fixed support for SwiftMailer 6.0+ in SwiftMailerHandler
+
+### 1.22.1 (2017-03-13)
+
+  * Fixed lots of minor issues in the new Slack integrations
+  * Fixed support for allowInlineLineBreaks in LineFormatter when formatting exception backtraces
+
+### 1.22.0 (2016-11-26)
+
+  * Added SlackbotHandler and SlackWebhookHandler to set up Slack integration more easily
+  * Added MercurialProcessor to add mercurial revision and branch names to log records
+  * Added support for AWS SDK v3 in DynamoDbHandler
+  * Fixed fatal errors occurring when normalizing generators that have been fully consumed
+  * Fixed RollbarHandler to include a level (rollbar level), monolog_level (original name), channel and datetime (unix)
+  * Fixed RollbarHandler not flushing records automatically, calling close() explicitly is not necessary anymore
+  * Fixed SyslogUdpHandler to avoid sending empty frames
+  * Fixed a few PHP 7.0 and 7.1 compatibility issues
+
+### 1.21.0 (2016-07-29)
+
+  * Break: Reverted the addition of $context when the ErrorHandler handles regular php errors from 1.20.0 as it was causing issues
+  * Added support for more formats in RotatingFileHandler::setFilenameFormat as long as they have Y, m and d in order
+  * Added ability to format the main line of text the SlackHandler sends by explicitly setting a formatter on the handler
+  * Added information about SoapFault instances in NormalizerFormatter
+  * Added $handleOnlyReportedErrors option on ErrorHandler::registerErrorHandler (default true) to allow logging of all errors no matter the error_reporting level
+
+### 1.20.0 (2016-07-02)
+
+  * Added FingersCrossedHandler::activate() to manually trigger the handler regardless of the activation policy
+  * Added StreamHandler::getUrl to retrieve the stream's URL
+  * Added ability to override addRow/addTitle in HtmlFormatter
+  * Added the $context to context information when the ErrorHandler handles a regular php error
+  * Deprecated RotatingFileHandler::setFilenameFormat to only support 3 formats: Y, Y-m and Y-m-d
+  * Fixed WhatFailureGroupHandler to work with PHP7 throwables
+  * Fixed a few minor bugs
+
+### 1.19.0 (2016-04-12)
+
+  * Break: StreamHandler will not close streams automatically that it does not own. If you pass in a stream (not a path/url), then it will not close it for you. You can retrieve those using getStream() if needed
+  * Added DeduplicationHandler to remove duplicate records from notifications across multiple requests, useful for email or other notifications on errors
+  * Added ability to use `%message%` and other LineFormatter replacements in the subject line of emails sent with NativeMailHandler and SwiftMailerHandler
+  * Fixed HipChatHandler handling of long messages
+
+### 1.18.2 (2016-04-02)
+
+  * Fixed ElasticaFormatter to use more precise dates
+  * Fixed GelfMessageFormatter sending too long messages
+
+### 1.18.1 (2016-03-13)
+
+  * Fixed SlackHandler bug where slack dropped messages randomly
+  * Fixed RedisHandler issue when using with the PHPRedis extension
+  * Fixed AmqpHandler content-type being incorrectly set when using with the AMQP extension
+  * Fixed BrowserConsoleHandler regression
+
+### 1.18.0 (2016-03-01)
+
+  * Added optional reduction of timestamp precision via `Logger->useMicrosecondTimestamps(false)`, disabling it gets you a bit of performance boost but reduces the precision to the second instead of microsecond
+  * Added possibility to skip some extra stack frames in IntrospectionProcessor if you have some library wrapping Monolog that is always adding frames
+  * Added `Logger->withName` to clone a logger (keeping all handlers) with a new name
+  * Added FluentdFormatter for the Fluentd unix socket protocol
+  * Added HandlerWrapper base class to ease the creation of handler wrappers, just extend it and override as needed
+  * Added support for replacing context sub-keys using `%context.*%` in LineFormatter
+  * Added support for `payload` context value in RollbarHandler
+  * Added setRelease to RavenHandler to describe the application version, sent with every log
+  * Added support for `fingerprint` context value in RavenHandler
+  * Fixed JSON encoding errors that would gobble up the whole log record, we now handle those more gracefully by dropping chars as needed
+  * Fixed write timeouts in SocketHandler and derivatives, set to 10sec by default, lower it with `setWritingTimeout()`
+  * Fixed PHP7 compatibility with regard to Exception/Throwable handling in a few places
+
+### 1.17.2 (2015-10-14)
+
+  * Fixed ErrorHandler compatibility with non-Monolog PSR-3 loggers
+  * Fixed SlackHandler handling to use slack functionalities better
+  * Fixed SwiftMailerHandler bug when sending multiple emails they all had the same id
+  * Fixed 5.3 compatibility regression
+
+### 1.17.1 (2015-08-31)
+
+  * Fixed RollbarHandler triggering PHP notices
+
+### 1.17.0 (2015-08-30)
+
+  * Added support for `checksum` and `release` context/extra values in RavenHandler
+  * Added better support for exceptions in RollbarHandler
+  * Added UidProcessor::getUid
+  * Added support for showing the resource type in NormalizedFormatter
+  * Fixed IntrospectionProcessor triggering PHP notices
+
+### 1.16.0 (2015-08-09)
+
+  * Added IFTTTHandler to notify ifttt.com triggers
+  * Added Logger::setHandlers() to allow setting/replacing all handlers
+  * Added $capSize in RedisHandler to cap the log size
+  * Fixed StreamHandler creation of directory to only trigger when the first log write happens
+  * Fixed bug in the handling of curl failures
+  * Fixed duplicate logging of fatal errors when both error and fatal error handlers are registered in monolog's ErrorHandler
+  * Fixed missing fatal errors records with handlers that need to be closed to flush log records
+  * Fixed TagProcessor::addTags support for associative arrays
+
+### 1.15.0 (2015-07-12)
+
+  * Added addTags and setTags methods to change a TagProcessor
+  * Added automatic creation of directories if they are missing for a StreamHandler to open a log file
+  * Added retry functionality to Loggly, Cube and Mandrill handlers so they retry up to 5 times in case of network failure
+  * Fixed process exit code being incorrectly reset to 0 if ErrorHandler::registerExceptionHandler was used
+  * Fixed HTML/JS escaping in BrowserConsoleHandler
+  * Fixed JSON encoding errors being silently suppressed (PHP 5.5+ only)
+
+### 1.14.0 (2015-06-19)
+
+  * Added PHPConsoleHandler to send record to Chrome's PHP Console extension and library
+  * Added support for objects implementing __toString in the NormalizerFormatter
+  * Added support for HipChat's v2 API in HipChatHandler
+  * Added Logger::setTimezone() to initialize the timezone monolog should use in case date.timezone isn't correct for your app
+  * Added an option to send formatted message instead of the raw record on PushoverHandler via ->useFormattedMessage(true)
+  * Fixed curl errors being silently suppressed
+
+### 1.13.1 (2015-03-09)
+
+  * Fixed regression in HipChat requiring a new token to be created
+
+### 1.13.0 (2015-03-05)
+
+  * Added Registry::hasLogger to check for the presence of a logger instance
+  * Added context.user support to RavenHandler
+  * Added HipChat API v2 support in the HipChatHandler
+  * Added NativeMailerHandler::addParameter to pass params to the mail() process
+  * Added context data to SlackHandler when $includeContextAndExtra is true
+  * Added ability to customize the Swift_Message per-email in SwiftMailerHandler
+  * Fixed SwiftMailerHandler to lazily create message instances if a callback is provided
+  * Fixed serialization of INF and NaN values in Normalizer and LineFormatter
+
+### 1.12.0 (2014-12-29)
+
+  * Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers.
+  * Added PsrHandler to forward records to another PSR-3 logger
+  * Added SamplingHandler to wrap around a handler and include only every Nth record
+  * Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now)
+  * Added exception codes in the output of most formatters
+  * Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line)
+  * Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data
+  * Added $host to HipChatHandler for users of private instances
+  * Added $transactionName to NewRelicHandler and support for a transaction_name context value
+  * Fixed MandrillHandler to avoid outputting API call responses
+  * Fixed some non-standard behaviors in SyslogUdpHandler
+
+### 1.11.0 (2014-09-30)
+
+  * Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names
+  * Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails
+  * Added MandrillHandler to send emails via the Mandrillapp.com API
+  * Added SlackHandler to log records to a Slack.com account
+  * Added FleepHookHandler to log records to a Fleep.io account
+  * Added LogglyHandler::addTag to allow adding tags to an existing handler
+  * Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end
+  * Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing
+  * Added support for PhpAmqpLib in the AmqpHandler
+  * Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs
+  * Added support for adding extra fields from $_SERVER in the WebProcessor
+  * Fixed support for non-string values in PrsLogMessageProcessor
+  * Fixed SwiftMailer messages being sent with the wrong date in long running scripts
+  * Fixed minor PHP 5.6 compatibility issues
+  * Fixed BufferHandler::close being called twice
+
+### 1.10.0 (2014-06-04)
+
+  * Added Logger::getHandlers() and Logger::getProcessors() methods
+  * Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached
+  * Added support for extra data in NewRelicHandler
+  * Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines
+
+### 1.9.1 (2014-04-24)
+
+  * Fixed regression in RotatingFileHandler file permissions
+  * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records
+  * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative
+
+### 1.9.0 (2014-04-20)
+
+  * Added LogEntriesHandler to send logs to a LogEntries account
+  * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler
+  * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes
+  * Added support for table formatting in FirePHPHandler via the table context key
+  * Added a TagProcessor to add tags to records, and support for tags in RavenHandler
+  * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files
+  * Added sound support to the PushoverHandler
+  * Fixed multi-threading support in StreamHandler
+  * Fixed empty headers issue when ChromePHPHandler received no records
+  * Fixed default format of the ErrorLogHandler
+
+### 1.8.0 (2014-03-23)
+
+  * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them
+  * Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output
+  * Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler
+  * Added FlowdockHandler to send logs to a Flowdock account
+  * Added RollbarHandler to send logs to a Rollbar account
+  * Added HtmlFormatter to send prettier log emails with colors for each log level
+  * Added GitProcessor to add the current branch/commit to extra record data
+  * Added a Monolog\Registry class to allow easier global access to pre-configured loggers
+  * Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement
+  * Added support for HHVM
+  * Added support for Loggly batch uploads
+  * Added support for tweaking the content type and encoding in NativeMailerHandler
+  * Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor
+  * Fixed batch request support in GelfHandler
+
+### 1.7.0 (2013-11-14)
+
+  * Added ElasticSearchHandler to send logs to an Elastic Search server
+  * Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB
+  * Added SyslogUdpHandler to send logs to a remote syslogd server
+  * Added LogglyHandler to send logs to a Loggly account
+  * Added $level to IntrospectionProcessor so it only adds backtraces when needed
+  * Added $version to LogstashFormatter to allow using the new v1 Logstash format
+  * Added $appName to NewRelicHandler
+  * Added configuration of Pushover notification retries/expiry
+  * Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default
+  * Added chainability to most setters for all handlers
+  * Fixed RavenHandler batch processing so it takes the message from the record with highest priority
+  * Fixed HipChatHandler batch processing so it sends all messages at once
+  * Fixed issues with eAccelerator
+  * Fixed and improved many small things
+
+### 1.6.0 (2013-07-29)
+
+  * Added HipChatHandler to send logs to a HipChat chat room
+  * Added ErrorLogHandler to send logs to PHP's error_log function
+  * Added NewRelicHandler to send logs to NewRelic's service
+  * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler
+  * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel
+  * Added stack traces output when normalizing exceptions (json output & co)
+  * Added Monolog\Logger::API constant (currently 1)
+  * Added support for ChromePHP's v4.0 extension
+  * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel
+  * Added support for sending messages to multiple users at once with the PushoverHandler
+  * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler)
+  * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now
+  * Fixed issue in RotatingFileHandler when an open_basedir restriction is active
+  * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0
+  * Fixed SyslogHandler issue when many were used concurrently with different facilities
+
+### 1.5.0 (2013-04-23)
+
+  * Added ProcessIdProcessor to inject the PID in log records
+  * Added UidProcessor to inject a unique identifier to all log records of one request/run
+  * Added support for previous exceptions in the LineFormatter exception serialization
+  * Added Monolog\Logger::getLevels() to get all available levels
+  * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle
+
+### 1.4.1 (2013-04-01)
+
+  * Fixed exception formatting in the LineFormatter to be more minimalistic
+  * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0
+  * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days
+  * Fixed WebProcessor array access so it checks for data presence
+  * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors
+
+### 1.4.0 (2013-02-13)
+
+  * Added RedisHandler to log to Redis via the Predis library or the phpredis extension
+  * Added ZendMonitorHandler to log to the Zend Server monitor
+  * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor
+  * Added `$useSSL` option to the PushoverHandler which is enabled by default
+  * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously
+  * Fixed header injection capability in the NativeMailHandler
+
+### 1.3.1 (2013-01-11)
+
+  * Fixed LogstashFormatter to be usable with stream handlers
+  * Fixed GelfMessageFormatter levels on Windows
+
+### 1.3.0 (2013-01-08)
+
+  * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface`
+  * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance
+  * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash)
+  * Added PushoverHandler to send mobile notifications
+  * Added CouchDBHandler and DoctrineCouchDBHandler
+  * Added RavenHandler to send data to Sentry servers
+  * Added support for the new MongoClient class in MongoDBHandler
+  * Added microsecond precision to log records' timestamps
+  * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing
+    the oldest entries
+  * Fixed normalization of objects with cyclic references
+
+### 1.2.1 (2012-08-29)
+
+  * Added new $logopts arg to SyslogHandler to provide custom openlog options
+  * Fixed fatal error in SyslogHandler
+
+### 1.2.0 (2012-08-18)
+
+  * Added AmqpHandler (for use with AMQP servers)
+  * Added CubeHandler
+  * Added NativeMailerHandler::addHeader() to send custom headers in mails
+  * Added the possibility to specify more than one recipient in NativeMailerHandler
+  * Added the possibility to specify float timeouts in SocketHandler
+  * Added NOTICE and EMERGENCY levels to conform with RFC 5424
+  * Fixed the log records to use the php default timezone instead of UTC
+  * Fixed BufferHandler not being flushed properly on PHP fatal errors
+  * Fixed normalization of exotic resource types
+  * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog
+
+### 1.1.0 (2012-04-23)
+
+  * Added Monolog\Logger::isHandling() to check if a handler will
+    handle the given log level
+  * Added ChromePHPHandler
+  * Added MongoDBHandler
+  * Added GelfHandler (for use with Graylog2 servers)
+  * Added SocketHandler (for use with syslog-ng for example)
+  * Added NormalizerFormatter
+  * Added the possibility to change the activation strategy of the FingersCrossedHandler
+  * Added possibility to show microseconds in logs
+  * Added `server` and `referer` to WebProcessor output
+
+### 1.0.2 (2011-10-24)
+
+  * Fixed bug in IE with large response headers and FirePHPHandler
+
+### 1.0.1 (2011-08-25)
+
+  * Added MemoryPeakUsageProcessor and MemoryUsageProcessor
+  * Added Monolog\Logger::getName() to get a logger's channel name
+
+### 1.0.0 (2011-07-06)
+
+  * Added IntrospectionProcessor to get info from where the logger was called
+  * Fixed WebProcessor in CLI
+
+### 1.0.0-RC1 (2011-07-01)
+
+  * Initial release
diff --git a/msd/vendor/monolog/monolog/LICENSE b/msd/vendor/monolog/monolog/LICENSE
new file mode 100644
index 00000000..aa2a0426
--- /dev/null
+++ b/msd/vendor/monolog/monolog/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011-2020 Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/msd/vendor/monolog/monolog/README.md b/msd/vendor/monolog/monolog/README.md
new file mode 100644
index 00000000..bfcae0c0
--- /dev/null
+++ b/msd/vendor/monolog/monolog/README.md
@@ -0,0 +1,112 @@
+# Monolog - Logging for PHP [![Continuous Integration](https://github.com/Seldaek/monolog/workflows/Continuous%20Integration/badge.svg?branch=main)](https://github.com/Seldaek/monolog/actions)
+
+[![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog)
+[![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog)
+
+
+Monolog sends your logs to files, sockets, inboxes, databases and various
+web services. See the complete list of handlers below. Special handlers
+allow you to build advanced logging strategies.
+
+This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+interface that you can type-hint against in your own libraries to keep
+a maximum of interoperability. You can also use it in your applications to
+make sure you can always use another compatible logger at a later time.
+As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels.
+Internally Monolog still uses its own level scheme since it predates PSR-3.
+
+## Installation
+
+Install the latest version with
+
+```bash
+$ composer require monolog/monolog
+```
+
+## Basic Usage
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\StreamHandler;
+
+// create a log channel
+$log = new Logger('name');
+$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
+
+// add records to the log
+$log->warning('Foo');
+$log->error('Bar');
+```
+
+## Documentation
+
+- [Usage Instructions](doc/01-usage.md)
+- [Handlers, Formatters and Processors](doc/02-handlers-formatters-processors.md)
+- [Utility Classes](doc/03-utilities.md)
+- [Extending Monolog](doc/04-extending.md)
+- [Log Record Structure](doc/message-structure.md)
+
+## Support Monolog Financially
+
+Get supported Monolog and help fund the project with the [Tidelift Subscription](https://tidelift.com/subscription/pkg/packagist-monolog-monolog?utm_source=packagist-monolog-monolog&utm_medium=referral&utm_campaign=enterprise) or via [GitHub sponsorship](https://github.com/sponsors/Seldaek). 
+
+Tidelift delivers commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.
+
+## Third Party Packages
+
+Third party handlers, formatters and processors are
+[listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You
+can also add your own there if you publish one.
+
+## About
+
+### Requirements
+
+- Monolog `^2.0` works with PHP 7.2 or above, use Monolog `^1.25` for PHP 5.3+ support.
+
+### Support
+
+Monolog 1.x support is somewhat limited at this point and only important fixes will be done. You should migrate to Monolog 2 where possible to benefit from all the latest features and fixes.
+
+### Submitting bugs and feature requests
+
+Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues)
+
+### Framework Integrations
+
+- Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+  can be used very easily with Monolog since it implements the interface.
+- [Symfony](http://symfony.com) comes out of the box with Monolog.
+- [Laravel](http://laravel.com/) comes out of the box with Monolog.
+- [Lumen](http://lumen.laravel.com/) comes out of the box with Monolog.
+- [PPI](https://github.com/ppi/framework) comes out of the box with Monolog.
+- [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin.
+- [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer.
+- [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog.
+- [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog.
+- [Nette Framework](http://nette.org/en/) is usable with Monolog via the [contributte/monolog](https://github.com/contributte/monolog) or [orisai/nette-monolog](https://github.com/orisai/nette-monolog) extensions.
+- [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog.
+- [FuelPHP](http://fuelphp.com/) comes out of the box with Monolog.
+- [Equip Framework](https://github.com/equip/framework) comes out of the box with Monolog.
+- [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) or [yii2-psr-log-target](https://github.com/samdark/yii2-psr-log-target) plugins.
+- [Hawkbit Micro Framework](https://github.com/HawkBitPhp/hawkbit) comes out of the box with Monolog.
+- [SilverStripe 4](https://www.silverstripe.org/) comes out of the box with Monolog.
+- [Drupal](https://www.drupal.org/) is usable with Monolog via the [monolog](https://www.drupal.org/project/monolog) module.
+- [Aimeos ecommerce framework](https://aimeos.org/) is usable with Monolog via the [ai-monolog](https://github.com/aimeos/ai-monolog) extension.
+- [Magento](https://magento.com/) comes out of the box with Monolog.
+
+### Author
+
+Jordi Boggiano - <j.boggiano@seld.be> - <http://twitter.com/seldaek><br />
+See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) who participated in this project.
+
+### License
+
+Monolog is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
+
+### Acknowledgements
+
+This library is heavily inspired by Python's [Logbook](https://logbook.readthedocs.io/en/stable/)
+library, although most concepts have been adjusted to fit to the PHP world.
diff --git a/msd/vendor/monolog/monolog/UPGRADE.md b/msd/vendor/monolog/monolog/UPGRADE.md
new file mode 100644
index 00000000..84e15e6b
--- /dev/null
+++ b/msd/vendor/monolog/monolog/UPGRADE.md
@@ -0,0 +1,72 @@
+### 2.0.0
+
+- `Monolog\Logger::API` can be used to distinguish between a Monolog `1` and `2`
+  install of Monolog when writing integration code.
+
+- Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`)
+  methods as well as `emerg`, `crit`, `err` and `warn`.
+
+- DateTime are now formatted with a timezone and microseconds (unless disabled).
+  Various formatters and log output might be affected, which may mess with log parsing
+  in some cases.
+
+- The `datetime` in every record array is now a DateTimeImmutable, not that you
+  should have been modifying these anyway.
+
+- The timezone is now set per Logger instance and not statically, either
+  via ->setTimezone or passed in the constructor. Calls to Logger::setTimezone
+  should be converted.
+
+- `HandlerInterface` has been split off and two new interfaces now exist for
+  more granular controls: `ProcessableHandlerInterface` and
+  `FormattableHandlerInterface`. Handlers not extending `AbstractHandler`
+  should make sure to implement the relevant interfaces.
+
+- `HandlerInterface` now requires the `close` method to be implemented. This
+  only impacts you if you implement the interface yourself, but you can extend
+  the new `Monolog\Handler\Handler` base class too.
+
+- There is no more default handler configured on empty Logger instances, if
+  you were relying on that you will not get any output anymore, make sure to
+  configure the handler you need.
+
+#### LogglyFormatter
+
+- The records' `datetime` is not sent anymore. Only `timestamp` is sent to Loggly.
+
+#### AmqpHandler
+
+- Log levels are not shortened to 4 characters anymore. e.g. a warning record
+  will be sent using the `warning.channel` routing key instead of `warn.channel`
+  as in 1.x.
+- The exchange name does not default to 'log' anymore, and it is completely ignored
+  now for the AMQP extension users. Only PHPAmqpLib uses it if provided.
+
+#### RotatingFileHandler
+
+- The file name format must now contain `{date}` and the date format must be set
+  to one of the predefined FILE_PER_* constants to avoid issues with file rotation.
+  See `setFilenameFormat`.
+
+#### LogstashFormatter
+
+- Removed Logstash V0 support
+- Context/extra prefix has been removed in favor of letting users configure the exact key being sent
+- Context/extra data are now sent as an object instead of single keys
+
+#### HipChatHandler
+
+- Removed deprecated HipChat handler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead
+
+#### SlackbotHandler
+
+- Removed deprecated SlackbotHandler handler, use SlackWebhookHandler or SlackHandler instead
+
+#### RavenHandler
+
+- Removed deprecated RavenHandler handler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead
+
+#### ElasticSearchHandler
+
+- As support for the official Elasticsearch library was added, the former ElasticSearchHandler has been
+  renamed to ElasticaHandler and the new one added as ElasticsearchHandler.
diff --git a/msd/vendor/monolog/monolog/composer.json b/msd/vendor/monolog/monolog/composer.json
new file mode 100644
index 00000000..ab775ad6
--- /dev/null
+++ b/msd/vendor/monolog/monolog/composer.json
@@ -0,0 +1,81 @@
+{
+    "name": "monolog/monolog",
+    "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+    "keywords": ["log", "logging", "psr-3"],
+    "homepage": "https://github.com/Seldaek/monolog",
+    "type": "library",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Jordi Boggiano",
+            "email": "j.boggiano@seld.be",
+            "homepage": "https://seld.be"
+        }
+    ],
+    "require": {
+        "php": ">=7.2",
+        "psr/log": "^1.0.1 || ^2.0 || ^3.0"
+    },
+    "require-dev": {
+        "ext-json": "*",
+        "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+        "doctrine/couchdb": "~1.0@dev",
+        "elasticsearch/elasticsearch": "^7 || ^8",
+        "graylog2/gelf-php": "^1.4.2",
+        "guzzlehttp/guzzle": "^7.4",
+        "guzzlehttp/psr7": "^2.2",
+        "mongodb/mongodb": "^1.8",
+        "php-amqplib/php-amqplib": "~2.4 || ^3",
+        "phpspec/prophecy": "^1.15",
+        "phpstan/phpstan": "^0.12.91",
+        "phpunit/phpunit": "^8.5.14",
+        "predis/predis": "^1.1 || ^2.0",
+        "rollbar/rollbar": "^1.3 || ^2 || ^3",
+        "ruflin/elastica": "^7",
+        "swiftmailer/swiftmailer": "^5.3|^6.0",
+        "symfony/mailer": "^5.4 || ^6",
+        "symfony/mime": "^5.4 || ^6"
+    },
+    "suggest": {
+        "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+        "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+        "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+        "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+        "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+        "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+        "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+        "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+        "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+        "rollbar/rollbar": "Allow sending log messages to Rollbar",
+        "ext-mbstring": "Allow to work properly with unicode symbols",
+        "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+        "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+        "ext-openssl": "Required to send log messages using SSL"
+    },
+    "autoload": {
+        "psr-4": {"Monolog\\": "src/Monolog"}
+    },
+    "autoload-dev": {
+        "psr-4": {"Monolog\\": "tests/Monolog"}
+    },
+    "provide": {
+        "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-main": "2.x-dev"
+        }
+    },
+    "scripts": {
+        "test": "@php vendor/bin/phpunit",
+        "phpstan": "@php vendor/bin/phpstan analyse"
+    },
+    "config": {
+        "lock": false,
+        "sort-packages": true,
+        "platform-check": false,
+        "allow-plugins": {
+            "composer/package-versions-deprecated": true
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Attribute/AsMonologProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Attribute/AsMonologProcessor.php
new file mode 100644
index 00000000..188bbb0d
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Attribute/AsMonologProcessor.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Attribute;
+
+/**
+ * A reusable attribute to help configure a class or a method as a processor.
+ * 
+ * Using it offers no guarantee: it needs to be leveraged by a Monolog third-party consumer.
+ * 
+ * Using it with the Monolog library only has no effect at all: processors should still be turned into a callable if
+ * needed and manually pushed to the loggers and to the processable handlers.
+ */
+#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
+class AsMonologProcessor
+{
+    /** @var string|null */
+    public $channel = null;
+    /** @var string|null */
+    public $handler = null;
+    /** @var string|null */
+    public $method = null;
+    
+    /**
+     * @param string|null $channel  The logging channel the processor should be pushed to.
+     * @param string|null $handler  The handler the processor should be pushed to.
+     * @param string|null $method   The method that processes the records (if the attribute is used at the class level).
+     */
+    public function __construct(
+        ?string $channel = null,
+        ?string $handler = null,
+        ?string $method = null
+    ) {
+        $this->channel = $channel;
+        $this->handler = $handler;
+        $this->method = $method;
+    }
+} 
diff --git a/msd/vendor/monolog/monolog/src/Monolog/DateTimeImmutable.php b/msd/vendor/monolog/monolog/src/Monolog/DateTimeImmutable.php
new file mode 100644
index 00000000..6a1ba9b2
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/DateTimeImmutable.php
@@ -0,0 +1,49 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use DateTimeZone;
+
+/**
+ * Overrides default json encoding of date time objects
+ *
+ * @author Menno Holtkamp
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class DateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable
+{
+    /**
+     * @var bool
+     */
+    private $useMicroseconds;
+
+    public function __construct(bool $useMicroseconds, ?DateTimeZone $timezone = null)
+    {
+        $this->useMicroseconds = $useMicroseconds;
+
+        parent::__construct('now', $timezone);
+    }
+
+    public function jsonSerialize(): string
+    {
+        if ($this->useMicroseconds) {
+            return $this->format('Y-m-d\TH:i:s.uP');
+        }
+
+        return $this->format('Y-m-d\TH:i:sP');
+    }
+
+    public function __toString(): string
+    {
+        return $this->jsonSerialize();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/ErrorHandler.php b/msd/vendor/monolog/monolog/src/Monolog/ErrorHandler.php
new file mode 100644
index 00000000..576f1713
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/ErrorHandler.php
@@ -0,0 +1,307 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * Monolog error handler
+ *
+ * A facility to enable logging of runtime errors, exceptions and fatal errors.
+ *
+ * Quick setup: <code>ErrorHandler::register($logger);</code>
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class ErrorHandler
+{
+    /** @var LoggerInterface */
+    private $logger;
+
+    /** @var ?callable */
+    private $previousExceptionHandler = null;
+    /** @var array<class-string, LogLevel::*> an array of class name to LogLevel::* constant mapping */
+    private $uncaughtExceptionLevelMap = [];
+
+    /** @var callable|true|null */
+    private $previousErrorHandler = null;
+    /** @var array<int, LogLevel::*> an array of E_* constant to LogLevel::* constant mapping */
+    private $errorLevelMap = [];
+    /** @var bool */
+    private $handleOnlyReportedErrors = true;
+
+    /** @var bool */
+    private $hasFatalErrorHandler = false;
+    /** @var LogLevel::* */
+    private $fatalLevel = LogLevel::ALERT;
+    /** @var ?string */
+    private $reservedMemory = null;
+    /** @var ?array{type: int, message: string, file: string, line: int, trace: mixed} */
+    private $lastFatalData = null;
+    /** @var int[] */
+    private static $fatalErrors = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR];
+
+    public function __construct(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+
+    /**
+     * Registers a new ErrorHandler for a given Logger
+     *
+     * By default it will handle errors, exceptions and fatal errors
+     *
+     * @param  LoggerInterface                        $logger
+     * @param  array<int, LogLevel::*>|false          $errorLevelMap     an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
+     * @param  array<class-string, LogLevel::*>|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling
+     * @param  LogLevel::*|null|false                 $fatalLevel        a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling
+     * @return ErrorHandler
+     */
+    public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self
+    {
+        /** @phpstan-ignore-next-line */
+        $handler = new static($logger);
+        if ($errorLevelMap !== false) {
+            $handler->registerErrorHandler($errorLevelMap);
+        }
+        if ($exceptionLevelMap !== false) {
+            $handler->registerExceptionHandler($exceptionLevelMap);
+        }
+        if ($fatalLevel !== false) {
+            $handler->registerFatalHandler($fatalLevel);
+        }
+
+        return $handler;
+    }
+
+    /**
+     * @param  array<class-string, LogLevel::*> $levelMap an array of class name to LogLevel::* constant mapping
+     * @return $this
+     */
+    public function registerExceptionHandler(array $levelMap = [], bool $callPrevious = true): self
+    {
+        $prev = set_exception_handler(function (\Throwable $e): void {
+            $this->handleException($e);
+        });
+        $this->uncaughtExceptionLevelMap = $levelMap;
+        foreach ($this->defaultExceptionLevelMap() as $class => $level) {
+            if (!isset($this->uncaughtExceptionLevelMap[$class])) {
+                $this->uncaughtExceptionLevelMap[$class] = $level;
+            }
+        }
+        if ($callPrevious && $prev) {
+            $this->previousExceptionHandler = $prev;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @param  array<int, LogLevel::*> $levelMap an array of E_* constant to LogLevel::* constant mapping
+     * @return $this
+     */
+    public function registerErrorHandler(array $levelMap = [], bool $callPrevious = true, int $errorTypes = -1, bool $handleOnlyReportedErrors = true): self
+    {
+        $prev = set_error_handler([$this, 'handleError'], $errorTypes);
+        $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap);
+        if ($callPrevious) {
+            $this->previousErrorHandler = $prev ?: true;
+        } else {
+            $this->previousErrorHandler = null;
+        }
+
+        $this->handleOnlyReportedErrors = $handleOnlyReportedErrors;
+
+        return $this;
+    }
+
+    /**
+     * @param LogLevel::*|null $level              a LogLevel::* constant, null to use the default LogLevel::ALERT
+     * @param int              $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done
+     */
+    public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self
+    {
+        register_shutdown_function([$this, 'handleFatalError']);
+
+        $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
+        $this->fatalLevel = null === $level ? LogLevel::ALERT : $level;
+        $this->hasFatalErrorHandler = true;
+
+        return $this;
+    }
+
+    /**
+     * @return array<class-string, LogLevel::*>
+     */
+    protected function defaultExceptionLevelMap(): array
+    {
+        return [
+            'ParseError' => LogLevel::CRITICAL,
+            'Throwable' => LogLevel::ERROR,
+        ];
+    }
+
+    /**
+     * @return array<int, LogLevel::*>
+     */
+    protected function defaultErrorLevelMap(): array
+    {
+        return [
+            E_ERROR             => LogLevel::CRITICAL,
+            E_WARNING           => LogLevel::WARNING,
+            E_PARSE             => LogLevel::ALERT,
+            E_NOTICE            => LogLevel::NOTICE,
+            E_CORE_ERROR        => LogLevel::CRITICAL,
+            E_CORE_WARNING      => LogLevel::WARNING,
+            E_COMPILE_ERROR     => LogLevel::ALERT,
+            E_COMPILE_WARNING   => LogLevel::WARNING,
+            E_USER_ERROR        => LogLevel::ERROR,
+            E_USER_WARNING      => LogLevel::WARNING,
+            E_USER_NOTICE       => LogLevel::NOTICE,
+            E_STRICT            => LogLevel::NOTICE,
+            E_RECOVERABLE_ERROR => LogLevel::ERROR,
+            E_DEPRECATED        => LogLevel::NOTICE,
+            E_USER_DEPRECATED   => LogLevel::NOTICE,
+        ];
+    }
+
+    /**
+     * @phpstan-return never
+     */
+    private function handleException(\Throwable $e): void
+    {
+        $level = LogLevel::ERROR;
+        foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) {
+            if ($e instanceof $class) {
+                $level = $candidate;
+                break;
+            }
+        }
+
+        $this->logger->log(
+            $level,
+            sprintf('Uncaught Exception %s: "%s" at %s line %s', Utils::getClass($e), $e->getMessage(), $e->getFile(), $e->getLine()),
+            ['exception' => $e]
+        );
+
+        if ($this->previousExceptionHandler) {
+            ($this->previousExceptionHandler)($e);
+        }
+
+        if (!headers_sent() && !ini_get('display_errors')) {
+            http_response_code(500);
+        }
+
+        exit(255);
+    }
+
+    /**
+     * @private
+     *
+     * @param mixed[] $context
+     */
+    public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool
+    {
+        if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) {
+            return false;
+        }
+
+        // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries
+        if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) {
+            $level = $this->errorLevelMap[$code] ?? LogLevel::CRITICAL;
+            $this->logger->log($level, self::codeToString($code).': '.$message, ['code' => $code, 'message' => $message, 'file' => $file, 'line' => $line]);
+        } else {
+            $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+            array_shift($trace); // Exclude handleError from trace
+            $this->lastFatalData = ['type' => $code, 'message' => $message, 'file' => $file, 'line' => $line, 'trace' => $trace];
+        }
+
+        if ($this->previousErrorHandler === true) {
+            return false;
+        } elseif ($this->previousErrorHandler) {
+            return (bool) ($this->previousErrorHandler)($code, $message, $file, $line, $context);
+        }
+
+        return true;
+    }
+
+    /**
+     * @private
+     */
+    public function handleFatalError(): void
+    {
+        $this->reservedMemory = '';
+
+        if (is_array($this->lastFatalData)) {
+            $lastError = $this->lastFatalData;
+        } else {
+            $lastError = error_get_last();
+        }
+
+        if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) {
+            $trace = $lastError['trace'] ?? null;
+            $this->logger->log(
+                $this->fatalLevel,
+                'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
+                ['code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $trace]
+            );
+
+            if ($this->logger instanceof Logger) {
+                foreach ($this->logger->getHandlers() as $handler) {
+                    $handler->close();
+                }
+            }
+        }
+    }
+
+    /**
+     * @param int $code
+     */
+    private static function codeToString($code): string
+    {
+        switch ($code) {
+            case E_ERROR:
+                return 'E_ERROR';
+            case E_WARNING:
+                return 'E_WARNING';
+            case E_PARSE:
+                return 'E_PARSE';
+            case E_NOTICE:
+                return 'E_NOTICE';
+            case E_CORE_ERROR:
+                return 'E_CORE_ERROR';
+            case E_CORE_WARNING:
+                return 'E_CORE_WARNING';
+            case E_COMPILE_ERROR:
+                return 'E_COMPILE_ERROR';
+            case E_COMPILE_WARNING:
+                return 'E_COMPILE_WARNING';
+            case E_USER_ERROR:
+                return 'E_USER_ERROR';
+            case E_USER_WARNING:
+                return 'E_USER_WARNING';
+            case E_USER_NOTICE:
+                return 'E_USER_NOTICE';
+            case E_STRICT:
+                return 'E_STRICT';
+            case E_RECOVERABLE_ERROR:
+                return 'E_RECOVERABLE_ERROR';
+            case E_DEPRECATED:
+                return 'E_DEPRECATED';
+            case E_USER_DEPRECATED:
+                return 'E_USER_DEPRECATED';
+        }
+
+        return 'Unknown PHP error';
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php
new file mode 100644
index 00000000..aa1884b9
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php
@@ -0,0 +1,83 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+/**
+ * Formats a log message according to the ChromePHP array format
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ChromePHPFormatter implements FormatterInterface
+{
+    /**
+     * Translates Monolog log levels to Wildfire levels.
+     *
+     * @var array<int, 'log'|'info'|'warn'|'error'>
+     */
+    private $logLevels = [
+        Logger::DEBUG     => 'log',
+        Logger::INFO      => 'info',
+        Logger::NOTICE    => 'info',
+        Logger::WARNING   => 'warn',
+        Logger::ERROR     => 'error',
+        Logger::CRITICAL  => 'error',
+        Logger::ALERT     => 'error',
+        Logger::EMERGENCY => 'error',
+    ];
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record)
+    {
+        // Retrieve the line and file if set and remove them from the formatted extra
+        $backtrace = 'unknown';
+        if (isset($record['extra']['file'], $record['extra']['line'])) {
+            $backtrace = $record['extra']['file'].' : '.$record['extra']['line'];
+            unset($record['extra']['file'], $record['extra']['line']);
+        }
+
+        $message = ['message' => $record['message']];
+        if ($record['context']) {
+            $message['context'] = $record['context'];
+        }
+        if ($record['extra']) {
+            $message['extra'] = $record['extra'];
+        }
+        if (count($message) === 1) {
+            $message = reset($message);
+        }
+
+        return [
+            $record['channel'],
+            $message,
+            $backtrace,
+            $this->logLevels[$record['level']],
+        ];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function formatBatch(array $records)
+    {
+        $formatted = [];
+
+        foreach ($records as $record) {
+            $formatted[] = $this->format($record);
+        }
+
+        return $formatted;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php
new file mode 100644
index 00000000..6c8a9ab5
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php
@@ -0,0 +1,89 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Elastica\Document;
+
+/**
+ * Format a log message into an Elastica Document
+ *
+ * @author Jelle Vink <jelle.vink@gmail.com>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class ElasticaFormatter extends NormalizerFormatter
+{
+    /**
+     * @var string Elastic search index name
+     */
+    protected $index;
+
+    /**
+     * @var ?string Elastic search document type
+     */
+    protected $type;
+
+    /**
+     * @param string  $index Elastic Search index name
+     * @param ?string $type  Elastic Search document type, deprecated as of Elastica 7
+     */
+    public function __construct(string $index, ?string $type)
+    {
+        // elasticsearch requires a ISO 8601 format date with optional millisecond precision.
+        parent::__construct('Y-m-d\TH:i:s.uP');
+
+        $this->index = $index;
+        $this->type = $type;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record)
+    {
+        $record = parent::format($record);
+
+        return $this->getDocument($record);
+    }
+
+    public function getIndex(): string
+    {
+        return $this->index;
+    }
+
+    /**
+     * @deprecated since Elastica 7 type has no effect
+     */
+    public function getType(): string
+    {
+        /** @phpstan-ignore-next-line */
+        return $this->type;
+    }
+
+    /**
+     * Convert a log message into an Elastica Document
+     *
+     * @phpstan-param Record $record
+     */
+    protected function getDocument(array $record): Document
+    {
+        $document = new Document();
+        $document->setData($record);
+        if (method_exists($document, 'setType')) {
+            /** @phpstan-ignore-next-line */
+            $document->setType($this->type);
+        }
+        $document->setIndex($this->index);
+
+        return $document;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/ElasticsearchFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ElasticsearchFormatter.php
new file mode 100644
index 00000000..b792b819
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ElasticsearchFormatter.php
@@ -0,0 +1,89 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use DateTimeInterface;
+
+/**
+ * Format a log message into an Elasticsearch record
+ *
+ * @author Avtandil Kikabidze <akalongman@gmail.com>
+ */
+class ElasticsearchFormatter extends NormalizerFormatter
+{
+    /**
+     * @var string Elasticsearch index name
+     */
+    protected $index;
+
+    /**
+     * @var string Elasticsearch record type
+     */
+    protected $type;
+
+    /**
+     * @param string $index Elasticsearch index name
+     * @param string $type  Elasticsearch record type
+     */
+    public function __construct(string $index, string $type)
+    {
+        // Elasticsearch requires an ISO 8601 format date with optional millisecond precision.
+        parent::__construct(DateTimeInterface::ISO8601);
+
+        $this->index = $index;
+        $this->type = $type;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record)
+    {
+        $record = parent::format($record);
+
+        return $this->getDocument($record);
+    }
+
+    /**
+     * Getter index
+     *
+     * @return string
+     */
+    public function getIndex(): string
+    {
+        return $this->index;
+    }
+
+    /**
+     * Getter type
+     *
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->type;
+    }
+
+    /**
+     * Convert a log message into an Elasticsearch record
+     *
+     * @param  mixed[] $record Log message
+     * @return mixed[]
+     */
+    protected function getDocument(array $record): array
+    {
+        $record['_index'] = $this->index;
+        $record['_type'] = $this->type;
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php
new file mode 100644
index 00000000..41b56b3c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php
@@ -0,0 +1,111 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * formats the record to be used in the FlowdockHandler
+ *
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
+ */
+class FlowdockFormatter implements FormatterInterface
+{
+    /**
+     * @var string
+     */
+    private $source;
+
+    /**
+     * @var string
+     */
+    private $sourceEmail;
+
+    public function __construct(string $source, string $sourceEmail)
+    {
+        $this->source = $source;
+        $this->sourceEmail = $sourceEmail;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return mixed[]
+     */
+    public function format(array $record): array
+    {
+        $tags = [
+            '#logs',
+            '#' . strtolower($record['level_name']),
+            '#' . $record['channel'],
+        ];
+
+        foreach ($record['extra'] as $value) {
+            $tags[] = '#' . $value;
+        }
+
+        $subject = sprintf(
+            'in %s: %s - %s',
+            $this->source,
+            $record['level_name'],
+            $this->getShortMessage($record['message'])
+        );
+
+        $record['flowdock'] = [
+            'source' => $this->source,
+            'from_address' => $this->sourceEmail,
+            'subject' => $subject,
+            'content' => $record['message'],
+            'tags' => $tags,
+            'project' => $this->source,
+        ];
+
+        return $record;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return mixed[][]
+     */
+    public function formatBatch(array $records): array
+    {
+        $formatted = [];
+
+        foreach ($records as $record) {
+            $formatted[] = $this->format($record);
+        }
+
+        return $formatted;
+    }
+
+    public function getShortMessage(string $message): string
+    {
+        static $hasMbString;
+
+        if (null === $hasMbString) {
+            $hasMbString = function_exists('mb_strlen');
+        }
+
+        $maxLength = 45;
+
+        if ($hasMbString) {
+            if (mb_strlen($message, 'UTF-8') > $maxLength) {
+                $message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...';
+            }
+        } else {
+            if (strlen($message) > $maxLength) {
+                $message = substr($message, 0, $maxLength - 4) . ' ...';
+            }
+        }
+
+        return $message;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php
new file mode 100644
index 00000000..29b14d30
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Utils;
+
+/**
+ * Class FluentdFormatter
+ *
+ * Serializes a log message to Fluentd unix socket protocol
+ *
+ * Fluentd config:
+ *
+ * <source>
+ *  type unix
+ *  path /var/run/td-agent/td-agent.sock
+ * </source>
+ *
+ * Monolog setup:
+ *
+ * $logger = new Monolog\Logger('fluent.tag');
+ * $fluentHandler = new Monolog\Handler\SocketHandler('unix:///var/run/td-agent/td-agent.sock');
+ * $fluentHandler->setFormatter(new Monolog\Formatter\FluentdFormatter());
+ * $logger->pushHandler($fluentHandler);
+ *
+ * @author Andrius Putna <fordnox@gmail.com>
+ */
+class FluentdFormatter implements FormatterInterface
+{
+    /**
+     * @var bool $levelTag should message level be a part of the fluentd tag
+     */
+    protected $levelTag = false;
+
+    public function __construct(bool $levelTag = false)
+    {
+        if (!function_exists('json_encode')) {
+            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s FluentdUnixFormatter');
+        }
+
+        $this->levelTag = $levelTag;
+    }
+
+    public function isUsingLevelsInTag(): bool
+    {
+        return $this->levelTag;
+    }
+
+    public function format(array $record): string
+    {
+        $tag = $record['channel'];
+        if ($this->levelTag) {
+            $tag .= '.' . strtolower($record['level_name']);
+        }
+
+        $message = [
+            'message' => $record['message'],
+            'context' => $record['context'],
+            'extra' => $record['extra'],
+        ];
+
+        if (!$this->levelTag) {
+            $message['level'] = $record['level'];
+            $message['level_name'] = $record['level_name'];
+        }
+
+        return Utils::jsonEncode([$tag, $record['datetime']->getTimestamp(), $message]);
+    }
+
+    public function formatBatch(array $records): string
+    {
+        $message = '';
+        foreach ($records as $record) {
+            $message .= $this->format($record);
+        }
+
+        return $message;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php
new file mode 100644
index 00000000..19617ec5
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php
@@ -0,0 +1,42 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Interface for formatters
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+interface FormatterInterface
+{
+    /**
+     * Formats a log record.
+     *
+     * @param  array $record A record to format
+     * @return mixed The formatted record
+     *
+     * @phpstan-param Record $record
+     */
+    public function format(array $record);
+
+    /**
+     * Formats a set of log records.
+     *
+     * @param  array $records A set of records to format
+     * @return mixed The formatted set of records
+     *
+     * @phpstan-param Record[] $records
+     */
+    public function formatBatch(array $records);
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php
new file mode 100644
index 00000000..a1a79372
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php
@@ -0,0 +1,160 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+use Gelf\Message;
+use Monolog\Utils;
+
+/**
+ * Serializes a log message to GELF
+ * @see http://docs.graylog.org/en/latest/pages/gelf.html
+ *
+ * @author Matt Lehner <mlehner@gmail.com>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+class GelfMessageFormatter extends NormalizerFormatter
+{
+    protected const DEFAULT_MAX_LENGTH = 32766;
+
+    /**
+     * @var string the name of the system for the Gelf log message
+     */
+    protected $systemName;
+
+    /**
+     * @var string a prefix for 'extra' fields from the Monolog record (optional)
+     */
+    protected $extraPrefix;
+
+    /**
+     * @var string a prefix for 'context' fields from the Monolog record (optional)
+     */
+    protected $contextPrefix;
+
+    /**
+     * @var int max length per field
+     */
+    protected $maxLength;
+
+    /**
+     * Translates Monolog log levels to Graylog2 log priorities.
+     *
+     * @var array<int, int>
+     *
+     * @phpstan-var array<Level, int>
+     */
+    private $logLevels = [
+        Logger::DEBUG     => 7,
+        Logger::INFO      => 6,
+        Logger::NOTICE    => 5,
+        Logger::WARNING   => 4,
+        Logger::ERROR     => 3,
+        Logger::CRITICAL  => 2,
+        Logger::ALERT     => 1,
+        Logger::EMERGENCY => 0,
+    ];
+
+    public function __construct(?string $systemName = null, ?string $extraPrefix = null, string $contextPrefix = 'ctxt_', ?int $maxLength = null)
+    {
+        if (!class_exists(Message::class)) {
+            throw new \RuntimeException('Composer package graylog2/gelf-php is required to use Monolog\'s GelfMessageFormatter');
+        }
+
+        parent::__construct('U.u');
+
+        $this->systemName = (is_null($systemName) || $systemName === '') ? (string) gethostname() : $systemName;
+
+        $this->extraPrefix = is_null($extraPrefix) ? '' : $extraPrefix;
+        $this->contextPrefix = $contextPrefix;
+        $this->maxLength = is_null($maxLength) ? self::DEFAULT_MAX_LENGTH : $maxLength;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record): Message
+    {
+        $context = $extra = [];
+        if (isset($record['context'])) {
+            /** @var mixed[] $context */
+            $context = parent::normalize($record['context']);
+        }
+        if (isset($record['extra'])) {
+            /** @var mixed[] $extra */
+            $extra = parent::normalize($record['extra']);
+        }
+
+        if (!isset($record['datetime'], $record['message'], $record['level'])) {
+            throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, '.var_export($record, true).' given');
+        }
+
+        $message = new Message();
+        $message
+            ->setTimestamp($record['datetime'])
+            ->setShortMessage((string) $record['message'])
+            ->setHost($this->systemName)
+            ->setLevel($this->logLevels[$record['level']]);
+
+        // message length + system name length + 200 for padding / metadata
+        $len = 200 + strlen((string) $record['message']) + strlen($this->systemName);
+
+        if ($len > $this->maxLength) {
+            $message->setShortMessage(Utils::substr($record['message'], 0, $this->maxLength));
+        }
+
+        if (isset($record['channel'])) {
+            $message->setFacility($record['channel']);
+        }
+        if (isset($extra['line'])) {
+            $message->setLine($extra['line']);
+            unset($extra['line']);
+        }
+        if (isset($extra['file'])) {
+            $message->setFile($extra['file']);
+            unset($extra['file']);
+        }
+
+        foreach ($extra as $key => $val) {
+            $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
+            $len = strlen($this->extraPrefix . $key . $val);
+            if ($len > $this->maxLength) {
+                $message->setAdditional($this->extraPrefix . $key, Utils::substr((string) $val, 0, $this->maxLength));
+
+                continue;
+            }
+            $message->setAdditional($this->extraPrefix . $key, $val);
+        }
+
+        foreach ($context as $key => $val) {
+            $val = is_scalar($val) || null === $val ? $val : $this->toJson($val);
+            $len = strlen($this->contextPrefix . $key . $val);
+            if ($len > $this->maxLength) {
+                $message->setAdditional($this->contextPrefix . $key, Utils::substr((string) $val, 0, $this->maxLength));
+
+                continue;
+            }
+            $message->setAdditional($this->contextPrefix . $key, $val);
+        }
+
+        /** @phpstan-ignore-next-line */
+        if (null === $message->getFile() && isset($context['exception']['file'])) {
+            if (preg_match("/^(.+):([0-9]+)$/", $context['exception']['file'], $matches)) {
+                $message->setFile($matches[1]);
+                $message->setLine($matches[2]);
+            }
+        }
+
+        return $message;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/GoogleCloudLoggingFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/GoogleCloudLoggingFormatter.php
new file mode 100644
index 00000000..0cd287f5
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/GoogleCloudLoggingFormatter.php
@@ -0,0 +1,39 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use DateTimeInterface;
+use Monolog\LogRecord;
+
+/**
+ * Encodes message information into JSON in a format compatible with Cloud logging.
+ *
+ * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
+ *
+ * @author Luís Cobucci <lcobucci@gmail.com>
+ */
+final class GoogleCloudLoggingFormatter extends JsonFormatter
+{
+    /** {@inheritdoc} **/
+    public function format(array $record): string
+    {
+        // Re-key level for GCP logging
+        $record['severity'] = $record['level_name'];
+        $record['timestamp'] = $record['datetime']->format(DateTimeInterface::RFC3339_EXTENDED);
+
+        // Remove keys that are not used by GCP
+        unset($record['level'], $record['level_name'], $record['datetime']);
+
+        return parent::format($record);
+    }
+}
+
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php
new file mode 100644
index 00000000..10a4311c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php
@@ -0,0 +1,142 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Formats incoming records into an HTML table
+ *
+ * This is especially useful for html email logging
+ *
+ * @author Tiago Brito <tlfbrito@gmail.com>
+ */
+class HtmlFormatter extends NormalizerFormatter
+{
+    /**
+     * Translates Monolog log levels to html color priorities.
+     *
+     * @var array<int, string>
+     */
+    protected $logLevels = [
+        Logger::DEBUG     => '#CCCCCC',
+        Logger::INFO      => '#28A745',
+        Logger::NOTICE    => '#17A2B8',
+        Logger::WARNING   => '#FFC107',
+        Logger::ERROR     => '#FD7E14',
+        Logger::CRITICAL  => '#DC3545',
+        Logger::ALERT     => '#821722',
+        Logger::EMERGENCY => '#000000',
+    ];
+
+    /**
+     * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format
+     */
+    public function __construct(?string $dateFormat = null)
+    {
+        parent::__construct($dateFormat);
+    }
+
+    /**
+     * Creates an HTML table row
+     *
+     * @param string $th       Row header content
+     * @param string $td       Row standard cell content
+     * @param bool   $escapeTd false if td content must not be html escaped
+     */
+    protected function addRow(string $th, string $td = ' ', bool $escapeTd = true): string
+    {
+        $th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8');
+        if ($escapeTd) {
+            $td = '<pre>'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'</pre>';
+        }
+
+        return "<tr style=\"padding: 4px;text-align: left;\">\n<th style=\"vertical-align: top;background: #ccc;color: #000\" width=\"100\">$th:</th>\n<td style=\"padding: 4px;text-align: left;vertical-align: top;background: #eee;color: #000\">".$td."</td>\n</tr>";
+    }
+
+    /**
+     * Create a HTML h1 tag
+     *
+     * @param  string $title Text to be in the h1
+     * @param  int    $level Error level
+     * @return string
+     */
+    protected function addTitle(string $title, int $level): string
+    {
+        $title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8');
+
+        return '<h1 style="background: '.$this->logLevels[$level].';color: #ffffff;padding: 5px;" class="monolog-output">'.$title.'</h1>';
+    }
+
+    /**
+     * Formats a log record.
+     *
+     * @return string The formatted record
+     */
+    public function format(array $record): string
+    {
+        $output = $this->addTitle($record['level_name'], $record['level']);
+        $output .= '<table cellspacing="1" width="100%" class="monolog-output">';
+
+        $output .= $this->addRow('Message', (string) $record['message']);
+        $output .= $this->addRow('Time', $this->formatDate($record['datetime']));
+        $output .= $this->addRow('Channel', $record['channel']);
+        if ($record['context']) {
+            $embeddedTable = '<table cellspacing="1" width="100%">';
+            foreach ($record['context'] as $key => $value) {
+                $embeddedTable .= $this->addRow((string) $key, $this->convertToString($value));
+            }
+            $embeddedTable .= '</table>';
+            $output .= $this->addRow('Context', $embeddedTable, false);
+        }
+        if ($record['extra']) {
+            $embeddedTable = '<table cellspacing="1" width="100%">';
+            foreach ($record['extra'] as $key => $value) {
+                $embeddedTable .= $this->addRow((string) $key, $this->convertToString($value));
+            }
+            $embeddedTable .= '</table>';
+            $output .= $this->addRow('Extra', $embeddedTable, false);
+        }
+
+        return $output.'</table>';
+    }
+
+    /**
+     * Formats a set of log records.
+     *
+     * @return string The formatted set of records
+     */
+    public function formatBatch(array $records): string
+    {
+        $message = '';
+        foreach ($records as $record) {
+            $message .= $this->format($record);
+        }
+
+        return $message;
+    }
+
+    /**
+     * @param mixed $data
+     */
+    protected function convertToString($data): string
+    {
+        if (null === $data || is_scalar($data)) {
+            return (string) $data;
+        }
+
+        $data = $this->normalize($data);
+
+        return Utils::jsonEncode($data, JSON_PRETTY_PRINT | Utils::DEFAULT_JSON_FLAGS, true);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php
new file mode 100644
index 00000000..b737d82e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php
@@ -0,0 +1,224 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Throwable;
+
+/**
+ * Encodes whatever record data is passed to it as json
+ *
+ * This can be useful to log to databases or remote APIs
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class JsonFormatter extends NormalizerFormatter
+{
+    public const BATCH_MODE_JSON = 1;
+    public const BATCH_MODE_NEWLINES = 2;
+
+    /** @var self::BATCH_MODE_* */
+    protected $batchMode;
+    /** @var bool */
+    protected $appendNewline;
+    /** @var bool */
+    protected $ignoreEmptyContextAndExtra;
+    /** @var bool */
+    protected $includeStacktraces = false;
+
+    /**
+     * @param self::BATCH_MODE_* $batchMode
+     */
+    public function __construct(int $batchMode = self::BATCH_MODE_JSON, bool $appendNewline = true, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false)
+    {
+        $this->batchMode = $batchMode;
+        $this->appendNewline = $appendNewline;
+        $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
+        $this->includeStacktraces = $includeStacktraces;
+
+        parent::__construct();
+    }
+
+    /**
+     * The batch mode option configures the formatting style for
+     * multiple records. By default, multiple records will be
+     * formatted as a JSON-encoded array. However, for
+     * compatibility with some API endpoints, alternative styles
+     * are available.
+     */
+    public function getBatchMode(): int
+    {
+        return $this->batchMode;
+    }
+
+    /**
+     * True if newlines are appended to every formatted record
+     */
+    public function isAppendingNewlines(): bool
+    {
+        return $this->appendNewline;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record): string
+    {
+        $normalized = $this->normalize($record);
+
+        if (isset($normalized['context']) && $normalized['context'] === []) {
+            if ($this->ignoreEmptyContextAndExtra) {
+                unset($normalized['context']);
+            } else {
+                $normalized['context'] = new \stdClass;
+            }
+        }
+        if (isset($normalized['extra']) && $normalized['extra'] === []) {
+            if ($this->ignoreEmptyContextAndExtra) {
+                unset($normalized['extra']);
+            } else {
+                $normalized['extra'] = new \stdClass;
+            }
+        }
+
+        return $this->toJson($normalized, true) . ($this->appendNewline ? "\n" : '');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function formatBatch(array $records): string
+    {
+        switch ($this->batchMode) {
+            case static::BATCH_MODE_NEWLINES:
+                return $this->formatBatchNewlines($records);
+
+            case static::BATCH_MODE_JSON:
+            default:
+                return $this->formatBatchJson($records);
+        }
+    }
+
+    /**
+     * @return self
+     */
+    public function includeStacktraces(bool $include = true): self
+    {
+        $this->includeStacktraces = $include;
+
+        return $this;
+    }
+
+    /**
+     * Return a JSON-encoded array of records.
+     *
+     * @phpstan-param Record[] $records
+     */
+    protected function formatBatchJson(array $records): string
+    {
+        return $this->toJson($this->normalize($records), true);
+    }
+
+    /**
+     * Use new lines to separate records instead of a
+     * JSON-encoded array.
+     *
+     * @phpstan-param Record[] $records
+     */
+    protected function formatBatchNewlines(array $records): string
+    {
+        $instance = $this;
+
+        $oldNewline = $this->appendNewline;
+        $this->appendNewline = false;
+        array_walk($records, function (&$value, $key) use ($instance) {
+            $value = $instance->format($value);
+        });
+        $this->appendNewline = $oldNewline;
+
+        return implode("\n", $records);
+    }
+
+    /**
+     * Normalizes given $data.
+     *
+     * @param mixed $data
+     *
+     * @return mixed
+     */
+    protected function normalize($data, int $depth = 0)
+    {
+        if ($depth > $this->maxNormalizeDepth) {
+            return 'Over '.$this->maxNormalizeDepth.' levels deep, aborting normalization';
+        }
+
+        if (is_array($data)) {
+            $normalized = [];
+
+            $count = 1;
+            foreach ($data as $key => $value) {
+                if ($count++ > $this->maxNormalizeItemCount) {
+                    $normalized['...'] = 'Over '.$this->maxNormalizeItemCount.' items ('.count($data).' total), aborting normalization';
+                    break;
+                }
+
+                $normalized[$key] = $this->normalize($value, $depth + 1);
+            }
+
+            return $normalized;
+        }
+
+        if (is_object($data)) {
+            if ($data instanceof \DateTimeInterface) {
+                return $this->formatDate($data);
+            }
+
+            if ($data instanceof Throwable) {
+                return $this->normalizeException($data, $depth);
+            }
+
+            // if the object has specific json serializability we want to make sure we skip the __toString treatment below
+            if ($data instanceof \JsonSerializable) {
+                return $data;
+            }
+
+            if (method_exists($data, '__toString')) {
+                return $data->__toString();
+            }
+
+            return $data;
+        }
+
+        if (is_resource($data)) {
+            return parent::normalize($data);
+        }
+
+        return $data;
+    }
+
+    /**
+     * Normalizes given exception with or without its own stack trace based on
+     * `includeStacktraces` property.
+     *
+     * {@inheritDoc}
+     */
+    protected function normalizeException(Throwable $e, int $depth = 0): array
+    {
+        $data = parent::normalizeException($e, $depth);
+        if (!$this->includeStacktraces) {
+            unset($data['trace']);
+        }
+
+        return $data;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php
new file mode 100644
index 00000000..b31b2971
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php
@@ -0,0 +1,246 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Utils;
+
+/**
+ * Formats incoming records into a one-line string
+ *
+ * This is especially useful for logging to files
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class LineFormatter extends NormalizerFormatter
+{
+    public const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
+
+    /** @var string */
+    protected $format;
+    /** @var bool */
+    protected $allowInlineLineBreaks;
+    /** @var bool */
+    protected $ignoreEmptyContextAndExtra;
+    /** @var bool */
+    protected $includeStacktraces;
+    /** @var ?callable */
+    protected $stacktracesParser;
+
+    /**
+     * @param string|null $format                     The format of the message
+     * @param string|null $dateFormat                 The format of the timestamp: one supported by DateTime::format
+     * @param bool        $allowInlineLineBreaks      Whether to allow inline line breaks in log entries
+     * @param bool        $ignoreEmptyContextAndExtra
+     */
+    public function __construct(?string $format = null, ?string $dateFormat = null, bool $allowInlineLineBreaks = false, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false)
+    {
+        $this->format = $format === null ? static::SIMPLE_FORMAT : $format;
+        $this->allowInlineLineBreaks = $allowInlineLineBreaks;
+        $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
+        $this->includeStacktraces($includeStacktraces);
+        parent::__construct($dateFormat);
+    }
+
+    public function includeStacktraces(bool $include = true, ?callable $parser = null): self
+    {
+        $this->includeStacktraces = $include;
+        if ($this->includeStacktraces) {
+            $this->allowInlineLineBreaks = true;
+            $this->stacktracesParser = $parser;
+        }
+
+        return $this;
+    }
+
+    public function allowInlineLineBreaks(bool $allow = true): self
+    {
+        $this->allowInlineLineBreaks = $allow;
+
+        return $this;
+    }
+
+    public function ignoreEmptyContextAndExtra(bool $ignore = true): self
+    {
+        $this->ignoreEmptyContextAndExtra = $ignore;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record): string
+    {
+        $vars = parent::format($record);
+
+        $output = $this->format;
+
+        foreach ($vars['extra'] as $var => $val) {
+            if (false !== strpos($output, '%extra.'.$var.'%')) {
+                $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output);
+                unset($vars['extra'][$var]);
+            }
+        }
+
+        foreach ($vars['context'] as $var => $val) {
+            if (false !== strpos($output, '%context.'.$var.'%')) {
+                $output = str_replace('%context.'.$var.'%', $this->stringify($val), $output);
+                unset($vars['context'][$var]);
+            }
+        }
+
+        if ($this->ignoreEmptyContextAndExtra) {
+            if (empty($vars['context'])) {
+                unset($vars['context']);
+                $output = str_replace('%context%', '', $output);
+            }
+
+            if (empty($vars['extra'])) {
+                unset($vars['extra']);
+                $output = str_replace('%extra%', '', $output);
+            }
+        }
+
+        foreach ($vars as $var => $val) {
+            if (false !== strpos($output, '%'.$var.'%')) {
+                $output = str_replace('%'.$var.'%', $this->stringify($val), $output);
+            }
+        }
+
+        // remove leftover %extra.xxx% and %context.xxx% if any
+        if (false !== strpos($output, '%')) {
+            $output = preg_replace('/%(?:extra|context)\..+?%/', '', $output);
+            if (null === $output) {
+                $pcreErrorCode = preg_last_error();
+                throw new \RuntimeException('Failed to run preg_replace: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
+            }
+        }
+
+        return $output;
+    }
+
+    public function formatBatch(array $records): string
+    {
+        $message = '';
+        foreach ($records as $record) {
+            $message .= $this->format($record);
+        }
+
+        return $message;
+    }
+
+    /**
+     * @param mixed $value
+     */
+    public function stringify($value): string
+    {
+        return $this->replaceNewlines($this->convertToString($value));
+    }
+
+    protected function normalizeException(\Throwable $e, int $depth = 0): string
+    {
+        $str = $this->formatException($e);
+
+        if ($previous = $e->getPrevious()) {
+            do {
+                $depth++;
+                if ($depth > $this->maxNormalizeDepth) {
+                    $str .= '\n[previous exception] Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization';
+                    break;
+                }
+
+                $str .= "\n[previous exception] " . $this->formatException($previous);
+            } while ($previous = $previous->getPrevious());
+        }
+
+        return $str;
+    }
+
+    /**
+     * @param mixed $data
+     */
+    protected function convertToString($data): string
+    {
+        if (null === $data || is_bool($data)) {
+            return var_export($data, true);
+        }
+
+        if (is_scalar($data)) {
+            return (string) $data;
+        }
+
+        return $this->toJson($data, true);
+    }
+
+    protected function replaceNewlines(string $str): string
+    {
+        if ($this->allowInlineLineBreaks) {
+            if (0 === strpos($str, '{')) {
+                $str = preg_replace('/(?<!\\\\)\\\\[rn]/', "\n", $str);
+                if (null === $str) {
+                    $pcreErrorCode = preg_last_error();
+                    throw new \RuntimeException('Failed to run preg_replace: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
+                }
+            }
+
+            return $str;
+        }
+
+        return str_replace(["\r\n", "\r", "\n"], ' ', $str);
+    }
+
+    private function formatException(\Throwable $e): string
+    {
+        $str = '[object] (' . Utils::getClass($e) . '(code: ' . $e->getCode();
+        if ($e instanceof \SoapFault) {
+            if (isset($e->faultcode)) {
+                $str .= ' faultcode: ' . $e->faultcode;
+            }
+
+            if (isset($e->faultactor)) {
+                $str .= ' faultactor: ' . $e->faultactor;
+            }
+
+            if (isset($e->detail)) {
+                if (is_string($e->detail)) {
+                    $str .= ' detail: ' . $e->detail;
+                } elseif (is_object($e->detail) || is_array($e->detail)) {
+                    $str .= ' detail: ' . $this->toJson($e->detail, true);
+                }
+            }
+        }
+        $str .= '): ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine() . ')';
+
+        if ($this->includeStacktraces) {
+            $str .= $this->stacktracesParser($e);
+        }
+
+        return $str;
+    }
+
+    private function stacktracesParser(\Throwable $e): string
+    {
+        $trace = $e->getTraceAsString();
+
+        if ($this->stacktracesParser) {
+            $trace = $this->stacktracesParserCustom($trace);
+        }
+
+        return "\n[stacktrace]\n" . $trace . "\n";
+    }
+
+    private function stacktracesParserCustom(string $trace): string
+    {
+        return implode("\n", array_filter(array_map($this->stacktracesParser, explode("\n", $trace))));
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php
new file mode 100644
index 00000000..29841aa3
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php
@@ -0,0 +1,45 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Encodes message information into JSON in a format compatible with Loggly.
+ *
+ * @author Adam Pancutt <adam@pancutt.com>
+ */
+class LogglyFormatter extends JsonFormatter
+{
+    /**
+     * Overrides the default batch mode to new lines for compatibility with the
+     * Loggly bulk API.
+     */
+    public function __construct(int $batchMode = self::BATCH_MODE_NEWLINES, bool $appendNewline = false)
+    {
+        parent::__construct($batchMode, $appendNewline);
+    }
+
+    /**
+     * Appends the 'timestamp' parameter for indexing by Loggly.
+     *
+     * @see https://www.loggly.com/docs/automated-parsing/#json
+     * @see \Monolog\Formatter\JsonFormatter::format()
+     */
+    public function format(array $record): string
+    {
+        if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTimeInterface)) {
+            $record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO");
+            unset($record["datetime"]);
+        }
+
+        return parent::format($record);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogmaticFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogmaticFormatter.php
new file mode 100644
index 00000000..b0451aba
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogmaticFormatter.php
@@ -0,0 +1,66 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Encodes message information into JSON in a format compatible with Logmatic.
+ *
+ * @author Julien Breux <julien.breux@gmail.com>
+ */
+class LogmaticFormatter extends JsonFormatter
+{
+    protected const MARKERS = ["sourcecode", "php"];
+
+    /**
+     * @var string
+     */
+    protected $hostname = '';
+
+    /**
+     * @var string
+     */
+    protected $appname = '';
+
+    public function setHostname(string $hostname): self
+    {
+        $this->hostname = $hostname;
+
+        return $this;
+    }
+
+    public function setAppname(string $appname): self
+    {
+        $this->appname = $appname;
+
+        return $this;
+    }
+
+    /**
+     * Appends the 'hostname' and 'appname' parameter for indexing by Logmatic.
+     *
+     * @see http://doc.logmatic.io/docs/basics-to-send-data
+     * @see \Monolog\Formatter\JsonFormatter::format()
+     */
+    public function format(array $record): string
+    {
+        if (!empty($this->hostname)) {
+            $record["hostname"] = $this->hostname;
+        }
+        if (!empty($this->appname)) {
+            $record["appname"] = $this->appname;
+        }
+
+        $record["@marker"] = static::MARKERS;
+
+        return parent::format($record);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php
new file mode 100644
index 00000000..f8de0d33
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php
@@ -0,0 +1,101 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Serializes a log message to Logstash Event Format
+ *
+ * @see https://www.elastic.co/products/logstash
+ * @see https://github.com/elastic/logstash/blob/master/logstash-core/src/main/java/org/logstash/Event.java
+ *
+ * @author Tim Mower <timothy.mower@gmail.com>
+ */
+class LogstashFormatter extends NormalizerFormatter
+{
+    /**
+     * @var string the name of the system for the Logstash log message, used to fill the @source field
+     */
+    protected $systemName;
+
+    /**
+     * @var string an application name for the Logstash log message, used to fill the @type field
+     */
+    protected $applicationName;
+
+    /**
+     * @var string the key for 'extra' fields from the Monolog record
+     */
+    protected $extraKey;
+
+    /**
+     * @var string the key for 'context' fields from the Monolog record
+     */
+    protected $contextKey;
+
+    /**
+     * @param string      $applicationName The application that sends the data, used as the "type" field of logstash
+     * @param string|null $systemName      The system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine
+     * @param string      $extraKey        The key for extra keys inside logstash "fields", defaults to extra
+     * @param string      $contextKey      The key for context keys inside logstash "fields", defaults to context
+     */
+    public function __construct(string $applicationName, ?string $systemName = null, string $extraKey = 'extra', string $contextKey = 'context')
+    {
+        // logstash requires a ISO 8601 format date with optional millisecond precision.
+        parent::__construct('Y-m-d\TH:i:s.uP');
+
+        $this->systemName = $systemName === null ? (string) gethostname() : $systemName;
+        $this->applicationName = $applicationName;
+        $this->extraKey = $extraKey;
+        $this->contextKey = $contextKey;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function format(array $record): string
+    {
+        $record = parent::format($record);
+
+        if (empty($record['datetime'])) {
+            $record['datetime'] = gmdate('c');
+        }
+        $message = [
+            '@timestamp' => $record['datetime'],
+            '@version' => 1,
+            'host' => $this->systemName,
+        ];
+        if (isset($record['message'])) {
+            $message['message'] = $record['message'];
+        }
+        if (isset($record['channel'])) {
+            $message['type'] = $record['channel'];
+            $message['channel'] = $record['channel'];
+        }
+        if (isset($record['level_name'])) {
+            $message['level'] = $record['level_name'];
+        }
+        if (isset($record['level'])) {
+            $message['monolog_level'] = $record['level'];
+        }
+        if ($this->applicationName) {
+            $message['type'] = $this->applicationName;
+        }
+        if (!empty($record['extra'])) {
+            $message[$this->extraKey] = $record['extra'];
+        }
+        if (!empty($record['context'])) {
+            $message[$this->contextKey] = $record['context'];
+        }
+
+        return $this->toJson($message) . "\n";
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php
new file mode 100644
index 00000000..fca69a89
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php
@@ -0,0 +1,162 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use MongoDB\BSON\Type;
+use MongoDB\BSON\UTCDateTime;
+use Monolog\Utils;
+
+/**
+ * Formats a record for use with the MongoDBHandler.
+ *
+ * @author Florian Plattner <me@florianplattner.de>
+ */
+class MongoDBFormatter implements FormatterInterface
+{
+    /** @var bool */
+    private $exceptionTraceAsString;
+    /** @var int */
+    private $maxNestingLevel;
+    /** @var bool */
+    private $isLegacyMongoExt;
+
+    /**
+     * @param int  $maxNestingLevel        0 means infinite nesting, the $record itself is level 1, $record['context'] is 2
+     * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings
+     */
+    public function __construct(int $maxNestingLevel = 3, bool $exceptionTraceAsString = true)
+    {
+        $this->maxNestingLevel = max($maxNestingLevel, 0);
+        $this->exceptionTraceAsString = $exceptionTraceAsString;
+
+        $this->isLegacyMongoExt = extension_loaded('mongodb') && version_compare((string) phpversion('mongodb'), '1.1.9', '<=');
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return mixed[]
+     */
+    public function format(array $record): array
+    {
+        /** @var mixed[] $res */
+        $res = $this->formatArray($record);
+
+        return $res;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return array<mixed[]>
+     */
+    public function formatBatch(array $records): array
+    {
+        $formatted = [];
+        foreach ($records as $key => $record) {
+            $formatted[$key] = $this->format($record);
+        }
+
+        return $formatted;
+    }
+
+    /**
+     * @param  mixed[]        $array
+     * @return mixed[]|string Array except when max nesting level is reached then a string "[...]"
+     */
+    protected function formatArray(array $array, int $nestingLevel = 0)
+    {
+        if ($this->maxNestingLevel > 0 && $nestingLevel > $this->maxNestingLevel) {
+            return '[...]';
+        }
+
+        foreach ($array as $name => $value) {
+            if ($value instanceof \DateTimeInterface) {
+                $array[$name] = $this->formatDate($value, $nestingLevel + 1);
+            } elseif ($value instanceof \Throwable) {
+                $array[$name] = $this->formatException($value, $nestingLevel + 1);
+            } elseif (is_array($value)) {
+                $array[$name] = $this->formatArray($value, $nestingLevel + 1);
+            } elseif (is_object($value) && !$value instanceof Type) {
+                $array[$name] = $this->formatObject($value, $nestingLevel + 1);
+            }
+        }
+
+        return $array;
+    }
+
+    /**
+     * @param  mixed          $value
+     * @return mixed[]|string
+     */
+    protected function formatObject($value, int $nestingLevel)
+    {
+        $objectVars = get_object_vars($value);
+        $objectVars['class'] = Utils::getClass($value);
+
+        return $this->formatArray($objectVars, $nestingLevel);
+    }
+
+    /**
+     * @return mixed[]|string
+     */
+    protected function formatException(\Throwable $exception, int $nestingLevel)
+    {
+        $formattedException = [
+            'class' => Utils::getClass($exception),
+            'message' => $exception->getMessage(),
+            'code' => (int) $exception->getCode(),
+            'file' => $exception->getFile() . ':' . $exception->getLine(),
+        ];
+
+        if ($this->exceptionTraceAsString === true) {
+            $formattedException['trace'] = $exception->getTraceAsString();
+        } else {
+            $formattedException['trace'] = $exception->getTrace();
+        }
+
+        return $this->formatArray($formattedException, $nestingLevel);
+    }
+
+    protected function formatDate(\DateTimeInterface $value, int $nestingLevel): UTCDateTime
+    {
+        if ($this->isLegacyMongoExt) {
+            return $this->legacyGetMongoDbDateTime($value);
+        }
+
+        return $this->getMongoDbDateTime($value);
+    }
+
+    private function getMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
+    {
+        return new UTCDateTime((int) floor(((float) $value->format('U.u')) * 1000));
+    }
+
+    /**
+     * This is needed to support MongoDB Driver v1.19 and below
+     *
+     * See https://github.com/mongodb/mongo-php-driver/issues/426
+     *
+     * It can probably be removed in 2.1 or later once MongoDB's 1.2 is released and widely adopted
+     */
+    private function legacyGetMongoDbDateTime(\DateTimeInterface $value): UTCDateTime
+    {
+        $milliseconds = floor(((float) $value->format('U.u')) * 1000);
+
+        $milliseconds = (PHP_INT_SIZE == 8) //64-bit OS?
+            ? (int) $milliseconds
+            : (string) $milliseconds;
+
+        // @phpstan-ignore-next-line
+        return new UTCDateTime($milliseconds);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php
new file mode 100644
index 00000000..5441bc0a
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php
@@ -0,0 +1,287 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\DateTimeImmutable;
+use Monolog\Utils;
+use Throwable;
+
+/**
+ * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class NormalizerFormatter implements FormatterInterface
+{
+    public const SIMPLE_DATE = "Y-m-d\TH:i:sP";
+
+    /** @var string */
+    protected $dateFormat;
+    /** @var int */
+    protected $maxNormalizeDepth = 9;
+    /** @var int */
+    protected $maxNormalizeItemCount = 1000;
+
+    /** @var int */
+    private $jsonEncodeOptions = Utils::DEFAULT_JSON_FLAGS;
+
+    /**
+     * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format
+     */
+    public function __construct(?string $dateFormat = null)
+    {
+        $this->dateFormat = null === $dateFormat ? static::SIMPLE_DATE : $dateFormat;
+        if (!function_exists('json_encode')) {
+            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter');
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param mixed[] $record
+     */
+    public function format(array $record)
+    {
+        return $this->normalize($record);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function formatBatch(array $records)
+    {
+        foreach ($records as $key => $record) {
+            $records[$key] = $this->format($record);
+        }
+
+        return $records;
+    }
+
+    public function getDateFormat(): string
+    {
+        return $this->dateFormat;
+    }
+
+    public function setDateFormat(string $dateFormat): self
+    {
+        $this->dateFormat = $dateFormat;
+
+        return $this;
+    }
+
+    /**
+     * The maximum number of normalization levels to go through
+     */
+    public function getMaxNormalizeDepth(): int
+    {
+        return $this->maxNormalizeDepth;
+    }
+
+    public function setMaxNormalizeDepth(int $maxNormalizeDepth): self
+    {
+        $this->maxNormalizeDepth = $maxNormalizeDepth;
+
+        return $this;
+    }
+
+    /**
+     * The maximum number of items to normalize per level
+     */
+    public function getMaxNormalizeItemCount(): int
+    {
+        return $this->maxNormalizeItemCount;
+    }
+
+    public function setMaxNormalizeItemCount(int $maxNormalizeItemCount): self
+    {
+        $this->maxNormalizeItemCount = $maxNormalizeItemCount;
+
+        return $this;
+    }
+
+    /**
+     * Enables `json_encode` pretty print.
+     */
+    public function setJsonPrettyPrint(bool $enable): self
+    {
+        if ($enable) {
+            $this->jsonEncodeOptions |= JSON_PRETTY_PRINT;
+        } else {
+            $this->jsonEncodeOptions &= ~JSON_PRETTY_PRINT;
+        }
+
+        return $this;
+    }
+
+    /**
+     * @param  mixed                $data
+     * @return null|scalar|array<array|scalar|null>
+     */
+    protected function normalize($data, int $depth = 0)
+    {
+        if ($depth > $this->maxNormalizeDepth) {
+            return 'Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization';
+        }
+
+        if (null === $data || is_scalar($data)) {
+            if (is_float($data)) {
+                if (is_infinite($data)) {
+                    return ($data > 0 ? '' : '-') . 'INF';
+                }
+                if (is_nan($data)) {
+                    return 'NaN';
+                }
+            }
+
+            return $data;
+        }
+
+        if (is_array($data)) {
+            $normalized = [];
+
+            $count = 1;
+            foreach ($data as $key => $value) {
+                if ($count++ > $this->maxNormalizeItemCount) {
+                    $normalized['...'] = 'Over ' . $this->maxNormalizeItemCount . ' items ('.count($data).' total), aborting normalization';
+                    break;
+                }
+
+                $normalized[$key] = $this->normalize($value, $depth + 1);
+            }
+
+            return $normalized;
+        }
+
+        if ($data instanceof \DateTimeInterface) {
+            return $this->formatDate($data);
+        }
+
+        if (is_object($data)) {
+            if ($data instanceof Throwable) {
+                return $this->normalizeException($data, $depth);
+            }
+
+            if ($data instanceof \JsonSerializable) {
+                /** @var null|scalar|array<array|scalar|null> $value */
+                $value = $data->jsonSerialize();
+            } elseif (method_exists($data, '__toString')) {
+                /** @var string $value */
+                $value = $data->__toString();
+            } else {
+                // the rest is normalized by json encoding and decoding it
+                /** @var null|scalar|array<array|scalar|null> $value */
+                $value = json_decode($this->toJson($data, true), true);
+            }
+
+            return [Utils::getClass($data) => $value];
+        }
+
+        if (is_resource($data)) {
+            return sprintf('[resource(%s)]', get_resource_type($data));
+        }
+
+        return '[unknown('.gettype($data).')]';
+    }
+
+    /**
+     * @return mixed[]
+     */
+    protected function normalizeException(Throwable $e, int $depth = 0)
+    {
+        if ($depth > $this->maxNormalizeDepth) {
+            return ['Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization'];
+        }
+
+        if ($e instanceof \JsonSerializable) {
+            return (array) $e->jsonSerialize();
+        }
+
+        $data = [
+            'class' => Utils::getClass($e),
+            'message' => $e->getMessage(),
+            'code' => (int) $e->getCode(),
+            'file' => $e->getFile().':'.$e->getLine(),
+        ];
+
+        if ($e instanceof \SoapFault) {
+            if (isset($e->faultcode)) {
+                $data['faultcode'] = $e->faultcode;
+            }
+
+            if (isset($e->faultactor)) {
+                $data['faultactor'] = $e->faultactor;
+            }
+
+            if (isset($e->detail)) {
+                if (is_string($e->detail)) {
+                    $data['detail'] = $e->detail;
+                } elseif (is_object($e->detail) || is_array($e->detail)) {
+                    $data['detail'] = $this->toJson($e->detail, true);
+                }
+            }
+        }
+
+        $trace = $e->getTrace();
+        foreach ($trace as $frame) {
+            if (isset($frame['file'])) {
+                $data['trace'][] = $frame['file'].':'.$frame['line'];
+            }
+        }
+
+        if ($previous = $e->getPrevious()) {
+            $data['previous'] = $this->normalizeException($previous, $depth + 1);
+        }
+
+        return $data;
+    }
+
+    /**
+     * Return the JSON representation of a value
+     *
+     * @param  mixed             $data
+     * @throws \RuntimeException if encoding fails and errors are not ignored
+     * @return string            if encoding fails and ignoreErrors is true 'null' is returned
+     */
+    protected function toJson($data, bool $ignoreErrors = false): string
+    {
+        return Utils::jsonEncode($data, $this->jsonEncodeOptions, $ignoreErrors);
+    }
+
+    /**
+     * @return string
+     */
+    protected function formatDate(\DateTimeInterface $date)
+    {
+        // in case the date format isn't custom then we defer to the custom DateTimeImmutable
+        // formatting logic, which will pick the right format based on whether useMicroseconds is on
+        if ($this->dateFormat === self::SIMPLE_DATE && $date instanceof DateTimeImmutable) {
+            return (string) $date;
+        }
+
+        return $date->format($this->dateFormat);
+    }
+
+    public function addJsonEncodeOption(int $option): self
+    {
+        $this->jsonEncodeOptions |= $option;
+
+        return $this;
+    }
+
+    public function removeJsonEncodeOption(int $option): self
+    {
+        $this->jsonEncodeOptions &= ~$option;
+
+        return $this;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php
new file mode 100644
index 00000000..187bc550
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php
@@ -0,0 +1,51 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Formats data into an associative array of scalar values.
+ * Objects and arrays will be JSON encoded.
+ *
+ * @author Andrew Lawson <adlawson@gmail.com>
+ */
+class ScalarFormatter extends NormalizerFormatter
+{
+    /**
+     * {@inheritDoc}
+     *
+     * @phpstan-return array<string, scalar|null> $record
+     */
+    public function format(array $record): array
+    {
+        $result = [];
+        foreach ($record as $key => $value) {
+            $result[$key] = $this->normalizeValue($value);
+        }
+
+        return $result;
+    }
+
+    /**
+     * @param  mixed                      $value
+     * @return scalar|null
+     */
+    protected function normalizeValue($value)
+    {
+        $normalized = $this->normalize($value);
+
+        if (is_array($normalized)) {
+            return $this->toJson($normalized, true);
+        }
+
+        return $normalized;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php b/msd/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php
new file mode 100644
index 00000000..6539b347
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php
@@ -0,0 +1,139 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+/**
+ * Serializes a log message according to Wildfire's header requirements
+ *
+ * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
+ * @author Christophe Coevoet <stof@notk.org>
+ * @author Kirill chEbba Chebunin <iam@chebba.org>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+class WildfireFormatter extends NormalizerFormatter
+{
+    /**
+     * Translates Monolog log levels to Wildfire levels.
+     *
+     * @var array<Level, string>
+     */
+    private $logLevels = [
+        Logger::DEBUG     => 'LOG',
+        Logger::INFO      => 'INFO',
+        Logger::NOTICE    => 'INFO',
+        Logger::WARNING   => 'WARN',
+        Logger::ERROR     => 'ERROR',
+        Logger::CRITICAL  => 'ERROR',
+        Logger::ALERT     => 'ERROR',
+        Logger::EMERGENCY => 'ERROR',
+    ];
+
+    /**
+     * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format
+     */
+    public function __construct(?string $dateFormat = null)
+    {
+        parent::__construct($dateFormat);
+
+        // http headers do not like non-ISO-8559-1 characters
+        $this->removeJsonEncodeOption(JSON_UNESCAPED_UNICODE);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return string
+     */
+    public function format(array $record): string
+    {
+        // Retrieve the line and file if set and remove them from the formatted extra
+        $file = $line = '';
+        if (isset($record['extra']['file'])) {
+            $file = $record['extra']['file'];
+            unset($record['extra']['file']);
+        }
+        if (isset($record['extra']['line'])) {
+            $line = $record['extra']['line'];
+            unset($record['extra']['line']);
+        }
+
+        /** @var mixed[] $record */
+        $record = $this->normalize($record);
+        $message = ['message' => $record['message']];
+        $handleError = false;
+        if ($record['context']) {
+            $message['context'] = $record['context'];
+            $handleError = true;
+        }
+        if ($record['extra']) {
+            $message['extra'] = $record['extra'];
+            $handleError = true;
+        }
+        if (count($message) === 1) {
+            $message = reset($message);
+        }
+
+        if (isset($record['context']['table'])) {
+            $type  = 'TABLE';
+            $label = $record['channel'] .': '. $record['message'];
+            $message = $record['context']['table'];
+        } else {
+            $type  = $this->logLevels[$record['level']];
+            $label = $record['channel'];
+        }
+
+        // Create JSON object describing the appearance of the message in the console
+        $json = $this->toJson([
+            [
+                'Type'  => $type,
+                'File'  => $file,
+                'Line'  => $line,
+                'Label' => $label,
+            ],
+            $message,
+        ], $handleError);
+
+        // The message itself is a serialization of the above JSON object + it's length
+        return sprintf(
+            '%d|%s|',
+            strlen($json),
+            $json
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @phpstan-return never
+     */
+    public function formatBatch(array $records)
+    {
+        throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter');
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return null|scalar|array<array|scalar|null>|object
+     */
+    protected function normalize($data, int $depth = 0)
+    {
+        if (is_object($data) && !$data instanceof \DateTimeInterface) {
+            return $data;
+        }
+
+        return parent::normalize($data, $depth);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php
new file mode 100644
index 00000000..a5cdaa71
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php
@@ -0,0 +1,112 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\ResettableInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * Base Handler class providing basic level/bubble support
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+abstract class AbstractHandler extends Handler implements ResettableInterface
+{
+    /**
+     * @var int
+     * @phpstan-var Level
+     */
+    protected $level = Logger::DEBUG;
+    /** @var bool */
+    protected $bubble = true;
+
+    /**
+     * @param int|string $level  The minimum logging level at which this handler will be triggered
+     * @param bool       $bubble Whether the messages that are handled can bubble up the stack or not
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function __construct($level = Logger::DEBUG, bool $bubble = true)
+    {
+        $this->setLevel($level);
+        $this->bubble = $bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        return $record['level'] >= $this->level;
+    }
+
+    /**
+     * Sets minimum logging level at which this handler will be triggered.
+     *
+     * @param  Level|LevelName|LogLevel::* $level Level or level name
+     * @return self
+     */
+    public function setLevel($level): self
+    {
+        $this->level = Logger::toMonologLevel($level);
+
+        return $this;
+    }
+
+    /**
+     * Gets minimum logging level at which this handler will be triggered.
+     *
+     * @return int
+     *
+     * @phpstan-return Level
+     */
+    public function getLevel(): int
+    {
+        return $this->level;
+    }
+
+    /**
+     * Sets the bubbling behavior.
+     *
+     * @param  bool $bubble true means that this handler allows bubbling.
+     *                      false means that bubbling is not permitted.
+     * @return self
+     */
+    public function setBubble(bool $bubble): self
+    {
+        $this->bubble = $bubble;
+
+        return $this;
+    }
+
+    /**
+     * Gets the bubbling behavior.
+     *
+     * @return bool true means that this handler allows bubbling.
+     *              false means that bubbling is not permitted.
+     */
+    public function getBubble(): bool
+    {
+        return $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function reset()
+    {
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php
new file mode 100644
index 00000000..77e533fc
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php
@@ -0,0 +1,69 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+/**
+ * Base Handler class providing the Handler structure, including processors and formatters
+ *
+ * Classes extending it should (in most cases) only implement write($record)
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @author Christophe Coevoet <stof@notk.org>
+ *
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-type FormattedRecord array{message: string, context: mixed[], level: Level, level_name: LevelName, channel: string, datetime: \DateTimeImmutable, extra: mixed[], formatted: mixed}
+ */
+abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
+{
+    use ProcessableHandlerTrait;
+    use FormattableHandlerTrait;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if (!$this->isHandling($record)) {
+            return false;
+        }
+
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+
+        $record['formatted'] = $this->getFormatter()->format($record);
+
+        $this->write($record);
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * Writes the record down to the log of the implementing handler
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    abstract protected function write(array $record): void;
+
+    /**
+     * @return void
+     */
+    public function reset()
+    {
+        parent::reset();
+
+        $this->resetProcessors();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php
new file mode 100644
index 00000000..5e5ad1c1
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php
@@ -0,0 +1,106 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LineFormatter;
+
+/**
+ * Common syslog functionality
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+abstract class AbstractSyslogHandler extends AbstractProcessingHandler
+{
+    /** @var int */
+    protected $facility;
+
+    /**
+     * Translates Monolog log levels to syslog log priorities.
+     * @var array
+     * @phpstan-var array<Level, int>
+     */
+    protected $logLevels = [
+        Logger::DEBUG     => LOG_DEBUG,
+        Logger::INFO      => LOG_INFO,
+        Logger::NOTICE    => LOG_NOTICE,
+        Logger::WARNING   => LOG_WARNING,
+        Logger::ERROR     => LOG_ERR,
+        Logger::CRITICAL  => LOG_CRIT,
+        Logger::ALERT     => LOG_ALERT,
+        Logger::EMERGENCY => LOG_EMERG,
+    ];
+
+    /**
+     * List of valid log facility names.
+     * @var array<string, int>
+     */
+    protected $facilities = [
+        'auth'     => LOG_AUTH,
+        'authpriv' => LOG_AUTHPRIV,
+        'cron'     => LOG_CRON,
+        'daemon'   => LOG_DAEMON,
+        'kern'     => LOG_KERN,
+        'lpr'      => LOG_LPR,
+        'mail'     => LOG_MAIL,
+        'news'     => LOG_NEWS,
+        'syslog'   => LOG_SYSLOG,
+        'user'     => LOG_USER,
+        'uucp'     => LOG_UUCP,
+    ];
+
+    /**
+     * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant
+     */
+    public function __construct($facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
+            $this->facilities['local0'] = LOG_LOCAL0;
+            $this->facilities['local1'] = LOG_LOCAL1;
+            $this->facilities['local2'] = LOG_LOCAL2;
+            $this->facilities['local3'] = LOG_LOCAL3;
+            $this->facilities['local4'] = LOG_LOCAL4;
+            $this->facilities['local5'] = LOG_LOCAL5;
+            $this->facilities['local6'] = LOG_LOCAL6;
+            $this->facilities['local7'] = LOG_LOCAL7;
+        } else {
+            $this->facilities['local0'] = 128; // LOG_LOCAL0
+            $this->facilities['local1'] = 136; // LOG_LOCAL1
+            $this->facilities['local2'] = 144; // LOG_LOCAL2
+            $this->facilities['local3'] = 152; // LOG_LOCAL3
+            $this->facilities['local4'] = 160; // LOG_LOCAL4
+            $this->facilities['local5'] = 168; // LOG_LOCAL5
+            $this->facilities['local6'] = 176; // LOG_LOCAL6
+            $this->facilities['local7'] = 184; // LOG_LOCAL7
+        }
+
+        // convert textual description of facility to syslog constant
+        if (is_string($facility) && array_key_exists(strtolower($facility), $this->facilities)) {
+            $facility = $this->facilities[strtolower($facility)];
+        } elseif (!in_array($facility, array_values($this->facilities), true)) {
+            throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
+        }
+
+        $this->facility = $facility;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php
new file mode 100644
index 00000000..c4997482
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php
@@ -0,0 +1,170 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\JsonFormatter;
+use PhpAmqpLib\Message\AMQPMessage;
+use PhpAmqpLib\Channel\AMQPChannel;
+use AMQPExchange;
+
+/**
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class AmqpHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var AMQPExchange|AMQPChannel $exchange
+     */
+    protected $exchange;
+    /** @var array<string, mixed> */
+    private $extraAttributes = [];
+
+    /**
+     * @return array<string, mixed>
+     */
+    public function getExtraAttributes(): array
+    {
+        return $this->extraAttributes;
+    }
+
+    /**
+     * Configure extra attributes to pass to the AMQPExchange (if you are using the amqp extension)
+     *
+     * @param array<string, mixed> $extraAttributes  One of content_type, content_encoding,
+     *                                               message_id, user_id, app_id, delivery_mode,
+     *                                               priority, timestamp, expiration, type
+     *                                               or reply_to, headers.
+     * @return AmqpHandler
+     */
+    public function setExtraAttributes(array $extraAttributes): self
+    {
+        $this->extraAttributes = $extraAttributes;
+        return $this;
+    }
+
+    /**
+     * @var string
+     */
+    protected $exchangeName;
+
+    /**
+     * @param AMQPExchange|AMQPChannel $exchange     AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use
+     * @param string|null              $exchangeName Optional exchange name, for AMQPChannel (PhpAmqpLib) only
+     */
+    public function __construct($exchange, ?string $exchangeName = null, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        if ($exchange instanceof AMQPChannel) {
+            $this->exchangeName = (string) $exchangeName;
+        } elseif (!$exchange instanceof AMQPExchange) {
+            throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required');
+        } elseif ($exchangeName) {
+            @trigger_error('The $exchangeName parameter can only be passed when using PhpAmqpLib, if using an AMQPExchange instance configure it beforehand', E_USER_DEPRECATED);
+        }
+        $this->exchange = $exchange;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $data = $record["formatted"];
+        $routingKey = $this->getRoutingKey($record);
+
+        if ($this->exchange instanceof AMQPExchange) {
+            $attributes = [
+                'delivery_mode' => 2,
+                'content_type'  => 'application/json',
+            ];
+            if ($this->extraAttributes) {
+                $attributes = array_merge($attributes, $this->extraAttributes);
+            }
+            $this->exchange->publish(
+                $data,
+                $routingKey,
+                0,
+                $attributes
+            );
+        } else {
+            $this->exchange->basic_publish(
+                $this->createAmqpMessage($data),
+                $this->exchangeName,
+                $routingKey
+            );
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        if ($this->exchange instanceof AMQPExchange) {
+            parent::handleBatch($records);
+
+            return;
+        }
+
+        foreach ($records as $record) {
+            if (!$this->isHandling($record)) {
+                continue;
+            }
+
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+            $data = $this->getFormatter()->format($record);
+
+            $this->exchange->batch_basic_publish(
+                $this->createAmqpMessage($data),
+                $this->exchangeName,
+                $this->getRoutingKey($record)
+            );
+        }
+
+        $this->exchange->publish_batch();
+    }
+
+    /**
+     * Gets the routing key for the AMQP exchange
+     *
+     * @phpstan-param Record $record
+     */
+    protected function getRoutingKey(array $record): string
+    {
+        $routingKey = sprintf('%s.%s', $record['level_name'], $record['channel']);
+
+        return strtolower($routingKey);
+    }
+
+    private function createAmqpMessage(string $data): AMQPMessage
+    {
+        return new AMQPMessage(
+            $data,
+            [
+                'delivery_mode' => 2,
+                'content_type' => 'application/json',
+            ]
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php
new file mode 100644
index 00000000..fa383f1c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php
@@ -0,0 +1,293 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LineFormatter;
+use Monolog\Utils;
+
+use function count;
+use function headers_list;
+use function stripos;
+use function trigger_error;
+
+use const E_USER_DEPRECATED;
+
+/**
+ * Handler sending logs to browser's javascript console with no browser extension required
+ *
+ * @author Olivier Poitrey <rs@dailymotion.com>
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class BrowserConsoleHandler extends AbstractProcessingHandler
+{
+    /** @var bool */
+    protected static $initialized = false;
+    /** @var FormattedRecord[] */
+    protected static $records = [];
+
+    protected const FORMAT_HTML = 'html';
+    protected const FORMAT_JS = 'js';
+    protected const FORMAT_UNKNOWN = 'unknown';
+
+    /**
+     * {@inheritDoc}
+     *
+     * Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format.
+     *
+     * Example of formatted string:
+     *
+     *     You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        // Accumulate records
+        static::$records[] = $record;
+
+        // Register shutdown handler if not already done
+        if (!static::$initialized) {
+            static::$initialized = true;
+            $this->registerShutdownFunction();
+        }
+    }
+
+    /**
+     * Convert records to javascript console commands and send it to the browser.
+     * This method is automatically called on PHP shutdown if output is HTML or Javascript.
+     */
+    public static function send(): void
+    {
+        $format = static::getResponseFormat();
+        if ($format === self::FORMAT_UNKNOWN) {
+            return;
+        }
+
+        if (count(static::$records)) {
+            if ($format === self::FORMAT_HTML) {
+                static::writeOutput('<script>' . static::generateScript() . '</script>');
+            } elseif ($format === self::FORMAT_JS) {
+                static::writeOutput(static::generateScript());
+            }
+            static::resetStatic();
+        }
+    }
+
+    public function close(): void
+    {
+        self::resetStatic();
+    }
+
+    public function reset()
+    {
+        parent::reset();
+
+        self::resetStatic();
+    }
+
+    /**
+     * Forget all logged records
+     */
+    public static function resetStatic(): void
+    {
+        static::$records = [];
+    }
+
+    /**
+     * Wrapper for register_shutdown_function to allow overriding
+     */
+    protected function registerShutdownFunction(): void
+    {
+        if (PHP_SAPI !== 'cli') {
+            register_shutdown_function(['Monolog\Handler\BrowserConsoleHandler', 'send']);
+        }
+    }
+
+    /**
+     * Wrapper for echo to allow overriding
+     */
+    protected static function writeOutput(string $str): void
+    {
+        echo $str;
+    }
+
+    /**
+     * Checks the format of the response
+     *
+     * If Content-Type is set to application/javascript or text/javascript -> js
+     * If Content-Type is set to text/html, or is unset -> html
+     * If Content-Type is anything else -> unknown
+     *
+     * @return string One of 'js', 'html' or 'unknown'
+     * @phpstan-return self::FORMAT_*
+     */
+    protected static function getResponseFormat(): string
+    {
+        // Check content type
+        foreach (headers_list() as $header) {
+            if (stripos($header, 'content-type:') === 0) {
+                return static::getResponseFormatFromContentType($header);
+            }
+        }
+
+        return self::FORMAT_HTML;
+    }
+
+    /**
+     * @return string One of 'js', 'html' or 'unknown'
+     * @phpstan-return self::FORMAT_*
+     */
+    protected static function getResponseFormatFromContentType(string $contentType): string
+    {
+        // This handler only works with HTML and javascript outputs
+        // text/javascript is obsolete in favour of application/javascript, but still used
+        if (stripos($contentType, 'application/javascript') !== false || stripos($contentType, 'text/javascript') !== false) {
+            return self::FORMAT_JS;
+        }
+
+        if (stripos($contentType, 'text/html') !== false) {
+            return self::FORMAT_HTML;
+        }
+
+        return self::FORMAT_UNKNOWN;
+    }
+
+    private static function generateScript(): string
+    {
+        $script = [];
+        foreach (static::$records as $record) {
+            $context = static::dump('Context', $record['context']);
+            $extra = static::dump('Extra', $record['extra']);
+
+            if (empty($context) && empty($extra)) {
+                $script[] = static::call_array('log', static::handleStyles($record['formatted']));
+            } else {
+                $script = array_merge(
+                    $script,
+                    [static::call_array('groupCollapsed', static::handleStyles($record['formatted']))],
+                    $context,
+                    $extra,
+                    [static::call('groupEnd')]
+                );
+            }
+        }
+
+        return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
+    }
+
+    /**
+     * @return string[]
+     */
+    private static function handleStyles(string $formatted): array
+    {
+        $args = [];
+        $format = '%c' . $formatted;
+        preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+
+        foreach (array_reverse($matches) as $match) {
+            $args[] = '"font-weight: normal"';
+            $args[] = static::quote(static::handleCustomStyles($match[2][0], $match[1][0]));
+
+            $pos = $match[0][1];
+            $format = Utils::substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . Utils::substr($format, $pos + strlen($match[0][0]));
+        }
+
+        $args[] = static::quote('font-weight: normal');
+        $args[] = static::quote($format);
+
+        return array_reverse($args);
+    }
+
+    private static function handleCustomStyles(string $style, string $string): string
+    {
+        static $colors = ['blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey'];
+        static $labels = [];
+
+        $style = preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function (array $m) use ($string, &$colors, &$labels) {
+            if (trim($m[1]) === 'autolabel') {
+                // Format the string as a label with consistent auto assigned background color
+                if (!isset($labels[$string])) {
+                    $labels[$string] = $colors[count($labels) % count($colors)];
+                }
+                $color = $labels[$string];
+
+                return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px";
+            }
+
+            return $m[1];
+        }, $style);
+
+        if (null === $style) {
+            $pcreErrorCode = preg_last_error();
+            throw new \RuntimeException('Failed to run preg_replace_callback: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
+        }
+
+        return $style;
+    }
+
+    /**
+     * @param  mixed[] $dict
+     * @return mixed[]
+     */
+    private static function dump(string $title, array $dict): array
+    {
+        $script = [];
+        $dict = array_filter($dict);
+        if (empty($dict)) {
+            return $script;
+        }
+        $script[] = static::call('log', static::quote('%c%s'), static::quote('font-weight: bold'), static::quote($title));
+        foreach ($dict as $key => $value) {
+            $value = json_encode($value);
+            if (empty($value)) {
+                $value = static::quote('');
+            }
+            $script[] = static::call('log', static::quote('%s: %o'), static::quote((string) $key), $value);
+        }
+
+        return $script;
+    }
+
+    private static function quote(string $arg): string
+    {
+        return '"' . addcslashes($arg, "\"\n\\") . '"';
+    }
+
+    /**
+     * @param mixed $args
+     */
+    private static function call(...$args): string
+    {
+        $method = array_shift($args);
+        if (!is_string($method)) {
+            throw new \UnexpectedValueException('Expected the first arg to be a string, got: '.var_export($method, true));
+        }
+
+        return static::call_array($method, $args);
+    }
+
+    /**
+     * @param mixed[] $args
+     */
+    private static function call_array(string $method, array $args): string
+    {
+        return 'c.' . $method . '(' . implode(', ', $args) . ');';
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php
new file mode 100644
index 00000000..fcce5d63
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php
@@ -0,0 +1,167 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\ResettableInterface;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Buffers all records until closing the handler and then pass them as batch.
+ *
+ * This is useful for a MailHandler to send only one mail per request instead of
+ * sending one per log message.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
+{
+    use ProcessableHandlerTrait;
+
+    /** @var HandlerInterface */
+    protected $handler;
+    /** @var int */
+    protected $bufferSize = 0;
+    /** @var int */
+    protected $bufferLimit;
+    /** @var bool */
+    protected $flushOnOverflow;
+    /** @var Record[] */
+    protected $buffer = [];
+    /** @var bool */
+    protected $initialized = false;
+
+    /**
+     * @param HandlerInterface $handler         Handler.
+     * @param int              $bufferLimit     How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
+     * @param bool             $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
+     */
+    public function __construct(HandlerInterface $handler, int $bufferLimit = 0, $level = Logger::DEBUG, bool $bubble = true, bool $flushOnOverflow = false)
+    {
+        parent::__construct($level, $bubble);
+        $this->handler = $handler;
+        $this->bufferLimit = $bufferLimit;
+        $this->flushOnOverflow = $flushOnOverflow;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($record['level'] < $this->level) {
+            return false;
+        }
+
+        if (!$this->initialized) {
+            // __destructor() doesn't get called on Fatal errors
+            register_shutdown_function([$this, 'close']);
+            $this->initialized = true;
+        }
+
+        if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
+            if ($this->flushOnOverflow) {
+                $this->flush();
+            } else {
+                array_shift($this->buffer);
+                $this->bufferSize--;
+            }
+        }
+
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+
+        $this->buffer[] = $record;
+        $this->bufferSize++;
+
+        return false === $this->bubble;
+    }
+
+    public function flush(): void
+    {
+        if ($this->bufferSize === 0) {
+            return;
+        }
+
+        $this->handler->handleBatch($this->buffer);
+        $this->clear();
+    }
+
+    public function __destruct()
+    {
+        // suppress the parent behavior since we already have register_shutdown_function()
+        // to call close(), and the reference contained there will prevent this from being
+        // GC'd until the end of the request
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        $this->flush();
+
+        $this->handler->close();
+    }
+
+    /**
+     * Clears the buffer without flushing any messages down to the wrapped handler.
+     */
+    public function clear(): void
+    {
+        $this->bufferSize = 0;
+        $this->buffer = [];
+    }
+
+    public function reset()
+    {
+        $this->flush();
+
+        parent::reset();
+
+        $this->resetProcessors();
+
+        if ($this->handler instanceof ResettableInterface) {
+            $this->handler->reset();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            $this->handler->setFormatter($formatter);
+
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            return $this->handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php
new file mode 100644
index 00000000..234ecf61
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php
@@ -0,0 +1,196 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\ChromePHPFormatter;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
+ *
+ * This also works out of the box with Firefox 43+
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class ChromePHPHandler extends AbstractProcessingHandler
+{
+    use WebRequestRecognizerTrait;
+
+    /**
+     * Version of the extension
+     */
+    protected const VERSION = '4.0';
+
+    /**
+     * Header name
+     */
+    protected const HEADER_NAME = 'X-ChromeLogger-Data';
+
+    /**
+     * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+)
+     */
+    protected const USER_AGENT_REGEX = '{\b(?:Chrome/\d+(?:\.\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\d|\d{3,})(?:\.\d)*)\b}';
+
+    /** @var bool */
+    protected static $initialized = false;
+
+    /**
+     * Tracks whether we sent too much data
+     *
+     * Chrome limits the headers to 4KB, so when we sent 3KB we stop sending
+     *
+     * @var bool
+     */
+    protected static $overflowed = false;
+
+    /** @var mixed[] */
+    protected static $json = [
+        'version' => self::VERSION,
+        'columns' => ['label', 'log', 'backtrace', 'type'],
+        'rows' => [],
+    ];
+
+    /** @var bool */
+    protected static $sendHeaders = true;
+
+    public function __construct($level = Logger::DEBUG, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+        if (!function_exists('json_encode')) {
+            throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler');
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        if (!$this->isWebRequest()) {
+            return;
+        }
+
+        $messages = [];
+
+        foreach ($records as $record) {
+            if ($record['level'] < $this->level) {
+                continue;
+            }
+            /** @var Record $message */
+            $message = $this->processRecord($record);
+            $messages[] = $message;
+        }
+
+        if (!empty($messages)) {
+            $messages = $this->getFormatter()->formatBatch($messages);
+            self::$json['rows'] = array_merge(self::$json['rows'], $messages);
+            $this->send();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new ChromePHPFormatter();
+    }
+
+    /**
+     * Creates & sends header for a record
+     *
+     * @see sendHeader()
+     * @see send()
+     */
+    protected function write(array $record): void
+    {
+        if (!$this->isWebRequest()) {
+            return;
+        }
+
+        self::$json['rows'][] = $record['formatted'];
+
+        $this->send();
+    }
+
+    /**
+     * Sends the log header
+     *
+     * @see sendHeader()
+     */
+    protected function send(): void
+    {
+        if (self::$overflowed || !self::$sendHeaders) {
+            return;
+        }
+
+        if (!self::$initialized) {
+            self::$initialized = true;
+
+            self::$sendHeaders = $this->headersAccepted();
+            if (!self::$sendHeaders) {
+                return;
+            }
+
+            self::$json['request_uri'] = $_SERVER['REQUEST_URI'] ?? '';
+        }
+
+        $json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true);
+        $data = base64_encode($json);
+        if (strlen($data) > 3 * 1024) {
+            self::$overflowed = true;
+
+            $record = [
+                'message' => 'Incomplete logs, chrome header size limit reached',
+                'context' => [],
+                'level' => Logger::WARNING,
+                'level_name' => Logger::getLevelName(Logger::WARNING),
+                'channel' => 'monolog',
+                'datetime' => new \DateTimeImmutable(),
+                'extra' => [],
+            ];
+            self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record);
+            $json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true);
+            $data = base64_encode($json);
+        }
+
+        if (trim($data) !== '') {
+            $this->sendHeader(static::HEADER_NAME, $data);
+        }
+    }
+
+    /**
+     * Send header string to the client
+     */
+    protected function sendHeader(string $header, string $content): void
+    {
+        if (!headers_sent() && self::$sendHeaders) {
+            header(sprintf('%s: %s', $header, $content));
+        }
+    }
+
+    /**
+     * Verifies if the headers are accepted by the current user agent
+     */
+    protected function headersAccepted(): bool
+    {
+        if (empty($_SERVER['HTTP_USER_AGENT'])) {
+            return false;
+        }
+
+        return preg_match(static::USER_AGENT_REGEX, $_SERVER['HTTP_USER_AGENT']) === 1;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php
new file mode 100644
index 00000000..52657613
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\JsonFormatter;
+use Monolog\Logger;
+
+/**
+ * CouchDB handler
+ *
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
+ */
+class CouchDBHandler extends AbstractProcessingHandler
+{
+    /** @var mixed[] */
+    private $options;
+
+    /**
+     * @param mixed[] $options
+     */
+    public function __construct(array $options = [], $level = Logger::DEBUG, bool $bubble = true)
+    {
+        $this->options = array_merge([
+            'host'     => 'localhost',
+            'port'     => 5984,
+            'dbname'   => 'logger',
+            'username' => null,
+            'password' => null,
+        ], $options);
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $basicAuth = null;
+        if ($this->options['username']) {
+            $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']);
+        }
+
+        $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname'];
+        $context = stream_context_create([
+            'http' => [
+                'method'        => 'POST',
+                'content'       => $record['formatted'],
+                'ignore_errors' => true,
+                'max_redirects' => 0,
+                'header'        => 'Content-type: application/json',
+            ],
+        ]);
+
+        if (false === @file_get_contents($url, false, $context)) {
+            throw new \RuntimeException(sprintf('Could not connect to %s', $url));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php
new file mode 100644
index 00000000..3535a4fc
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php
@@ -0,0 +1,167 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Logs to Cube.
+ *
+ * @link https://github.com/square/cube/wiki
+ * @author Wan Chen <kami@kamisama.me>
+ * @deprecated Since 2.8.0 and 3.2.0, Cube appears abandoned and thus we will drop this handler in Monolog 4
+ */
+class CubeHandler extends AbstractProcessingHandler
+{
+    /** @var resource|\Socket|null */
+    private $udpConnection = null;
+    /** @var resource|\CurlHandle|null */
+    private $httpConnection = null;
+    /** @var string */
+    private $scheme;
+    /** @var string */
+    private $host;
+    /** @var int */
+    private $port;
+    /** @var string[] */
+    private $acceptedSchemes = ['http', 'udp'];
+
+    /**
+     * Create a Cube handler
+     *
+     * @throws \UnexpectedValueException when given url is not a valid url.
+     *                                   A valid url must consist of three parts : protocol://host:port
+     *                                   Only valid protocols used by Cube are http and udp
+     */
+    public function __construct(string $url, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        $urlInfo = parse_url($url);
+
+        if ($urlInfo === false || !isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) {
+            throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
+        }
+
+        if (!in_array($urlInfo['scheme'], $this->acceptedSchemes)) {
+            throw new \UnexpectedValueException(
+                'Invalid protocol (' . $urlInfo['scheme']  . ').'
+                . ' Valid options are ' . implode(', ', $this->acceptedSchemes)
+            );
+        }
+
+        $this->scheme = $urlInfo['scheme'];
+        $this->host = $urlInfo['host'];
+        $this->port = (int) $urlInfo['port'];
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * Establish a connection to an UDP socket
+     *
+     * @throws \LogicException           when unable to connect to the socket
+     * @throws MissingExtensionException when there is no socket extension
+     */
+    protected function connectUdp(): void
+    {
+        if (!extension_loaded('sockets')) {
+            throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler');
+        }
+
+        $udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
+        if (false === $udpConnection) {
+            throw new \LogicException('Unable to create a socket');
+        }
+
+        $this->udpConnection = $udpConnection;
+        if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
+            throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
+        }
+    }
+
+    /**
+     * Establish a connection to an http server
+     *
+     * @throws \LogicException           when unable to connect to the socket
+     * @throws MissingExtensionException when no curl extension
+     */
+    protected function connectHttp(): void
+    {
+        if (!extension_loaded('curl')) {
+            throw new MissingExtensionException('The curl extension is required to use http URLs with the CubeHandler');
+        }
+
+        $httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
+        if (false === $httpConnection) {
+            throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
+        }
+
+        $this->httpConnection = $httpConnection;
+        curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
+        curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $date = $record['datetime'];
+
+        $data = ['time' => $date->format('Y-m-d\TH:i:s.uO')];
+        unset($record['datetime']);
+
+        if (isset($record['context']['type'])) {
+            $data['type'] = $record['context']['type'];
+            unset($record['context']['type']);
+        } else {
+            $data['type'] = $record['channel'];
+        }
+
+        $data['data'] = $record['context'];
+        $data['data']['level'] = $record['level'];
+
+        if ($this->scheme === 'http') {
+            $this->writeHttp(Utils::jsonEncode($data));
+        } else {
+            $this->writeUdp(Utils::jsonEncode($data));
+        }
+    }
+
+    private function writeUdp(string $data): void
+    {
+        if (!$this->udpConnection) {
+            $this->connectUdp();
+        }
+
+        socket_send($this->udpConnection, $data, strlen($data), 0);
+    }
+
+    private function writeHttp(string $data): void
+    {
+        if (!$this->httpConnection) {
+            $this->connectHttp();
+        }
+
+        if (null === $this->httpConnection) {
+            throw new \LogicException('No connection could be established');
+        }
+
+        curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
+        curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [
+            'Content-Type: application/json',
+            'Content-Length: ' . strlen('['.$data.']'),
+        ]);
+
+        Curl\Util::execute($this->httpConnection, 5, false);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php
new file mode 100644
index 00000000..7213e8ee
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php
@@ -0,0 +1,71 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\Curl;
+
+use CurlHandle;
+
+/**
+ * This class is marked as internal and it is not under the BC promise of the package.
+ *
+ * @internal
+ */
+final class Util
+{
+    /** @var array<int> */
+    private static $retriableErrorCodes = [
+        CURLE_COULDNT_RESOLVE_HOST,
+        CURLE_COULDNT_CONNECT,
+        CURLE_HTTP_NOT_FOUND,
+        CURLE_READ_ERROR,
+        CURLE_OPERATION_TIMEOUTED,
+        CURLE_HTTP_POST_ERROR,
+        CURLE_SSL_CONNECT_ERROR,
+    ];
+
+    /**
+     * Executes a CURL request with optional retries and exception on failure
+     *
+     * @param  resource|CurlHandle $ch             curl handler
+     * @param  int                 $retries
+     * @param  bool                $closeAfterDone
+     * @return bool|string         @see curl_exec
+     */
+    public static function execute($ch, int $retries = 5, bool $closeAfterDone = true)
+    {
+        while ($retries--) {
+            $curlResponse = curl_exec($ch);
+            if ($curlResponse === false) {
+                $curlErrno = curl_errno($ch);
+
+                if (false === in_array($curlErrno, self::$retriableErrorCodes, true) || !$retries) {
+                    $curlError = curl_error($ch);
+
+                    if ($closeAfterDone) {
+                        curl_close($ch);
+                    }
+
+                    throw new \RuntimeException(sprintf('Curl error (code %d): %s', $curlErrno, $curlError));
+                }
+
+                continue;
+            }
+
+            if ($closeAfterDone) {
+                curl_close($ch);
+            }
+
+            return $curlResponse;
+        }
+
+        return false;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php
new file mode 100644
index 00000000..9b85ae7e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php
@@ -0,0 +1,186 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Simple handler wrapper that deduplicates log records across multiple requests
+ *
+ * It also includes the BufferHandler functionality and will buffer
+ * all messages until the end of the request or flush() is called.
+ *
+ * This works by storing all log records' messages above $deduplicationLevel
+ * to the file specified by $deduplicationStore. When further logs come in at the end of the
+ * request (or when flush() is called), all those above $deduplicationLevel are checked
+ * against the existing stored logs. If they match and the timestamps in the stored log is
+ * not older than $time seconds, the new log record is discarded. If no log record is new, the
+ * whole data set is discarded.
+ *
+ * This is mainly useful in combination with Mail handlers or things like Slack or HipChat handlers
+ * that send messages to people, to avoid spamming with the same message over and over in case of
+ * a major component failure like a database server being down which makes all requests fail in the
+ * same way.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+class DeduplicationHandler extends BufferHandler
+{
+    /**
+     * @var string
+     */
+    protected $deduplicationStore;
+
+    /**
+     * @var Level
+     */
+    protected $deduplicationLevel;
+
+    /**
+     * @var int
+     */
+    protected $time;
+
+    /**
+     * @var bool
+     */
+    private $gc = false;
+
+    /**
+     * @param HandlerInterface $handler            Handler.
+     * @param string           $deduplicationStore The file/path where the deduplication log should be kept
+     * @param string|int       $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes
+     * @param int              $time               The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through
+     * @param bool             $bubble             Whether the messages that are handled can bubble up the stack or not
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $deduplicationLevel
+     */
+    public function __construct(HandlerInterface $handler, ?string $deduplicationStore = null, $deduplicationLevel = Logger::ERROR, int $time = 60, bool $bubble = true)
+    {
+        parent::__construct($handler, 0, Logger::DEBUG, $bubble, false);
+
+        $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore;
+        $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel);
+        $this->time = $time;
+    }
+
+    public function flush(): void
+    {
+        if ($this->bufferSize === 0) {
+            return;
+        }
+
+        $passthru = null;
+
+        foreach ($this->buffer as $record) {
+            if ($record['level'] >= $this->deduplicationLevel) {
+                $passthru = $passthru || !$this->isDuplicate($record);
+                if ($passthru) {
+                    $this->appendRecord($record);
+                }
+            }
+        }
+
+        // default of null is valid as well as if no record matches duplicationLevel we just pass through
+        if ($passthru === true || $passthru === null) {
+            $this->handler->handleBatch($this->buffer);
+        }
+
+        $this->clear();
+
+        if ($this->gc) {
+            $this->collectLogs();
+        }
+    }
+
+    /**
+     * @phpstan-param Record $record
+     */
+    private function isDuplicate(array $record): bool
+    {
+        if (!file_exists($this->deduplicationStore)) {
+            return false;
+        }
+
+        $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+        if (!is_array($store)) {
+            return false;
+        }
+
+        $yesterday = time() - 86400;
+        $timestampValidity = $record['datetime']->getTimestamp() - $this->time;
+        $expectedMessage = preg_replace('{[\r\n].*}', '', $record['message']);
+
+        for ($i = count($store) - 1; $i >= 0; $i--) {
+            list($timestamp, $level, $message) = explode(':', $store[$i], 3);
+
+            if ($level === $record['level_name'] && $message === $expectedMessage && $timestamp > $timestampValidity) {
+                return true;
+            }
+
+            if ($timestamp < $yesterday) {
+                $this->gc = true;
+            }
+        }
+
+        return false;
+    }
+
+    private function collectLogs(): void
+    {
+        if (!file_exists($this->deduplicationStore)) {
+            return;
+        }
+
+        $handle = fopen($this->deduplicationStore, 'rw+');
+
+        if (!$handle) {
+            throw new \RuntimeException('Failed to open file for reading and writing: ' . $this->deduplicationStore);
+        }
+
+        flock($handle, LOCK_EX);
+        $validLogs = [];
+
+        $timestampValidity = time() - $this->time;
+
+        while (!feof($handle)) {
+            $log = fgets($handle);
+            if ($log && substr($log, 0, 10) >= $timestampValidity) {
+                $validLogs[] = $log;
+            }
+        }
+
+        ftruncate($handle, 0);
+        rewind($handle);
+        foreach ($validLogs as $log) {
+            fwrite($handle, $log);
+        }
+
+        flock($handle, LOCK_UN);
+        fclose($handle);
+
+        $this->gc = false;
+    }
+
+    /**
+     * @phpstan-param Record $record
+     */
+    private function appendRecord(array $record): void
+    {
+        file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php
new file mode 100644
index 00000000..ebd52c3a
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php
@@ -0,0 +1,47 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\NormalizerFormatter;
+use Monolog\Formatter\FormatterInterface;
+use Doctrine\CouchDB\CouchDBClient;
+
+/**
+ * CouchDB handler for Doctrine CouchDB ODM
+ *
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
+ */
+class DoctrineCouchDBHandler extends AbstractProcessingHandler
+{
+    /** @var CouchDBClient */
+    private $client;
+
+    public function __construct(CouchDBClient $client, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        $this->client = $client;
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->client->postDocument($record['formatted']);
+    }
+
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new NormalizerFormatter;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php
new file mode 100644
index 00000000..21840bf6
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php
@@ -0,0 +1,104 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Aws\Sdk;
+use Aws\DynamoDb\DynamoDbClient;
+use Monolog\Formatter\FormatterInterface;
+use Aws\DynamoDb\Marshaler;
+use Monolog\Formatter\ScalarFormatter;
+use Monolog\Logger;
+
+/**
+ * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
+ *
+ * @link https://github.com/aws/aws-sdk-php/
+ * @author Andrew Lawson <adlawson@gmail.com>
+ */
+class DynamoDbHandler extends AbstractProcessingHandler
+{
+    public const DATE_FORMAT = 'Y-m-d\TH:i:s.uO';
+
+    /**
+     * @var DynamoDbClient
+     */
+    protected $client;
+
+    /**
+     * @var string
+     */
+    protected $table;
+
+    /**
+     * @var int
+     */
+    protected $version;
+
+    /**
+     * @var Marshaler
+     */
+    protected $marshaler;
+
+    public function __construct(DynamoDbClient $client, string $table, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        /** @phpstan-ignore-next-line */
+        if (defined('Aws\Sdk::VERSION') && version_compare(Sdk::VERSION, '3.0', '>=')) {
+            $this->version = 3;
+            $this->marshaler = new Marshaler;
+        } else {
+            $this->version = 2;
+        }
+
+        $this->client = $client;
+        $this->table = $table;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $filtered = $this->filterEmptyFields($record['formatted']);
+        if ($this->version === 3) {
+            $formatted = $this->marshaler->marshalItem($filtered);
+        } else {
+            /** @phpstan-ignore-next-line */
+            $formatted = $this->client->formatAttributes($filtered);
+        }
+
+        $this->client->putItem([
+            'TableName' => $this->table,
+            'Item' => $formatted,
+        ]);
+    }
+
+    /**
+     * @param  mixed[] $record
+     * @return mixed[]
+     */
+    protected function filterEmptyFields(array $record): array
+    {
+        return array_filter($record, function ($value) {
+            return !empty($value) || false === $value || 0 === $value;
+        });
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new ScalarFormatter(self::DATE_FORMAT);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ElasticaHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ElasticaHandler.php
new file mode 100644
index 00000000..fc92ca42
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ElasticaHandler.php
@@ -0,0 +1,129 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Elastica\Document;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\ElasticaFormatter;
+use Monolog\Logger;
+use Elastica\Client;
+use Elastica\Exception\ExceptionInterface;
+
+/**
+ * Elastic Search handler
+ *
+ * Usage example:
+ *
+ *    $client = new \Elastica\Client();
+ *    $options = array(
+ *        'index' => 'elastic_index_name',
+ *        'type' => 'elastic_doc_type', Types have been removed in Elastica 7
+ *    );
+ *    $handler = new ElasticaHandler($client, $options);
+ *    $log = new Logger('application');
+ *    $log->pushHandler($handler);
+ *
+ * @author Jelle Vink <jelle.vink@gmail.com>
+ */
+class ElasticaHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var Client
+     */
+    protected $client;
+
+    /**
+     * @var mixed[] Handler config options
+     */
+    protected $options = [];
+
+    /**
+     * @param Client  $client  Elastica Client object
+     * @param mixed[] $options Handler configuration
+     */
+    public function __construct(Client $client, array $options = [], $level = Logger::DEBUG, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+        $this->client = $client;
+        $this->options = array_merge(
+            [
+                'index'          => 'monolog',      // Elastic index name
+                'type'           => 'record',       // Elastic document type
+                'ignore_error'   => false,          // Suppress Elastica exceptions
+            ],
+            $options
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->bulkSend([$record['formatted']]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        if ($formatter instanceof ElasticaFormatter) {
+            return parent::setFormatter($formatter);
+        }
+
+        throw new \InvalidArgumentException('ElasticaHandler is only compatible with ElasticaFormatter');
+    }
+
+    /**
+     * @return mixed[]
+     */
+    public function getOptions(): array
+    {
+        return $this->options;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new ElasticaFormatter($this->options['index'], $this->options['type']);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        $documents = $this->getFormatter()->formatBatch($records);
+        $this->bulkSend($documents);
+    }
+
+    /**
+     * Use Elasticsearch bulk API to send list of documents
+     *
+     * @param Document[] $documents
+     *
+     * @throws \RuntimeException
+     */
+    protected function bulkSend(array $documents): void
+    {
+        try {
+            $this->client->addDocuments($documents);
+        } catch (ExceptionInterface $e) {
+            if (!$this->options['ignore_error']) {
+                throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e);
+            }
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php
new file mode 100644
index 00000000..e88375c0
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php
@@ -0,0 +1,218 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Elastic\Elasticsearch\Response\Elasticsearch;
+use Throwable;
+use RuntimeException;
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\ElasticsearchFormatter;
+use InvalidArgumentException;
+use Elasticsearch\Common\Exceptions\RuntimeException as ElasticsearchRuntimeException;
+use Elasticsearch\Client;
+use Elastic\Elasticsearch\Exception\InvalidArgumentException as ElasticInvalidArgumentException;
+use Elastic\Elasticsearch\Client as Client8;
+
+/**
+ * Elasticsearch handler
+ *
+ * @link https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html
+ *
+ * Simple usage example:
+ *
+ *    $client = \Elasticsearch\ClientBuilder::create()
+ *        ->setHosts($hosts)
+ *        ->build();
+ *
+ *    $options = array(
+ *        'index' => 'elastic_index_name',
+ *        'type'  => 'elastic_doc_type',
+ *    );
+ *    $handler = new ElasticsearchHandler($client, $options);
+ *    $log = new Logger('application');
+ *    $log->pushHandler($handler);
+ *
+ * @author Avtandil Kikabidze <akalongman@gmail.com>
+ */
+class ElasticsearchHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var Client|Client8
+     */
+    protected $client;
+
+    /**
+     * @var mixed[] Handler config options
+     */
+    protected $options = [];
+
+    /**
+     * @var bool
+     */
+    private $needsType;
+
+    /**
+     * @param Client|Client8 $client  Elasticsearch Client object
+     * @param mixed[]        $options Handler configuration
+     */
+    public function __construct($client, array $options = [], $level = Logger::DEBUG, bool $bubble = true)
+    {
+        if (!$client instanceof Client && !$client instanceof Client8) {
+            throw new \TypeError('Elasticsearch\Client or Elastic\Elasticsearch\Client instance required');
+        }
+
+        parent::__construct($level, $bubble);
+        $this->client = $client;
+        $this->options = array_merge(
+            [
+                'index'        => 'monolog', // Elastic index name
+                'type'         => '_doc',    // Elastic document type
+                'ignore_error' => false,     // Suppress Elasticsearch exceptions
+            ],
+            $options
+        );
+
+        if ($client instanceof Client8 || $client::VERSION[0] === '7') {
+            $this->needsType = false;
+            // force the type to _doc for ES8/ES7
+            $this->options['type'] = '_doc';
+        } else {
+            $this->needsType = true;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->bulkSend([$record['formatted']]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        if ($formatter instanceof ElasticsearchFormatter) {
+            return parent::setFormatter($formatter);
+        }
+
+        throw new InvalidArgumentException('ElasticsearchHandler is only compatible with ElasticsearchFormatter');
+    }
+
+    /**
+     * Getter options
+     *
+     * @return mixed[]
+     */
+    public function getOptions(): array
+    {
+        return $this->options;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new ElasticsearchFormatter($this->options['index'], $this->options['type']);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        $documents = $this->getFormatter()->formatBatch($records);
+        $this->bulkSend($documents);
+    }
+
+    /**
+     * Use Elasticsearch bulk API to send list of documents
+     *
+     * @param  array[]           $records Records + _index/_type keys
+     * @throws \RuntimeException
+     */
+    protected function bulkSend(array $records): void
+    {
+        try {
+            $params = [
+                'body' => [],
+            ];
+
+            foreach ($records as $record) {
+                $params['body'][] = [
+                    'index' => $this->needsType ? [
+                        '_index' => $record['_index'],
+                        '_type'  => $record['_type'],
+                    ] : [
+                        '_index' => $record['_index'],
+                    ],
+                ];
+                unset($record['_index'], $record['_type']);
+
+                $params['body'][] = $record;
+            }
+
+            /** @var Elasticsearch */
+            $responses = $this->client->bulk($params);
+
+            if ($responses['errors'] === true) {
+                throw $this->createExceptionFromResponses($responses);
+            }
+        } catch (Throwable $e) {
+            if (! $this->options['ignore_error']) {
+                throw new RuntimeException('Error sending messages to Elasticsearch', 0, $e);
+            }
+        }
+    }
+
+    /**
+     * Creates elasticsearch exception from responses array
+     *
+     * Only the first error is converted into an exception.
+     *
+     * @param mixed[]|Elasticsearch $responses returned by $this->client->bulk()
+     */
+    protected function createExceptionFromResponses($responses): Throwable
+    {
+        foreach ($responses['items'] ?? [] as $item) {
+            if (isset($item['index']['error'])) {
+                return $this->createExceptionFromError($item['index']['error']);
+            }
+        }
+
+        if (class_exists(ElasticInvalidArgumentException::class)) {
+            return new ElasticInvalidArgumentException('Elasticsearch failed to index one or more records.');
+        }
+
+        return new ElasticsearchRuntimeException('Elasticsearch failed to index one or more records.');
+    }
+
+    /**
+     * Creates elasticsearch exception from error array
+     *
+     * @param mixed[] $error
+     */
+    protected function createExceptionFromError(array $error): Throwable
+    {
+        $previous = isset($error['caused_by']) ? $this->createExceptionFromError($error['caused_by']) : null;
+
+        if (class_exists(ElasticInvalidArgumentException::class)) {
+            return new ElasticInvalidArgumentException($error['type'] . ': ' . $error['reason'], 0, $previous);
+        }
+
+        return new ElasticsearchRuntimeException($error['type'] . ': ' . $error['reason'], 0, $previous);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php
new file mode 100644
index 00000000..f2e22036
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php
@@ -0,0 +1,91 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\LineFormatter;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Stores to PHP error_log() handler.
+ *
+ * @author Elan Ruusamäe <glen@delfi.ee>
+ */
+class ErrorLogHandler extends AbstractProcessingHandler
+{
+    public const OPERATING_SYSTEM = 0;
+    public const SAPI = 4;
+
+    /** @var int */
+    protected $messageType;
+    /** @var bool */
+    protected $expandNewlines;
+
+    /**
+     * @param int  $messageType    Says where the error should go.
+     * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
+     */
+    public function __construct(int $messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, bool $bubble = true, bool $expandNewlines = false)
+    {
+        parent::__construct($level, $bubble);
+
+        if (false === in_array($messageType, self::getAvailableTypes(), true)) {
+            $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true));
+
+            throw new \InvalidArgumentException($message);
+        }
+
+        $this->messageType = $messageType;
+        $this->expandNewlines = $expandNewlines;
+    }
+
+    /**
+     * @return int[] With all available types
+     */
+    public static function getAvailableTypes(): array
+    {
+        return [
+            self::OPERATING_SYSTEM,
+            self::SAPI,
+        ];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if (!$this->expandNewlines) {
+            error_log((string) $record['formatted'], $this->messageType);
+
+            return;
+        }
+
+        $lines = preg_split('{[\r\n]+}', (string) $record['formatted']);
+        if ($lines === false) {
+            $pcreErrorCode = preg_last_error();
+            throw new \RuntimeException('Failed to preg_split formatted string: ' . $pcreErrorCode . ' / '. Utils::pcreLastErrorMessage($pcreErrorCode));
+        }
+        foreach ($lines as $line) {
+            error_log($line, $this->messageType);
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FallbackGroupHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FallbackGroupHandler.php
new file mode 100644
index 00000000..d4e234ce
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FallbackGroupHandler.php
@@ -0,0 +1,71 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Throwable;
+
+/**
+ * Forwards records to at most one handler
+ *
+ * If a handler fails, the exception is suppressed and the record is forwarded to the next handler.
+ *
+ * As soon as one handler handles a record successfully, the handling stops there.
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class FallbackGroupHandler extends GroupHandler
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+        foreach ($this->handlers as $handler) {
+            try {
+                $handler->handle($record);
+                break;
+            } catch (Throwable $e) {
+                // What throwable?
+            }
+        }
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        if ($this->processors) {
+            $processed = [];
+            foreach ($records as $record) {
+                $processed[] = $this->processRecord($record);
+            }
+            /** @var Record[] $records */
+            $records = $processed;
+        }
+
+        foreach ($this->handlers as $handler) {
+            try {
+                $handler->handleBatch($records);
+                break;
+            } catch (Throwable $e) {
+                // What throwable?
+            }
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php
new file mode 100644
index 00000000..718f17ef
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php
@@ -0,0 +1,212 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\ResettableInterface;
+use Monolog\Formatter\FormatterInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * Simple handler wrapper that filters records based on a list of levels
+ *
+ * It can be configured with an exact list of levels to allow, or a min/max level.
+ *
+ * @author Hennadiy Verkh
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface
+{
+    use ProcessableHandlerTrait;
+
+    /**
+     * Handler or factory callable($record, $this)
+     *
+     * @var callable|HandlerInterface
+     * @phpstan-var callable(?Record, HandlerInterface): HandlerInterface|HandlerInterface
+     */
+    protected $handler;
+
+    /**
+     * Minimum level for logs that are passed to handler
+     *
+     * @var int[]
+     * @phpstan-var array<Level, int>
+     */
+    protected $acceptedLevels;
+
+    /**
+     * Whether the messages that are handled can bubble up the stack or not
+     *
+     * @var bool
+     */
+    protected $bubble;
+
+    /**
+     * @psalm-param HandlerInterface|callable(?Record, HandlerInterface): HandlerInterface $handler
+     *
+     * @param callable|HandlerInterface $handler        Handler or factory callable($record|null, $filterHandler).
+     * @param int|array                 $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
+     * @param int|string                $maxLevel       Maximum level to accept, only used if $minLevelOrList is not an array
+     * @param bool                      $bubble         Whether the messages that are handled can bubble up the stack or not
+     *
+     * @phpstan-param Level|LevelName|LogLevel::*|array<Level|LevelName|LogLevel::*> $minLevelOrList
+     * @phpstan-param Level|LevelName|LogLevel::* $maxLevel
+     */
+    public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, bool $bubble = true)
+    {
+        $this->handler  = $handler;
+        $this->bubble   = $bubble;
+        $this->setAcceptedLevels($minLevelOrList, $maxLevel);
+
+        if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
+            throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
+        }
+    }
+
+    /**
+     * @phpstan-return array<int, Level>
+     */
+    public function getAcceptedLevels(): array
+    {
+        return array_flip($this->acceptedLevels);
+    }
+
+    /**
+     * @param int|string|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided
+     * @param int|string       $maxLevel       Maximum level or level name to accept, only used if $minLevelOrList is not an array
+     *
+     * @phpstan-param Level|LevelName|LogLevel::*|array<Level|LevelName|LogLevel::*> $minLevelOrList
+     * @phpstan-param Level|LevelName|LogLevel::*                                    $maxLevel
+     */
+    public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY): self
+    {
+        if (is_array($minLevelOrList)) {
+            $acceptedLevels = array_map('Monolog\Logger::toMonologLevel', $minLevelOrList);
+        } else {
+            $minLevelOrList = Logger::toMonologLevel($minLevelOrList);
+            $maxLevel = Logger::toMonologLevel($maxLevel);
+            $acceptedLevels = array_values(array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) {
+                return $level >= $minLevelOrList && $level <= $maxLevel;
+            }));
+        }
+        $this->acceptedLevels = array_flip($acceptedLevels);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        return isset($this->acceptedLevels[$record['level']]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if (!$this->isHandling($record)) {
+            return false;
+        }
+
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+
+        $this->getHandler($record)->handle($record);
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        $filtered = [];
+        foreach ($records as $record) {
+            if ($this->isHandling($record)) {
+                $filtered[] = $record;
+            }
+        }
+
+        if (count($filtered) > 0) {
+            $this->getHandler($filtered[count($filtered) - 1])->handleBatch($filtered);
+        }
+    }
+
+    /**
+     * Return the nested handler
+     *
+     * If the handler was provided as a factory callable, this will trigger the handler's instantiation.
+     *
+     * @return HandlerInterface
+     *
+     * @phpstan-param Record $record
+     */
+    public function getHandler(array $record = null)
+    {
+        if (!$this->handler instanceof HandlerInterface) {
+            $this->handler = ($this->handler)($record, $this);
+            if (!$this->handler instanceof HandlerInterface) {
+                throw new \RuntimeException("The factory callable should return a HandlerInterface");
+            }
+        }
+
+        return $this->handler;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            $handler->setFormatter($formatter);
+
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            return $handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
+    }
+
+    public function reset()
+    {
+        $this->resetProcessors();
+
+        if ($this->getHandler() instanceof ResettableInterface) {
+            $this->getHandler()->reset();
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php
new file mode 100644
index 00000000..0aa5607b
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php
@@ -0,0 +1,29 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\FingersCrossed;
+
+/**
+ * Interface for activation strategies for the FingersCrossedHandler.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+interface ActivationStrategyInterface
+{
+    /**
+     * Returns whether the given record activates the handler.
+     *
+     * @phpstan-param Record $record
+     */
+    public function isHandlerActivated(array $record): bool;
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php
new file mode 100644
index 00000000..7b9abb58
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\FingersCrossed;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Channel and Error level based monolog activation strategy. Allows to trigger activation
+ * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except
+ * for records of the 'sql' channel; those should trigger activation on level 'WARN'.
+ *
+ * Example:
+ *
+ * <code>
+ *   $activationStrategy = new ChannelLevelActivationStrategy(
+ *       Logger::CRITICAL,
+ *       array(
+ *           'request' => Logger::ALERT,
+ *           'sensitive' => Logger::ERROR,
+ *       )
+ *   );
+ *   $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy);
+ * </code>
+ *
+ * @author Mike Meessen <netmikey@gmail.com>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class ChannelLevelActivationStrategy implements ActivationStrategyInterface
+{
+    /**
+     * @var Level
+     */
+    private $defaultActionLevel;
+
+    /**
+     * @var array<string, Level>
+     */
+    private $channelToActionLevel;
+
+    /**
+     * @param int|string         $defaultActionLevel   The default action level to be used if the record's category doesn't match any
+     * @param array<string, int> $channelToActionLevel An array that maps channel names to action levels.
+     *
+     * @phpstan-param array<string, Level>        $channelToActionLevel
+     * @phpstan-param Level|LevelName|LogLevel::* $defaultActionLevel
+     */
+    public function __construct($defaultActionLevel, array $channelToActionLevel = [])
+    {
+        $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel);
+        $this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel);
+    }
+
+    /**
+     * @phpstan-param Record $record
+     */
+    public function isHandlerActivated(array $record): bool
+    {
+        if (isset($this->channelToActionLevel[$record['channel']])) {
+            return $record['level'] >= $this->channelToActionLevel[$record['channel']];
+        }
+
+        return $record['level'] >= $this->defaultActionLevel;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php
new file mode 100644
index 00000000..5ec88eab
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php
@@ -0,0 +1,46 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\FingersCrossed;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Error level based activation strategy.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class ErrorLevelActivationStrategy implements ActivationStrategyInterface
+{
+    /**
+     * @var Level
+     */
+    private $actionLevel;
+
+    /**
+     * @param int|string $actionLevel Level or name or value
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $actionLevel
+     */
+    public function __construct($actionLevel)
+    {
+        $this->actionLevel = Logger::toMonologLevel($actionLevel);
+    }
+
+    public function isHandlerActivated(array $record): bool
+    {
+        return $record['level'] >= $this->actionLevel;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php
new file mode 100644
index 00000000..0627b445
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php
@@ -0,0 +1,252 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
+use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
+use Monolog\Logger;
+use Monolog\ResettableInterface;
+use Monolog\Formatter\FormatterInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * Buffers all records until a certain level is reached
+ *
+ * The advantage of this approach is that you don't get any clutter in your log files.
+ * Only requests which actually trigger an error (or whatever your actionLevel is) will be
+ * in the logs, but they will contain all records, not only those above the level threshold.
+ *
+ * You can then have a passthruLevel as well which means that at the end of the request,
+ * even if it did not get activated, it will still send through log records of e.g. at least a
+ * warning level.
+ *
+ * You can find the various activation strategies in the
+ * Monolog\Handler\FingersCrossed\ namespace.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface
+{
+    use ProcessableHandlerTrait;
+
+    /**
+     * @var callable|HandlerInterface
+     * @phpstan-var callable(?Record, HandlerInterface): HandlerInterface|HandlerInterface
+     */
+    protected $handler;
+    /** @var ActivationStrategyInterface */
+    protected $activationStrategy;
+    /** @var bool */
+    protected $buffering = true;
+    /** @var int */
+    protected $bufferSize;
+    /** @var Record[] */
+    protected $buffer = [];
+    /** @var bool */
+    protected $stopBuffering;
+    /**
+     * @var ?int
+     * @phpstan-var ?Level
+     */
+    protected $passthruLevel;
+    /** @var bool */
+    protected $bubble;
+
+    /**
+     * @psalm-param HandlerInterface|callable(?Record, HandlerInterface): HandlerInterface $handler
+     *
+     * @param callable|HandlerInterface              $handler            Handler or factory callable($record|null, $fingersCrossedHandler).
+     * @param int|string|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated
+     * @param int                                    $bufferSize         How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
+     * @param bool                                   $bubble             Whether the messages that are handled can bubble up the stack or not
+     * @param bool                                   $stopBuffering      Whether the handler should stop buffering after being triggered (default true)
+     * @param int|string                             $passthruLevel      Minimum level to always flush to handler on close, even if strategy not triggered
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $passthruLevel
+     * @phpstan-param Level|LevelName|LogLevel::*|ActivationStrategyInterface $activationStrategy
+     */
+    public function __construct($handler, $activationStrategy = null, int $bufferSize = 0, bool $bubble = true, bool $stopBuffering = true, $passthruLevel = null)
+    {
+        if (null === $activationStrategy) {
+            $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING);
+        }
+
+        // convert simple int activationStrategy to an object
+        if (!$activationStrategy instanceof ActivationStrategyInterface) {
+            $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy);
+        }
+
+        $this->handler = $handler;
+        $this->activationStrategy = $activationStrategy;
+        $this->bufferSize = $bufferSize;
+        $this->bubble = $bubble;
+        $this->stopBuffering = $stopBuffering;
+
+        if ($passthruLevel !== null) {
+            $this->passthruLevel = Logger::toMonologLevel($passthruLevel);
+        }
+
+        if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
+            throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        return true;
+    }
+
+    /**
+     * Manually activate this logger regardless of the activation strategy
+     */
+    public function activate(): void
+    {
+        if ($this->stopBuffering) {
+            $this->buffering = false;
+        }
+
+        $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer);
+        $this->buffer = [];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+
+        if ($this->buffering) {
+            $this->buffer[] = $record;
+            if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) {
+                array_shift($this->buffer);
+            }
+            if ($this->activationStrategy->isHandlerActivated($record)) {
+                $this->activate();
+            }
+        } else {
+            $this->getHandler($record)->handle($record);
+        }
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        $this->flushBuffer();
+
+        $this->getHandler()->close();
+    }
+
+    public function reset()
+    {
+        $this->flushBuffer();
+
+        $this->resetProcessors();
+
+        if ($this->getHandler() instanceof ResettableInterface) {
+            $this->getHandler()->reset();
+        }
+    }
+
+    /**
+     * Clears the buffer without flushing any messages down to the wrapped handler.
+     *
+     * It also resets the handler to its initial buffering state.
+     */
+    public function clear(): void
+    {
+        $this->buffer = [];
+        $this->reset();
+    }
+
+    /**
+     * Resets the state of the handler. Stops forwarding records to the wrapped handler.
+     */
+    private function flushBuffer(): void
+    {
+        if (null !== $this->passthruLevel) {
+            $level = $this->passthruLevel;
+            $this->buffer = array_filter($this->buffer, function ($record) use ($level) {
+                return $record['level'] >= $level;
+            });
+            if (count($this->buffer) > 0) {
+                $this->getHandler(end($this->buffer))->handleBatch($this->buffer);
+            }
+        }
+
+        $this->buffer = [];
+        $this->buffering = true;
+    }
+
+    /**
+     * Return the nested handler
+     *
+     * If the handler was provided as a factory callable, this will trigger the handler's instantiation.
+     *
+     * @return HandlerInterface
+     *
+     * @phpstan-param Record $record
+     */
+    public function getHandler(array $record = null)
+    {
+        if (!$this->handler instanceof HandlerInterface) {
+            $this->handler = ($this->handler)($record, $this);
+            if (!$this->handler instanceof HandlerInterface) {
+                throw new \RuntimeException("The factory callable should return a HandlerInterface");
+            }
+        }
+
+        return $this->handler;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            $handler->setFormatter($formatter);
+
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            return $handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php
new file mode 100644
index 00000000..72718de6
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php
@@ -0,0 +1,180 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\WildfireFormatter;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
+ *
+ * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class FirePHPHandler extends AbstractProcessingHandler
+{
+    use WebRequestRecognizerTrait;
+
+    /**
+     * WildFire JSON header message format
+     */
+    protected const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2';
+
+    /**
+     * FirePHP structure for parsing messages & their presentation
+     */
+    protected const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1';
+
+    /**
+     * Must reference a "known" plugin, otherwise headers won't display in FirePHP
+     */
+    protected const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3';
+
+    /**
+     * Header prefix for Wildfire to recognize & parse headers
+     */
+    protected const HEADER_PREFIX = 'X-Wf';
+
+    /**
+     * Whether or not Wildfire vendor-specific headers have been generated & sent yet
+     * @var bool
+     */
+    protected static $initialized = false;
+
+    /**
+     * Shared static message index between potentially multiple handlers
+     * @var int
+     */
+    protected static $messageIndex = 1;
+
+    /** @var bool */
+    protected static $sendHeaders = true;
+
+    /**
+     * Base header creation function used by init headers & record headers
+     *
+     * @param array<int|string> $meta    Wildfire Plugin, Protocol & Structure Indexes
+     * @param string            $message Log message
+     *
+     * @return array<string, string> Complete header string ready for the client as key and message as value
+     *
+     * @phpstan-return non-empty-array<string, string>
+     */
+    protected function createHeader(array $meta, string $message): array
+    {
+        $header = sprintf('%s-%s', static::HEADER_PREFIX, join('-', $meta));
+
+        return [$header => $message];
+    }
+
+    /**
+     * Creates message header from record
+     *
+     * @return array<string, string>
+     *
+     * @phpstan-return non-empty-array<string, string>
+     *
+     * @see createHeader()
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    protected function createRecordHeader(array $record): array
+    {
+        // Wildfire is extensible to support multiple protocols & plugins in a single request,
+        // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake.
+        return $this->createHeader(
+            [1, 1, 1, self::$messageIndex++],
+            $record['formatted']
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new WildfireFormatter();
+    }
+
+    /**
+     * Wildfire initialization headers to enable message parsing
+     *
+     * @see createHeader()
+     * @see sendHeader()
+     *
+     * @return array<string, string>
+     */
+    protected function getInitHeaders(): array
+    {
+        // Initial payload consists of required headers for Wildfire
+        return array_merge(
+            $this->createHeader(['Protocol', 1], static::PROTOCOL_URI),
+            $this->createHeader([1, 'Structure', 1], static::STRUCTURE_URI),
+            $this->createHeader([1, 'Plugin', 1], static::PLUGIN_URI)
+        );
+    }
+
+    /**
+     * Send header string to the client
+     */
+    protected function sendHeader(string $header, string $content): void
+    {
+        if (!headers_sent() && self::$sendHeaders) {
+            header(sprintf('%s: %s', $header, $content));
+        }
+    }
+
+    /**
+     * Creates & sends header for a record, ensuring init headers have been sent prior
+     *
+     * @see sendHeader()
+     * @see sendInitHeaders()
+     */
+    protected function write(array $record): void
+    {
+        if (!self::$sendHeaders || !$this->isWebRequest()) {
+            return;
+        }
+
+        // WildFire-specific headers must be sent prior to any messages
+        if (!self::$initialized) {
+            self::$initialized = true;
+
+            self::$sendHeaders = $this->headersAccepted();
+            if (!self::$sendHeaders) {
+                return;
+            }
+
+            foreach ($this->getInitHeaders() as $header => $content) {
+                $this->sendHeader($header, $content);
+            }
+        }
+
+        $header = $this->createRecordHeader($record);
+        if (trim(current($header)) !== '') {
+            $this->sendHeader(key($header), current($header));
+        }
+    }
+
+    /**
+     * Verifies if the headers are accepted by the current user agent
+     */
+    protected function headersAccepted(): bool
+    {
+        if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) {
+            return true;
+        }
+
+        return isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php
new file mode 100644
index 00000000..85c95b9d
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php
@@ -0,0 +1,135 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LineFormatter;
+use Monolog\Logger;
+
+/**
+ * Sends logs to Fleep.io using Webhook integrations
+ *
+ * You'll need a Fleep.io account to use this handler.
+ *
+ * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation
+ * @author Ando Roots <ando@sqroot.eu>
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class FleepHookHandler extends SocketHandler
+{
+    protected const FLEEP_HOST = 'fleep.io';
+
+    protected const FLEEP_HOOK_URI = '/hook/';
+
+    /**
+     * @var string Webhook token (specifies the conversation where logs are sent)
+     */
+    protected $token;
+
+    /**
+     * Construct a new Fleep.io Handler.
+     *
+     * For instructions on how to create a new web hook in your conversations
+     * see https://fleep.io/integrations/webhooks/
+     *
+     * @param  string                    $token  Webhook token
+     * @throws MissingExtensionException
+     */
+    public function __construct(
+        string $token,
+        $level = Logger::DEBUG,
+        bool $bubble = true,
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        if (!extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler');
+        }
+
+        $this->token = $token;
+
+        $connectionString = 'ssl://' . static::FLEEP_HOST . ':443';
+        parent::__construct(
+            $connectionString,
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+    }
+
+    /**
+     * Returns the default formatter to use with this handler
+     *
+     * Overloaded to remove empty context and extra arrays from the end of the log message.
+     *
+     * @return LineFormatter
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter(null, null, true, true);
+    }
+
+    /**
+     * Handles a log record
+     */
+    public function write(array $record): void
+    {
+        parent::write($record);
+        $this->closeSocket();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function generateDataStream(array $record): string
+    {
+        $content = $this->buildContent($record);
+
+        return $this->buildHeader($content) . $content;
+    }
+
+    /**
+     * Builds the header of the API Call
+     */
+    private function buildHeader(string $content): string
+    {
+        $header = "POST " . static::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n";
+        $header .= "Host: " . static::FLEEP_HOST . "\r\n";
+        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
+        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "\r\n";
+
+        return $header;
+    }
+
+    /**
+     * Builds the body of API call
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    private function buildContent(array $record): string
+    {
+        $dataArray = [
+            'message' => $record['formatted'],
+        ];
+
+        return http_build_query($dataArray);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php
new file mode 100644
index 00000000..b837bdb6
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php
@@ -0,0 +1,132 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Formatter\FlowdockFormatter;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Sends notifications through the Flowdock push API
+ *
+ * This must be configured with a FlowdockFormatter instance via setFormatter()
+ *
+ * Notes:
+ * API token - Flowdock API token
+ *
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
+ * @see https://www.flowdock.com/api/push
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class FlowdockHandler extends SocketHandler
+{
+    /**
+     * @var string
+     */
+    protected $apiToken;
+
+    /**
+     * @throws MissingExtensionException if OpenSSL is missing
+     */
+    public function __construct(
+        string $apiToken,
+        $level = Logger::DEBUG,
+        bool $bubble = true,
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        if (!extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler');
+        }
+
+        parent::__construct(
+            'ssl://api.flowdock.com:443',
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+        $this->apiToken = $apiToken;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        if (!$formatter instanceof FlowdockFormatter) {
+            throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly');
+        }
+
+        return parent::setFormatter($formatter);
+    }
+
+    /**
+     * Gets the default formatter.
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        parent::write($record);
+
+        $this->closeSocket();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function generateDataStream(array $record): string
+    {
+        $content = $this->buildContent($record);
+
+        return $this->buildHeader($content) . $content;
+    }
+
+    /**
+     * Builds the body of API call
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    private function buildContent(array $record): string
+    {
+        return Utils::jsonEncode($record['formatted']['flowdock']);
+    }
+
+    /**
+     * Builds the header of the API Call
+     */
+    private function buildHeader(string $content): string
+    {
+        $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
+        $header .= "Host: api.flowdock.com\r\n";
+        $header .= "Content-Type: application/json\r\n";
+        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "\r\n";
+
+        return $header;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php
new file mode 100644
index 00000000..fc1693cd
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Interface to describe loggers that have a formatter
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface FormattableHandlerInterface
+{
+    /**
+     * Sets the formatter.
+     *
+     * @param  FormatterInterface $formatter
+     * @return HandlerInterface   self
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface;
+
+    /**
+     * Gets the formatter.
+     *
+     * @return FormatterInterface
+     */
+    public function getFormatter(): FormatterInterface;
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php
new file mode 100644
index 00000000..b60bdce0
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php
@@ -0,0 +1,60 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LineFormatter;
+
+/**
+ * Helper trait for implementing FormattableInterface
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+trait FormattableHandlerTrait
+{
+    /**
+     * @var ?FormatterInterface
+     */
+    protected $formatter;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        $this->formatter = $formatter;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        if (!$this->formatter) {
+            $this->formatter = $this->getDefaultFormatter();
+        }
+
+        return $this->formatter;
+    }
+
+    /**
+     * Gets the default formatter.
+     *
+     * Overwrite this if the LineFormatter is not a good default for your handler.
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php
new file mode 100644
index 00000000..4ff26c4c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php
@@ -0,0 +1,57 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Gelf\PublisherInterface;
+use Monolog\Logger;
+use Monolog\Formatter\GelfMessageFormatter;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Handler to send messages to a Graylog2 (http://www.graylog2.org) server
+ *
+ * @author Matt Lehner <mlehner@gmail.com>
+ * @author Benjamin Zikarsky <benjamin@zikarsky.de>
+ */
+class GelfHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var PublisherInterface the publisher object that sends the message to the server
+     */
+    protected $publisher;
+
+    /**
+     * @param PublisherInterface $publisher a gelf publisher object
+     */
+    public function __construct(PublisherInterface $publisher, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        $this->publisher = $publisher;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->publisher->publish($record['formatted']);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new GelfMessageFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php
new file mode 100644
index 00000000..3c9dc4b3
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php
@@ -0,0 +1,132 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\ResettableInterface;
+
+/**
+ * Forwards records to multiple handlers
+ *
+ * @author Lenar Lõhmus <lenar@city.ee>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class GroupHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface
+{
+    use ProcessableHandlerTrait;
+
+    /** @var HandlerInterface[] */
+    protected $handlers;
+    /** @var bool */
+    protected $bubble;
+
+    /**
+     * @param HandlerInterface[] $handlers Array of Handlers.
+     * @param bool               $bubble   Whether the messages that are handled can bubble up the stack or not
+     */
+    public function __construct(array $handlers, bool $bubble = true)
+    {
+        foreach ($handlers as $handler) {
+            if (!$handler instanceof HandlerInterface) {
+                throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.');
+            }
+        }
+
+        $this->handlers = $handlers;
+        $this->bubble = $bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        foreach ($this->handlers as $handler) {
+            if ($handler->isHandling($record)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+
+        foreach ($this->handlers as $handler) {
+            $handler->handle($record);
+        }
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        if ($this->processors) {
+            $processed = [];
+            foreach ($records as $record) {
+                $processed[] = $this->processRecord($record);
+            }
+            /** @var Record[] $records */
+            $records = $processed;
+        }
+
+        foreach ($this->handlers as $handler) {
+            $handler->handleBatch($records);
+        }
+    }
+
+    public function reset()
+    {
+        $this->resetProcessors();
+
+        foreach ($this->handlers as $handler) {
+            if ($handler instanceof ResettableInterface) {
+                $handler->reset();
+            }
+        }
+    }
+
+    public function close(): void
+    {
+        parent::close();
+
+        foreach ($this->handlers as $handler) {
+            $handler->close();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        foreach ($this->handlers as $handler) {
+            if ($handler instanceof FormattableHandlerInterface) {
+                $handler->setFormatter($formatter);
+            }
+        }
+
+        return $this;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/Handler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/Handler.php
new file mode 100644
index 00000000..34b4935d
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/Handler.php
@@ -0,0 +1,62 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+/**
+ * Base Handler class providing basic close() support as well as handleBatch
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+abstract class Handler implements HandlerInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        foreach ($records as $record) {
+            $this->handle($record);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+    }
+
+    public function __destruct()
+    {
+        try {
+            $this->close();
+        } catch (\Throwable $e) {
+            // do nothing
+        }
+    }
+
+    public function __sleep()
+    {
+        $this->close();
+
+        $reflClass = new \ReflectionClass($this);
+
+        $keys = [];
+        foreach ($reflClass->getProperties() as $reflProp) {
+            if (!$reflProp->isStatic()) {
+                $keys[] = $reflProp->getName();
+            }
+        }
+
+        return $keys;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php
new file mode 100644
index 00000000..affcc51f
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php
@@ -0,0 +1,85 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+/**
+ * Interface that all Monolog Handlers must implement
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+interface HandlerInterface
+{
+    /**
+     * Checks whether the given record will be handled by this handler.
+     *
+     * This is mostly done for performance reasons, to avoid calling processors for nothing.
+     *
+     * Handlers should still check the record levels within handle(), returning false in isHandling()
+     * is no guarantee that handle() will not be called, and isHandling() might not be called
+     * for a given record.
+     *
+     * @param array $record Partial log record containing only a level key
+     *
+     * @return bool
+     *
+     * @phpstan-param array{level: Level} $record
+     */
+    public function isHandling(array $record): bool;
+
+    /**
+     * Handles a record.
+     *
+     * All records may be passed to this method, and the handler should discard
+     * those that it does not want to handle.
+     *
+     * The return value of this function controls the bubbling process of the handler stack.
+     * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
+     * calling further handlers in the stack with a given log record.
+     *
+     * @param  array $record The record to handle
+     * @return bool  true means that this handler handled the record, and that bubbling is not permitted.
+     *                      false means the record was either not processed or that this handler allows bubbling.
+     *
+     * @phpstan-param Record $record
+     */
+    public function handle(array $record): bool;
+
+    /**
+     * Handles a set of records at once.
+     *
+     * @param array $records The records to handle (an array of record arrays)
+     *
+     * @phpstan-param Record[] $records
+     */
+    public function handleBatch(array $records): void;
+
+    /**
+     * Closes the handler.
+     *
+     * Ends a log cycle and frees all resources used by the handler.
+     *
+     * Closing a Handler means flushing all buffers and freeing any open resources/handles.
+     *
+     * Implementations have to be idempotent (i.e. it should be possible to call close several times without breakage)
+     * and ideally handlers should be able to reopen themselves on handle() after they have been closed.
+     *
+     * This is useful at the end of a request and will be called automatically when the object
+     * is destroyed if you extend Monolog\Handler\Handler.
+     *
+     * If you are thinking of calling this method yourself, most likely you should be
+     * calling ResettableInterface::reset instead. Have a look.
+     */
+    public function close(): void;
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php
new file mode 100644
index 00000000..d4351b9f
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php
@@ -0,0 +1,136 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\ResettableInterface;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * This simple wrapper class can be used to extend handlers functionality.
+ *
+ * Example: A custom filtering that can be applied to any handler.
+ *
+ * Inherit from this class and override handle() like this:
+ *
+ *   public function handle(array $record)
+ *   {
+ *        if ($record meets certain conditions) {
+ *            return false;
+ *        }
+ *        return $this->handler->handle($record);
+ *   }
+ *
+ * @author Alexey Karapetov <alexey@karapetov.com>
+ */
+class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, FormattableHandlerInterface, ResettableInterface
+{
+    /**
+     * @var HandlerInterface
+     */
+    protected $handler;
+
+    public function __construct(HandlerInterface $handler)
+    {
+        $this->handler = $handler;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        return $this->handler->isHandling($record);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        return $this->handler->handle($record);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        $this->handler->handleBatch($records);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        $this->handler->close();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function pushProcessor(callable $callback): HandlerInterface
+    {
+        if ($this->handler instanceof ProcessableHandlerInterface) {
+            $this->handler->pushProcessor($callback);
+
+            return $this;
+        }
+
+        throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function popProcessor(): callable
+    {
+        if ($this->handler instanceof ProcessableHandlerInterface) {
+            return $this->handler->popProcessor();
+        }
+
+        throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            $this->handler->setFormatter($formatter);
+
+            return $this;
+        }
+
+        throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            return $this->handler->getFormatter();
+        }
+
+        throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class);
+    }
+
+    public function reset()
+    {
+        if ($this->handler instanceof ResettableInterface) {
+            $this->handler->reset();
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php
new file mode 100644
index 00000000..000ccea4
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php
@@ -0,0 +1,74 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * IFTTTHandler uses cURL to trigger IFTTT Maker actions
+ *
+ * Register a secret key and trigger/event name at https://ifttt.com/maker
+ *
+ * value1 will be the channel from monolog's Logger constructor,
+ * value2 will be the level name (ERROR, WARNING, ..)
+ * value3 will be the log record's message
+ *
+ * @author Nehal Patel <nehal@nehalpatel.me>
+ */
+class IFTTTHandler extends AbstractProcessingHandler
+{
+    /** @var string */
+    private $eventName;
+    /** @var string */
+    private $secretKey;
+
+    /**
+     * @param string $eventName The name of the IFTTT Maker event that should be triggered
+     * @param string $secretKey A valid IFTTT secret key
+     */
+    public function __construct(string $eventName, string $secretKey, $level = Logger::ERROR, bool $bubble = true)
+    {
+        if (!extension_loaded('curl')) {
+            throw new MissingExtensionException('The curl extension is needed to use the IFTTTHandler');
+        }
+
+        $this->eventName = $eventName;
+        $this->secretKey = $secretKey;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function write(array $record): void
+    {
+        $postData = [
+            "value1" => $record["channel"],
+            "value2" => $record["level_name"],
+            "value3" => $record["message"],
+        ];
+        $postString = Utils::jsonEncode($postData);
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey);
+        curl_setopt($ch, CURLOPT_POST, true);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, [
+            "Content-Type: application/json",
+        ]);
+
+        Curl\Util::execute($ch);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php
new file mode 100644
index 00000000..71f64a26
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php
@@ -0,0 +1,76 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * Inspired on LogEntriesHandler.
+ *
+ * @author Robert Kaufmann III <rok3@rok3.me>
+ * @author Gabriel Machado <gabriel.ms1@hotmail.com>
+ */
+class InsightOpsHandler extends SocketHandler
+{
+    /**
+     * @var string
+     */
+    protected $logToken;
+
+    /**
+     * @param string     $token  Log token supplied by InsightOps
+     * @param string     $region Region where InsightOps account is hosted. Could be 'us' or 'eu'.
+     * @param bool       $useSSL Whether or not SSL encryption should be used
+     *
+     * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
+     */
+    public function __construct(
+        string $token,
+        string $region = 'us',
+        bool $useSSL = true,
+        $level = Logger::DEBUG,
+        bool $bubble = true,
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        if ($useSSL && !extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for InsightOpsHandler');
+        }
+
+        $endpoint = $useSSL
+            ? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443'
+            : $region . '.data.logs.insight.rapid7.com:80';
+
+        parent::__construct(
+            $endpoint,
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+        $this->logToken = $token;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function generateDataStream(array $record): string
+    {
+        return $this->logToken . ' ' . $record['formatted'];
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php
new file mode 100644
index 00000000..25fcd159
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php
@@ -0,0 +1,70 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * @author Robert Kaufmann III <rok3@rok3.me>
+ */
+class LogEntriesHandler extends SocketHandler
+{
+    /**
+     * @var string
+     */
+    protected $logToken;
+
+    /**
+     * @param string     $token  Log token supplied by LogEntries
+     * @param bool       $useSSL Whether or not SSL encryption should be used.
+     * @param string     $host   Custom hostname to send the data to if needed
+     *
+     * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
+     */
+    public function __construct(
+        string $token,
+        bool $useSSL = true,
+        $level = Logger::DEBUG,
+        bool $bubble = true,
+        string $host = 'data.logentries.com',
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        if ($useSSL && !extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler');
+        }
+
+        $endpoint = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80';
+        parent::__construct(
+            $endpoint,
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+        $this->logToken = $token;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function generateDataStream(array $record): string
+    {
+        return $this->logToken . ' ' . $record['formatted'];
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php
new file mode 100644
index 00000000..6d13db37
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php
@@ -0,0 +1,160 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LogglyFormatter;
+use function array_key_exists;
+use CurlHandle;
+
+/**
+ * Sends errors to Loggly.
+ *
+ * @author Przemek Sobstel <przemek@sobstel.org>
+ * @author Adam Pancutt <adam@pancutt.com>
+ * @author Gregory Barchard <gregory@barchard.net>
+ */
+class LogglyHandler extends AbstractProcessingHandler
+{
+    protected const HOST = 'logs-01.loggly.com';
+    protected const ENDPOINT_SINGLE = 'inputs';
+    protected const ENDPOINT_BATCH = 'bulk';
+
+    /**
+     * Caches the curl handlers for every given endpoint.
+     *
+     * @var resource[]|CurlHandle[]
+     */
+    protected $curlHandlers = [];
+
+    /** @var string */
+    protected $token;
+
+    /** @var string[] */
+    protected $tag = [];
+
+    /**
+     * @param string $token API token supplied by Loggly
+     *
+     * @throws MissingExtensionException If the curl extension is missing
+     */
+    public function __construct(string $token, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        if (!extension_loaded('curl')) {
+            throw new MissingExtensionException('The curl extension is needed to use the LogglyHandler');
+        }
+
+        $this->token = $token;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * Loads and returns the shared curl handler for the given endpoint.
+     *
+     * @param string $endpoint
+     *
+     * @return resource|CurlHandle
+     */
+    protected function getCurlHandler(string $endpoint)
+    {
+        if (!array_key_exists($endpoint, $this->curlHandlers)) {
+            $this->curlHandlers[$endpoint] = $this->loadCurlHandle($endpoint);
+        }
+
+        return $this->curlHandlers[$endpoint];
+    }
+
+    /**
+     * Starts a fresh curl session for the given endpoint and returns its handler.
+     *
+     * @param string $endpoint
+     *
+     * @return resource|CurlHandle
+     */
+    private function loadCurlHandle(string $endpoint)
+    {
+        $url = sprintf("https://%s/%s/%s/", static::HOST, $endpoint, $this->token);
+
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_POST, true);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+        return $ch;
+    }
+
+    /**
+     * @param string[]|string $tag
+     */
+    public function setTag($tag): self
+    {
+        $tag = !empty($tag) ? $tag : [];
+        $this->tag = is_array($tag) ? $tag : [$tag];
+
+        return $this;
+    }
+
+    /**
+     * @param string[]|string $tag
+     */
+    public function addTag($tag): self
+    {
+        if (!empty($tag)) {
+            $tag = is_array($tag) ? $tag : [$tag];
+            $this->tag = array_unique(array_merge($this->tag, $tag));
+        }
+
+        return $this;
+    }
+
+    protected function write(array $record): void
+    {
+        $this->send($record["formatted"], static::ENDPOINT_SINGLE);
+    }
+
+    public function handleBatch(array $records): void
+    {
+        $level = $this->level;
+
+        $records = array_filter($records, function ($record) use ($level) {
+            return ($record['level'] >= $level);
+        });
+
+        if ($records) {
+            $this->send($this->getFormatter()->formatBatch($records), static::ENDPOINT_BATCH);
+        }
+    }
+
+    protected function send(string $data, string $endpoint): void
+    {
+        $ch = $this->getCurlHandler($endpoint);
+
+        $headers = ['Content-Type: application/json'];
+
+        if (!empty($this->tag)) {
+            $headers[] = 'X-LOGGLY-TAG: '.implode(',', $this->tag);
+        }
+
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+        Curl\Util::execute($ch, 5, false);
+    }
+
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LogglyFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/LogmaticHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/LogmaticHandler.php
new file mode 100644
index 00000000..859a4690
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/LogmaticHandler.php
@@ -0,0 +1,106 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LogmaticFormatter;
+
+/**
+ * @author Julien Breux <julien.breux@gmail.com>
+ */
+class LogmaticHandler extends SocketHandler
+{
+    /**
+     * @var string
+     */
+    private $logToken;
+
+    /**
+     * @var string
+     */
+    private $hostname;
+
+    /**
+     * @var string
+     */
+    private $appname;
+
+    /**
+     * @param string     $token    Log token supplied by Logmatic.
+     * @param string     $hostname Host name supplied by Logmatic.
+     * @param string     $appname  Application name supplied by Logmatic.
+     * @param bool       $useSSL   Whether or not SSL encryption should be used.
+     *
+     * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
+     */
+    public function __construct(
+        string $token,
+        string $hostname = '',
+        string $appname = '',
+        bool $useSSL = true,
+        $level = Logger::DEBUG,
+        bool $bubble = true,
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        if ($useSSL && !extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP extension is required to use SSL encrypted connection for LogmaticHandler');
+        }
+
+        $endpoint = $useSSL ? 'ssl://api.logmatic.io:10515' : 'api.logmatic.io:10514';
+        $endpoint .= '/v1/';
+
+        parent::__construct(
+            $endpoint,
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+
+        $this->logToken = $token;
+        $this->hostname = $hostname;
+        $this->appname  = $appname;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function generateDataStream(array $record): string
+    {
+        return $this->logToken . ' ' . $record['formatted'];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        $formatter = new LogmaticFormatter();
+
+        if (!empty($this->hostname)) {
+            $formatter->setHostname($this->hostname);
+        }
+        if (!empty($this->appname)) {
+            $formatter->setAppname($this->appname);
+        }
+
+        return $formatter;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php
new file mode 100644
index 00000000..97f34320
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php
@@ -0,0 +1,95 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\HtmlFormatter;
+
+/**
+ * Base class for all mail handlers
+ *
+ * @author Gyula Sallai
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+abstract class MailHandler extends AbstractProcessingHandler
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        $messages = [];
+
+        foreach ($records as $record) {
+            if ($record['level'] < $this->level) {
+                continue;
+            }
+            /** @var Record $message */
+            $message = $this->processRecord($record);
+            $messages[] = $message;
+        }
+
+        if (!empty($messages)) {
+            $this->send((string) $this->getFormatter()->formatBatch($messages), $messages);
+        }
+    }
+
+    /**
+     * Send a mail with the given content
+     *
+     * @param string $content formatted email body to be sent
+     * @param array  $records the array of log records that formed this content
+     *
+     * @phpstan-param Record[] $records
+     */
+    abstract protected function send(string $content, array $records): void;
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->send((string) $record['formatted'], [$record]);
+    }
+
+    /**
+     * @phpstan-param non-empty-array<Record> $records
+     * @phpstan-return Record
+     */
+    protected function getHighestRecord(array $records): array
+    {
+        $highestRecord = null;
+        foreach ($records as $record) {
+            if ($highestRecord === null || $highestRecord['level'] < $record['level']) {
+                $highestRecord = $record;
+            }
+        }
+
+        return $highestRecord;
+    }
+
+    protected function isHtmlBody(string $body): bool
+    {
+        return ($body[0] ?? null) === '<';
+    }
+
+    /**
+     * Gets the default formatter.
+     *
+     * @return FormatterInterface
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new HtmlFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php
new file mode 100644
index 00000000..3003500e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php
@@ -0,0 +1,83 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Swift;
+use Swift_Message;
+
+/**
+ * MandrillHandler uses cURL to send the emails to the Mandrill API
+ *
+ * @author Adam Nicholson <adamnicholson10@gmail.com>
+ */
+class MandrillHandler extends MailHandler
+{
+    /** @var Swift_Message */
+    protected $message;
+    /** @var string */
+    protected $apiKey;
+
+    /**
+     * @psalm-param Swift_Message|callable(): Swift_Message $message
+     *
+     * @param string                 $apiKey  A valid Mandrill API key
+     * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced
+     */
+    public function __construct(string $apiKey, $message, $level = Logger::ERROR, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        if (!$message instanceof Swift_Message && is_callable($message)) {
+            $message = $message();
+        }
+        if (!$message instanceof Swift_Message) {
+            throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it');
+        }
+        $this->message = $message;
+        $this->apiKey = $apiKey;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function send(string $content, array $records): void
+    {
+        $mime = 'text/plain';
+        if ($this->isHtmlBody($content)) {
+            $mime = 'text/html';
+        }
+
+        $message = clone $this->message;
+        $message->setBody($content, $mime);
+        /** @phpstan-ignore-next-line */
+        if (version_compare(Swift::VERSION, '6.0.0', '>=')) {
+            $message->setDate(new \DateTimeImmutable());
+        } else {
+            /** @phpstan-ignore-next-line */
+            $message->setDate(time());
+        }
+
+        $ch = curl_init();
+
+        curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json');
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
+            'key' => $this->apiKey,
+            'raw_message' => (string) $message,
+            'async' => false,
+        ]));
+
+        Curl\Util::execute($ch);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php
new file mode 100644
index 00000000..3965aeea
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php
@@ -0,0 +1,21 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+/**
+ * Exception can be thrown if an extension for a handler is missing
+ *
+ * @author Christian Bergau <cbergau86@gmail.com>
+ */
+class MissingExtensionException extends \Exception
+{
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php
new file mode 100644
index 00000000..30630911
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php
@@ -0,0 +1,86 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\Manager;
+use MongoDB\Client;
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\MongoDBFormatter;
+
+/**
+ * Logs to a MongoDB database.
+ *
+ * Usage example:
+ *
+ *   $log = new \Monolog\Logger('application');
+ *   $client = new \MongoDB\Client('mongodb://localhost:27017');
+ *   $mongodb = new \Monolog\Handler\MongoDBHandler($client, 'logs', 'prod');
+ *   $log->pushHandler($mongodb);
+ *
+ * The above examples uses the MongoDB PHP library's client class; however, the
+ * MongoDB\Driver\Manager class from ext-mongodb is also supported.
+ */
+class MongoDBHandler extends AbstractProcessingHandler
+{
+    /** @var \MongoDB\Collection */
+    private $collection;
+    /** @var Client|Manager */
+    private $manager;
+    /** @var string */
+    private $namespace;
+
+    /**
+     * Constructor.
+     *
+     * @param Client|Manager $mongodb    MongoDB library or driver client
+     * @param string         $database   Database name
+     * @param string         $collection Collection name
+     */
+    public function __construct($mongodb, string $database, string $collection, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        if (!($mongodb instanceof Client || $mongodb instanceof Manager)) {
+            throw new \InvalidArgumentException('MongoDB\Client or MongoDB\Driver\Manager instance required');
+        }
+
+        if ($mongodb instanceof Client) {
+            $this->collection = $mongodb->selectCollection($database, $collection);
+        } else {
+            $this->manager = $mongodb;
+            $this->namespace = $database . '.' . $collection;
+        }
+
+        parent::__construct($level, $bubble);
+    }
+
+    protected function write(array $record): void
+    {
+        if (isset($this->collection)) {
+            $this->collection->insertOne($record['formatted']);
+        }
+
+        if (isset($this->manager, $this->namespace)) {
+            $bulk = new BulkWrite;
+            $bulk->insert($record["formatted"]);
+            $this->manager->executeBulkWrite($this->namespace, $bulk);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new MongoDBFormatter;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php
new file mode 100644
index 00000000..0c0a3bdb
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php
@@ -0,0 +1,174 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\LineFormatter;
+
+/**
+ * NativeMailerHandler uses the mail() function to send the emails
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ * @author Mark Garrett <mark@moderndeveloperllc.com>
+ */
+class NativeMailerHandler extends MailHandler
+{
+    /**
+     * The email addresses to which the message will be sent
+     * @var string[]
+     */
+    protected $to;
+
+    /**
+     * The subject of the email
+     * @var string
+     */
+    protected $subject;
+
+    /**
+     * Optional headers for the message
+     * @var string[]
+     */
+    protected $headers = [];
+
+    /**
+     * Optional parameters for the message
+     * @var string[]
+     */
+    protected $parameters = [];
+
+    /**
+     * The wordwrap length for the message
+     * @var int
+     */
+    protected $maxColumnWidth;
+
+    /**
+     * The Content-type for the message
+     * @var string|null
+     */
+    protected $contentType;
+
+    /**
+     * The encoding for the message
+     * @var string
+     */
+    protected $encoding = 'utf-8';
+
+    /**
+     * @param string|string[] $to             The receiver of the mail
+     * @param string          $subject        The subject of the mail
+     * @param string          $from           The sender of the mail
+     * @param int             $maxColumnWidth The maximum column width that the message lines will have
+     */
+    public function __construct($to, string $subject, string $from, $level = Logger::ERROR, bool $bubble = true, int $maxColumnWidth = 70)
+    {
+        parent::__construct($level, $bubble);
+        $this->to = (array) $to;
+        $this->subject = $subject;
+        $this->addHeader(sprintf('From: %s', $from));
+        $this->maxColumnWidth = $maxColumnWidth;
+    }
+
+    /**
+     * Add headers to the message
+     *
+     * @param string|string[] $headers Custom added headers
+     */
+    public function addHeader($headers): self
+    {
+        foreach ((array) $headers as $header) {
+            if (strpos($header, "\n") !== false || strpos($header, "\r") !== false) {
+                throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons');
+            }
+            $this->headers[] = $header;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Add parameters to the message
+     *
+     * @param string|string[] $parameters Custom added parameters
+     */
+    public function addParameter($parameters): self
+    {
+        $this->parameters = array_merge($this->parameters, (array) $parameters);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function send(string $content, array $records): void
+    {
+        $contentType = $this->getContentType() ?: ($this->isHtmlBody($content) ? 'text/html' : 'text/plain');
+
+        if ($contentType !== 'text/html') {
+            $content = wordwrap($content, $this->maxColumnWidth);
+        }
+
+        $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n");
+        $headers .= 'Content-type: ' . $contentType . '; charset=' . $this->getEncoding() . "\r\n";
+        if ($contentType === 'text/html' && false === strpos($headers, 'MIME-Version:')) {
+            $headers .= 'MIME-Version: 1.0' . "\r\n";
+        }
+
+        $subject = $this->subject;
+        if ($records) {
+            $subjectFormatter = new LineFormatter($this->subject);
+            $subject = $subjectFormatter->format($this->getHighestRecord($records));
+        }
+
+        $parameters = implode(' ', $this->parameters);
+        foreach ($this->to as $to) {
+            mail($to, $subject, $content, $headers, $parameters);
+        }
+    }
+
+    public function getContentType(): ?string
+    {
+        return $this->contentType;
+    }
+
+    public function getEncoding(): string
+    {
+        return $this->encoding;
+    }
+
+    /**
+     * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML messages.
+     */
+    public function setContentType(string $contentType): self
+    {
+        if (strpos($contentType, "\n") !== false || strpos($contentType, "\r") !== false) {
+            throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection');
+        }
+
+        $this->contentType = $contentType;
+
+        return $this;
+    }
+
+    public function setEncoding(string $encoding): self
+    {
+        if (strpos($encoding, "\n") !== false || strpos($encoding, "\r") !== false) {
+            throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection');
+        }
+
+        $this->encoding = $encoding;
+
+        return $this;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php
new file mode 100644
index 00000000..114d749e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php
@@ -0,0 +1,199 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Formatter\NormalizerFormatter;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Class to record a log on a NewRelic application.
+ * Enabling New Relic High Security mode may prevent capture of useful information.
+ *
+ * This handler requires a NormalizerFormatter to function and expects an array in $record['formatted']
+ *
+ * @see https://docs.newrelic.com/docs/agents/php-agent
+ * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security
+ */
+class NewRelicHandler extends AbstractProcessingHandler
+{
+    /**
+     * Name of the New Relic application that will receive logs from this handler.
+     *
+     * @var ?string
+     */
+    protected $appName;
+
+    /**
+     * Name of the current transaction
+     *
+     * @var ?string
+     */
+    protected $transactionName;
+
+    /**
+     * Some context and extra data is passed into the handler as arrays of values. Do we send them as is
+     * (useful if we are using the API), or explode them for display on the NewRelic RPM website?
+     *
+     * @var bool
+     */
+    protected $explodeArrays;
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param string|null $appName
+     * @param bool        $explodeArrays
+     * @param string|null $transactionName
+     */
+    public function __construct(
+        $level = Logger::ERROR,
+        bool $bubble = true,
+        ?string $appName = null,
+        bool $explodeArrays = false,
+        ?string $transactionName = null
+    ) {
+        parent::__construct($level, $bubble);
+
+        $this->appName       = $appName;
+        $this->explodeArrays = $explodeArrays;
+        $this->transactionName = $transactionName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if (!$this->isNewRelicEnabled()) {
+            throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler');
+        }
+
+        if ($appName = $this->getAppName($record['context'])) {
+            $this->setNewRelicAppName($appName);
+        }
+
+        if ($transactionName = $this->getTransactionName($record['context'])) {
+            $this->setNewRelicTransactionName($transactionName);
+            unset($record['formatted']['context']['transaction_name']);
+        }
+
+        if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Throwable) {
+            newrelic_notice_error($record['message'], $record['context']['exception']);
+            unset($record['formatted']['context']['exception']);
+        } else {
+            newrelic_notice_error($record['message']);
+        }
+
+        if (isset($record['formatted']['context']) && is_array($record['formatted']['context'])) {
+            foreach ($record['formatted']['context'] as $key => $parameter) {
+                if (is_array($parameter) && $this->explodeArrays) {
+                    foreach ($parameter as $paramKey => $paramValue) {
+                        $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue);
+                    }
+                } else {
+                    $this->setNewRelicParameter('context_' . $key, $parameter);
+                }
+            }
+        }
+
+        if (isset($record['formatted']['extra']) && is_array($record['formatted']['extra'])) {
+            foreach ($record['formatted']['extra'] as $key => $parameter) {
+                if (is_array($parameter) && $this->explodeArrays) {
+                    foreach ($parameter as $paramKey => $paramValue) {
+                        $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue);
+                    }
+                } else {
+                    $this->setNewRelicParameter('extra_' . $key, $parameter);
+                }
+            }
+        }
+    }
+
+    /**
+     * Checks whether the NewRelic extension is enabled in the system.
+     *
+     * @return bool
+     */
+    protected function isNewRelicEnabled(): bool
+    {
+        return extension_loaded('newrelic');
+    }
+
+    /**
+     * Returns the appname where this log should be sent. Each log can override the default appname, set in this
+     * handler's constructor, by providing the appname in it's context.
+     *
+     * @param mixed[] $context
+     */
+    protected function getAppName(array $context): ?string
+    {
+        if (isset($context['appname'])) {
+            return $context['appname'];
+        }
+
+        return $this->appName;
+    }
+
+    /**
+     * Returns the name of the current transaction. Each log can override the default transaction name, set in this
+     * handler's constructor, by providing the transaction_name in it's context
+     *
+     * @param mixed[] $context
+     */
+    protected function getTransactionName(array $context): ?string
+    {
+        if (isset($context['transaction_name'])) {
+            return $context['transaction_name'];
+        }
+
+        return $this->transactionName;
+    }
+
+    /**
+     * Sets the NewRelic application that should receive this log.
+     */
+    protected function setNewRelicAppName(string $appName): void
+    {
+        newrelic_set_appname($appName);
+    }
+
+    /**
+     * Overwrites the name of the current transaction
+     */
+    protected function setNewRelicTransactionName(string $transactionName): void
+    {
+        newrelic_name_transaction($transactionName);
+    }
+
+    /**
+     * @param string $key
+     * @param mixed  $value
+     */
+    protected function setNewRelicParameter(string $key, $value): void
+    {
+        if (null === $value || is_scalar($value)) {
+            newrelic_add_custom_parameter($key, $value);
+        } else {
+            newrelic_add_custom_parameter($key, Utils::jsonEncode($value, null, true));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new NormalizerFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/NoopHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/NoopHandler.php
new file mode 100644
index 00000000..1ddf0beb
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/NoopHandler.php
@@ -0,0 +1,40 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+/**
+ * No-op
+ *
+ * This handler handles anything, but does nothing, and does not stop bubbling to the rest of the stack.
+ * This can be used for testing, or to disable a handler when overriding a configuration without
+ * influencing the rest of the stack.
+ *
+ * @author Roel Harbers <roelharbers@gmail.com>
+ */
+class NoopHandler extends Handler
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        return false;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php
new file mode 100644
index 00000000..e75ee0c6
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php
@@ -0,0 +1,60 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Blackhole
+ *
+ * Any record it can handle will be thrown away. This can be used
+ * to put on top of an existing stack to override it temporarily.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class NullHandler extends Handler
+{
+    /**
+     * @var int
+     */
+    private $level;
+
+    /**
+     * @param string|int $level The minimum logging level at which this handler will be triggered
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function __construct($level = Logger::DEBUG)
+    {
+        $this->level = Logger::toMonologLevel($level);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function isHandling(array $record): bool
+    {
+        return $record['level'] >= $this->level;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        return $record['level'] >= $this->level;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/OverflowHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/OverflowHandler.php
new file mode 100644
index 00000000..22068c9a
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/OverflowHandler.php
@@ -0,0 +1,149 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Handler to only pass log messages when a certain threshold of number of messages is reached.
+ *
+ * This can be useful in cases of processing a batch of data, but you're for example only interested
+ * in case it fails catastrophically instead of a warning for 1 or 2 events. Worse things can happen, right?
+ *
+ * Usage example:
+ *
+ * ```
+ *   $log = new Logger('application');
+ *   $handler = new SomeHandler(...)
+ *
+ *   // Pass all warnings to the handler when more than 10 & all error messages when more then 5
+ *   $overflow = new OverflowHandler($handler, [Logger::WARNING => 10, Logger::ERROR => 5]);
+ *
+ *   $log->pushHandler($overflow);
+ *```
+ *
+ * @author Kris Buist <krisbuist@gmail.com>
+ */
+class OverflowHandler extends AbstractHandler implements FormattableHandlerInterface
+{
+    /** @var HandlerInterface */
+    private $handler;
+
+    /** @var int[] */
+    private $thresholdMap = [
+        Logger::DEBUG => 0,
+        Logger::INFO => 0,
+        Logger::NOTICE => 0,
+        Logger::WARNING => 0,
+        Logger::ERROR => 0,
+        Logger::CRITICAL => 0,
+        Logger::ALERT => 0,
+        Logger::EMERGENCY => 0,
+    ];
+
+    /**
+     * Buffer of all messages passed to the handler before the threshold was reached
+     *
+     * @var mixed[][]
+     */
+    private $buffer = [];
+
+    /**
+     * @param HandlerInterface $handler
+     * @param int[]            $thresholdMap Dictionary of logger level => threshold
+     */
+    public function __construct(
+        HandlerInterface $handler,
+        array $thresholdMap = [],
+        $level = Logger::DEBUG,
+        bool $bubble = true
+    ) {
+        $this->handler = $handler;
+        foreach ($thresholdMap as $thresholdLevel => $threshold) {
+            $this->thresholdMap[$thresholdLevel] = $threshold;
+        }
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * Handles a record.
+     *
+     * All records may be passed to this method, and the handler should discard
+     * those that it does not want to handle.
+     *
+     * The return value of this function controls the bubbling process of the handler stack.
+     * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
+     * calling further handlers in the stack with a given log record.
+     *
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($record['level'] < $this->level) {
+            return false;
+        }
+
+        $level = $record['level'];
+
+        if (!isset($this->thresholdMap[$level])) {
+            $this->thresholdMap[$level] = 0;
+        }
+
+        if ($this->thresholdMap[$level] > 0) {
+            // The overflow threshold is not yet reached, so we're buffering the record and lowering the threshold by 1
+            $this->thresholdMap[$level]--;
+            $this->buffer[$level][] = $record;
+
+            return false === $this->bubble;
+        }
+
+        if ($this->thresholdMap[$level] == 0) {
+            // This current message is breaking the threshold. Flush the buffer and continue handling the current record
+            foreach ($this->buffer[$level] ?? [] as $buffered) {
+                $this->handler->handle($buffered);
+            }
+            $this->thresholdMap[$level]--;
+            unset($this->buffer[$level]);
+        }
+
+        $this->handler->handle($record);
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            $this->handler->setFormatter($formatter);
+
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        if ($this->handler instanceof FormattableHandlerInterface) {
+            return $this->handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php
new file mode 100644
index 00000000..23a1d117
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php
@@ -0,0 +1,263 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\LineFormatter;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+use Monolog\Utils;
+use PhpConsole\Connector;
+use PhpConsole\Handler as VendorPhpConsoleHandler;
+use PhpConsole\Helper;
+
+/**
+ * Monolog handler for Google Chrome extension "PHP Console"
+ *
+ * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely
+ *
+ * Usage:
+ * 1. Install Google Chrome extension [now dead and removed from the chrome store]
+ * 2. See overview https://github.com/barbushin/php-console#overview
+ * 3. Install PHP Console library https://github.com/barbushin/php-console#installation
+ * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png)
+ *
+ *      $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler()));
+ *      \Monolog\ErrorHandler::register($logger);
+ *      echo $undefinedVar;
+ *      $logger->debug('SELECT * FROM users', array('db', 'time' => 0.012));
+ *      PC::debug($_SERVER); // PHP Console debugger for any type of vars
+ *
+ * @author Sergey Barbushin https://www.linkedin.com/in/barbushin
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @deprecated Since 2.8.0 and 3.2.0, PHPConsole is abandoned and thus we will drop this handler in Monolog 4
+ */
+class PHPConsoleHandler extends AbstractProcessingHandler
+{
+    /** @var array<string, mixed> */
+    private $options = [
+        'enabled' => true, // bool Is PHP Console server enabled
+        'classesPartialsTraceIgnore' => ['Monolog\\'], // array Hide calls of classes started with...
+        'debugTagsKeysInContext' => [0, 'tag'], // bool Is PHP Console server enabled
+        'useOwnErrorsHandler' => false, // bool Enable errors handling
+        'useOwnExceptionsHandler' => false, // bool Enable exceptions handling
+        'sourcesBasePath' => null, // string Base path of all project sources to strip in errors source paths
+        'registerHelper' => true, // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s')
+        'serverEncoding' => null, // string|null Server internal encoding
+        'headersLimit' => null, // int|null Set headers size limit for your web-server
+        'password' => null, // string|null Protect PHP Console connection by password
+        'enableSslOnlyMode' => false, // bool Force connection by SSL for clients with PHP Console installed
+        'ipMasks' => [], // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1')
+        'enableEvalListener' => false, // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required)
+        'dumperDetectCallbacks' => false, // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings
+        'dumperLevelLimit' => 5, // int Maximum dumped vars array or object nested dump level
+        'dumperItemsCountLimit' => 100, // int Maximum dumped var same level array items or object properties number
+        'dumperItemSizeLimit' => 5000, // int Maximum length of any string or dumped array item
+        'dumperDumpSizeLimit' => 500000, // int Maximum approximate size of dumped vars result formatted in JSON
+        'detectDumpTraceAndSource' => false, // bool Autodetect and append trace data to debug
+        'dataStorage' => null, // \PhpConsole\Storage|null Fixes problem with custom $_SESSION handler(see http://goo.gl/Ne8juJ)
+    ];
+
+    /** @var Connector */
+    private $connector;
+
+    /**
+     * @param  array<string, mixed> $options   See \Monolog\Handler\PHPConsoleHandler::$options for more details
+     * @param  Connector|null       $connector Instance of \PhpConsole\Connector class (optional)
+     * @throws \RuntimeException
+     */
+    public function __construct(array $options = [], ?Connector $connector = null, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        if (!class_exists('PhpConsole\Connector')) {
+            throw new \RuntimeException('PHP Console library not found. See https://github.com/barbushin/php-console#installation');
+        }
+        parent::__construct($level, $bubble);
+        $this->options = $this->initOptions($options);
+        $this->connector = $this->initConnector($connector);
+    }
+
+    /**
+     * @param array<string, mixed> $options
+     *
+     * @return array<string, mixed>
+     */
+    private function initOptions(array $options): array
+    {
+        $wrongOptions = array_diff(array_keys($options), array_keys($this->options));
+        if ($wrongOptions) {
+            throw new \RuntimeException('Unknown options: ' . implode(', ', $wrongOptions));
+        }
+
+        return array_replace($this->options, $options);
+    }
+
+    private function initConnector(?Connector $connector = null): Connector
+    {
+        if (!$connector) {
+            if ($this->options['dataStorage']) {
+                Connector::setPostponeStorage($this->options['dataStorage']);
+            }
+            $connector = Connector::getInstance();
+        }
+
+        if ($this->options['registerHelper'] && !Helper::isRegistered()) {
+            Helper::register();
+        }
+
+        if ($this->options['enabled'] && $connector->isActiveClient()) {
+            if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) {
+                $handler = VendorPhpConsoleHandler::getInstance();
+                $handler->setHandleErrors($this->options['useOwnErrorsHandler']);
+                $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']);
+                $handler->start();
+            }
+            if ($this->options['sourcesBasePath']) {
+                $connector->setSourcesBasePath($this->options['sourcesBasePath']);
+            }
+            if ($this->options['serverEncoding']) {
+                $connector->setServerEncoding($this->options['serverEncoding']);
+            }
+            if ($this->options['password']) {
+                $connector->setPassword($this->options['password']);
+            }
+            if ($this->options['enableSslOnlyMode']) {
+                $connector->enableSslOnlyMode();
+            }
+            if ($this->options['ipMasks']) {
+                $connector->setAllowedIpMasks($this->options['ipMasks']);
+            }
+            if ($this->options['headersLimit']) {
+                $connector->setHeadersLimit($this->options['headersLimit']);
+            }
+            if ($this->options['detectDumpTraceAndSource']) {
+                $connector->getDebugDispatcher()->detectTraceAndSource = true;
+            }
+            $dumper = $connector->getDumper();
+            $dumper->levelLimit = $this->options['dumperLevelLimit'];
+            $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit'];
+            $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit'];
+            $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit'];
+            $dumper->detectCallbacks = $this->options['dumperDetectCallbacks'];
+            if ($this->options['enableEvalListener']) {
+                $connector->startEvalRequestsListener();
+            }
+        }
+
+        return $connector;
+    }
+
+    public function getConnector(): Connector
+    {
+        return $this->connector;
+    }
+
+    /**
+     * @return array<string, mixed>
+     */
+    public function getOptions(): array
+    {
+        return $this->options;
+    }
+
+    public function handle(array $record): bool
+    {
+        if ($this->options['enabled'] && $this->connector->isActiveClient()) {
+            return parent::handle($record);
+        }
+
+        return !$this->bubble;
+    }
+
+    /**
+     * Writes the record down to the log of the implementing handler
+     */
+    protected function write(array $record): void
+    {
+        if ($record['level'] < Logger::NOTICE) {
+            $this->handleDebugRecord($record);
+        } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Throwable) {
+            $this->handleExceptionRecord($record);
+        } else {
+            $this->handleErrorRecord($record);
+        }
+    }
+
+    /**
+     * @phpstan-param Record $record
+     */
+    private function handleDebugRecord(array $record): void
+    {
+        $tags = $this->getRecordTags($record);
+        $message = $record['message'];
+        if ($record['context']) {
+            $message .= ' ' . Utils::jsonEncode($this->connector->getDumper()->dump(array_filter($record['context'])), null, true);
+        }
+        $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']);
+    }
+
+    /**
+     * @phpstan-param Record $record
+     */
+    private function handleExceptionRecord(array $record): void
+    {
+        $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']);
+    }
+
+    /**
+     * @phpstan-param Record $record
+     */
+    private function handleErrorRecord(array $record): void
+    {
+        $context = $record['context'];
+
+        $this->connector->getErrorsDispatcher()->dispatchError(
+            $context['code'] ?? null,
+            $context['message'] ?? $record['message'],
+            $context['file'] ?? null,
+            $context['line'] ?? null,
+            $this->options['classesPartialsTraceIgnore']
+        );
+    }
+
+    /**
+     * @phpstan-param Record $record
+     * @return string
+     */
+    private function getRecordTags(array &$record)
+    {
+        $tags = null;
+        if (!empty($record['context'])) {
+            $context = & $record['context'];
+            foreach ($this->options['debugTagsKeysInContext'] as $key) {
+                if (!empty($context[$key])) {
+                    $tags = $context[$key];
+                    if ($key === 0) {
+                        array_shift($context);
+                    } else {
+                        unset($context[$key]);
+                    }
+                    break;
+                }
+            }
+        }
+
+        return $tags ?: strtolower($record['level_name']);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter('%message%');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessHandler.php
new file mode 100644
index 00000000..8a8cf1be
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessHandler.php
@@ -0,0 +1,191 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * Stores to STDIN of any process, specified by a command.
+ *
+ * Usage example:
+ * <pre>
+ * $log = new Logger('myLogger');
+ * $log->pushHandler(new ProcessHandler('/usr/bin/php /var/www/monolog/someScript.php'));
+ * </pre>
+ *
+ * @author Kolja Zuelsdorf <koljaz@web.de>
+ */
+class ProcessHandler extends AbstractProcessingHandler
+{
+    /**
+     * Holds the process to receive data on its STDIN.
+     *
+     * @var resource|bool|null
+     */
+    private $process;
+
+    /**
+     * @var string
+     */
+    private $command;
+
+    /**
+     * @var string|null
+     */
+    private $cwd;
+
+    /**
+     * @var resource[]
+     */
+    private $pipes = [];
+
+    /**
+     * @var array<int, string[]>
+     */
+    protected const DESCRIPTOR_SPEC = [
+        0 => ['pipe', 'r'],  // STDIN is a pipe that the child will read from
+        1 => ['pipe', 'w'],  // STDOUT is a pipe that the child will write to
+        2 => ['pipe', 'w'],  // STDERR is a pipe to catch the any errors
+    ];
+
+    /**
+     * @param  string                    $command Command for the process to start. Absolute paths are recommended,
+     *                                            especially if you do not use the $cwd parameter.
+     * @param  string|null               $cwd     "Current working directory" (CWD) for the process to be executed in.
+     * @throws \InvalidArgumentException
+     */
+    public function __construct(string $command, $level = Logger::DEBUG, bool $bubble = true, ?string $cwd = null)
+    {
+        if ($command === '') {
+            throw new \InvalidArgumentException('The command argument must be a non-empty string.');
+        }
+        if ($cwd === '') {
+            throw new \InvalidArgumentException('The optional CWD argument must be a non-empty string or null.');
+        }
+
+        parent::__construct($level, $bubble);
+
+        $this->command = $command;
+        $this->cwd = $cwd;
+    }
+
+    /**
+     * Writes the record down to the log of the implementing handler
+     *
+     * @throws \UnexpectedValueException
+     */
+    protected function write(array $record): void
+    {
+        $this->ensureProcessIsStarted();
+
+        $this->writeProcessInput($record['formatted']);
+
+        $errors = $this->readProcessErrors();
+        if (empty($errors) === false) {
+            throw new \UnexpectedValueException(sprintf('Errors while writing to process: %s', $errors));
+        }
+    }
+
+    /**
+     * Makes sure that the process is actually started, and if not, starts it,
+     * assigns the stream pipes, and handles startup errors, if any.
+     */
+    private function ensureProcessIsStarted(): void
+    {
+        if (is_resource($this->process) === false) {
+            $this->startProcess();
+
+            $this->handleStartupErrors();
+        }
+    }
+
+    /**
+     * Starts the actual process and sets all streams to non-blocking.
+     */
+    private function startProcess(): void
+    {
+        $this->process = proc_open($this->command, static::DESCRIPTOR_SPEC, $this->pipes, $this->cwd);
+
+        foreach ($this->pipes as $pipe) {
+            stream_set_blocking($pipe, false);
+        }
+    }
+
+    /**
+     * Selects the STDERR stream, handles upcoming startup errors, and throws an exception, if any.
+     *
+     * @throws \UnexpectedValueException
+     */
+    private function handleStartupErrors(): void
+    {
+        $selected = $this->selectErrorStream();
+        if (false === $selected) {
+            throw new \UnexpectedValueException('Something went wrong while selecting a stream.');
+        }
+
+        $errors = $this->readProcessErrors();
+
+        if (is_resource($this->process) === false || empty($errors) === false) {
+            throw new \UnexpectedValueException(
+                sprintf('The process "%s" could not be opened: ' . $errors, $this->command)
+            );
+        }
+    }
+
+    /**
+     * Selects the STDERR stream.
+     *
+     * @return int|bool
+     */
+    protected function selectErrorStream()
+    {
+        $empty = [];
+        $errorPipes = [$this->pipes[2]];
+
+        return stream_select($errorPipes, $empty, $empty, 1);
+    }
+
+    /**
+     * Reads the errors of the process, if there are any.
+     *
+     * @codeCoverageIgnore
+     * @return string Empty string if there are no errors.
+     */
+    protected function readProcessErrors(): string
+    {
+        return (string) stream_get_contents($this->pipes[2]);
+    }
+
+    /**
+     * Writes to the input stream of the opened process.
+     *
+     * @codeCoverageIgnore
+     */
+    protected function writeProcessInput(string $string): void
+    {
+        fwrite($this->pipes[0], $string);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        if (is_resource($this->process)) {
+            foreach ($this->pipes as $pipe) {
+                fclose($pipe);
+            }
+            proc_close($this->process);
+            $this->process = null;
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php
new file mode 100644
index 00000000..3adec7a4
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php
@@ -0,0 +1,44 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Processor\ProcessorInterface;
+
+/**
+ * Interface to describe loggers that have processors
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+interface ProcessableHandlerInterface
+{
+    /**
+     * Adds a processor in the stack.
+     *
+     * @psalm-param ProcessorInterface|callable(Record): Record $callback
+     *
+     * @param  ProcessorInterface|callable $callback
+     * @return HandlerInterface            self
+     */
+    public function pushProcessor(callable $callback): HandlerInterface;
+
+    /**
+     * Removes the processor on top of the stack and returns it.
+     *
+     * @psalm-return ProcessorInterface|callable(Record): Record $callback
+     *
+     * @throws \LogicException             In case the processor stack is empty
+     * @return callable|ProcessorInterface
+     */
+    public function popProcessor(): callable;
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php
new file mode 100644
index 00000000..9ef6e301
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\ResettableInterface;
+use Monolog\Processor\ProcessorInterface;
+
+/**
+ * Helper trait for implementing ProcessableInterface
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+trait ProcessableHandlerTrait
+{
+    /**
+     * @var callable[]
+     * @phpstan-var array<ProcessorInterface|callable(Record): Record>
+     */
+    protected $processors = [];
+
+    /**
+     * {@inheritDoc}
+     */
+    public function pushProcessor(callable $callback): HandlerInterface
+    {
+        array_unshift($this->processors, $callback);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function popProcessor(): callable
+    {
+        if (!$this->processors) {
+            throw new \LogicException('You tried to pop from an empty processor stack.');
+        }
+
+        return array_shift($this->processors);
+    }
+
+    /**
+     * Processes a record.
+     *
+     * @phpstan-param  Record $record
+     * @phpstan-return Record
+     */
+    protected function processRecord(array $record): array
+    {
+        foreach ($this->processors as $processor) {
+            $record = $processor($record);
+        }
+
+        return $record;
+    }
+
+    protected function resetProcessors(): void
+    {
+        foreach ($this->processors as $processor) {
+            if ($processor instanceof ResettableInterface) {
+                $processor->reset();
+            }
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php
new file mode 100644
index 00000000..36e19ccc
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php
@@ -0,0 +1,95 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Psr\Log\LoggerInterface;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Proxies log messages to an existing PSR-3 compliant logger.
+ *
+ * If a formatter is configured, the formatter's output MUST be a string and the
+ * formatted message will be fed to the wrapped PSR logger instead of the original
+ * log record's message.
+ *
+ * @author Michael Moussa <michael.moussa@gmail.com>
+ */
+class PsrHandler extends AbstractHandler implements FormattableHandlerInterface
+{
+    /**
+     * PSR-3 compliant logger
+     *
+     * @var LoggerInterface
+     */
+    protected $logger;
+
+    /**
+     * @var FormatterInterface|null
+     */
+    protected $formatter;
+
+    /**
+     * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied
+     */
+    public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        $this->logger = $logger;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if (!$this->isHandling($record)) {
+            return false;
+        }
+
+        if ($this->formatter) {
+            $formatted = $this->formatter->format($record);
+            $this->logger->log(strtolower($record['level_name']), (string) $formatted, $record['context']);
+        } else {
+            $this->logger->log(strtolower($record['level_name']), $record['message'], $record['context']);
+        }
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * Sets the formatter.
+     *
+     * @param FormatterInterface $formatter
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        $this->formatter = $formatter;
+
+        return $this;
+    }
+
+    /**
+     * Gets the formatter.
+     *
+     * @return FormatterInterface
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        if (!$this->formatter) {
+            throw new \LogicException('No formatter has been set and this handler does not have a default formatter');
+        }
+
+        return $this->formatter;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php
new file mode 100644
index 00000000..fed2303d
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php
@@ -0,0 +1,246 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+use Psr\Log\LogLevel;
+
+/**
+ * Sends notifications through the pushover api to mobile phones
+ *
+ * @author Sebastian Göttschkes <sebastian.goettschkes@googlemail.com>
+ * @see    https://www.pushover.net/api
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class PushoverHandler extends SocketHandler
+{
+    /** @var string */
+    private $token;
+    /** @var array<int|string> */
+    private $users;
+    /** @var string */
+    private $title;
+    /** @var string|int|null */
+    private $user = null;
+    /** @var int */
+    private $retry;
+    /** @var int */
+    private $expire;
+
+    /** @var int */
+    private $highPriorityLevel;
+    /** @var int */
+    private $emergencyLevel;
+    /** @var bool */
+    private $useFormattedMessage = false;
+
+    /**
+     * All parameters that can be sent to Pushover
+     * @see https://pushover.net/api
+     * @var array<string, bool>
+     */
+    private $parameterNames = [
+        'token' => true,
+        'user' => true,
+        'message' => true,
+        'device' => true,
+        'title' => true,
+        'url' => true,
+        'url_title' => true,
+        'priority' => true,
+        'timestamp' => true,
+        'sound' => true,
+        'retry' => true,
+        'expire' => true,
+        'callback' => true,
+    ];
+
+    /**
+     * Sounds the api supports by default
+     * @see https://pushover.net/api#sounds
+     * @var string[]
+     */
+    private $sounds = [
+        'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming',
+        'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb',
+        'persistent', 'echo', 'updown', 'none',
+    ];
+
+    /**
+     * @param string       $token             Pushover api token
+     * @param string|array $users             Pushover user id or array of ids the message will be sent to
+     * @param string|null  $title             Title sent to the Pushover API
+     * @param bool         $useSSL            Whether to connect via SSL. Required when pushing messages to users that are not
+     *                                        the pushover.net app owner. OpenSSL is required for this option.
+     * @param string|int   $highPriorityLevel The minimum logging level at which this handler will start
+     *                                        sending "high priority" requests to the Pushover API
+     * @param string|int   $emergencyLevel    The minimum logging level at which this handler will start
+     *                                        sending "emergency" requests to the Pushover API
+     * @param int          $retry             The retry parameter specifies how often (in seconds) the Pushover servers will
+     *                                        send the same notification to the user.
+     * @param int          $expire            The expire parameter specifies how many seconds your notification will continue
+     *                                        to be retried for (every retry seconds).
+     *
+     * @phpstan-param string|array<int|string>    $users
+     * @phpstan-param Level|LevelName|LogLevel::* $highPriorityLevel
+     * @phpstan-param Level|LevelName|LogLevel::* $emergencyLevel
+     */
+    public function __construct(
+        string $token,
+        $users,
+        ?string $title = null,
+        $level = Logger::CRITICAL,
+        bool $bubble = true,
+        bool $useSSL = true,
+        $highPriorityLevel = Logger::CRITICAL,
+        $emergencyLevel = Logger::EMERGENCY,
+        int $retry = 30,
+        int $expire = 25200,
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80';
+        parent::__construct(
+            $connectionString,
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+
+        $this->token = $token;
+        $this->users = (array) $users;
+        $this->title = $title ?: (string) gethostname();
+        $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel);
+        $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel);
+        $this->retry = $retry;
+        $this->expire = $expire;
+    }
+
+    protected function generateDataStream(array $record): string
+    {
+        $content = $this->buildContent($record);
+
+        return $this->buildHeader($content) . $content;
+    }
+
+    /**
+     * @phpstan-param FormattedRecord $record
+     */
+    private function buildContent(array $record): string
+    {
+        // Pushover has a limit of 512 characters on title and message combined.
+        $maxMessageLength = 512 - strlen($this->title);
+
+        $message = ($this->useFormattedMessage) ? $record['formatted'] : $record['message'];
+        $message = Utils::substr($message, 0, $maxMessageLength);
+
+        $timestamp = $record['datetime']->getTimestamp();
+
+        $dataArray = [
+            'token' => $this->token,
+            'user' => $this->user,
+            'message' => $message,
+            'title' => $this->title,
+            'timestamp' => $timestamp,
+        ];
+
+        if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) {
+            $dataArray['priority'] = 2;
+            $dataArray['retry'] = $this->retry;
+            $dataArray['expire'] = $this->expire;
+        } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) {
+            $dataArray['priority'] = 1;
+        }
+
+        // First determine the available parameters
+        $context = array_intersect_key($record['context'], $this->parameterNames);
+        $extra = array_intersect_key($record['extra'], $this->parameterNames);
+
+        // Least important info should be merged with subsequent info
+        $dataArray = array_merge($extra, $context, $dataArray);
+
+        // Only pass sounds that are supported by the API
+        if (isset($dataArray['sound']) && !in_array($dataArray['sound'], $this->sounds)) {
+            unset($dataArray['sound']);
+        }
+
+        return http_build_query($dataArray);
+    }
+
+    private function buildHeader(string $content): string
+    {
+        $header = "POST /1/messages.json HTTP/1.1\r\n";
+        $header .= "Host: api.pushover.net\r\n";
+        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
+        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "\r\n";
+
+        return $header;
+    }
+
+    protected function write(array $record): void
+    {
+        foreach ($this->users as $user) {
+            $this->user = $user;
+
+            parent::write($record);
+            $this->closeSocket();
+        }
+
+        $this->user = null;
+    }
+
+    /**
+     * @param int|string $value
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $value
+     */
+    public function setHighPriorityLevel($value): self
+    {
+        $this->highPriorityLevel = Logger::toMonologLevel($value);
+
+        return $this;
+    }
+
+    /**
+     * @param int|string $value
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $value
+     */
+    public function setEmergencyLevel($value): self
+    {
+        $this->emergencyLevel = Logger::toMonologLevel($value);
+
+        return $this;
+    }
+
+    /**
+     * Use the formatted message?
+     */
+    public function useFormattedMessage(bool $value): self
+    {
+        $this->useFormattedMessage = $value;
+
+        return $this;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php
new file mode 100644
index 00000000..91d16eaf
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php
@@ -0,0 +1,101 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\LineFormatter;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+
+/**
+ * Logs to a Redis key using rpush
+ *
+ * usage example:
+ *
+ *   $log = new Logger('application');
+ *   $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod");
+ *   $log->pushHandler($redis);
+ *
+ * @author Thomas Tourlourat <thomas@tourlourat.com>
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class RedisHandler extends AbstractProcessingHandler
+{
+    /** @var \Predis\Client<\Predis\Client>|\Redis */
+    private $redisClient;
+    /** @var string */
+    private $redisKey;
+    /** @var int */
+    protected $capSize;
+
+    /**
+     * @param \Predis\Client<\Predis\Client>|\Redis $redis   The redis instance
+     * @param string                $key     The key name to push records to
+     * @param int                   $capSize Number of entries to limit list size to, 0 = unlimited
+     */
+    public function __construct($redis, string $key, $level = Logger::DEBUG, bool $bubble = true, int $capSize = 0)
+    {
+        if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) {
+            throw new \InvalidArgumentException('Predis\Client or Redis instance required');
+        }
+
+        $this->redisClient = $redis;
+        $this->redisKey = $key;
+        $this->capSize = $capSize;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if ($this->capSize) {
+            $this->writeCapped($record);
+        } else {
+            $this->redisClient->rpush($this->redisKey, $record["formatted"]);
+        }
+    }
+
+    /**
+     * Write and cap the collection
+     * Writes the record to the redis list and caps its
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    protected function writeCapped(array $record): void
+    {
+        if ($this->redisClient instanceof \Redis) {
+            $mode = defined('\Redis::MULTI') ? \Redis::MULTI : 1;
+            $this->redisClient->multi($mode)
+                ->rpush($this->redisKey, $record["formatted"])
+                ->ltrim($this->redisKey, -$this->capSize, -1)
+                ->exec();
+        } else {
+            $redisKey = $this->redisKey;
+            $capSize = $this->capSize;
+            $this->redisClient->transaction(function ($tx) use ($record, $redisKey, $capSize) {
+                $tx->rpush($redisKey, $record["formatted"]);
+                $tx->ltrim($redisKey, -$capSize, -1);
+            });
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/RedisPubSubHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/RedisPubSubHandler.php
new file mode 100644
index 00000000..7789309c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/RedisPubSubHandler.php
@@ -0,0 +1,67 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\LineFormatter;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+
+/**
+ * Sends the message to a Redis Pub/Sub channel using PUBLISH
+ *
+ * usage example:
+ *
+ *   $log = new Logger('application');
+ *   $redis = new RedisPubSubHandler(new Predis\Client("tcp://localhost:6379"), "logs", Logger::WARNING);
+ *   $log->pushHandler($redis);
+ *
+ * @author Gaëtan Faugère <gaetan@fauge.re>
+ */
+class RedisPubSubHandler extends AbstractProcessingHandler
+{
+    /** @var \Predis\Client<\Predis\Client>|\Redis */
+    private $redisClient;
+    /** @var string */
+    private $channelKey;
+
+    /**
+     * @param \Predis\Client<\Predis\Client>|\Redis $redis The redis instance
+     * @param string                $key   The channel key to publish records to
+     */
+    public function __construct($redis, string $key, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) {
+            throw new \InvalidArgumentException('Predis\Client or Redis instance required');
+        }
+
+        $this->redisClient = $redis;
+        $this->channelKey = $key;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->redisClient->publish($this->channelKey, $record["formatted"]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getDefaultFormatter(): FormatterInterface
+    {
+        return new LineFormatter();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php
new file mode 100644
index 00000000..adcc9395
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php
@@ -0,0 +1,131 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Rollbar\RollbarLogger;
+use Throwable;
+use Monolog\Logger;
+
+/**
+ * Sends errors to Rollbar
+ *
+ * If the context data contains a `payload` key, that is used as an array
+ * of payload options to RollbarLogger's log method.
+ *
+ * Rollbar's context info will contain the context + extra keys from the log record
+ * merged, and then on top of that a few keys:
+ *
+ *  - level (rollbar level name)
+ *  - monolog_level (monolog level name, raw level, as rollbar only has 5 but monolog 8)
+ *  - channel
+ *  - datetime (unix timestamp)
+ *
+ * @author Paul Statezny <paulstatezny@gmail.com>
+ */
+class RollbarHandler extends AbstractProcessingHandler
+{
+    /**
+     * @var RollbarLogger
+     */
+    protected $rollbarLogger;
+
+    /** @var string[] */
+    protected $levelMap = [
+        Logger::DEBUG     => 'debug',
+        Logger::INFO      => 'info',
+        Logger::NOTICE    => 'info',
+        Logger::WARNING   => 'warning',
+        Logger::ERROR     => 'error',
+        Logger::CRITICAL  => 'critical',
+        Logger::ALERT     => 'critical',
+        Logger::EMERGENCY => 'critical',
+    ];
+
+    /**
+     * Records whether any log records have been added since the last flush of the rollbar notifier
+     *
+     * @var bool
+     */
+    private $hasRecords = false;
+
+    /** @var bool */
+    protected $initialized = false;
+
+    /**
+     * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token
+     */
+    public function __construct(RollbarLogger $rollbarLogger, $level = Logger::ERROR, bool $bubble = true)
+    {
+        $this->rollbarLogger = $rollbarLogger;
+
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if (!$this->initialized) {
+            // __destructor() doesn't get called on Fatal errors
+            register_shutdown_function(array($this, 'close'));
+            $this->initialized = true;
+        }
+
+        $context = $record['context'];
+        $context = array_merge($context, $record['extra'], [
+            'level' => $this->levelMap[$record['level']],
+            'monolog_level' => $record['level_name'],
+            'channel' => $record['channel'],
+            'datetime' => $record['datetime']->format('U'),
+        ]);
+
+        if (isset($context['exception']) && $context['exception'] instanceof Throwable) {
+            $exception = $context['exception'];
+            unset($context['exception']);
+            $toLog = $exception;
+        } else {
+            $toLog = $record['message'];
+        }
+
+        // @phpstan-ignore-next-line
+        $this->rollbarLogger->log($context['level'], $toLog, $context);
+
+        $this->hasRecords = true;
+    }
+
+    public function flush(): void
+    {
+        if ($this->hasRecords) {
+            $this->rollbarLogger->flush();
+            $this->hasRecords = false;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        $this->flush();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function reset()
+    {
+        $this->flush();
+
+        parent::reset();
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php
new file mode 100644
index 00000000..17745d22
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php
@@ -0,0 +1,207 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use InvalidArgumentException;
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Stores logs to files that are rotated every day and a limited number of files are kept.
+ *
+ * This rotation is only intended to be used as a workaround. Using logrotate to
+ * handle the rotation is strongly encouraged when you can use it.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class RotatingFileHandler extends StreamHandler
+{
+    public const FILE_PER_DAY = 'Y-m-d';
+    public const FILE_PER_MONTH = 'Y-m';
+    public const FILE_PER_YEAR = 'Y';
+
+    /** @var string */
+    protected $filename;
+    /** @var int */
+    protected $maxFiles;
+    /** @var bool */
+    protected $mustRotate;
+    /** @var \DateTimeImmutable */
+    protected $nextRotation;
+    /** @var string */
+    protected $filenameFormat;
+    /** @var string */
+    protected $dateFormat;
+
+    /**
+     * @param string     $filename
+     * @param int        $maxFiles       The maximal amount of files to keep (0 means unlimited)
+     * @param int|null   $filePermission Optional file permissions (default (0644) are only for owner read/write)
+     * @param bool       $useLocking     Try to lock log file before doing any writes
+     */
+    public function __construct(string $filename, int $maxFiles = 0, $level = Logger::DEBUG, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
+    {
+        $this->filename = Utils::canonicalizePath($filename);
+        $this->maxFiles = $maxFiles;
+        $this->nextRotation = new \DateTimeImmutable('tomorrow');
+        $this->filenameFormat = '{filename}-{date}';
+        $this->dateFormat = static::FILE_PER_DAY;
+
+        parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        parent::close();
+
+        if (true === $this->mustRotate) {
+            $this->rotate();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function reset()
+    {
+        parent::reset();
+
+        if (true === $this->mustRotate) {
+            $this->rotate();
+        }
+    }
+
+    public function setFilenameFormat(string $filenameFormat, string $dateFormat): self
+    {
+        if (!preg_match('{^[Yy](([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) {
+            throw new InvalidArgumentException(
+                'Invalid date format - format must be one of '.
+                'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '.
+                'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '.
+                'date formats using slashes, underscores and/or dots instead of dashes.'
+            );
+        }
+        if (substr_count($filenameFormat, '{date}') === 0) {
+            throw new InvalidArgumentException(
+                'Invalid filename format - format must contain at least `{date}`, because otherwise rotating is impossible.'
+            );
+        }
+        $this->filenameFormat = $filenameFormat;
+        $this->dateFormat = $dateFormat;
+        $this->url = $this->getTimedFilename();
+        $this->close();
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        // on the first record written, if the log is new, we should rotate (once per day)
+        if (null === $this->mustRotate) {
+            $this->mustRotate = null === $this->url || !file_exists($this->url);
+        }
+
+        if ($this->nextRotation <= $record['datetime']) {
+            $this->mustRotate = true;
+            $this->close();
+        }
+
+        parent::write($record);
+    }
+
+    /**
+     * Rotates the files.
+     */
+    protected function rotate(): void
+    {
+        // update filename
+        $this->url = $this->getTimedFilename();
+        $this->nextRotation = new \DateTimeImmutable('tomorrow');
+
+        // skip GC of old logs if files are unlimited
+        if (0 === $this->maxFiles) {
+            return;
+        }
+
+        $logFiles = glob($this->getGlobPattern());
+        if (false === $logFiles) {
+            // failed to glob
+            return;
+        }
+
+        if ($this->maxFiles >= count($logFiles)) {
+            // no files to remove
+            return;
+        }
+
+        // Sorting the files by name to remove the older ones
+        usort($logFiles, function ($a, $b) {
+            return strcmp($b, $a);
+        });
+
+        foreach (array_slice($logFiles, $this->maxFiles) as $file) {
+            if (is_writable($file)) {
+                // suppress errors here as unlink() might fail if two processes
+                // are cleaning up/rotating at the same time
+                set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline): bool {
+                    return false;
+                });
+                unlink($file);
+                restore_error_handler();
+            }
+        }
+
+        $this->mustRotate = false;
+    }
+
+    protected function getTimedFilename(): string
+    {
+        $fileInfo = pathinfo($this->filename);
+        $timedFilename = str_replace(
+            ['{filename}', '{date}'],
+            [$fileInfo['filename'], date($this->dateFormat)],
+            $fileInfo['dirname'] . '/' . $this->filenameFormat
+        );
+
+        if (isset($fileInfo['extension'])) {
+            $timedFilename .= '.'.$fileInfo['extension'];
+        }
+
+        return $timedFilename;
+    }
+
+    protected function getGlobPattern(): string
+    {
+        $fileInfo = pathinfo($this->filename);
+        $glob = str_replace(
+            ['{filename}', '{date}'],
+            [$fileInfo['filename'], str_replace(
+                ['Y', 'y', 'm', 'd'],
+                ['[0-9][0-9][0-9][0-9]', '[0-9][0-9]', '[0-9][0-9]', '[0-9][0-9]'],
+                $this->dateFormat)
+            ],
+            $fileInfo['dirname'] . '/' . $this->filenameFormat
+        );
+        if (isset($fileInfo['extension'])) {
+            $glob .= '.'.$fileInfo['extension'];
+        }
+
+        return $glob;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php
new file mode 100644
index 00000000..c128a32d
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php
@@ -0,0 +1,132 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Sampling handler
+ *
+ * A sampled event stream can be useful for logging high frequency events in
+ * a production environment where you only need an idea of what is happening
+ * and are not concerned with capturing every occurrence. Since the decision to
+ * handle or not handle a particular event is determined randomly, the
+ * resulting sampled log is not guaranteed to contain 1/N of the events that
+ * occurred in the application, but based on the Law of large numbers, it will
+ * tend to be close to this ratio with a large number of attempts.
+ *
+ * @author Bryan Davis <bd808@wikimedia.org>
+ * @author Kunal Mehta <legoktm@gmail.com>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface
+{
+    use ProcessableHandlerTrait;
+
+    /**
+     * @var HandlerInterface|callable
+     * @phpstan-var HandlerInterface|callable(Record|array{level: Level}|null, HandlerInterface): HandlerInterface
+     */
+    protected $handler;
+
+    /**
+     * @var int $factor
+     */
+    protected $factor;
+
+    /**
+     * @psalm-param HandlerInterface|callable(Record|array{level: Level}|null, HandlerInterface): HandlerInterface $handler
+     *
+     * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $samplingHandler).
+     * @param int                       $factor  Sample factor (e.g. 10 means every ~10th record is sampled)
+     */
+    public function __construct($handler, int $factor)
+    {
+        parent::__construct();
+        $this->handler = $handler;
+        $this->factor = $factor;
+
+        if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
+            throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
+        }
+    }
+
+    public function isHandling(array $record): bool
+    {
+        return $this->getHandler($record)->isHandling($record);
+    }
+
+    public function handle(array $record): bool
+    {
+        if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) {
+            if ($this->processors) {
+                /** @var Record $record */
+                $record = $this->processRecord($record);
+            }
+
+            $this->getHandler($record)->handle($record);
+        }
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * Return the nested handler
+     *
+     * If the handler was provided as a factory callable, this will trigger the handler's instantiation.
+     *
+     * @phpstan-param Record|array{level: Level}|null $record
+     *
+     * @return HandlerInterface
+     */
+    public function getHandler(array $record = null)
+    {
+        if (!$this->handler instanceof HandlerInterface) {
+            $this->handler = ($this->handler)($record, $this);
+            if (!$this->handler instanceof HandlerInterface) {
+                throw new \RuntimeException("The factory callable should return a HandlerInterface");
+            }
+        }
+
+        return $this->handler;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            $handler->setFormatter($formatter);
+
+            return $this;
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFormatter(): FormatterInterface
+    {
+        $handler = $this->getHandler();
+        if ($handler instanceof FormattableHandlerInterface) {
+            return $handler->getFormatter();
+        }
+
+        throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SendGridHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SendGridHandler.php
new file mode 100644
index 00000000..1280ee70
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SendGridHandler.php
@@ -0,0 +1,102 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * SendGridrHandler uses the SendGrid API v2 function to send Log emails, more information in https://sendgrid.com/docs/API_Reference/Web_API/mail.html
+ *
+ * @author Ricardo Fontanelli <ricardo.fontanelli@hotmail.com>
+ */
+class SendGridHandler extends MailHandler
+{
+    /**
+     * The SendGrid API User
+     * @var string
+     */
+    protected $apiUser;
+
+    /**
+     * The SendGrid API Key
+     * @var string
+     */
+    protected $apiKey;
+
+    /**
+     * The email addresses to which the message will be sent
+     * @var string
+     */
+    protected $from;
+
+    /**
+     * The email addresses to which the message will be sent
+     * @var string[]
+     */
+    protected $to;
+
+    /**
+     * The subject of the email
+     * @var string
+     */
+    protected $subject;
+
+    /**
+     * @param string          $apiUser The SendGrid API User
+     * @param string          $apiKey  The SendGrid API Key
+     * @param string          $from    The sender of the email
+     * @param string|string[] $to      The recipients of the email
+     * @param string          $subject The subject of the mail
+     */
+    public function __construct(string $apiUser, string $apiKey, string $from, $to, string $subject, $level = Logger::ERROR, bool $bubble = true)
+    {
+        if (!extension_loaded('curl')) {
+            throw new MissingExtensionException('The curl extension is needed to use the SendGridHandler');
+        }
+
+        parent::__construct($level, $bubble);
+        $this->apiUser = $apiUser;
+        $this->apiKey = $apiKey;
+        $this->from = $from;
+        $this->to = (array) $to;
+        $this->subject = $subject;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function send(string $content, array $records): void
+    {
+        $message = [];
+        $message['api_user'] = $this->apiUser;
+        $message['api_key'] = $this->apiKey;
+        $message['from'] = $this->from;
+        foreach ($this->to as $recipient) {
+            $message['to[]'] = $recipient;
+        }
+        $message['subject'] = $this->subject;
+        $message['date'] = date('r');
+
+        if ($this->isHtmlBody($content)) {
+            $message['html'] = $content;
+        } else {
+            $message['text'] = $content;
+        }
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, 'https://api.sendgrid.com/api/mail.send.json');
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($message));
+        Curl\Util::execute($ch, 2);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php
new file mode 100644
index 00000000..71a41094
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php
@@ -0,0 +1,387 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\Slack;
+
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Formatter\NormalizerFormatter;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Slack record utility helping to log to Slack webhooks or API.
+ *
+ * @author Greg Kedzierski <greg@gregkedzierski.com>
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
+ * @see    https://api.slack.com/incoming-webhooks
+ * @see    https://api.slack.com/docs/message-attachments
+ *
+ * @phpstan-import-type FormattedRecord from \Monolog\Handler\AbstractProcessingHandler
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class SlackRecord
+{
+    public const COLOR_DANGER = 'danger';
+
+    public const COLOR_WARNING = 'warning';
+
+    public const COLOR_GOOD = 'good';
+
+    public const COLOR_DEFAULT = '#e3e4e6';
+
+    /**
+     * Slack channel (encoded ID or name)
+     * @var string|null
+     */
+    private $channel;
+
+    /**
+     * Name of a bot
+     * @var string|null
+     */
+    private $username;
+
+    /**
+     * User icon e.g. 'ghost', 'http://example.com/user.png'
+     * @var string|null
+     */
+    private $userIcon;
+
+    /**
+     * Whether the message should be added to Slack as attachment (plain text otherwise)
+     * @var bool
+     */
+    private $useAttachment;
+
+    /**
+     * Whether the the context/extra messages added to Slack as attachments are in a short style
+     * @var bool
+     */
+    private $useShortAttachment;
+
+    /**
+     * Whether the attachment should include context and extra data
+     * @var bool
+     */
+    private $includeContextAndExtra;
+
+    /**
+     * Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
+     * @var string[]
+     */
+    private $excludeFields;
+
+    /**
+     * @var ?FormatterInterface
+     */
+    private $formatter;
+
+    /**
+     * @var NormalizerFormatter
+     */
+    private $normalizerFormatter;
+
+    /**
+     * @param string[] $excludeFields
+     */
+    public function __construct(
+        ?string $channel = null,
+        ?string $username = null,
+        bool $useAttachment = true,
+        ?string $userIcon = null,
+        bool $useShortAttachment = false,
+        bool $includeContextAndExtra = false,
+        array $excludeFields = array(),
+        FormatterInterface $formatter = null
+    ) {
+        $this
+            ->setChannel($channel)
+            ->setUsername($username)
+            ->useAttachment($useAttachment)
+            ->setUserIcon($userIcon)
+            ->useShortAttachment($useShortAttachment)
+            ->includeContextAndExtra($includeContextAndExtra)
+            ->excludeFields($excludeFields)
+            ->setFormatter($formatter);
+
+        if ($this->includeContextAndExtra) {
+            $this->normalizerFormatter = new NormalizerFormatter();
+        }
+    }
+
+    /**
+     * Returns required data in format that Slack
+     * is expecting.
+     *
+     * @phpstan-param FormattedRecord $record
+     * @phpstan-return mixed[]
+     */
+    public function getSlackData(array $record): array
+    {
+        $dataArray = array();
+        $record = $this->removeExcludedFields($record);
+
+        if ($this->username) {
+            $dataArray['username'] = $this->username;
+        }
+
+        if ($this->channel) {
+            $dataArray['channel'] = $this->channel;
+        }
+
+        if ($this->formatter && !$this->useAttachment) {
+            /** @phpstan-ignore-next-line */
+            $message = $this->formatter->format($record);
+        } else {
+            $message = $record['message'];
+        }
+
+        if ($this->useAttachment) {
+            $attachment = array(
+                'fallback'    => $message,
+                'text'        => $message,
+                'color'       => $this->getAttachmentColor($record['level']),
+                'fields'      => array(),
+                'mrkdwn_in'   => array('fields'),
+                'ts'          => $record['datetime']->getTimestamp(),
+                'footer'      => $this->username,
+                'footer_icon' => $this->userIcon,
+            );
+
+            if ($this->useShortAttachment) {
+                $attachment['title'] = $record['level_name'];
+            } else {
+                $attachment['title'] = 'Message';
+                $attachment['fields'][] = $this->generateAttachmentField('Level', $record['level_name']);
+            }
+
+            if ($this->includeContextAndExtra) {
+                foreach (array('extra', 'context') as $key) {
+                    if (empty($record[$key])) {
+                        continue;
+                    }
+
+                    if ($this->useShortAttachment) {
+                        $attachment['fields'][] = $this->generateAttachmentField(
+                            (string) $key,
+                            $record[$key]
+                        );
+                    } else {
+                        // Add all extra fields as individual fields in attachment
+                        $attachment['fields'] = array_merge(
+                            $attachment['fields'],
+                            $this->generateAttachmentFields($record[$key])
+                        );
+                    }
+                }
+            }
+
+            $dataArray['attachments'] = array($attachment);
+        } else {
+            $dataArray['text'] = $message;
+        }
+
+        if ($this->userIcon) {
+            if (filter_var($this->userIcon, FILTER_VALIDATE_URL)) {
+                $dataArray['icon_url'] = $this->userIcon;
+            } else {
+                $dataArray['icon_emoji'] = ":{$this->userIcon}:";
+            }
+        }
+
+        return $dataArray;
+    }
+
+    /**
+     * Returns a Slack message attachment color associated with
+     * provided level.
+     */
+    public function getAttachmentColor(int $level): string
+    {
+        switch (true) {
+            case $level >= Logger::ERROR:
+                return static::COLOR_DANGER;
+            case $level >= Logger::WARNING:
+                return static::COLOR_WARNING;
+            case $level >= Logger::INFO:
+                return static::COLOR_GOOD;
+            default:
+                return static::COLOR_DEFAULT;
+        }
+    }
+
+    /**
+     * Stringifies an array of key/value pairs to be used in attachment fields
+     *
+     * @param mixed[] $fields
+     */
+    public function stringify(array $fields): string
+    {
+        /** @var Record $fields */
+        $normalized = $this->normalizerFormatter->format($fields);
+
+        $hasSecondDimension = count(array_filter($normalized, 'is_array'));
+        $hasNonNumericKeys = !count(array_filter(array_keys($normalized), 'is_numeric'));
+
+        return $hasSecondDimension || $hasNonNumericKeys
+            ? Utils::jsonEncode($normalized, JSON_PRETTY_PRINT|Utils::DEFAULT_JSON_FLAGS)
+            : Utils::jsonEncode($normalized, Utils::DEFAULT_JSON_FLAGS);
+    }
+
+    /**
+     * Channel used by the bot when posting
+     *
+     * @param ?string $channel
+     *
+     * @return static
+     */
+    public function setChannel(?string $channel = null): self
+    {
+        $this->channel = $channel;
+
+        return $this;
+    }
+
+    /**
+     * Username used by the bot when posting
+     *
+     * @param ?string $username
+     *
+     * @return static
+     */
+    public function setUsername(?string $username = null): self
+    {
+        $this->username = $username;
+
+        return $this;
+    }
+
+    public function useAttachment(bool $useAttachment = true): self
+    {
+        $this->useAttachment = $useAttachment;
+
+        return $this;
+    }
+
+    public function setUserIcon(?string $userIcon = null): self
+    {
+        $this->userIcon = $userIcon;
+
+        if (\is_string($userIcon)) {
+            $this->userIcon = trim($userIcon, ':');
+        }
+
+        return $this;
+    }
+
+    public function useShortAttachment(bool $useShortAttachment = false): self
+    {
+        $this->useShortAttachment = $useShortAttachment;
+
+        return $this;
+    }
+
+    public function includeContextAndExtra(bool $includeContextAndExtra = false): self
+    {
+        $this->includeContextAndExtra = $includeContextAndExtra;
+
+        if ($this->includeContextAndExtra) {
+            $this->normalizerFormatter = new NormalizerFormatter();
+        }
+
+        return $this;
+    }
+
+    /**
+     * @param string[] $excludeFields
+     */
+    public function excludeFields(array $excludeFields = []): self
+    {
+        $this->excludeFields = $excludeFields;
+
+        return $this;
+    }
+
+    public function setFormatter(?FormatterInterface $formatter = null): self
+    {
+        $this->formatter = $formatter;
+
+        return $this;
+    }
+
+    /**
+     * Generates attachment field
+     *
+     * @param string|mixed[] $value
+     *
+     * @return array{title: string, value: string, short: false}
+     */
+    private function generateAttachmentField(string $title, $value): array
+    {
+        $value = is_array($value)
+            ? sprintf('```%s```', substr($this->stringify($value), 0, 1990))
+            : $value;
+
+        return array(
+            'title' => ucfirst($title),
+            'value' => $value,
+            'short' => false,
+        );
+    }
+
+    /**
+     * Generates a collection of attachment fields from array
+     *
+     * @param mixed[] $data
+     *
+     * @return array<array{title: string, value: string, short: false}>
+     */
+    private function generateAttachmentFields(array $data): array
+    {
+        /** @var Record $data */
+        $normalized = $this->normalizerFormatter->format($data);
+
+        $fields = array();
+        foreach ($normalized as $key => $value) {
+            $fields[] = $this->generateAttachmentField((string) $key, $value);
+        }
+
+        return $fields;
+    }
+
+    /**
+     * Get a copy of record with fields excluded according to $this->excludeFields
+     *
+     * @phpstan-param FormattedRecord $record
+     *
+     * @return mixed[]
+     */
+    private function removeExcludedFields(array $record): array
+    {
+        foreach ($this->excludeFields as $field) {
+            $keys = explode('.', $field);
+            $node = &$record;
+            $lastKey = end($keys);
+            foreach ($keys as $key) {
+                if (!isset($node[$key])) {
+                    break;
+                }
+                if ($lastKey === $key) {
+                    unset($node[$key]);
+                    break;
+                }
+                $node = &$node[$key];
+            }
+        }
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php
new file mode 100644
index 00000000..a648513e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php
@@ -0,0 +1,256 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Handler\Slack\SlackRecord;
+
+/**
+ * Sends notifications through Slack API
+ *
+ * @author Greg Kedzierski <greg@gregkedzierski.com>
+ * @see    https://api.slack.com/
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class SlackHandler extends SocketHandler
+{
+    /**
+     * Slack API token
+     * @var string
+     */
+    private $token;
+
+    /**
+     * Instance of the SlackRecord util class preparing data for Slack API.
+     * @var SlackRecord
+     */
+    private $slackRecord;
+
+    /**
+     * @param  string                    $token                  Slack API token
+     * @param  string                    $channel                Slack channel (encoded ID or name)
+     * @param  string|null               $username               Name of a bot
+     * @param  bool                      $useAttachment          Whether the message should be added to Slack as attachment (plain text otherwise)
+     * @param  string|null               $iconEmoji              The emoji name to use (or null)
+     * @param  bool                      $useShortAttachment     Whether the context/extra messages added to Slack as attachments are in a short style
+     * @param  bool                      $includeContextAndExtra Whether the attachment should include context and extra data
+     * @param  string[]                  $excludeFields          Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
+     * @throws MissingExtensionException If no OpenSSL PHP extension configured
+     */
+    public function __construct(
+        string $token,
+        string $channel,
+        ?string $username = null,
+        bool $useAttachment = true,
+        ?string $iconEmoji = null,
+        $level = Logger::CRITICAL,
+        bool $bubble = true,
+        bool $useShortAttachment = false,
+        bool $includeContextAndExtra = false,
+        array $excludeFields = array(),
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        if (!extension_loaded('openssl')) {
+            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler');
+        }
+
+        parent::__construct(
+            'ssl://slack.com:443',
+            $level,
+            $bubble,
+            $persistent,
+            $timeout,
+            $writingTimeout,
+            $connectionTimeout,
+            $chunkSize
+        );
+
+        $this->slackRecord = new SlackRecord(
+            $channel,
+            $username,
+            $useAttachment,
+            $iconEmoji,
+            $useShortAttachment,
+            $includeContextAndExtra,
+            $excludeFields
+        );
+
+        $this->token = $token;
+    }
+
+    public function getSlackRecord(): SlackRecord
+    {
+        return $this->slackRecord;
+    }
+
+    public function getToken(): string
+    {
+        return $this->token;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function generateDataStream(array $record): string
+    {
+        $content = $this->buildContent($record);
+
+        return $this->buildHeader($content) . $content;
+    }
+
+    /**
+     * Builds the body of API call
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    private function buildContent(array $record): string
+    {
+        $dataArray = $this->prepareContentData($record);
+
+        return http_build_query($dataArray);
+    }
+
+    /**
+     * @phpstan-param FormattedRecord $record
+     * @return string[]
+     */
+    protected function prepareContentData(array $record): array
+    {
+        $dataArray = $this->slackRecord->getSlackData($record);
+        $dataArray['token'] = $this->token;
+
+        if (!empty($dataArray['attachments'])) {
+            $dataArray['attachments'] = Utils::jsonEncode($dataArray['attachments']);
+        }
+
+        return $dataArray;
+    }
+
+    /**
+     * Builds the header of the API Call
+     */
+    private function buildHeader(string $content): string
+    {
+        $header = "POST /api/chat.postMessage HTTP/1.1\r\n";
+        $header .= "Host: slack.com\r\n";
+        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
+        $header .= "Content-Length: " . strlen($content) . "\r\n";
+        $header .= "\r\n";
+
+        return $header;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        parent::write($record);
+        $this->finalizeWrite();
+    }
+
+    /**
+     * Finalizes the request by reading some bytes and then closing the socket
+     *
+     * If we do not read some but close the socket too early, slack sometimes
+     * drops the request entirely.
+     */
+    protected function finalizeWrite(): void
+    {
+        $res = $this->getResource();
+        if (is_resource($res)) {
+            @fread($res, 2048);
+        }
+        $this->closeSocket();
+    }
+
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        parent::setFormatter($formatter);
+        $this->slackRecord->setFormatter($formatter);
+
+        return $this;
+    }
+
+    public function getFormatter(): FormatterInterface
+    {
+        $formatter = parent::getFormatter();
+        $this->slackRecord->setFormatter($formatter);
+
+        return $formatter;
+    }
+
+    /**
+     * Channel used by the bot when posting
+     */
+    public function setChannel(string $channel): self
+    {
+        $this->slackRecord->setChannel($channel);
+
+        return $this;
+    }
+
+    /**
+     * Username used by the bot when posting
+     */
+    public function setUsername(string $username): self
+    {
+        $this->slackRecord->setUsername($username);
+
+        return $this;
+    }
+
+    public function useAttachment(bool $useAttachment): self
+    {
+        $this->slackRecord->useAttachment($useAttachment);
+
+        return $this;
+    }
+
+    public function setIconEmoji(string $iconEmoji): self
+    {
+        $this->slackRecord->setUserIcon($iconEmoji);
+
+        return $this;
+    }
+
+    public function useShortAttachment(bool $useShortAttachment): self
+    {
+        $this->slackRecord->useShortAttachment($useShortAttachment);
+
+        return $this;
+    }
+
+    public function includeContextAndExtra(bool $includeContextAndExtra): self
+    {
+        $this->slackRecord->includeContextAndExtra($includeContextAndExtra);
+
+        return $this;
+    }
+
+    /**
+     * @param string[] $excludeFields
+     */
+    public function excludeFields(array $excludeFields): self
+    {
+        $this->slackRecord->excludeFields($excludeFields);
+
+        return $this;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php
new file mode 100644
index 00000000..8ae3c788
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php
@@ -0,0 +1,130 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Handler\Slack\SlackRecord;
+
+/**
+ * Sends notifications through Slack Webhooks
+ *
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
+ * @see    https://api.slack.com/incoming-webhooks
+ */
+class SlackWebhookHandler extends AbstractProcessingHandler
+{
+    /**
+     * Slack Webhook token
+     * @var string
+     */
+    private $webhookUrl;
+
+    /**
+     * Instance of the SlackRecord util class preparing data for Slack API.
+     * @var SlackRecord
+     */
+    private $slackRecord;
+
+    /**
+     * @param string      $webhookUrl             Slack Webhook URL
+     * @param string|null $channel                Slack channel (encoded ID or name)
+     * @param string|null $username               Name of a bot
+     * @param bool        $useAttachment          Whether the message should be added to Slack as attachment (plain text otherwise)
+     * @param string|null $iconEmoji              The emoji name to use (or null)
+     * @param bool        $useShortAttachment     Whether the the context/extra messages added to Slack as attachments are in a short style
+     * @param bool        $includeContextAndExtra Whether the attachment should include context and extra data
+     * @param string[]    $excludeFields          Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
+     */
+    public function __construct(
+        string $webhookUrl,
+        ?string $channel = null,
+        ?string $username = null,
+        bool $useAttachment = true,
+        ?string $iconEmoji = null,
+        bool $useShortAttachment = false,
+        bool $includeContextAndExtra = false,
+        $level = Logger::CRITICAL,
+        bool $bubble = true,
+        array $excludeFields = array()
+    ) {
+        if (!extension_loaded('curl')) {
+            throw new MissingExtensionException('The curl extension is needed to use the SlackWebhookHandler');
+        }
+
+        parent::__construct($level, $bubble);
+
+        $this->webhookUrl = $webhookUrl;
+
+        $this->slackRecord = new SlackRecord(
+            $channel,
+            $username,
+            $useAttachment,
+            $iconEmoji,
+            $useShortAttachment,
+            $includeContextAndExtra,
+            $excludeFields
+        );
+    }
+
+    public function getSlackRecord(): SlackRecord
+    {
+        return $this->slackRecord;
+    }
+
+    public function getWebhookUrl(): string
+    {
+        return $this->webhookUrl;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $postData = $this->slackRecord->getSlackData($record);
+        $postString = Utils::jsonEncode($postData);
+
+        $ch = curl_init();
+        $options = array(
+            CURLOPT_URL => $this->webhookUrl,
+            CURLOPT_POST => true,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_HTTPHEADER => array('Content-type: application/json'),
+            CURLOPT_POSTFIELDS => $postString,
+        );
+        if (defined('CURLOPT_SAFE_UPLOAD')) {
+            $options[CURLOPT_SAFE_UPLOAD] = true;
+        }
+
+        curl_setopt_array($ch, $options);
+
+        Curl\Util::execute($ch);
+    }
+
+    public function setFormatter(FormatterInterface $formatter): HandlerInterface
+    {
+        parent::setFormatter($formatter);
+        $this->slackRecord->setFormatter($formatter);
+
+        return $this;
+    }
+
+    public function getFormatter(): FormatterInterface
+    {
+        $formatter = parent::getFormatter();
+        $this->slackRecord->setFormatter($formatter);
+
+        return $formatter;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php
new file mode 100644
index 00000000..21701afa
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php
@@ -0,0 +1,448 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+
+/**
+ * Stores to any socket - uses fsockopen() or pfsockopen().
+ *
+ * @author Pablo de Leon Belloc <pablolb@gmail.com>
+ * @see    http://php.net/manual/en/function.fsockopen.php
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class SocketHandler extends AbstractProcessingHandler
+{
+    /** @var string */
+    private $connectionString;
+    /** @var float */
+    private $connectionTimeout;
+    /** @var resource|null */
+    private $resource;
+    /** @var float */
+    private $timeout;
+    /** @var float */
+    private $writingTimeout;
+    /** @var ?int */
+    private $lastSentBytes = null;
+    /** @var ?int */
+    private $chunkSize;
+    /** @var bool */
+    private $persistent;
+    /** @var ?int */
+    private $errno = null;
+    /** @var ?string */
+    private $errstr = null;
+    /** @var ?float */
+    private $lastWritingAt = null;
+
+    /**
+     * @param string     $connectionString  Socket connection string
+     * @param bool       $persistent        Flag to enable/disable persistent connections
+     * @param float      $timeout           Socket timeout to wait until the request is being aborted
+     * @param float      $writingTimeout    Socket timeout to wait until the request should've been sent/written
+     * @param float|null $connectionTimeout Socket connect timeout to wait until the connection should've been
+     *                                      established
+     * @param int|null   $chunkSize         Sets the chunk size. Only has effect during connection in the writing cycle
+     *
+     * @throws \InvalidArgumentException    If an invalid timeout value (less than 0) is passed.
+     */
+    public function __construct(
+        string $connectionString,
+        $level = Logger::DEBUG,
+        bool $bubble = true,
+        bool $persistent = false,
+        float $timeout = 0.0,
+        float $writingTimeout = 10.0,
+        ?float $connectionTimeout = null,
+        ?int $chunkSize = null
+    ) {
+        parent::__construct($level, $bubble);
+        $this->connectionString = $connectionString;
+
+        if ($connectionTimeout !== null) {
+            $this->validateTimeout($connectionTimeout);
+        }
+
+        $this->connectionTimeout = $connectionTimeout ?? (float) ini_get('default_socket_timeout');
+        $this->persistent = $persistent;
+        $this->validateTimeout($timeout);
+        $this->timeout = $timeout;
+        $this->validateTimeout($writingTimeout);
+        $this->writingTimeout = $writingTimeout;
+        $this->chunkSize = $chunkSize;
+    }
+
+    /**
+     * Connect (if necessary) and write to the socket
+     *
+     * {@inheritDoc}
+     *
+     * @throws \UnexpectedValueException
+     * @throws \RuntimeException
+     */
+    protected function write(array $record): void
+    {
+        $this->connectIfNotConnected();
+        $data = $this->generateDataStream($record);
+        $this->writeToSocket($data);
+    }
+
+    /**
+     * We will not close a PersistentSocket instance so it can be reused in other requests.
+     */
+    public function close(): void
+    {
+        if (!$this->isPersistent()) {
+            $this->closeSocket();
+        }
+    }
+
+    /**
+     * Close socket, if open
+     */
+    public function closeSocket(): void
+    {
+        if (is_resource($this->resource)) {
+            fclose($this->resource);
+            $this->resource = null;
+        }
+    }
+
+    /**
+     * Set socket connection to be persistent. It only has effect before the connection is initiated.
+     */
+    public function setPersistent(bool $persistent): self
+    {
+        $this->persistent = $persistent;
+
+        return $this;
+    }
+
+    /**
+     * Set connection timeout.  Only has effect before we connect.
+     *
+     * @see http://php.net/manual/en/function.fsockopen.php
+     */
+    public function setConnectionTimeout(float $seconds): self
+    {
+        $this->validateTimeout($seconds);
+        $this->connectionTimeout = $seconds;
+
+        return $this;
+    }
+
+    /**
+     * Set write timeout. Only has effect before we connect.
+     *
+     * @see http://php.net/manual/en/function.stream-set-timeout.php
+     */
+    public function setTimeout(float $seconds): self
+    {
+        $this->validateTimeout($seconds);
+        $this->timeout = $seconds;
+
+        return $this;
+    }
+
+    /**
+     * Set writing timeout. Only has effect during connection in the writing cycle.
+     *
+     * @param float $seconds 0 for no timeout
+     */
+    public function setWritingTimeout(float $seconds): self
+    {
+        $this->validateTimeout($seconds);
+        $this->writingTimeout = $seconds;
+
+        return $this;
+    }
+
+    /**
+     * Set chunk size. Only has effect during connection in the writing cycle.
+     */
+    public function setChunkSize(int $bytes): self
+    {
+        $this->chunkSize = $bytes;
+
+        return $this;
+    }
+
+    /**
+     * Get current connection string
+     */
+    public function getConnectionString(): string
+    {
+        return $this->connectionString;
+    }
+
+    /**
+     * Get persistent setting
+     */
+    public function isPersistent(): bool
+    {
+        return $this->persistent;
+    }
+
+    /**
+     * Get current connection timeout setting
+     */
+    public function getConnectionTimeout(): float
+    {
+        return $this->connectionTimeout;
+    }
+
+    /**
+     * Get current in-transfer timeout
+     */
+    public function getTimeout(): float
+    {
+        return $this->timeout;
+    }
+
+    /**
+     * Get current local writing timeout
+     *
+     * @return float
+     */
+    public function getWritingTimeout(): float
+    {
+        return $this->writingTimeout;
+    }
+
+    /**
+     * Get current chunk size
+     */
+    public function getChunkSize(): ?int
+    {
+        return $this->chunkSize;
+    }
+
+    /**
+     * Check to see if the socket is currently available.
+     *
+     * UDP might appear to be connected but might fail when writing.  See http://php.net/fsockopen for details.
+     */
+    public function isConnected(): bool
+    {
+        return is_resource($this->resource)
+            && !feof($this->resource);  // on TCP - other party can close connection.
+    }
+
+    /**
+     * Wrapper to allow mocking
+     *
+     * @return resource|false
+     */
+    protected function pfsockopen()
+    {
+        return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout);
+    }
+
+    /**
+     * Wrapper to allow mocking
+     *
+     * @return resource|false
+     */
+    protected function fsockopen()
+    {
+        return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout);
+    }
+
+    /**
+     * Wrapper to allow mocking
+     *
+     * @see http://php.net/manual/en/function.stream-set-timeout.php
+     *
+     * @return bool
+     */
+    protected function streamSetTimeout()
+    {
+        $seconds = floor($this->timeout);
+        $microseconds = round(($this->timeout - $seconds) * 1e6);
+
+        if (!is_resource($this->resource)) {
+            throw new \LogicException('streamSetTimeout called but $this->resource is not a resource');
+        }
+
+        return stream_set_timeout($this->resource, (int) $seconds, (int) $microseconds);
+    }
+
+    /**
+     * Wrapper to allow mocking
+     *
+     * @see http://php.net/manual/en/function.stream-set-chunk-size.php
+     *
+     * @return int|bool
+     */
+    protected function streamSetChunkSize()
+    {
+        if (!is_resource($this->resource)) {
+            throw new \LogicException('streamSetChunkSize called but $this->resource is not a resource');
+        }
+
+        if (null === $this->chunkSize) {
+            throw new \LogicException('streamSetChunkSize called but $this->chunkSize is not set');
+        }
+
+        return stream_set_chunk_size($this->resource, $this->chunkSize);
+    }
+
+    /**
+     * Wrapper to allow mocking
+     *
+     * @return int|bool
+     */
+    protected function fwrite(string $data)
+    {
+        if (!is_resource($this->resource)) {
+            throw new \LogicException('fwrite called but $this->resource is not a resource');
+        }
+
+        return @fwrite($this->resource, $data);
+    }
+
+    /**
+     * Wrapper to allow mocking
+     *
+     * @return mixed[]|bool
+     */
+    protected function streamGetMetadata()
+    {
+        if (!is_resource($this->resource)) {
+            throw new \LogicException('streamGetMetadata called but $this->resource is not a resource');
+        }
+
+        return stream_get_meta_data($this->resource);
+    }
+
+    private function validateTimeout(float $value): void
+    {
+        if ($value < 0) {
+            throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)");
+        }
+    }
+
+    private function connectIfNotConnected(): void
+    {
+        if ($this->isConnected()) {
+            return;
+        }
+        $this->connect();
+    }
+
+    /**
+     * @phpstan-param FormattedRecord $record
+     */
+    protected function generateDataStream(array $record): string
+    {
+        return (string) $record['formatted'];
+    }
+
+    /**
+     * @return resource|null
+     */
+    protected function getResource()
+    {
+        return $this->resource;
+    }
+
+    private function connect(): void
+    {
+        $this->createSocketResource();
+        $this->setSocketTimeout();
+        $this->setStreamChunkSize();
+    }
+
+    private function createSocketResource(): void
+    {
+        if ($this->isPersistent()) {
+            $resource = $this->pfsockopen();
+        } else {
+            $resource = $this->fsockopen();
+        }
+        if (is_bool($resource)) {
+            throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)");
+        }
+        $this->resource = $resource;
+    }
+
+    private function setSocketTimeout(): void
+    {
+        if (!$this->streamSetTimeout()) {
+            throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()");
+        }
+    }
+
+    private function setStreamChunkSize(): void
+    {
+        if ($this->chunkSize && !$this->streamSetChunkSize()) {
+            throw new \UnexpectedValueException("Failed setting chunk size with stream_set_chunk_size()");
+        }
+    }
+
+    private function writeToSocket(string $data): void
+    {
+        $length = strlen($data);
+        $sent = 0;
+        $this->lastSentBytes = $sent;
+        while ($this->isConnected() && $sent < $length) {
+            if (0 == $sent) {
+                $chunk = $this->fwrite($data);
+            } else {
+                $chunk = $this->fwrite(substr($data, $sent));
+            }
+            if ($chunk === false) {
+                throw new \RuntimeException("Could not write to socket");
+            }
+            $sent += $chunk;
+            $socketInfo = $this->streamGetMetadata();
+            if (is_array($socketInfo) && $socketInfo['timed_out']) {
+                throw new \RuntimeException("Write timed-out");
+            }
+
+            if ($this->writingIsTimedOut($sent)) {
+                throw new \RuntimeException("Write timed-out, no data sent for `{$this->writingTimeout}` seconds, probably we got disconnected (sent $sent of $length)");
+            }
+        }
+        if (!$this->isConnected() && $sent < $length) {
+            throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)");
+        }
+    }
+
+    private function writingIsTimedOut(int $sent): bool
+    {
+        // convert to ms
+        if (0.0 == $this->writingTimeout) {
+            return false;
+        }
+
+        if ($sent !== $this->lastSentBytes) {
+            $this->lastWritingAt = microtime(true);
+            $this->lastSentBytes = $sent;
+
+            return false;
+        } else {
+            usleep(100);
+        }
+
+        if ((microtime(true) - $this->lastWritingAt) >= $this->writingTimeout) {
+            $this->closeSocket();
+
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SqsHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SqsHandler.php
new file mode 100644
index 00000000..dcf282b4
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SqsHandler.php
@@ -0,0 +1,62 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Aws\Sqs\SqsClient;
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Writes to any sqs queue.
+ *
+ * @author Martijn van Calker <git@amvc.nl>
+ */
+class SqsHandler extends AbstractProcessingHandler
+{
+    /** 256 KB in bytes - maximum message size in SQS */
+    protected const MAX_MESSAGE_SIZE = 262144;
+    /** 100 KB in bytes - head message size for new error log */
+    protected const HEAD_MESSAGE_SIZE = 102400;
+
+    /** @var SqsClient */
+    private $client;
+    /** @var string */
+    private $queueUrl;
+
+    public function __construct(SqsClient $sqsClient, string $queueUrl, $level = Logger::DEBUG, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        $this->client = $sqsClient;
+        $this->queueUrl = $queueUrl;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if (!isset($record['formatted']) || 'string' !== gettype($record['formatted'])) {
+            throw new \InvalidArgumentException('SqsHandler accepts only formatted records as a string' . Utils::getRecordMessageForException($record));
+        }
+
+        $messageBody = $record['formatted'];
+        if (strlen($messageBody) >= static::MAX_MESSAGE_SIZE) {
+            $messageBody = Utils::substr($messageBody, 0, static::HEAD_MESSAGE_SIZE);
+        }
+
+        $this->client->sendMessage([
+            'QueueUrl' => $this->queueUrl,
+            'MessageBody' => $messageBody,
+        ]);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php
new file mode 100644
index 00000000..65183512
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php
@@ -0,0 +1,221 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Stores to any stream resource
+ *
+ * Can be used to store into php://stderr, remote and local files, etc.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class StreamHandler extends AbstractProcessingHandler
+{
+    /** @const int */
+    protected const MAX_CHUNK_SIZE = 2147483647;
+    /** @const int 10MB */
+    protected const DEFAULT_CHUNK_SIZE = 10 * 1024 * 1024;
+    /** @var int */
+    protected $streamChunkSize;
+    /** @var resource|null */
+    protected $stream;
+    /** @var ?string */
+    protected $url = null;
+    /** @var ?string */
+    private $errorMessage = null;
+    /** @var ?int */
+    protected $filePermission;
+    /** @var bool */
+    protected $useLocking;
+    /** @var true|null */
+    private $dirCreated = null;
+
+    /**
+     * @param resource|string $stream         If a missing path can't be created, an UnexpectedValueException will be thrown on first write
+     * @param int|null        $filePermission Optional file permissions (default (0644) are only for owner read/write)
+     * @param bool            $useLocking     Try to lock log file before doing any writes
+     *
+     * @throws \InvalidArgumentException If stream is not a resource or string
+     */
+    public function __construct($stream, $level = Logger::DEBUG, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
+    {
+        parent::__construct($level, $bubble);
+
+        if (($phpMemoryLimit = Utils::expandIniShorthandBytes(ini_get('memory_limit'))) !== false) {
+            if ($phpMemoryLimit > 0) {
+                // use max 10% of allowed memory for the chunk size, and at least 100KB
+                $this->streamChunkSize = min(static::MAX_CHUNK_SIZE, max((int) ($phpMemoryLimit / 10), 100 * 1024));
+            } else {
+                // memory is unlimited, set to the default 10MB
+                $this->streamChunkSize = static::DEFAULT_CHUNK_SIZE;
+            }
+        } else {
+            // no memory limit information, set to the default 10MB
+            $this->streamChunkSize = static::DEFAULT_CHUNK_SIZE;
+        }
+
+        if (is_resource($stream)) {
+            $this->stream = $stream;
+
+            stream_set_chunk_size($this->stream, $this->streamChunkSize);
+        } elseif (is_string($stream)) {
+            $this->url = Utils::canonicalizePath($stream);
+        } else {
+            throw new \InvalidArgumentException('A stream must either be a resource or a string.');
+        }
+
+        $this->filePermission = $filePermission;
+        $this->useLocking = $useLocking;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        if ($this->url && is_resource($this->stream)) {
+            fclose($this->stream);
+        }
+        $this->stream = null;
+        $this->dirCreated = null;
+    }
+
+    /**
+     * Return the currently active stream if it is open
+     *
+     * @return resource|null
+     */
+    public function getStream()
+    {
+        return $this->stream;
+    }
+
+    /**
+     * Return the stream URL if it was configured with a URL and not an active resource
+     *
+     * @return string|null
+     */
+    public function getUrl(): ?string
+    {
+        return $this->url;
+    }
+
+    /**
+     * @return int
+     */
+    public function getStreamChunkSize(): int
+    {
+        return $this->streamChunkSize;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if (!is_resource($this->stream)) {
+            $url = $this->url;
+            if (null === $url || '' === $url) {
+                throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().' . Utils::getRecordMessageForException($record));
+            }
+            $this->createDir($url);
+            $this->errorMessage = null;
+            set_error_handler([$this, 'customErrorHandler']);
+            $stream = fopen($url, 'a');
+            if ($this->filePermission !== null) {
+                @chmod($url, $this->filePermission);
+            }
+            restore_error_handler();
+            if (!is_resource($stream)) {
+                $this->stream = null;
+
+                throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $url) . Utils::getRecordMessageForException($record));
+            }
+            stream_set_chunk_size($stream, $this->streamChunkSize);
+            $this->stream = $stream;
+        }
+
+        $stream = $this->stream;
+        if (!is_resource($stream)) {
+            throw new \LogicException('No stream was opened yet' . Utils::getRecordMessageForException($record));
+        }
+
+        if ($this->useLocking) {
+            // ignoring errors here, there's not much we can do about them
+            flock($stream, LOCK_EX);
+        }
+
+        $this->streamWrite($stream, $record);
+
+        if ($this->useLocking) {
+            flock($stream, LOCK_UN);
+        }
+    }
+
+    /**
+     * Write to stream
+     * @param resource $stream
+     * @param array    $record
+     *
+     * @phpstan-param FormattedRecord $record
+     */
+    protected function streamWrite($stream, array $record): void
+    {
+        fwrite($stream, (string) $record['formatted']);
+    }
+
+    private function customErrorHandler(int $code, string $msg): bool
+    {
+        $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg);
+
+        return true;
+    }
+
+    private function getDirFromStream(string $stream): ?string
+    {
+        $pos = strpos($stream, '://');
+        if ($pos === false) {
+            return dirname($stream);
+        }
+
+        if ('file://' === substr($stream, 0, 7)) {
+            return dirname(substr($stream, 7));
+        }
+
+        return null;
+    }
+
+    private function createDir(string $url): void
+    {
+        // Do not try to create dir if it has already been tried.
+        if ($this->dirCreated) {
+            return;
+        }
+
+        $dir = $this->getDirFromStream($url);
+        if (null !== $dir && !is_dir($dir)) {
+            $this->errorMessage = null;
+            set_error_handler([$this, 'customErrorHandler']);
+            $status = mkdir($dir, 0777, true);
+            restore_error_handler();
+            if (false === $status && !is_dir($dir) && strpos((string) $this->errorMessage, 'File exists') === false) {
+                throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and it could not be created: '.$this->errorMessage, $dir));
+            }
+        }
+        $this->dirCreated = true;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php
new file mode 100644
index 00000000..fae92514
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php
@@ -0,0 +1,115 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LineFormatter;
+use Swift_Message;
+use Swift;
+
+/**
+ * SwiftMailerHandler uses Swift_Mailer to send the emails
+ *
+ * @author Gyula Sallai
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @deprecated Since Monolog 2.6. Use SymfonyMailerHandler instead.
+ */
+class SwiftMailerHandler extends MailHandler
+{
+    /** @var \Swift_Mailer */
+    protected $mailer;
+    /** @var Swift_Message|callable(string, Record[]): Swift_Message */
+    private $messageTemplate;
+
+    /**
+     * @psalm-param Swift_Message|callable(string, Record[]): Swift_Message $message
+     *
+     * @param \Swift_Mailer          $mailer  The mailer to use
+     * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced
+     */
+    public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        @trigger_error('The SwiftMailerHandler is deprecated since Monolog 2.6. Use SymfonyMailerHandler instead.', E_USER_DEPRECATED);
+
+        $this->mailer = $mailer;
+        $this->messageTemplate = $message;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function send(string $content, array $records): void
+    {
+        $this->mailer->send($this->buildMessage($content, $records));
+    }
+
+    /**
+     * Gets the formatter for the Swift_Message subject.
+     *
+     * @param string|null $format The format of the subject
+     */
+    protected function getSubjectFormatter(?string $format): FormatterInterface
+    {
+        return new LineFormatter($format);
+    }
+
+    /**
+     * Creates instance of Swift_Message to be sent
+     *
+     * @param  string        $content formatted email body to be sent
+     * @param  array         $records Log records that formed the content
+     * @return Swift_Message
+     *
+     * @phpstan-param Record[] $records
+     */
+    protected function buildMessage(string $content, array $records): Swift_Message
+    {
+        $message = null;
+        if ($this->messageTemplate instanceof Swift_Message) {
+            $message = clone $this->messageTemplate;
+            $message->generateId();
+        } elseif (is_callable($this->messageTemplate)) {
+            $message = ($this->messageTemplate)($content, $records);
+        }
+
+        if (!$message instanceof Swift_Message) {
+            $record = reset($records);
+            throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it' . ($record ? Utils::getRecordMessageForException($record) : ''));
+        }
+
+        if ($records) {
+            $subjectFormatter = $this->getSubjectFormatter($message->getSubject());
+            $message->setSubject($subjectFormatter->format($this->getHighestRecord($records)));
+        }
+
+        $mime = 'text/plain';
+        if ($this->isHtmlBody($content)) {
+            $mime = 'text/html';
+        }
+
+        $message->setBody($content, $mime);
+        /** @phpstan-ignore-next-line */
+        if (version_compare(Swift::VERSION, '6.0.0', '>=')) {
+            $message->setDate(new \DateTimeImmutable());
+        } else {
+            /** @phpstan-ignore-next-line */
+            $message->setDate(time());
+        }
+
+        return $message;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SymfonyMailerHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SymfonyMailerHandler.php
new file mode 100644
index 00000000..130e6f1f
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SymfonyMailerHandler.php
@@ -0,0 +1,111 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\LineFormatter;
+use Symfony\Component\Mailer\MailerInterface;
+use Symfony\Component\Mailer\Transport\TransportInterface;
+use Symfony\Component\Mime\Email;
+
+/**
+ * SymfonyMailerHandler uses Symfony's Mailer component to send the emails
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class SymfonyMailerHandler extends MailHandler
+{
+    /** @var MailerInterface|TransportInterface */
+    protected $mailer;
+    /** @var Email|callable(string, Record[]): Email */
+    private $emailTemplate;
+
+    /**
+     * @psalm-param Email|callable(string, Record[]): Email $email
+     *
+     * @param MailerInterface|TransportInterface $mailer The mailer to use
+     * @param callable|Email                     $email  An email template, the subject/body will be replaced
+     */
+    public function __construct($mailer, $email, $level = Logger::ERROR, bool $bubble = true)
+    {
+        parent::__construct($level, $bubble);
+
+        $this->mailer = $mailer;
+        $this->emailTemplate = $email;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function send(string $content, array $records): void
+    {
+        $this->mailer->send($this->buildMessage($content, $records));
+    }
+
+    /**
+     * Gets the formatter for the Swift_Message subject.
+     *
+     * @param string|null $format The format of the subject
+     */
+    protected function getSubjectFormatter(?string $format): FormatterInterface
+    {
+        return new LineFormatter($format);
+    }
+
+    /**
+     * Creates instance of Email to be sent
+     *
+     * @param  string        $content formatted email body to be sent
+     * @param  array         $records Log records that formed the content
+     *
+     * @phpstan-param Record[] $records
+     */
+    protected function buildMessage(string $content, array $records): Email
+    {
+        $message = null;
+        if ($this->emailTemplate instanceof Email) {
+            $message = clone $this->emailTemplate;
+        } elseif (is_callable($this->emailTemplate)) {
+            $message = ($this->emailTemplate)($content, $records);
+        }
+
+        if (!$message instanceof Email) {
+            $record = reset($records);
+            throw new \InvalidArgumentException('Could not resolve message as instance of Email or a callable returning it' . ($record ? Utils::getRecordMessageForException($record) : ''));
+        }
+
+        if ($records) {
+            $subjectFormatter = $this->getSubjectFormatter($message->getSubject());
+            $message->subject($subjectFormatter->format($this->getHighestRecord($records)));
+        }
+
+        if ($this->isHtmlBody($content)) {
+            if (null !== ($charset = $message->getHtmlCharset())) {
+                $message->html($content, $charset);
+            } else {
+                $message->html($content);
+            }
+        } else {
+            if (null !== ($charset = $message->getTextCharset())) {
+                $message->text($content, $charset);
+            } else {
+                $message->text($content);
+            }
+        }
+
+        return $message->date(new \DateTimeImmutable());
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php
new file mode 100644
index 00000000..1d543b7e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php
@@ -0,0 +1,68 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Logs to syslog service.
+ *
+ * usage example:
+ *
+ *   $log = new Logger('application');
+ *   $syslog = new SyslogHandler('myfacility', 'local6');
+ *   $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%");
+ *   $syslog->setFormatter($formatter);
+ *   $log->pushHandler($syslog);
+ *
+ * @author Sven Paulus <sven@karlsruhe.org>
+ */
+class SyslogHandler extends AbstractSyslogHandler
+{
+    /** @var string */
+    protected $ident;
+    /** @var int */
+    protected $logopts;
+
+    /**
+     * @param string     $ident
+     * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant
+     * @param int        $logopts  Option flags for the openlog() call, defaults to LOG_PID
+     */
+    public function __construct(string $ident, $facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true, int $logopts = LOG_PID)
+    {
+        parent::__construct($facility, $level, $bubble);
+
+        $this->ident = $ident;
+        $this->logopts = $logopts;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function close(): void
+    {
+        closelog();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        if (!openlog($this->ident, $this->logopts, $this->facility)) {
+            throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"' . Utils::getRecordMessageForException($record));
+        }
+        syslog($this->logLevels[$record['level']], (string) $record['formatted']);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php
new file mode 100644
index 00000000..dbd8ef69
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler\SyslogUdp;
+
+use Monolog\Utils;
+use Socket;
+
+class UdpSocket
+{
+    protected const DATAGRAM_MAX_LENGTH = 65023;
+
+    /** @var string */
+    protected $ip;
+    /** @var int */
+    protected $port;
+    /** @var resource|Socket|null */
+    protected $socket = null;
+
+    public function __construct(string $ip, int $port = 514)
+    {
+        $this->ip = $ip;
+        $this->port = $port;
+    }
+
+    /**
+     * @param  string $line
+     * @param  string $header
+     * @return void
+     */
+    public function write($line, $header = "")
+    {
+        $this->send($this->assembleMessage($line, $header));
+    }
+
+    public function close(): void
+    {
+        if (is_resource($this->socket) || $this->socket instanceof Socket) {
+            socket_close($this->socket);
+            $this->socket = null;
+        }
+    }
+
+    /**
+     * @return resource|Socket
+     */
+    protected function getSocket()
+    {
+        if (null !== $this->socket) {
+            return $this->socket;
+        }
+
+        $domain = AF_INET;
+        $protocol = SOL_UDP;
+        // Check if we are using unix sockets.
+        if ($this->port === 0) {
+            $domain = AF_UNIX;
+            $protocol = IPPROTO_IP;
+        }
+
+        $this->socket = socket_create($domain, SOCK_DGRAM, $protocol) ?: null;
+        if (null === $this->socket) {
+            throw new \RuntimeException('The UdpSocket to '.$this->ip.':'.$this->port.' could not be opened via socket_create');
+        }
+
+        return $this->socket;
+    }
+
+    protected function send(string $chunk): void
+    {
+        socket_sendto($this->getSocket(), $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port);
+    }
+
+    protected function assembleMessage(string $line, string $header): string
+    {
+        $chunkSize = static::DATAGRAM_MAX_LENGTH - strlen($header);
+
+        return $header . Utils::substr($line, 0, $chunkSize);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php
new file mode 100644
index 00000000..deaa19f8
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php
@@ -0,0 +1,150 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use DateTimeInterface;
+use Monolog\Logger;
+use Monolog\Handler\SyslogUdp\UdpSocket;
+use Monolog\Utils;
+
+/**
+ * A Handler for logging to a remote syslogd server.
+ *
+ * @author Jesper Skovgaard Nielsen <nulpunkt@gmail.com>
+ * @author Dominik Kukacka <dominik.kukacka@gmail.com>
+ */
+class SyslogUdpHandler extends AbstractSyslogHandler
+{
+    const RFC3164 = 0;
+    const RFC5424 = 1;
+    const RFC5424e = 2;
+
+    /** @var array<self::RFC*, string> */
+    private $dateFormats = array(
+        self::RFC3164 => 'M d H:i:s',
+        self::RFC5424 => \DateTime::RFC3339,
+        self::RFC5424e => \DateTime::RFC3339_EXTENDED,
+    );
+
+    /** @var UdpSocket */
+    protected $socket;
+    /** @var string */
+    protected $ident;
+    /** @var self::RFC* */
+    protected $rfc;
+
+    /**
+     * @param string     $host     Either IP/hostname or a path to a unix socket (port must be 0 then)
+     * @param int        $port     Port number, or 0 if $host is a unix socket
+     * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant
+     * @param bool       $bubble   Whether the messages that are handled can bubble up the stack or not
+     * @param string     $ident    Program name or tag for each log message.
+     * @param int        $rfc      RFC to format the message for.
+     * @throws MissingExtensionException
+     *
+     * @phpstan-param self::RFC* $rfc
+     */
+    public function __construct(string $host, int $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true, string $ident = 'php', int $rfc = self::RFC5424)
+    {
+        if (!extension_loaded('sockets')) {
+            throw new MissingExtensionException('The sockets extension is required to use the SyslogUdpHandler');
+        }
+
+        parent::__construct($facility, $level, $bubble);
+
+        $this->ident = $ident;
+        $this->rfc = $rfc;
+
+        $this->socket = new UdpSocket($host, $port);
+    }
+
+    protected function write(array $record): void
+    {
+        $lines = $this->splitMessageIntoLines($record['formatted']);
+
+        $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']], $record['datetime']);
+
+        foreach ($lines as $line) {
+            $this->socket->write($line, $header);
+        }
+    }
+
+    public function close(): void
+    {
+        $this->socket->close();
+    }
+
+    /**
+     * @param  string|string[] $message
+     * @return string[]
+     */
+    private function splitMessageIntoLines($message): array
+    {
+        if (is_array($message)) {
+            $message = implode("\n", $message);
+        }
+
+        $lines = preg_split('/$\R?^/m', (string) $message, -1, PREG_SPLIT_NO_EMPTY);
+        if (false === $lines) {
+            $pcreErrorCode = preg_last_error();
+            throw new \RuntimeException('Could not preg_split: ' . $pcreErrorCode . ' / ' . Utils::pcreLastErrorMessage($pcreErrorCode));
+        }
+
+        return $lines;
+    }
+
+    /**
+     * Make common syslog header (see rfc5424 or rfc3164)
+     */
+    protected function makeCommonSyslogHeader(int $severity, DateTimeInterface $datetime): string
+    {
+        $priority = $severity + $this->facility;
+
+        if (!$pid = getmypid()) {
+            $pid = '-';
+        }
+
+        if (!$hostname = gethostname()) {
+            $hostname = '-';
+        }
+
+        if ($this->rfc === self::RFC3164) {
+            // see https://github.com/phpstan/phpstan/issues/5348
+            // @phpstan-ignore-next-line
+            $dateNew = $datetime->setTimezone(new \DateTimeZone('UTC'));
+            $date = $dateNew->format($this->dateFormats[$this->rfc]);
+
+            return "<$priority>" .
+                $date . " " .
+                $hostname . " " .
+                $this->ident . "[" . $pid . "]: ";
+        }
+
+        $date = $datetime->format($this->dateFormats[$this->rfc]);
+
+        return "<$priority>1 " .
+            $date . " " .
+            $hostname . " " .
+            $this->ident . " " .
+            $pid . " - - ";
+    }
+
+    /**
+     * Inject your own socket, mainly used for testing
+     */
+    public function setSocket(UdpSocket $socket): self
+    {
+        $this->socket = $socket;
+
+        return $this;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/TelegramBotHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/TelegramBotHandler.php
new file mode 100644
index 00000000..8912eba5
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/TelegramBotHandler.php
@@ -0,0 +1,274 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use RuntimeException;
+use Monolog\Logger;
+use Monolog\Utils;
+
+/**
+ * Handler send logs to Telegram using Telegram Bot API.
+ *
+ * How to use:
+ *  1) Create telegram bot with https://telegram.me/BotFather
+ *  2) Create a telegram channel where logs will be recorded.
+ *  3) Add created bot from step 1 to the created channel from step 2.
+ *
+ * Use telegram bot API key from step 1 and channel name with '@' prefix from step 2 to create instance of TelegramBotHandler
+ *
+ * @link https://core.telegram.org/bots/api
+ *
+ * @author Mazur Alexandr <alexandrmazur96@gmail.com>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class TelegramBotHandler extends AbstractProcessingHandler
+{
+    private const BOT_API = 'https://api.telegram.org/bot';
+
+    /**
+     * The available values of parseMode according to the Telegram api documentation
+     */
+    private const AVAILABLE_PARSE_MODES = [
+        'HTML',
+        'MarkdownV2',
+        'Markdown', // legacy mode without underline and strikethrough, use MarkdownV2 instead
+    ];
+
+    /**
+     * The maximum number of characters allowed in a message according to the Telegram api documentation
+     */
+    private const MAX_MESSAGE_LENGTH = 4096;
+
+    /**
+     * Telegram bot access token provided by BotFather.
+     * Create telegram bot with https://telegram.me/BotFather and use access token from it.
+     * @var string
+     */
+    private $apiKey;
+
+    /**
+     * Telegram channel name.
+     * Since to start with '@' symbol as prefix.
+     * @var string
+     */
+    private $channel;
+
+    /**
+     * The kind of formatting that is used for the message.
+     * See available options at https://core.telegram.org/bots/api#formatting-options
+     * or in AVAILABLE_PARSE_MODES
+     * @var ?string
+     */
+    private $parseMode;
+
+    /**
+     * Disables link previews for links in the message.
+     * @var ?bool
+     */
+    private $disableWebPagePreview;
+
+    /**
+     * Sends the message silently. Users will receive a notification with no sound.
+     * @var ?bool
+     */
+    private $disableNotification;
+
+    /**
+     * True - split a message longer than MAX_MESSAGE_LENGTH into parts and send in multiple messages.
+     * False - truncates a message that is too long.
+     * @var bool
+     */
+    private $splitLongMessages;
+
+    /**
+     * Adds 1-second delay between sending a split message (according to Telegram API to avoid 429 Too Many Requests).
+     * @var bool
+     */
+    private $delayBetweenMessages;
+
+    /**
+     * @param string $apiKey Telegram bot access token provided by BotFather
+     * @param string $channel Telegram channel name
+     * @param bool $splitLongMessages Split a message longer than MAX_MESSAGE_LENGTH into parts and send in multiple messages
+     * @param bool $delayBetweenMessages Adds delay between sending a split message according to Telegram API
+     * @throws MissingExtensionException
+     */
+    public function __construct(
+        string $apiKey,
+        string $channel,
+               $level = Logger::DEBUG,
+        bool   $bubble = true,
+        string $parseMode = null,
+        bool   $disableWebPagePreview = null,
+        bool   $disableNotification = null,
+        bool   $splitLongMessages = false,
+        bool   $delayBetweenMessages = false
+    )
+    {
+        if (!extension_loaded('curl')) {
+            throw new MissingExtensionException('The curl extension is needed to use the TelegramBotHandler');
+        }
+
+        parent::__construct($level, $bubble);
+
+        $this->apiKey = $apiKey;
+        $this->channel = $channel;
+        $this->setParseMode($parseMode);
+        $this->disableWebPagePreview($disableWebPagePreview);
+        $this->disableNotification($disableNotification);
+        $this->splitLongMessages($splitLongMessages);
+        $this->delayBetweenMessages($delayBetweenMessages);
+    }
+
+    public function setParseMode(string $parseMode = null): self
+    {
+        if ($parseMode !== null && !in_array($parseMode, self::AVAILABLE_PARSE_MODES)) {
+            throw new \InvalidArgumentException('Unknown parseMode, use one of these: ' . implode(', ', self::AVAILABLE_PARSE_MODES) . '.');
+        }
+
+        $this->parseMode = $parseMode;
+
+        return $this;
+    }
+
+    public function disableWebPagePreview(bool $disableWebPagePreview = null): self
+    {
+        $this->disableWebPagePreview = $disableWebPagePreview;
+
+        return $this;
+    }
+
+    public function disableNotification(bool $disableNotification = null): self
+    {
+        $this->disableNotification = $disableNotification;
+
+        return $this;
+    }
+
+    /**
+     * True - split a message longer than MAX_MESSAGE_LENGTH into parts and send in multiple messages.
+     * False - truncates a message that is too long.
+     * @param bool $splitLongMessages
+     * @return $this
+     */
+    public function splitLongMessages(bool $splitLongMessages = false): self
+    {
+        $this->splitLongMessages = $splitLongMessages;
+
+        return $this;
+    }
+
+    /**
+     * Adds 1-second delay between sending a split message (according to Telegram API to avoid 429 Too Many Requests).
+     * @param bool $delayBetweenMessages
+     * @return $this
+     */
+    public function delayBetweenMessages(bool $delayBetweenMessages = false): self
+    {
+        $this->delayBetweenMessages = $delayBetweenMessages;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        /** @var Record[] $messages */
+        $messages = [];
+
+        foreach ($records as $record) {
+            if (!$this->isHandling($record)) {
+                continue;
+            }
+
+            if ($this->processors) {
+                /** @var Record $record */
+                $record = $this->processRecord($record);
+            }
+
+            $messages[] = $record;
+        }
+
+        if (!empty($messages)) {
+            $this->send((string)$this->getFormatter()->formatBatch($messages));
+        }
+    }
+
+    /**
+     * @inheritDoc
+     */
+    protected function write(array $record): void
+    {
+        $this->send($record['formatted']);
+    }
+
+    /**
+     * Send request to @link https://api.telegram.org/bot on SendMessage action.
+     * @param string $message
+     */
+    protected function send(string $message): void
+    {
+        $messages = $this->handleMessageLength($message);
+
+        foreach ($messages as $key => $msg) {
+            if ($this->delayBetweenMessages && $key > 0) {
+                sleep(1);
+            }
+
+            $this->sendCurl($msg);
+        }
+    }
+
+    protected function sendCurl(string $message): void
+    {
+        $ch = curl_init();
+        $url = self::BOT_API . $this->apiKey . '/SendMessage';
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
+            'text' => $message,
+            'chat_id' => $this->channel,
+            'parse_mode' => $this->parseMode,
+            'disable_web_page_preview' => $this->disableWebPagePreview,
+            'disable_notification' => $this->disableNotification,
+        ]));
+
+        $result = Curl\Util::execute($ch);
+        if (!is_string($result)) {
+            throw new RuntimeException('Telegram API error. Description: No response');
+        }
+        $result = json_decode($result, true);
+
+        if ($result['ok'] === false) {
+            throw new RuntimeException('Telegram API error. Description: ' . $result['description']);
+        }
+    }
+
+    /**
+     * Handle a message that is too long: truncates or splits into several
+     * @param string $message
+     * @return string[]
+     */
+    private function handleMessageLength(string $message): array
+    {
+        $truncatedMarker = ' (...truncated)';
+        if (!$this->splitLongMessages && strlen($message) > self::MAX_MESSAGE_LENGTH) {
+            return [Utils::substr($message, 0, self::MAX_MESSAGE_LENGTH - strlen($truncatedMarker)) . $truncatedMarker];
+        }
+
+        return str_split($message, self::MAX_MESSAGE_LENGTH);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php
new file mode 100644
index 00000000..0986da27
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php
@@ -0,0 +1,231 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Used for testing purposes.
+ *
+ * It records all records and gives you access to them for verification.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @method bool hasEmergency($record)
+ * @method bool hasAlert($record)
+ * @method bool hasCritical($record)
+ * @method bool hasError($record)
+ * @method bool hasWarning($record)
+ * @method bool hasNotice($record)
+ * @method bool hasInfo($record)
+ * @method bool hasDebug($record)
+ *
+ * @method bool hasEmergencyRecords()
+ * @method bool hasAlertRecords()
+ * @method bool hasCriticalRecords()
+ * @method bool hasErrorRecords()
+ * @method bool hasWarningRecords()
+ * @method bool hasNoticeRecords()
+ * @method bool hasInfoRecords()
+ * @method bool hasDebugRecords()
+ *
+ * @method bool hasEmergencyThatContains($message)
+ * @method bool hasAlertThatContains($message)
+ * @method bool hasCriticalThatContains($message)
+ * @method bool hasErrorThatContains($message)
+ * @method bool hasWarningThatContains($message)
+ * @method bool hasNoticeThatContains($message)
+ * @method bool hasInfoThatContains($message)
+ * @method bool hasDebugThatContains($message)
+ *
+ * @method bool hasEmergencyThatMatches($message)
+ * @method bool hasAlertThatMatches($message)
+ * @method bool hasCriticalThatMatches($message)
+ * @method bool hasErrorThatMatches($message)
+ * @method bool hasWarningThatMatches($message)
+ * @method bool hasNoticeThatMatches($message)
+ * @method bool hasInfoThatMatches($message)
+ * @method bool hasDebugThatMatches($message)
+ *
+ * @method bool hasEmergencyThatPasses($message)
+ * @method bool hasAlertThatPasses($message)
+ * @method bool hasCriticalThatPasses($message)
+ * @method bool hasErrorThatPasses($message)
+ * @method bool hasWarningThatPasses($message)
+ * @method bool hasNoticeThatPasses($message)
+ * @method bool hasInfoThatPasses($message)
+ * @method bool hasDebugThatPasses($message)
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class TestHandler extends AbstractProcessingHandler
+{
+    /** @var Record[] */
+    protected $records = [];
+    /** @var array<Level, Record[]> */
+    protected $recordsByLevel = [];
+    /** @var bool */
+    private $skipReset = false;
+
+    /**
+     * @return array
+     *
+     * @phpstan-return Record[]
+     */
+    public function getRecords()
+    {
+        return $this->records;
+    }
+
+    /**
+     * @return void
+     */
+    public function clear()
+    {
+        $this->records = [];
+        $this->recordsByLevel = [];
+    }
+
+    /**
+     * @return void
+     */
+    public function reset()
+    {
+        if (!$this->skipReset) {
+            $this->clear();
+        }
+    }
+
+    /**
+     * @return void
+     */
+    public function setSkipReset(bool $skipReset)
+    {
+        $this->skipReset = $skipReset;
+    }
+
+    /**
+     * @param string|int $level Logging level value or name
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function hasRecords($level): bool
+    {
+        return isset($this->recordsByLevel[Logger::toMonologLevel($level)]);
+    }
+
+    /**
+     * @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records
+     * @param string|int   $level  Logging level value or name
+     *
+     * @phpstan-param array{message: string, context?: mixed[]}|string $record
+     * @phpstan-param Level|LevelName|LogLevel::*                      $level
+     */
+    public function hasRecord($record, $level): bool
+    {
+        if (is_string($record)) {
+            $record = array('message' => $record);
+        }
+
+        return $this->hasRecordThatPasses(function ($rec) use ($record) {
+            if ($rec['message'] !== $record['message']) {
+                return false;
+            }
+            if (isset($record['context']) && $rec['context'] !== $record['context']) {
+                return false;
+            }
+
+            return true;
+        }, $level);
+    }
+
+    /**
+     * @param string|int $level Logging level value or name
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function hasRecordThatContains(string $message, $level): bool
+    {
+        return $this->hasRecordThatPasses(function ($rec) use ($message) {
+            return strpos($rec['message'], $message) !== false;
+        }, $level);
+    }
+
+    /**
+     * @param string|int $level Logging level value or name
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function hasRecordThatMatches(string $regex, $level): bool
+    {
+        return $this->hasRecordThatPasses(function (array $rec) use ($regex): bool {
+            return preg_match($regex, $rec['message']) > 0;
+        }, $level);
+    }
+
+    /**
+     * @param  string|int $level Logging level value or name
+     * @return bool
+     *
+     * @psalm-param callable(Record, int): mixed $predicate
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function hasRecordThatPasses(callable $predicate, $level)
+    {
+        $level = Logger::toMonologLevel($level);
+
+        if (!isset($this->recordsByLevel[$level])) {
+            return false;
+        }
+
+        foreach ($this->recordsByLevel[$level] as $i => $rec) {
+            if ($predicate($rec, $i)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->recordsByLevel[$record['level']][] = $record;
+        $this->records[] = $record;
+    }
+
+    /**
+     * @param  string  $method
+     * @param  mixed[] $args
+     * @return bool
+     */
+    public function __call($method, $args)
+    {
+        if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
+            $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3];
+            $level = constant('Monolog\Logger::' . strtoupper($matches[2]));
+            $callback = [$this, $genericMethod];
+            if (is_callable($callback)) {
+                $args[] = $level;
+
+                return call_user_func_array($callback, $args);
+            }
+        }
+
+        throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()');
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/WebRequestRecognizerTrait.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/WebRequestRecognizerTrait.php
new file mode 100644
index 00000000..c8183528
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/WebRequestRecognizerTrait.php
@@ -0,0 +1,24 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+trait WebRequestRecognizerTrait
+{
+    /**
+     * Checks if PHP's serving a web request
+     * @return bool
+     */
+    protected function isWebRequest(): bool
+    {
+        return 'cli' !== \PHP_SAPI && 'phpdbg' !== \PHP_SAPI;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php
new file mode 100644
index 00000000..2dd13672
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php
@@ -0,0 +1,67 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+/**
+ * Forwards records to multiple handlers suppressing failures of each handler
+ * and continuing through to give every handler a chance to succeed.
+ *
+ * @author Craig D'Amelio <craig@damelio.ca>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+class WhatFailureGroupHandler extends GroupHandler
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function handle(array $record): bool
+    {
+        if ($this->processors) {
+            /** @var Record $record */
+            $record = $this->processRecord($record);
+        }
+
+        foreach ($this->handlers as $handler) {
+            try {
+                $handler->handle($record);
+            } catch (\Throwable $e) {
+                // What failure?
+            }
+        }
+
+        return false === $this->bubble;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function handleBatch(array $records): void
+    {
+        if ($this->processors) {
+            $processed = array();
+            foreach ($records as $record) {
+                $processed[] = $this->processRecord($record);
+            }
+            /** @var Record[] $records */
+            $records = $processed;
+        }
+
+        foreach ($this->handlers as $handler) {
+            try {
+                $handler->handleBatch($records);
+            } catch (\Throwable $e) {
+                // What failure?
+            }
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php b/msd/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php
new file mode 100644
index 00000000..ddd46d8c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php
@@ -0,0 +1,101 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Handler;
+
+use Monolog\Formatter\FormatterInterface;
+use Monolog\Formatter\NormalizerFormatter;
+use Monolog\Logger;
+
+/**
+ * Handler sending logs to Zend Monitor
+ *
+ * @author  Christian Bergau <cbergau86@gmail.com>
+ * @author  Jason Davis <happydude@jasondavis.net>
+ *
+ * @phpstan-import-type FormattedRecord from AbstractProcessingHandler
+ */
+class ZendMonitorHandler extends AbstractProcessingHandler
+{
+    /**
+     * Monolog level / ZendMonitor Custom Event priority map
+     *
+     * @var array<int, int>
+     */
+    protected $levelMap = [];
+
+    /**
+     * @throws MissingExtensionException
+     */
+    public function __construct($level = Logger::DEBUG, bool $bubble = true)
+    {
+        if (!function_exists('zend_monitor_custom_event')) {
+            throw new MissingExtensionException(
+                'You must have Zend Server installed with Zend Monitor enabled in order to use this handler'
+            );
+        }
+        //zend monitor constants are not defined if zend monitor is not enabled.
+        $this->levelMap = [
+            Logger::DEBUG     => \ZEND_MONITOR_EVENT_SEVERITY_INFO,
+            Logger::INFO      => \ZEND_MONITOR_EVENT_SEVERITY_INFO,
+            Logger::NOTICE    => \ZEND_MONITOR_EVENT_SEVERITY_INFO,
+            Logger::WARNING   => \ZEND_MONITOR_EVENT_SEVERITY_WARNING,
+            Logger::ERROR     => \ZEND_MONITOR_EVENT_SEVERITY_ERROR,
+            Logger::CRITICAL  => \ZEND_MONITOR_EVENT_SEVERITY_ERROR,
+            Logger::ALERT     => \ZEND_MONITOR_EVENT_SEVERITY_ERROR,
+            Logger::EMERGENCY => \ZEND_MONITOR_EVENT_SEVERITY_ERROR,
+        ];
+        parent::__construct($level, $bubble);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function write(array $record): void
+    {
+        $this->writeZendMonitorCustomEvent(
+            Logger::getLevelName($record['level']),
+            $record['message'],
+            $record['formatted'],
+            $this->levelMap[$record['level']]
+        );
+    }
+
+    /**
+     * Write to Zend Monitor Events
+     * @param string $type      Text displayed in "Class Name (custom)" field
+     * @param string $message   Text displayed in "Error String"
+     * @param array  $formatted Displayed in Custom Variables tab
+     * @param int    $severity  Set the event severity level (-1,0,1)
+     *
+     * @phpstan-param FormattedRecord $formatted
+     */
+    protected function writeZendMonitorCustomEvent(string $type, string $message, array $formatted, int $severity): void
+    {
+        zend_monitor_custom_event($type, $message, $formatted, $severity);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultFormatter(): FormatterInterface
+    {
+        return new NormalizerFormatter();
+    }
+
+    /**
+     * @return array<int, int>
+     */
+    public function getLevelMap(): array
+    {
+        return $this->levelMap;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/LogRecord.php b/msd/vendor/monolog/monolog/src/Monolog/LogRecord.php
new file mode 100644
index 00000000..702807d7
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/LogRecord.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use ArrayAccess;
+
+/**
+ * Monolog log record interface for forward compatibility with Monolog 3.0
+ *
+ * This is just present in Monolog 2.4+ to allow interoperable code to be written against
+ * both versions by type-hinting arguments as `array|\Monolog\LogRecord $record`
+ *
+ * Do not rely on this interface for other purposes, and do not implement it.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @template-extends \ArrayAccess<'message'|'level'|'context'|'level_name'|'channel'|'datetime'|'extra'|'formatted', mixed>
+ * @phpstan-import-type Record from Logger
+ */
+interface LogRecord extends \ArrayAccess
+{
+    /**
+     * @phpstan-return Record
+     */
+    public function toArray(): array;
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Logger.php b/msd/vendor/monolog/monolog/src/Monolog/Logger.php
new file mode 100644
index 00000000..1ab75b9e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Logger.php
@@ -0,0 +1,701 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use DateTimeZone;
+use Monolog\Handler\HandlerInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\InvalidArgumentException;
+use Psr\Log\LogLevel;
+use Throwable;
+use Stringable;
+
+/**
+ * Monolog log channel
+ *
+ * It contains a stack of Handlers and a stack of Processors,
+ * and uses them to store records that are added to it.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-type Level Logger::DEBUG|Logger::INFO|Logger::NOTICE|Logger::WARNING|Logger::ERROR|Logger::CRITICAL|Logger::ALERT|Logger::EMERGENCY
+ * @phpstan-type LevelName 'DEBUG'|'INFO'|'NOTICE'|'WARNING'|'ERROR'|'CRITICAL'|'ALERT'|'EMERGENCY'
+ * @phpstan-type Record array{message: string, context: mixed[], level: Level, level_name: LevelName, channel: string, datetime: \DateTimeImmutable, extra: mixed[]}
+ */
+class Logger implements LoggerInterface, ResettableInterface
+{
+    /**
+     * Detailed debug information
+     */
+    public const DEBUG = 100;
+
+    /**
+     * Interesting events
+     *
+     * Examples: User logs in, SQL logs.
+     */
+    public const INFO = 200;
+
+    /**
+     * Uncommon events
+     */
+    public const NOTICE = 250;
+
+    /**
+     * Exceptional occurrences that are not errors
+     *
+     * Examples: Use of deprecated APIs, poor use of an API,
+     * undesirable things that are not necessarily wrong.
+     */
+    public const WARNING = 300;
+
+    /**
+     * Runtime errors
+     */
+    public const ERROR = 400;
+
+    /**
+     * Critical conditions
+     *
+     * Example: Application component unavailable, unexpected exception.
+     */
+    public const CRITICAL = 500;
+
+    /**
+     * Action must be taken immediately
+     *
+     * Example: Entire website down, database unavailable, etc.
+     * This should trigger the SMS alerts and wake you up.
+     */
+    public const ALERT = 550;
+
+    /**
+     * Urgent alert.
+     */
+    public const EMERGENCY = 600;
+
+    /**
+     * Monolog API version
+     *
+     * This is only bumped when API breaks are done and should
+     * follow the major version of the library
+     *
+     * @var int
+     */
+    public const API = 2;
+
+    /**
+     * This is a static variable and not a constant to serve as an extension point for custom levels
+     *
+     * @var array<int, string> $levels Logging levels with the levels as key
+     *
+     * @phpstan-var array<Level, LevelName> $levels Logging levels with the levels as key
+     */
+    protected static $levels = [
+        self::DEBUG     => 'DEBUG',
+        self::INFO      => 'INFO',
+        self::NOTICE    => 'NOTICE',
+        self::WARNING   => 'WARNING',
+        self::ERROR     => 'ERROR',
+        self::CRITICAL  => 'CRITICAL',
+        self::ALERT     => 'ALERT',
+        self::EMERGENCY => 'EMERGENCY',
+    ];
+
+    /**
+     * Mapping between levels numbers defined in RFC 5424 and Monolog ones
+     *
+     * @phpstan-var array<int, Level> $rfc_5424_levels
+     */
+    private const RFC_5424_LEVELS = [
+        7 => self::DEBUG,
+        6 => self::INFO,
+        5 => self::NOTICE,
+        4 => self::WARNING,
+        3 => self::ERROR,
+        2 => self::CRITICAL,
+        1 => self::ALERT,
+        0 => self::EMERGENCY,
+    ];
+
+    /**
+     * @var string
+     */
+    protected $name;
+
+    /**
+     * The handler stack
+     *
+     * @var HandlerInterface[]
+     */
+    protected $handlers;
+
+    /**
+     * Processors that will process all log records
+     *
+     * To process records of a single handler instead, add the processor on that specific handler
+     *
+     * @var callable[]
+     */
+    protected $processors;
+
+    /**
+     * @var bool
+     */
+    protected $microsecondTimestamps = true;
+
+    /**
+     * @var DateTimeZone
+     */
+    protected $timezone;
+
+    /**
+     * @var callable|null
+     */
+    protected $exceptionHandler;
+
+    /**
+     * @var int Keeps track of depth to prevent infinite logging loops
+     */
+    private $logDepth = 0;
+
+    /**
+     * @var bool Whether to detect infinite logging loops
+     *
+     * This can be disabled via {@see useLoggingLoopDetection} if you have async handlers that do not play well with this
+     */
+    private $detectCycles = true;
+
+    /**
+     * @psalm-param array<callable(array): array> $processors
+     *
+     * @param string             $name       The logging channel, a simple descriptive name that is attached to all log records
+     * @param HandlerInterface[] $handlers   Optional stack of handlers, the first one in the array is called first, etc.
+     * @param callable[]         $processors Optional array of processors
+     * @param DateTimeZone|null  $timezone   Optional timezone, if not provided date_default_timezone_get() will be used
+     */
+    public function __construct(string $name, array $handlers = [], array $processors = [], ?DateTimeZone $timezone = null)
+    {
+        $this->name = $name;
+        $this->setHandlers($handlers);
+        $this->processors = $processors;
+        $this->timezone = $timezone ?: new DateTimeZone(date_default_timezone_get() ?: 'UTC');
+    }
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+
+    /**
+     * Return a new cloned instance with the name changed
+     */
+    public function withName(string $name): self
+    {
+        $new = clone $this;
+        $new->name = $name;
+
+        return $new;
+    }
+
+    /**
+     * Pushes a handler on to the stack.
+     */
+    public function pushHandler(HandlerInterface $handler): self
+    {
+        array_unshift($this->handlers, $handler);
+
+        return $this;
+    }
+
+    /**
+     * Pops a handler from the stack
+     *
+     * @throws \LogicException If empty handler stack
+     */
+    public function popHandler(): HandlerInterface
+    {
+        if (!$this->handlers) {
+            throw new \LogicException('You tried to pop from an empty handler stack.');
+        }
+
+        return array_shift($this->handlers);
+    }
+
+    /**
+     * Set handlers, replacing all existing ones.
+     *
+     * If a map is passed, keys will be ignored.
+     *
+     * @param HandlerInterface[] $handlers
+     */
+    public function setHandlers(array $handlers): self
+    {
+        $this->handlers = [];
+        foreach (array_reverse($handlers) as $handler) {
+            $this->pushHandler($handler);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @return HandlerInterface[]
+     */
+    public function getHandlers(): array
+    {
+        return $this->handlers;
+    }
+
+    /**
+     * Adds a processor on to the stack.
+     */
+    public function pushProcessor(callable $callback): self
+    {
+        array_unshift($this->processors, $callback);
+
+        return $this;
+    }
+
+    /**
+     * Removes the processor on top of the stack and returns it.
+     *
+     * @throws \LogicException If empty processor stack
+     * @return callable
+     */
+    public function popProcessor(): callable
+    {
+        if (!$this->processors) {
+            throw new \LogicException('You tried to pop from an empty processor stack.');
+        }
+
+        return array_shift($this->processors);
+    }
+
+    /**
+     * @return callable[]
+     */
+    public function getProcessors(): array
+    {
+        return $this->processors;
+    }
+
+    /**
+     * Control the use of microsecond resolution timestamps in the 'datetime'
+     * member of new records.
+     *
+     * As of PHP7.1 microseconds are always included by the engine, so
+     * there is no performance penalty and Monolog 2 enabled microseconds
+     * by default. This function lets you disable them though in case you want
+     * to suppress microseconds from the output.
+     *
+     * @param bool $micro True to use microtime() to create timestamps
+     */
+    public function useMicrosecondTimestamps(bool $micro): self
+    {
+        $this->microsecondTimestamps = $micro;
+
+        return $this;
+    }
+
+    public function useLoggingLoopDetection(bool $detectCycles): self
+    {
+        $this->detectCycles = $detectCycles;
+
+        return $this;
+    }
+
+    /**
+     * Adds a log record.
+     *
+     * @param  int               $level    The logging level (a Monolog or RFC 5424 level)
+     * @param  string            $message  The log message
+     * @param  mixed[]           $context  The log context
+     * @param  DateTimeImmutable $datetime Optional log date to log into the past or future
+     * @return bool              Whether the record has been processed
+     *
+     * @phpstan-param Level $level
+     */
+    public function addRecord(int $level, string $message, array $context = [], DateTimeImmutable $datetime = null): bool
+    {
+        if (isset(self::RFC_5424_LEVELS[$level])) {
+            $level = self::RFC_5424_LEVELS[$level];
+        }
+
+        if ($this->detectCycles) {
+            $this->logDepth += 1;
+        }
+        if ($this->logDepth === 3) {
+            $this->warning('A possible infinite logging loop was detected and aborted. It appears some of your handler code is triggering logging, see the previous log record for a hint as to what may be the cause.');
+            return false;
+        } elseif ($this->logDepth >= 5) { // log depth 4 is let through so we can log the warning above
+            return false;
+        }
+
+        try {
+            $record = null;
+
+            foreach ($this->handlers as $handler) {
+                if (null === $record) {
+                    // skip creating the record as long as no handler is going to handle it
+                    if (!$handler->isHandling(['level' => $level])) {
+                        continue;
+                    }
+
+                    $levelName = static::getLevelName($level);
+
+                    $record = [
+                        'message' => $message,
+                        'context' => $context,
+                        'level' => $level,
+                        'level_name' => $levelName,
+                        'channel' => $this->name,
+                        'datetime' => $datetime ?? new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
+                        'extra' => [],
+                    ];
+
+                    try {
+                        foreach ($this->processors as $processor) {
+                            $record = $processor($record);
+                        }
+                    } catch (Throwable $e) {
+                        $this->handleException($e, $record);
+
+                        return true;
+                    }
+                }
+
+                // once the record exists, send it to all handlers as long as the bubbling chain is not interrupted
+                try {
+                    if (true === $handler->handle($record)) {
+                        break;
+                    }
+                } catch (Throwable $e) {
+                    $this->handleException($e, $record);
+
+                    return true;
+                }
+            }
+        } finally {
+            if ($this->detectCycles) {
+                $this->logDepth--;
+            }
+        }
+
+        return null !== $record;
+    }
+
+    /**
+     * Ends a log cycle and frees all resources used by handlers.
+     *
+     * Closing a Handler means flushing all buffers and freeing any open resources/handles.
+     * Handlers that have been closed should be able to accept log records again and re-open
+     * themselves on demand, but this may not always be possible depending on implementation.
+     *
+     * This is useful at the end of a request and will be called automatically on every handler
+     * when they get destructed.
+     */
+    public function close(): void
+    {
+        foreach ($this->handlers as $handler) {
+            $handler->close();
+        }
+    }
+
+    /**
+     * Ends a log cycle and resets all handlers and processors to their initial state.
+     *
+     * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
+     * state, and getting it back to a state in which it can receive log records again.
+     *
+     * This is useful in case you want to avoid logs leaking between two requests or jobs when you
+     * have a long running process like a worker or an application server serving multiple requests
+     * in one process.
+     */
+    public function reset(): void
+    {
+        foreach ($this->handlers as $handler) {
+            if ($handler instanceof ResettableInterface) {
+                $handler->reset();
+            }
+        }
+
+        foreach ($this->processors as $processor) {
+            if ($processor instanceof ResettableInterface) {
+                $processor->reset();
+            }
+        }
+    }
+
+    /**
+     * Gets all supported logging levels.
+     *
+     * @return array<string, int> Assoc array with human-readable level names => level codes.
+     * @phpstan-return array<LevelName, Level>
+     */
+    public static function getLevels(): array
+    {
+        return array_flip(static::$levels);
+    }
+
+    /**
+     * Gets the name of the logging level.
+     *
+     * @throws \Psr\Log\InvalidArgumentException If level is not defined
+     *
+     * @phpstan-param  Level     $level
+     * @phpstan-return LevelName
+     */
+    public static function getLevelName(int $level): string
+    {
+        if (!isset(static::$levels[$level])) {
+            throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
+        }
+
+        return static::$levels[$level];
+    }
+
+    /**
+     * Converts PSR-3 levels to Monolog ones if necessary
+     *
+     * @param  string|int                        $level Level number (monolog) or name (PSR-3)
+     * @throws \Psr\Log\InvalidArgumentException If level is not defined
+     *
+     * @phpstan-param  Level|LevelName|LogLevel::* $level
+     * @phpstan-return Level
+     */
+    public static function toMonologLevel($level): int
+    {
+        if (is_string($level)) {
+            if (is_numeric($level)) {
+                /** @phpstan-ignore-next-line */
+                return intval($level);
+            }
+
+            // Contains chars of all log levels and avoids using strtoupper() which may have
+            // strange results depending on locale (for example, "i" will become "İ" in Turkish locale)
+            $upper = strtr($level, 'abcdefgilmnortuwy', 'ABCDEFGILMNORTUWY');
+            if (defined(__CLASS__.'::'.$upper)) {
+                return constant(__CLASS__ . '::' . $upper);
+            }
+
+            throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
+        }
+
+        if (!is_int($level)) {
+            throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
+        }
+
+        return $level;
+    }
+
+    /**
+     * Checks whether the Logger has a handler that listens on the given level
+     *
+     * @phpstan-param Level $level
+     */
+    public function isHandling(int $level): bool
+    {
+        $record = [
+            'level' => $level,
+        ];
+
+        foreach ($this->handlers as $handler) {
+            if ($handler->isHandling($record)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Set a custom exception handler that will be called if adding a new record fails
+     *
+     * The callable will receive an exception object and the record that failed to be logged
+     */
+    public function setExceptionHandler(?callable $callback): self
+    {
+        $this->exceptionHandler = $callback;
+
+        return $this;
+    }
+
+    public function getExceptionHandler(): ?callable
+    {
+        return $this->exceptionHandler;
+    }
+
+    /**
+     * Adds a log record at an arbitrary level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param mixed             $level   The log level (a Monolog, PSR-3 or RFC 5424 level)
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function log($level, $message, array $context = []): void
+    {
+        if (!is_int($level) && !is_string($level)) {
+            throw new \InvalidArgumentException('$level is expected to be a string or int');
+        }
+
+        if (isset(self::RFC_5424_LEVELS[$level])) {
+            $level = self::RFC_5424_LEVELS[$level];
+        }
+
+        $level = static::toMonologLevel($level);
+
+        $this->addRecord($level, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the DEBUG level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function debug($message, array $context = []): void
+    {
+        $this->addRecord(static::DEBUG, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the INFO level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function info($message, array $context = []): void
+    {
+        $this->addRecord(static::INFO, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the NOTICE level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function notice($message, array $context = []): void
+    {
+        $this->addRecord(static::NOTICE, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the WARNING level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function warning($message, array $context = []): void
+    {
+        $this->addRecord(static::WARNING, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the ERROR level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function error($message, array $context = []): void
+    {
+        $this->addRecord(static::ERROR, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the CRITICAL level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function critical($message, array $context = []): void
+    {
+        $this->addRecord(static::CRITICAL, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the ALERT level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function alert($message, array $context = []): void
+    {
+        $this->addRecord(static::ALERT, (string) $message, $context);
+    }
+
+    /**
+     * Adds a log record at the EMERGENCY level.
+     *
+     * This method allows for compatibility with common interfaces.
+     *
+     * @param string|Stringable $message The log message
+     * @param mixed[]           $context The log context
+     */
+    public function emergency($message, array $context = []): void
+    {
+        $this->addRecord(static::EMERGENCY, (string) $message, $context);
+    }
+
+    /**
+     * Sets the timezone to be used for the timestamp of log records.
+     */
+    public function setTimezone(DateTimeZone $tz): self
+    {
+        $this->timezone = $tz;
+
+        return $this;
+    }
+
+    /**
+     * Returns the timezone to be used for the timestamp of log records.
+     */
+    public function getTimezone(): DateTimeZone
+    {
+        return $this->timezone;
+    }
+
+    /**
+     * Delegates exception management to the custom exception handler,
+     * or throws the exception if no custom handler is set.
+     *
+     * @param array $record
+     * @phpstan-param Record $record
+     */
+    protected function handleException(Throwable $e, array $record): void
+    {
+        if (!$this->exceptionHandler) {
+            throw $e;
+        }
+
+        ($this->exceptionHandler)($e, $record);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php
new file mode 100644
index 00000000..8166bdca
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Injects Git branch and Git commit SHA in all records
+ *
+ * @author Nick Otter
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class GitProcessor implements ProcessorInterface
+{
+    /** @var int */
+    private $level;
+    /** @var array{branch: string, commit: string}|array<never>|null */
+    private static $cache = null;
+
+    /**
+     * @param string|int $level The minimum logging level at which this Processor will be triggered
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function __construct($level = Logger::DEBUG)
+    {
+        $this->level = Logger::toMonologLevel($level);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        // return if the level is not high enough
+        if ($record['level'] < $this->level) {
+            return $record;
+        }
+
+        $record['extra']['git'] = self::getGitInfo();
+
+        return $record;
+    }
+
+    /**
+     * @return array{branch: string, commit: string}|array<never>
+     */
+    private static function getGitInfo(): array
+    {
+        if (self::$cache) {
+            return self::$cache;
+        }
+
+        $branches = `git branch -v --no-abbrev`;
+        if ($branches && preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) {
+            return self::$cache = [
+                'branch' => $matches[1],
+                'commit' => $matches[2],
+            ];
+        }
+
+        return self::$cache = [];
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/HostnameProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/HostnameProcessor.php
new file mode 100644
index 00000000..91fda7d6
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/HostnameProcessor.php
@@ -0,0 +1,36 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Injects value of gethostname in all records
+ */
+class HostnameProcessor implements ProcessorInterface
+{
+    /** @var string */
+    private static $host;
+
+    public function __construct()
+    {
+        self::$host = (string) gethostname();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        $record['extra']['hostname'] = self::$host;
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php
new file mode 100644
index 00000000..a32e76b2
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php
@@ -0,0 +1,123 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Injects line/file:class/function where the log message came from
+ *
+ * Warning: This only works if the handler processes the logs directly.
+ * If you put the processor on a handler that is behind a FingersCrossedHandler
+ * for example, the processor will only be called once the trigger level is reached,
+ * and all the log records will have the same file/line/.. data from the call that
+ * triggered the FingersCrossedHandler.
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class IntrospectionProcessor implements ProcessorInterface
+{
+    /** @var int */
+    private $level;
+    /** @var string[] */
+    private $skipClassesPartials;
+    /** @var int */
+    private $skipStackFramesCount;
+    /** @var string[] */
+    private $skipFunctions = [
+        'call_user_func',
+        'call_user_func_array',
+    ];
+
+    /**
+     * @param string|int $level               The minimum logging level at which this Processor will be triggered
+     * @param string[]   $skipClassesPartials
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function __construct($level = Logger::DEBUG, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
+    {
+        $this->level = Logger::toMonologLevel($level);
+        $this->skipClassesPartials = array_merge(['Monolog\\'], $skipClassesPartials);
+        $this->skipStackFramesCount = $skipStackFramesCount;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        // return if the level is not high enough
+        if ($record['level'] < $this->level) {
+            return $record;
+        }
+
+        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+
+        // skip first since it's always the current method
+        array_shift($trace);
+        // the call_user_func call is also skipped
+        array_shift($trace);
+
+        $i = 0;
+
+        while ($this->isTraceClassOrSkippedFunction($trace, $i)) {
+            if (isset($trace[$i]['class'])) {
+                foreach ($this->skipClassesPartials as $part) {
+                    if (strpos($trace[$i]['class'], $part) !== false) {
+                        $i++;
+
+                        continue 2;
+                    }
+                }
+            } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) {
+                $i++;
+
+                continue;
+            }
+
+            break;
+        }
+
+        $i += $this->skipStackFramesCount;
+
+        // we should have the call source now
+        $record['extra'] = array_merge(
+            $record['extra'],
+            [
+                'file'      => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null,
+                'line'      => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null,
+                'class'     => isset($trace[$i]['class']) ? $trace[$i]['class'] : null,
+                'callType'  => isset($trace[$i]['type']) ? $trace[$i]['type'] : null,
+                'function'  => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
+            ]
+        );
+
+        return $record;
+    }
+
+    /**
+     * @param array[] $trace
+     */
+    private function isTraceClassOrSkippedFunction(array $trace, int $index): bool
+    {
+        if (!isset($trace[$index])) {
+            return false;
+        }
+
+        return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php
new file mode 100644
index 00000000..37c756fc
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Injects memory_get_peak_usage in all records
+ *
+ * @see Monolog\Processor\MemoryProcessor::__construct() for options
+ * @author Rob Jensen
+ */
+class MemoryPeakUsageProcessor extends MemoryProcessor
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        $usage = memory_get_peak_usage($this->realUsage);
+
+        if ($this->useFormatting) {
+            $usage = $this->formatBytes($usage);
+        }
+
+        $record['extra']['memory_peak_usage'] = $usage;
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php
new file mode 100644
index 00000000..227deb7c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php
@@ -0,0 +1,61 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Some methods that are common for all memory processors
+ *
+ * @author Rob Jensen
+ */
+abstract class MemoryProcessor implements ProcessorInterface
+{
+    /**
+     * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported.
+     */
+    protected $realUsage;
+
+    /**
+     * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size)
+     */
+    protected $useFormatting;
+
+    /**
+     * @param bool $realUsage     Set this to true to get the real size of memory allocated from system.
+     * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size)
+     */
+    public function __construct(bool $realUsage = true, bool $useFormatting = true)
+    {
+        $this->realUsage = $realUsage;
+        $this->useFormatting = $useFormatting;
+    }
+
+    /**
+     * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is
+     *
+     * @param  int        $bytes
+     * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as int
+     */
+    protected function formatBytes(int $bytes)
+    {
+        if (!$this->useFormatting) {
+            return $bytes;
+        }
+
+        if ($bytes > 1024 * 1024) {
+            return round($bytes / 1024 / 1024, 2).' MB';
+        } elseif ($bytes > 1024) {
+            return round($bytes / 1024, 2).' KB';
+        }
+
+        return $bytes . ' B';
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php
new file mode 100644
index 00000000..e141921e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php
@@ -0,0 +1,37 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Injects memory_get_usage in all records
+ *
+ * @see Monolog\Processor\MemoryProcessor::__construct() for options
+ * @author Rob Jensen
+ */
+class MemoryUsageProcessor extends MemoryProcessor
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        $usage = memory_get_usage($this->realUsage);
+
+        if ($this->useFormatting) {
+            $usage = $this->formatBytes($usage);
+        }
+
+        $record['extra']['memory_usage'] = $usage;
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php
new file mode 100644
index 00000000..d4a628f5
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php
@@ -0,0 +1,77 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\Logger;
+use Psr\Log\LogLevel;
+
+/**
+ * Injects Hg branch and Hg revision number in all records
+ *
+ * @author Jonathan A. Schweder <jonathanschweder@gmail.com>
+ *
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ */
+class MercurialProcessor implements ProcessorInterface
+{
+    /** @var Level */
+    private $level;
+    /** @var array{branch: string, revision: string}|array<never>|null */
+    private static $cache = null;
+
+    /**
+     * @param int|string $level The minimum logging level at which this Processor will be triggered
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function __construct($level = Logger::DEBUG)
+    {
+        $this->level = Logger::toMonologLevel($level);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        // return if the level is not high enough
+        if ($record['level'] < $this->level) {
+            return $record;
+        }
+
+        $record['extra']['hg'] = self::getMercurialInfo();
+
+        return $record;
+    }
+
+    /**
+     * @return array{branch: string, revision: string}|array<never>
+     */
+    private static function getMercurialInfo(): array
+    {
+        if (self::$cache) {
+            return self::$cache;
+        }
+
+        $result = explode(' ', trim(`hg id -nb`));
+
+        if (count($result) >= 3) {
+            return self::$cache = [
+                'branch' => $result[1],
+                'revision' => $result[2],
+            ];
+        }
+
+        return self::$cache = [];
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php
new file mode 100644
index 00000000..3b939a95
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php
@@ -0,0 +1,30 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Adds value of getmypid into records
+ *
+ * @author Andreas Hörnicke
+ */
+class ProcessIdProcessor implements ProcessorInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        $record['extra']['process_id'] = getmypid();
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php
new file mode 100644
index 00000000..5defb7eb
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php
@@ -0,0 +1,30 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * An optional interface to allow labelling Monolog processors.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ */
+interface ProcessorInterface
+{
+    /**
+     * @return array The processed record
+     *
+     * @phpstan-param  Record $record
+     * @phpstan-return Record
+     */
+    public function __invoke(array $record);
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php
new file mode 100644
index 00000000..2c2a00e7
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php
@@ -0,0 +1,86 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\Utils;
+
+/**
+ * Processes a record's message according to PSR-3 rules
+ *
+ * It replaces {foo} with the value from $context['foo']
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class PsrLogMessageProcessor implements ProcessorInterface
+{
+    public const SIMPLE_DATE = "Y-m-d\TH:i:s.uP";
+
+    /** @var string|null */
+    private $dateFormat;
+
+    /** @var bool */
+    private $removeUsedContextFields;
+
+    /**
+     * @param string|null $dateFormat              The format of the timestamp: one supported by DateTime::format
+     * @param bool        $removeUsedContextFields If set to true the fields interpolated into message gets unset
+     */
+    public function __construct(?string $dateFormat = null, bool $removeUsedContextFields = false)
+    {
+        $this->dateFormat = $dateFormat;
+        $this->removeUsedContextFields = $removeUsedContextFields;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        if (false === strpos($record['message'], '{')) {
+            return $record;
+        }
+
+        $replacements = [];
+        foreach ($record['context'] as $key => $val) {
+            $placeholder = '{' . $key . '}';
+            if (strpos($record['message'], $placeholder) === false) {
+                continue;
+            }
+
+            if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) {
+                $replacements[$placeholder] = $val;
+            } elseif ($val instanceof \DateTimeInterface) {
+                if (!$this->dateFormat && $val instanceof \Monolog\DateTimeImmutable) {
+                    // handle monolog dates using __toString if no specific dateFormat was asked for
+                    // so that it follows the useMicroseconds flag
+                    $replacements[$placeholder] = (string) $val;
+                } else {
+                    $replacements[$placeholder] = $val->format($this->dateFormat ?: static::SIMPLE_DATE);
+                }
+            } elseif (is_object($val)) {
+                $replacements[$placeholder] = '[object '.Utils::getClass($val).']';
+            } elseif (is_array($val)) {
+                $replacements[$placeholder] = 'array'.Utils::jsonEncode($val, null, true);
+            } else {
+                $replacements[$placeholder] = '['.gettype($val).']';
+            }
+
+            if ($this->removeUsedContextFields) {
+                unset($record['context'][$key]);
+            }
+        }
+
+        $record['message'] = strtr($record['message'], $replacements);
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php
new file mode 100644
index 00000000..80f18747
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php
@@ -0,0 +1,61 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Adds a tags array into record
+ *
+ * @author Martijn Riemers
+ */
+class TagProcessor implements ProcessorInterface
+{
+    /** @var string[] */
+    private $tags;
+
+    /**
+     * @param string[] $tags
+     */
+    public function __construct(array $tags = [])
+    {
+        $this->setTags($tags);
+    }
+
+    /**
+     * @param string[] $tags
+     */
+    public function addTags(array $tags = []): self
+    {
+        $this->tags = array_merge($this->tags, $tags);
+
+        return $this;
+    }
+
+    /**
+     * @param string[] $tags
+     */
+    public function setTags(array $tags = []): self
+    {
+        $this->tags = $tags;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        $record['extra']['tags'] = $this->tags;
+
+        return $record;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php
new file mode 100644
index 00000000..a27b74db
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php
@@ -0,0 +1,59 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+use Monolog\ResettableInterface;
+
+/**
+ * Adds a unique identifier into records
+ *
+ * @author Simon Mönch <sm@webfactory.de>
+ */
+class UidProcessor implements ProcessorInterface, ResettableInterface
+{
+    /** @var string */
+    private $uid;
+
+    public function __construct(int $length = 7)
+    {
+        if ($length > 32 || $length < 1) {
+            throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32');
+        }
+
+        $this->uid = $this->generateUid($length);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        $record['extra']['uid'] = $this->uid;
+
+        return $record;
+    }
+
+    public function getUid(): string
+    {
+        return $this->uid;
+    }
+
+    public function reset()
+    {
+        $this->uid = $this->generateUid(strlen($this->uid));
+    }
+
+    private function generateUid(int $length): string
+    {
+        return substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php b/msd/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php
new file mode 100644
index 00000000..51850e17
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php
@@ -0,0 +1,111 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Processor;
+
+/**
+ * Injects url/method and remote IP of the current web request in all records
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class WebProcessor implements ProcessorInterface
+{
+    /**
+     * @var array<string, mixed>|\ArrayAccess<string, mixed>
+     */
+    protected $serverData;
+
+    /**
+     * Default fields
+     *
+     * Array is structured as [key in record.extra => key in $serverData]
+     *
+     * @var array<string, string>
+     */
+    protected $extraFields = [
+        'url'         => 'REQUEST_URI',
+        'ip'          => 'REMOTE_ADDR',
+        'http_method' => 'REQUEST_METHOD',
+        'server'      => 'SERVER_NAME',
+        'referrer'    => 'HTTP_REFERER',
+        'user_agent'  => 'HTTP_USER_AGENT',
+    ];
+
+    /**
+     * @param array<string, mixed>|\ArrayAccess<string, mixed>|null $serverData  Array or object w/ ArrayAccess that provides access to the $_SERVER data
+     * @param array<string, string>|array<string>|null              $extraFields Field names and the related key inside $serverData to be added (or just a list of field names to use the default configured $serverData mapping). If not provided it defaults to: [url, ip, http_method, server, referrer] + unique_id if present in server data
+     */
+    public function __construct($serverData = null, array $extraFields = null)
+    {
+        if (null === $serverData) {
+            $this->serverData = &$_SERVER;
+        } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) {
+            $this->serverData = $serverData;
+        } else {
+            throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.');
+        }
+
+        $defaultEnabled = ['url', 'ip', 'http_method', 'server', 'referrer'];
+        if (isset($this->serverData['UNIQUE_ID'])) {
+            $this->extraFields['unique_id'] = 'UNIQUE_ID';
+            $defaultEnabled[] = 'unique_id';
+        }
+
+        if (null === $extraFields) {
+            $extraFields = $defaultEnabled;
+        }
+        if (isset($extraFields[0])) {
+            foreach (array_keys($this->extraFields) as $fieldName) {
+                if (!in_array($fieldName, $extraFields)) {
+                    unset($this->extraFields[$fieldName]);
+                }
+            }
+        } else {
+            $this->extraFields = $extraFields;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __invoke(array $record): array
+    {
+        // skip processing if for some reason request data
+        // is not present (CLI or wonky SAPIs)
+        if (!isset($this->serverData['REQUEST_URI'])) {
+            return $record;
+        }
+
+        $record['extra'] = $this->appendExtraFields($record['extra']);
+
+        return $record;
+    }
+
+    public function addExtraField(string $extraName, string $serverName): self
+    {
+        $this->extraFields[$extraName] = $serverName;
+
+        return $this;
+    }
+
+    /**
+     * @param  mixed[] $extra
+     * @return mixed[]
+     */
+    private function appendExtraFields(array $extra): array
+    {
+        foreach ($this->extraFields as $extraName => $serverName) {
+            $extra[$extraName] = $this->serverData[$serverName] ?? null;
+        }
+
+        return $extra;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Registry.php b/msd/vendor/monolog/monolog/src/Monolog/Registry.php
new file mode 100644
index 00000000..ae94ae6c
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Registry.php
@@ -0,0 +1,134 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use InvalidArgumentException;
+
+/**
+ * Monolog log registry
+ *
+ * Allows to get `Logger` instances in the global scope
+ * via static method calls on this class.
+ *
+ * <code>
+ * $application = new Monolog\Logger('application');
+ * $api = new Monolog\Logger('api');
+ *
+ * Monolog\Registry::addLogger($application);
+ * Monolog\Registry::addLogger($api);
+ *
+ * function testLogger()
+ * {
+ *     Monolog\Registry::api()->error('Sent to $api Logger instance');
+ *     Monolog\Registry::application()->error('Sent to $application Logger instance');
+ * }
+ * </code>
+ *
+ * @author Tomas Tatarko <tomas@tatarko.sk>
+ */
+class Registry
+{
+    /**
+     * List of all loggers in the registry (by named indexes)
+     *
+     * @var Logger[]
+     */
+    private static $loggers = [];
+
+    /**
+     * Adds new logging channel to the registry
+     *
+     * @param  Logger                    $logger    Instance of the logging channel
+     * @param  string|null               $name      Name of the logging channel ($logger->getName() by default)
+     * @param  bool                      $overwrite Overwrite instance in the registry if the given name already exists?
+     * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists
+     * @return void
+     */
+    public static function addLogger(Logger $logger, ?string $name = null, bool $overwrite = false)
+    {
+        $name = $name ?: $logger->getName();
+
+        if (isset(self::$loggers[$name]) && !$overwrite) {
+            throw new InvalidArgumentException('Logger with the given name already exists');
+        }
+
+        self::$loggers[$name] = $logger;
+    }
+
+    /**
+     * Checks if such logging channel exists by name or instance
+     *
+     * @param string|Logger $logger Name or logger instance
+     */
+    public static function hasLogger($logger): bool
+    {
+        if ($logger instanceof Logger) {
+            $index = array_search($logger, self::$loggers, true);
+
+            return false !== $index;
+        }
+
+        return isset(self::$loggers[$logger]);
+    }
+
+    /**
+     * Removes instance from registry by name or instance
+     *
+     * @param string|Logger $logger Name or logger instance
+     */
+    public static function removeLogger($logger): void
+    {
+        if ($logger instanceof Logger) {
+            if (false !== ($idx = array_search($logger, self::$loggers, true))) {
+                unset(self::$loggers[$idx]);
+            }
+        } else {
+            unset(self::$loggers[$logger]);
+        }
+    }
+
+    /**
+     * Clears the registry
+     */
+    public static function clear(): void
+    {
+        self::$loggers = [];
+    }
+
+    /**
+     * Gets Logger instance from the registry
+     *
+     * @param  string                    $name Name of the requested Logger instance
+     * @throws \InvalidArgumentException If named Logger instance is not in the registry
+     */
+    public static function getInstance($name): Logger
+    {
+        if (!isset(self::$loggers[$name])) {
+            throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name));
+        }
+
+        return self::$loggers[$name];
+    }
+
+    /**
+     * Gets Logger instance from the registry via static method call
+     *
+     * @param  string                    $name      Name of the requested Logger instance
+     * @param  mixed[]                   $arguments Arguments passed to static method call
+     * @throws \InvalidArgumentException If named Logger instance is not in the registry
+     * @return Logger                    Requested instance of Logger
+     */
+    public static function __callStatic($name, $arguments)
+    {
+        return self::getInstance($name);
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/ResettableInterface.php b/msd/vendor/monolog/monolog/src/Monolog/ResettableInterface.php
new file mode 100644
index 00000000..2c5fd785
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/ResettableInterface.php
@@ -0,0 +1,34 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+/**
+ * Handler or Processor implementing this interface will be reset when Logger::reset() is called.
+ *
+ * Resetting ends a log cycle gets them back to their initial state.
+ *
+ * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
+ * state, and getting it back to a state in which it can receive log records again.
+ *
+ * This is useful in case you want to avoid logs leaking between two requests or jobs when you
+ * have a long running process like a worker or an application server serving multiple requests
+ * in one process.
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ */
+interface ResettableInterface
+{
+    /**
+     * @return void
+     */
+    public function reset();
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/SignalHandler.php b/msd/vendor/monolog/monolog/src/Monolog/SignalHandler.php
new file mode 100644
index 00000000..d730eea3
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/SignalHandler.php
@@ -0,0 +1,120 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use ReflectionExtension;
+
+/**
+ * Monolog POSIX signal handler
+ *
+ * @author Robert Gust-Bardon <robert@gust-bardon.org>
+ *
+ * @phpstan-import-type Level from \Monolog\Logger
+ * @phpstan-import-type LevelName from \Monolog\Logger
+ */
+class SignalHandler
+{
+    /** @var LoggerInterface */
+    private $logger;
+
+    /** @var array<int, callable|string|int> SIG_DFL, SIG_IGN or previous callable */
+    private $previousSignalHandler = [];
+    /** @var array<int, int> */
+    private $signalLevelMap = [];
+    /** @var array<int, bool> */
+    private $signalRestartSyscalls = [];
+
+    public function __construct(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+
+    /**
+     * @param  int|string $level           Level or level name
+     * @param  bool       $callPrevious
+     * @param  bool       $restartSyscalls
+     * @param  bool|null  $async
+     * @return $this
+     *
+     * @phpstan-param Level|LevelName|LogLevel::* $level
+     */
+    public function registerSignalHandler(int $signo, $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self
+    {
+        if (!extension_loaded('pcntl') || !function_exists('pcntl_signal')) {
+            return $this;
+        }
+
+        $level = Logger::toMonologLevel($level);
+
+        if ($callPrevious) {
+            $handler = pcntl_signal_get_handler($signo);
+            $this->previousSignalHandler[$signo] = $handler;
+        } else {
+            unset($this->previousSignalHandler[$signo]);
+        }
+        $this->signalLevelMap[$signo] = $level;
+        $this->signalRestartSyscalls[$signo] = $restartSyscalls;
+
+        if ($async !== null) {
+            pcntl_async_signals($async);
+        }
+
+        pcntl_signal($signo, [$this, 'handleSignal'], $restartSyscalls);
+
+        return $this;
+    }
+
+    /**
+     * @param mixed $siginfo
+     */
+    public function handleSignal(int $signo, $siginfo = null): void
+    {
+        static $signals = [];
+
+        if (!$signals && extension_loaded('pcntl')) {
+            $pcntl = new ReflectionExtension('pcntl');
+            // HHVM 3.24.2 returns an empty array.
+            foreach ($pcntl->getConstants() ?: get_defined_constants(true)['Core'] as $name => $value) {
+                if (substr($name, 0, 3) === 'SIG' && $name[3] !== '_' && is_int($value)) {
+                    $signals[$value] = $name;
+                }
+            }
+        }
+
+        $level = $this->signalLevelMap[$signo] ?? LogLevel::CRITICAL;
+        $signal = $signals[$signo] ?? $signo;
+        $context = $siginfo ?? [];
+        $this->logger->log($level, sprintf('Program received signal %s', $signal), $context);
+
+        if (!isset($this->previousSignalHandler[$signo])) {
+            return;
+        }
+
+        if ($this->previousSignalHandler[$signo] === SIG_DFL) {
+            if (extension_loaded('pcntl') && function_exists('pcntl_signal') && function_exists('pcntl_sigprocmask') && function_exists('pcntl_signal_dispatch')
+                && extension_loaded('posix') && function_exists('posix_getpid') && function_exists('posix_kill')
+            ) {
+                $restartSyscalls = $this->signalRestartSyscalls[$signo] ?? true;
+                pcntl_signal($signo, SIG_DFL, $restartSyscalls);
+                pcntl_sigprocmask(SIG_UNBLOCK, [$signo], $oldset);
+                posix_kill(posix_getpid(), $signo);
+                pcntl_signal_dispatch();
+                pcntl_sigprocmask(SIG_SETMASK, $oldset);
+                pcntl_signal($signo, [$this, 'handleSignal'], $restartSyscalls);
+            }
+        } elseif (is_callable($this->previousSignalHandler[$signo])) {
+            $this->previousSignalHandler[$signo]($signo, $siginfo);
+        }
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Test/TestCase.php b/msd/vendor/monolog/monolog/src/Monolog/Test/TestCase.php
new file mode 100644
index 00000000..bc0b425e
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Test/TestCase.php
@@ -0,0 +1,85 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Test;
+
+use Monolog\Logger;
+use Monolog\DateTimeImmutable;
+use Monolog\Formatter\FormatterInterface;
+
+/**
+ * Lets you easily generate log records and a dummy formatter for testing purposes
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * @phpstan-import-type Record from \Monolog\Logger
+ * @phpstan-import-type Level from \Monolog\Logger
+ *
+ * @internal feel free to reuse this to test your own handlers, this is marked internal to avoid issues with PHPStorm https://github.com/Seldaek/monolog/issues/1677
+ */
+class TestCase extends \PHPUnit\Framework\TestCase
+{
+    public function tearDown(): void
+    {
+        parent::tearDown();
+
+        if (isset($this->handler)) {
+            unset($this->handler);
+        }
+    }
+
+    /**
+     * @param mixed[] $context
+     *
+     * @return array Record
+     *
+     * @phpstan-param  Level $level
+     * @phpstan-return Record
+     */
+    protected function getRecord(int $level = Logger::WARNING, string $message = 'test', array $context = []): array
+    {
+        return [
+            'message' => (string) $message,
+            'context' => $context,
+            'level' => $level,
+            'level_name' => Logger::getLevelName($level),
+            'channel' => 'test',
+            'datetime' => new DateTimeImmutable(true),
+            'extra' => [],
+        ];
+    }
+
+    /**
+     * @phpstan-return Record[]
+     */
+    protected function getMultipleRecords(): array
+    {
+        return [
+            $this->getRecord(Logger::DEBUG, 'debug message 1'),
+            $this->getRecord(Logger::DEBUG, 'debug message 2'),
+            $this->getRecord(Logger::INFO, 'information'),
+            $this->getRecord(Logger::WARNING, 'warning'),
+            $this->getRecord(Logger::ERROR, 'error'),
+        ];
+    }
+
+    protected function getIdentityFormatter(): FormatterInterface
+    {
+        $formatter = $this->createMock(FormatterInterface::class);
+        $formatter->expects($this->any())
+            ->method('format')
+            ->will($this->returnCallback(function ($record) {
+                return $record['message'];
+            }));
+
+        return $formatter;
+    }
+}
diff --git a/msd/vendor/monolog/monolog/src/Monolog/Utils.php b/msd/vendor/monolog/monolog/src/Monolog/Utils.php
new file mode 100644
index 00000000..360c4219
--- /dev/null
+++ b/msd/vendor/monolog/monolog/src/Monolog/Utils.php
@@ -0,0 +1,284 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+final class Utils
+{
+    const DEFAULT_JSON_FLAGS = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR;
+
+    public static function getClass(object $object): string
+    {
+        $class = \get_class($object);
+
+        if (false === ($pos = \strpos($class, "@anonymous\0"))) {
+            return $class;
+        }
+
+        if (false === ($parent = \get_parent_class($class))) {
+            return \substr($class, 0, $pos + 10);
+        }
+
+        return $parent . '@anonymous';
+    }
+
+    public static function substr(string $string, int $start, ?int $length = null): string
+    {
+        if (extension_loaded('mbstring')) {
+            return mb_strcut($string, $start, $length);
+        }
+
+        return substr($string, $start, (null === $length) ? strlen($string) : $length);
+    }
+
+    /**
+     * Makes sure if a relative path is passed in it is turned into an absolute path
+     *
+     * @param string $streamUrl stream URL or path without protocol
+     */
+    public static function canonicalizePath(string $streamUrl): string
+    {
+        $prefix = '';
+        if ('file://' === substr($streamUrl, 0, 7)) {
+            $streamUrl = substr($streamUrl, 7);
+            $prefix = 'file://';
+        }
+
+        // other type of stream, not supported
+        if (false !== strpos($streamUrl, '://')) {
+            return $streamUrl;
+        }
+
+        // already absolute
+        if (substr($streamUrl, 0, 1) === '/' || substr($streamUrl, 1, 1) === ':' || substr($streamUrl, 0, 2) === '\\\\') {
+            return $prefix.$streamUrl;
+        }
+
+        $streamUrl = getcwd() . '/' . $streamUrl;
+
+        return $prefix.$streamUrl;
+    }
+
+    /**
+     * Return the JSON representation of a value
+     *
+     * @param  mixed             $data
+     * @param  int               $encodeFlags  flags to pass to json encode, defaults to DEFAULT_JSON_FLAGS
+     * @param  bool              $ignoreErrors whether to ignore encoding errors or to throw on error, when ignored and the encoding fails, "null" is returned which is valid json for null
+     * @throws \RuntimeException if encoding fails and errors are not ignored
+     * @return string            when errors are ignored and the encoding fails, "null" is returned which is valid json for null
+     */
+    public static function jsonEncode($data, ?int $encodeFlags = null, bool $ignoreErrors = false): string
+    {
+        if (null === $encodeFlags) {
+            $encodeFlags = self::DEFAULT_JSON_FLAGS;
+        }
+
+        if ($ignoreErrors) {
+            $json = @json_encode($data, $encodeFlags);
+            if (false === $json) {
+                return 'null';
+            }
+
+            return $json;
+        }
+
+        $json = json_encode($data, $encodeFlags);
+        if (false === $json) {
+            $json = self::handleJsonError(json_last_error(), $data);
+        }
+
+        return $json;
+    }
+
+    /**
+     * Handle a json_encode failure.
+     *
+     * If the failure is due to invalid string encoding, try to clean the
+     * input and encode again. If the second encoding attempt fails, the
+     * initial error is not encoding related or the input can't be cleaned then
+     * raise a descriptive exception.
+     *
+     * @param  int               $code        return code of json_last_error function
+     * @param  mixed             $data        data that was meant to be encoded
+     * @param  int               $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION
+     * @throws \RuntimeException if failure can't be corrected
+     * @return string            JSON encoded data after error correction
+     */
+    public static function handleJsonError(int $code, $data, ?int $encodeFlags = null): string
+    {
+        if ($code !== JSON_ERROR_UTF8) {
+            self::throwEncodeError($code, $data);
+        }
+
+        if (is_string($data)) {
+            self::detectAndCleanUtf8($data);
+        } elseif (is_array($data)) {
+            array_walk_recursive($data, array('Monolog\Utils', 'detectAndCleanUtf8'));
+        } else {
+            self::throwEncodeError($code, $data);
+        }
+
+        if (null === $encodeFlags) {
+            $encodeFlags = self::DEFAULT_JSON_FLAGS;
+        }
+
+        $json = json_encode($data, $encodeFlags);
+
+        if ($json === false) {
+            self::throwEncodeError(json_last_error(), $data);
+        }
+
+        return $json;
+    }
+
+    /**
+     * @internal
+     */
+    public static function pcreLastErrorMessage(int $code): string
+    {
+        if (PHP_VERSION_ID >= 80000) {
+            return preg_last_error_msg();
+        }
+
+        $constants = (get_defined_constants(true))['pcre'];
+        $constants = array_filter($constants, function ($key) {
+            return substr($key, -6) == '_ERROR';
+        }, ARRAY_FILTER_USE_KEY);
+
+        $constants = array_flip($constants);
+
+        return $constants[$code] ?? 'UNDEFINED_ERROR';
+    }
+
+    /**
+     * Throws an exception according to a given code with a customized message
+     *
+     * @param  int               $code return code of json_last_error function
+     * @param  mixed             $data data that was meant to be encoded
+     * @throws \RuntimeException
+     *
+     * @return never
+     */
+    private static function throwEncodeError(int $code, $data): void
+    {
+        switch ($code) {
+            case JSON_ERROR_DEPTH:
+                $msg = 'Maximum stack depth exceeded';
+                break;
+            case JSON_ERROR_STATE_MISMATCH:
+                $msg = 'Underflow or the modes mismatch';
+                break;
+            case JSON_ERROR_CTRL_CHAR:
+                $msg = 'Unexpected control character found';
+                break;
+            case JSON_ERROR_UTF8:
+                $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
+                break;
+            default:
+                $msg = 'Unknown error';
+        }
+
+        throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true));
+    }
+
+    /**
+     * Detect invalid UTF-8 string characters and convert to valid UTF-8.
+     *
+     * Valid UTF-8 input will be left unmodified, but strings containing
+     * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed
+     * original encoding of ISO-8859-15. This conversion may result in
+     * incorrect output if the actual encoding was not ISO-8859-15, but it
+     * will be clean UTF-8 output and will not rely on expensive and fragile
+     * detection algorithms.
+     *
+     * Function converts the input in place in the passed variable so that it
+     * can be used as a callback for array_walk_recursive.
+     *
+     * @param mixed $data Input to check and convert if needed, passed by ref
+     */
+    private static function detectAndCleanUtf8(&$data): void
+    {
+        if (is_string($data) && !preg_match('//u', $data)) {
+            $data = preg_replace_callback(
+                '/[\x80-\xFF]+/',
+                function ($m) {
+                    return function_exists('mb_convert_encoding') ? mb_convert_encoding($m[0], 'UTF-8', 'ISO-8859-1') : utf8_encode($m[0]);
+                },
+                $data
+            );
+            if (!is_string($data)) {
+                $pcreErrorCode = preg_last_error();
+                throw new \RuntimeException('Failed to preg_replace_callback: ' . $pcreErrorCode . ' / ' . self::pcreLastErrorMessage($pcreErrorCode));
+            }
+            $data = str_replace(
+                ['¤', '¦', '¨', '´', '¸', '¼', '½', '¾'],
+                ['€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'],
+                $data
+            );
+        }
+    }
+
+    /**
+     * Converts a string with a valid 'memory_limit' format, to bytes.
+     *
+     * @param string|false $val
+     * @return int|false Returns an integer representing bytes. Returns FALSE in case of error.
+     */
+    public static function expandIniShorthandBytes($val)
+    {
+        if (!is_string($val)) {
+            return false;
+        }
+
+        // support -1
+        if ((int) $val < 0) {
+            return (int) $val;
+        }
+
+        if (!preg_match('/^\s*(?<val>\d+)(?:\.\d+)?\s*(?<unit>[gmk]?)\s*$/i', $val, $match)) {
+            return false;
+        }
+
+        $val = (int) $match['val'];
+        switch (strtolower($match['unit'] ?? '')) {
+            case 'g':
+                $val *= 1024;
+            case 'm':
+                $val *= 1024;
+            case 'k':
+                $val *= 1024;
+        }
+
+        return $val;
+    }
+
+    /**
+     * @param array<mixed> $record
+     */
+    public static function getRecordMessageForException(array $record): string
+    {
+        $context = '';
+        $extra = '';
+        try {
+            if ($record['context']) {
+                $context = "\nContext: " . json_encode($record['context']);
+            }
+            if ($record['extra']) {
+                $extra = "\nExtra: " . json_encode($record['extra']);
+            }
+        } catch (\Throwable $e) {
+            // noop
+        }
+
+        return "\nThe exception occurred while attempting to log: " . $record['message'] . $context . $extra;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/AUTHORS b/msd/vendor/phpseclib/phpseclib/AUTHORS
new file mode 100644
index 00000000..9f10d267
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/AUTHORS
@@ -0,0 +1,7 @@
+phpseclib Lead Developer:  TerraFrost (Jim Wigginton)
+
+phpseclib Developers:      monnerat (Patrick Monnerat)
+                           bantu (Andreas Fischer)
+                           petrich (Hans-Jürgen Petrich)
+                           GrahamCampbell (Graham Campbell)
+                           hc-jworman
\ No newline at end of file
diff --git a/msd/vendor/phpseclib/phpseclib/BACKERS.md b/msd/vendor/phpseclib/phpseclib/BACKERS.md
new file mode 100644
index 00000000..f942f48f
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/BACKERS.md
@@ -0,0 +1,14 @@
+# Backers
+
+phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you.
+
+## Backers
+
+- Allan Simon
+- [ChargeOver](https://chargeover.com/)
+- Raghu Veer Dendukuri
+- Zane Hooper
+- [Setasign](https://www.setasign.com/)
+- [Charles Severance](https://github.com/csev)
+- [Rachel Fish](https://github.com/itsrachelfish)
+- Tharyrok
\ No newline at end of file
diff --git a/msd/vendor/phpseclib/phpseclib/LICENSE b/msd/vendor/phpseclib/phpseclib/LICENSE
new file mode 100644
index 00000000..e7214ebb
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2011-2019 TerraFrost and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/msd/vendor/phpseclib/phpseclib/README.md b/msd/vendor/phpseclib/phpseclib/README.md
new file mode 100644
index 00000000..9be5517e
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/README.md
@@ -0,0 +1,101 @@
+# phpseclib - PHP Secure Communications Library
+
+[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.com/github/phpseclib/phpseclib)
+
+## Supporting phpseclib
+
+- [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib)
+- [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487)
+- [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme)
+
+## Introduction
+
+MIT-licensed pure-PHP implementations of the following:
+
+SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305
+
+* [Browse Git](https://github.com/phpseclib/phpseclib)
+
+## Documentation
+
+* [Documentation / Manual](https://phpseclib.com/)
+* [API Documentation](https://api.phpseclib.com/2.0/) (generated by Doctum)
+
+## Branches
+
+### master
+
+* Development Branch
+* Unstable API
+* Do not use in production
+
+### 3.0
+
+* Long term support (LTS) release
+* Major expansion of cryptographic primitives
+* Minimum PHP version: 5.6.1
+* PSR-4 autoloading with namespace rooted at `\phpseclib3`
+* Install via Composer: `composer require phpseclib/phpseclib:~3.0`
+
+### 2.0
+
+* Long term support (LTS) release
+* Modernized version of 1.0
+* Minimum PHP version: 5.3.3
+* PSR-4 autoloading with namespace rooted at `\phpseclib`
+* Install via Composer: `composer require phpseclib/phpseclib:~2.0`
+
+### 1.0
+
+* Long term support (LTS) release
+* PHP4 compatible
+* Composer compatible (PSR-0 autoloading)
+* Install using Composer: `composer require phpseclib/phpseclib:~1.0`
+* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
+* [Download 1.0.20 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.20.zip/download)
+
+## Security contact information
+
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
+
+## Support
+
+Need Support?
+
+* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib)
+* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new)
+* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use)
+
+## Special Thanks
+
+Special Thanks to our $50+ sponsors!:
+
+- Allan Simon
+- [ChargeOver](https://chargeover.com/)
+
+## Contributing
+
+1. Fork the Project
+
+2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/))
+
+3. Install Development Dependencies
+
+    ``` sh
+    composer install
+    ```
+
+4. Create a Feature Branch
+
+5. (Recommended) Run the Test Suite
+
+    ``` sh
+    vendor/bin/phpunit
+    ```
+6. (Recommended) Check whether your code conforms to our Coding Standards by running
+
+    ``` sh
+    vendor/bin/phing -f build/build.xml sniff
+    ```
+
+7. Send us a Pull Request
diff --git a/msd/vendor/phpseclib/phpseclib/appveyor.yml b/msd/vendor/phpseclib/phpseclib/appveyor.yml
new file mode 100644
index 00000000..210a9034
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/appveyor.yml
@@ -0,0 +1,27 @@
+build: false
+shallow_clone: false
+platform:
+  - x86
+  - x64
+clone_folder: C:\projects\phpseclib
+
+install:
+  - cinst -y OpenSSL.Light
+  - SET PATH=C:\Program Files\OpenSSL;%PATH%
+  - sc config wuauserv start= auto
+  - net start wuauserv
+  - cinst -y php --version 5.6.30
+  - cd c:\tools\php56
+  - copy php.ini-production php.ini
+  - echo date.timezone="UTC" >> php.ini
+  - echo extension_dir=ext >> php.ini
+  - echo extension=php_openssl.dll >> php.ini
+  - echo extension=php_gmp.dll >> php.ini
+  - cd C:\projects\phpseclib
+  - SET PATH=C:\tools\php56;%PATH%
+  - php.exe -r "readfile('http://getcomposer.org/installer');" | php.exe
+  - php.exe composer.phar install --prefer-source --no-interaction
+
+test_script:
+  - cd C:\projects\phpseclib
+  - vendor\bin\phpunit.bat tests/Windows32Test.php
\ No newline at end of file
diff --git a/msd/vendor/phpseclib/phpseclib/composer.json b/msd/vendor/phpseclib/phpseclib/composer.json
new file mode 100644
index 00000000..3fbffa67
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/composer.json
@@ -0,0 +1,76 @@
+{
+    "name": "phpseclib/phpseclib",
+    "type": "library",
+    "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+    "keywords": [
+        "security",
+        "crypto",
+        "cryptography",
+        "encryption",
+        "signature",
+        "signing",
+        "rsa",
+        "aes",
+        "blowfish",
+        "twofish",
+        "ssh",
+        "sftp",
+        "x509",
+        "x.509",
+        "asn1",
+        "asn.1",
+        "BigInteger"
+        ],
+    "homepage": "http://phpseclib.sourceforge.net",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Jim Wigginton",
+            "email": "terrafrost@php.net",
+            "role": "Lead Developer"
+        },
+        {
+            "name": "Patrick Monnerat",
+            "email": "pm@datasphere.ch",
+            "role": "Developer"
+        },
+        {
+            "name": "Andreas Fischer",
+            "email": "bantu@phpbb.com",
+            "role": "Developer"
+        },
+        {
+            "name": "Hans-Jürgen Petrich",
+            "email": "petrich@tronic-media.com",
+            "role": "Developer"
+        },
+        {
+            "name": "Graham Campbell",
+            "email": "graham@alt-three.com",
+            "role": "Developer"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.3"
+    },
+    "require-dev": {
+        "phing/phing": "~2.7",
+        "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4",
+        "squizlabs/php_codesniffer": "~2.0"
+    },
+    "suggest": {
+        "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+        "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
+        "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+        "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+        "ext-xml": "Install the XML extension to load XML formatted public keys."
+    },
+    "autoload": {
+        "files": [
+            "phpseclib/bootstrap.php"
+        ],
+        "psr-4": {
+            "phpseclib\\": "phpseclib/"
+        }
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
new file mode 100644
index 00000000..7d8cb8b0
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * Pure-PHP implementation of AES.
+ *
+ * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
+ * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
+ * to save one include_once().
+ *
+ * If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link self::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's 136-bits
+ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
+ * is called, again, at which point, it'll be recalculated.
+ *
+ * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't
+ * make a whole lot of sense.  {@link self::setBlockLength() setBlockLength()}, for instance.  Calling that function,
+ * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $aes = new \phpseclib\Crypt\AES();
+ *
+ *    $aes->setKey('abcdefghijklmnop');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $aes->decrypt($aes->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   AES
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2008 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of AES.
+ *
+ * @package AES
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class AES extends Rijndael
+{
+    /**
+     * Dummy function
+     *
+     * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything.
+     *
+     * @see \phpseclib\Crypt\Rijndael::setBlockLength()
+     * @access public
+     * @param int $length
+     */
+    function setBlockLength($length)
+    {
+        return;
+    }
+
+    /**
+     * Sets the key length
+     *
+     * Valid key lengths are 128, 192, and 256.  If the length is less than 128, it will be rounded up to
+     * 128.  If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
+     *
+     * @see \phpseclib\Crypt\Rijndael:setKeyLength()
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        switch ($length) {
+            case 160:
+                $length = 192;
+                break;
+            case 224:
+                $length = 256;
+        }
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Sets the key.
+     *
+     * Rijndael supports five different key lengths, AES only supports three.
+     *
+     * @see \phpseclib\Crypt\Rijndael:setKey()
+     * @see setKeyLength()
+     * @access public
+     * @param string $key
+     */
+    function setKey($key)
+    {
+        parent::setKey($key);
+
+        if (!$this->explicit_key_length) {
+            $length = strlen($key);
+            switch (true) {
+                case $length <= 16:
+                    $this->key_length = 16;
+                    break;
+                case $length <= 24:
+                    $this->key_length = 24;
+                    break;
+                default:
+                    $this->key_length = 32;
+            }
+            $this->_setEngine();
+        }
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
new file mode 100644
index 00000000..7bb357a7
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
@@ -0,0 +1,2907 @@
+<?php
+
+/**
+ * Base Class for all \phpseclib\Crypt\* cipher classes
+ *
+ * PHP version 5
+ *
+ * Internally for phpseclib developers:
+ *  If you plan to add a new cipher class, please note following rules:
+ *
+ *  - The new \phpseclib\Crypt\* cipher class should extend \phpseclib\Crypt\Base
+ *
+ *  - Following methods are then required to be overridden/overloaded:
+ *
+ *    - _encryptBlock()
+ *
+ *    - _decryptBlock()
+ *
+ *    - _setupKey()
+ *
+ *  - All other methods are optional to be overridden/overloaded
+ *
+ *  - Look at the source code of the current ciphers how they extend \phpseclib\Crypt\Base
+ *    and take one of them as a start up for the new cipher class.
+ *
+ *  - Please read all the other comments/notes/hints here also for each class var/method
+ *
+ * @category  Crypt
+ * @package   Base
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @author    Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Base Class for all \phpseclib\Crypt\* cipher classes
+ *
+ * @package Base
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
+ */
+abstract class Base
+{
+    /**#@+
+     * @access public
+     * @see \phpseclib\Crypt\Base::encrypt()
+     * @see \phpseclib\Crypt\Base::decrypt()
+     */
+    /**
+     * Encrypt / decrypt using the Counter mode.
+     *
+     * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
+     *
+     * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
+     */
+    const MODE_CTR = -1;
+    /**
+     * Encrypt / decrypt using the Electronic Code Book mode.
+     *
+     * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
+     */
+    const MODE_ECB = 1;
+    /**
+     * Encrypt / decrypt using the Code Book Chaining mode.
+     *
+     * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
+     */
+    const MODE_CBC = 2;
+    /**
+     * Encrypt / decrypt using the Cipher Feedback mode.
+     *
+     * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
+     */
+    const MODE_CFB = 3;
+    /**
+     * Encrypt / decrypt using the Cipher Feedback mode (8bit)
+     */
+    const MODE_CFB8 = 6;
+    /**
+     * Encrypt / decrypt using the Output Feedback mode (8bit)
+     */
+    const MODE_OFB8 = 7;
+    /**
+     * Encrypt / decrypt using the Output Feedback mode.
+     *
+     * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
+     */
+    const MODE_OFB = 4;
+    /**
+     * Encrypt / decrypt using streaming mode.
+     */
+    const MODE_STREAM = 5;
+    /**#@-*/
+
+    /**
+     * Whirlpool available flag
+     *
+     * @see \phpseclib\Crypt\Base::_hashInlineCryptFunction()
+     * @var bool
+     * @access private
+     */
+    static $WHIRLPOOL_AVAILABLE;
+
+    /**#@+
+     * @access private
+     * @see \phpseclib\Crypt\Base::__construct()
+     */
+    /**
+     * Base value for the internal implementation $engine switch
+     */
+    const ENGINE_INTERNAL = 1;
+    /**
+     * Base value for the mcrypt implementation $engine switch
+     */
+    const ENGINE_MCRYPT = 2;
+    /**
+     * Base value for the mcrypt implementation $engine switch
+     */
+    const ENGINE_OPENSSL = 3;
+    /**#@-*/
+
+    /**
+     * The Encryption Mode
+     *
+     * @see self::__construct()
+     * @var int
+     * @access private
+     */
+    var $mode;
+
+    /**
+     * The Block Length of the block cipher
+     *
+     * @var int
+     * @access private
+     */
+    var $block_size = 16;
+
+    /**
+     * The Key
+     *
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+    /**
+     * The Initialization Vector
+     *
+     * @see self::setIV()
+     * @var string
+     * @access private
+     */
+    var $iv = '';
+
+    /**
+     * A "sliding" Initialization Vector
+     *
+     * @see self::enableContinuousBuffer()
+     * @see self::_clearBuffers()
+     * @var string
+     * @access private
+     */
+    var $encryptIV;
+
+    /**
+     * A "sliding" Initialization Vector
+     *
+     * @see self::enableContinuousBuffer()
+     * @see self::_clearBuffers()
+     * @var string
+     * @access private
+     */
+    var $decryptIV;
+
+    /**
+     * Continuous Buffer status
+     *
+     * @see self::enableContinuousBuffer()
+     * @var bool
+     * @access private
+     */
+    var $continuousBuffer = false;
+
+    /**
+     * Encryption buffer for CTR, OFB and CFB modes
+     *
+     * @see self::encrypt()
+     * @see self::_clearBuffers()
+     * @var array
+     * @access private
+     */
+    var $enbuffer;
+
+    /**
+     * Decryption buffer for CTR, OFB and CFB modes
+     *
+     * @see self::decrypt()
+     * @see self::_clearBuffers()
+     * @var array
+     * @access private
+     */
+    var $debuffer;
+
+    /**
+     * mcrypt resource for encryption
+     *
+     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
+     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
+     *
+     * @see self::encrypt()
+     * @var resource
+     * @access private
+     */
+    var $enmcrypt;
+
+    /**
+     * mcrypt resource for decryption
+     *
+     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
+     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
+     *
+     * @see self::decrypt()
+     * @var resource
+     * @access private
+     */
+    var $demcrypt;
+
+    /**
+     * Does the enmcrypt resource need to be (re)initialized?
+     *
+     * @see \phpseclib\Crypt\Twofish::setKey()
+     * @see \phpseclib\Crypt\Twofish::setIV()
+     * @var bool
+     * @access private
+     */
+    var $enchanged = true;
+
+    /**
+     * Does the demcrypt resource need to be (re)initialized?
+     *
+     * @see \phpseclib\Crypt\Twofish::setKey()
+     * @see \phpseclib\Crypt\Twofish::setIV()
+     * @var bool
+     * @access private
+     */
+    var $dechanged = true;
+
+    /**
+     * mcrypt resource for CFB mode
+     *
+     * mcrypt's CFB mode, in (and only in) buffered context,
+     * is broken, so phpseclib implements the CFB mode by it self,
+     * even when the mcrypt php extension is available.
+     *
+     * In order to do the CFB-mode work (fast) phpseclib
+     * use a separate ECB-mode mcrypt resource.
+     *
+     * @link http://phpseclib.sourceforge.net/cfb-demo.phps
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @see self::_setupMcrypt()
+     * @var resource
+     * @access private
+     */
+    var $ecb;
+
+    /**
+     * Optimizing value while CFB-encrypting
+     *
+     * Only relevant if $continuousBuffer enabled
+     * and $engine == self::ENGINE_MCRYPT
+     *
+     * It's faster to re-init $enmcrypt if
+     * $buffer bytes > $cfb_init_len than
+     * using the $ecb resource furthermore.
+     *
+     * This value depends of the chosen cipher
+     * and the time it would be needed for it's
+     * initialization [by mcrypt_generic_init()]
+     * which, typically, depends on the complexity
+     * on its internaly Key-expanding algorithm.
+     *
+     * @see self::encrypt()
+     * @var int
+     * @access private
+     */
+    var $cfb_init_len = 600;
+
+    /**
+     * Does internal cipher state need to be (re)initialized?
+     *
+     * @see self::setKey()
+     * @see self::setIV()
+     * @see self::disableContinuousBuffer()
+     * @var bool
+     * @access private
+     */
+    var $changed = true;
+
+    /**
+     * Padding status
+     *
+     * @see self::enablePadding()
+     * @var bool
+     * @access private
+     */
+    var $padding = true;
+
+    /**
+     * Is the mode one that is paddable?
+     *
+     * @see self::__construct()
+     * @var bool
+     * @access private
+     */
+    var $paddable = false;
+
+    /**
+     * Holds which crypt engine internaly should be use,
+     * which will be determined automatically on __construct()
+     *
+     * Currently available $engines are:
+     * - self::ENGINE_OPENSSL  (very fast, php-extension: openssl, extension_loaded('openssl') required)
+     * - self::ENGINE_MCRYPT   (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
+     * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required)
+     *
+     * @see self::_setEngine()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @var int
+     * @access private
+     */
+    var $engine;
+
+    /**
+     * Holds the preferred crypt engine
+     *
+     * @see self::_setEngine()
+     * @see self::setPreferredEngine()
+     * @var int
+     * @access private
+     */
+    var $preferredEngine;
+
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * Only used if $engine == self::ENGINE_MCRYPT
+     *
+     * @link http://www.php.net/mcrypt_module_open
+     * @link http://www.php.net/mcrypt_list_algorithms
+     * @see self::_setupMcrypt()
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt;
+
+    /**
+     * The openssl specific name of the cipher
+     *
+     * Only used if $engine == self::ENGINE_OPENSSL
+     *
+     * @link http://www.php.net/openssl-get-cipher-methods
+     * @var string
+     * @access private
+     */
+    var $cipher_name_openssl;
+
+    /**
+     * The openssl specific name of the cipher in ECB mode
+     *
+     * If OpenSSL does not support the mode we're trying to use (CTR)
+     * it can still be emulated with ECB mode.
+     *
+     * @link http://www.php.net/openssl-get-cipher-methods
+     * @var string
+     * @access private
+     */
+    var $cipher_name_openssl_ecb;
+
+    /**
+     * The default salt used by setPassword()
+     *
+     * @see self::setPassword()
+     * @var string
+     * @access private
+     */
+    var $password_default_salt = 'phpseclib/salt';
+
+    /**
+     * The name of the performance-optimized callback function
+     *
+     * Used by encrypt() / decrypt()
+     * only if $engine == self::ENGINE_INTERNAL
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @see self::_setupInlineCrypt()
+     * @see self::$use_inline_crypt
+     * @var Callback
+     * @access private
+     */
+    var $inline_crypt;
+
+    /**
+     * Holds whether performance-optimized $inline_crypt() can/should be used.
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @see self::inline_crypt
+     * @var mixed
+     * @access private
+     */
+    var $use_inline_crypt = true;
+
+    /**
+     * If OpenSSL can be used in ECB but not in CTR we can emulate CTR
+     *
+     * @see self::_openssl_ctr_process()
+     * @var bool
+     * @access private
+     */
+    var $openssl_emulate_ctr = false;
+
+    /**
+     * Determines what options are passed to openssl_encrypt/decrypt
+     *
+     * @see self::isValidEngine()
+     * @var mixed
+     * @access private
+     */
+    var $openssl_options;
+
+    /**
+     * Has the key length explicitly been set or should it be derived from the key, itself?
+     *
+     * @see self::setKeyLength()
+     * @var bool
+     * @access private
+     */
+    var $explicit_key_length = false;
+
+    /**
+     * Don't truncate / null pad key
+     *
+     * @see self::_clearBuffers()
+     * @var bool
+     * @access private
+     */
+    var $skip_key_adjustment = false;
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.
+     *
+     * $mode could be:
+     *
+     * - self::MODE_ECB
+     *
+     * - self::MODE_CBC
+     *
+     * - self::MODE_CTR
+     *
+     * - self::MODE_CFB
+     *
+     * - self::MODE_OFB
+     *
+     * If not explicitly set, self::MODE_CBC will be used.
+     *
+     * @param int $mode
+     * @access public
+     */
+    function __construct($mode = self::MODE_CBC)
+    {
+        // $mode dependent settings
+        switch ($mode) {
+            case self::MODE_ECB:
+                $this->paddable = true;
+                $this->mode = self::MODE_ECB;
+                break;
+            case self::MODE_CTR:
+            case self::MODE_CFB:
+            case self::MODE_CFB8:
+            case self::MODE_OFB8:
+            case self::MODE_OFB:
+            case self::MODE_STREAM:
+                $this->mode = $mode;
+                break;
+            case self::MODE_CBC:
+            default:
+                $this->paddable = true;
+                $this->mode = self::MODE_CBC;
+        }
+
+        $this->_setEngine();
+
+        // Determining whether inline crypting can be used by the cipher
+        if ($this->use_inline_crypt !== false) {
+            $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
+        }
+
+        if (!defined('PHP_INT_SIZE')) {
+            define('PHP_INT_SIZE', 4);
+        }
+
+        if (!defined('CRYPT_BASE_USE_REG_INTVAL')) {
+            switch (true) {
+                // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
+                case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
+                case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
+                case PHP_INT_SIZE == 8:
+                    define('CRYPT_BASE_USE_REG_INTVAL', true);
+                    break;
+                case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM':
+                    switch (true) {
+                        /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors:
+
+                           https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd
+
+                           altho the changelogs make no mention of it, this bug was fixed with this commit:
+
+                           https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8
+
+                           affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */
+                        case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123:
+                        case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211:
+                            define('CRYPT_BASE_USE_REG_INTVAL', false);
+                            break;
+                        default:
+                            define('CRYPT_BASE_USE_REG_INTVAL', true);
+                    }
+            }
+        }
+    }
+
+    /**
+     * Sets the initialization vector. (optional)
+     *
+     * SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used.  If not explicitly set, it'll be assumed
+     * to be all zero's.
+     *
+     * @access public
+     * @param string $iv
+     * @internal Can be overwritten by a sub class, but does not have to be
+     */
+    function setIV($iv)
+    {
+        if ($this->mode == self::MODE_ECB) {
+            return;
+        }
+
+        $this->iv = $iv;
+        $this->changed = true;
+    }
+
+    /**
+     * Sets the key length.
+     *
+     * Keys with explicitly set lengths need to be treated accordingly
+     *
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        $this->explicit_key_length = true;
+        $this->changed = true;
+        $this->_setEngine();
+    }
+
+    /**
+     * Returns the current key length in bits
+     *
+     * @access public
+     * @return int
+     */
+    function getKeyLength()
+    {
+        return $this->key_length << 3;
+    }
+
+    /**
+     * Returns the current block length in bits
+     *
+     * @access public
+     * @return int
+     */
+    function getBlockLength()
+    {
+        return $this->block_size << 3;
+    }
+
+    /**
+     * Sets the key.
+     *
+     * The min/max length(s) of the key depends on the cipher which is used.
+     * If the key not fits the length(s) of the cipher it will paded with null bytes
+     * up to the closest valid key length.  If the key is more than max length,
+     * we trim the excess bits.
+     *
+     * If the key is not explicitly set, it'll be assumed to be all null bytes.
+     *
+     * @access public
+     * @param string $key
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function setKey($key)
+    {
+        if (!$this->explicit_key_length) {
+            $this->setKeyLength(strlen($key) << 3);
+            $this->explicit_key_length = false;
+        }
+
+        $this->key = $key;
+        $this->changed = true;
+        $this->_setEngine();
+    }
+
+    /**
+     * Sets the password.
+     *
+     * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
+     *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
+     *         $hash, $salt, $count, $dkLen
+     *
+     *         Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
+     *     {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}:
+     *         $salt, $rounds, $keylen
+     *
+     *         This is a modified version of bcrypt used by OpenSSH.
+     *
+     * @see Crypt/Hash.php
+     * @param string $password
+     * @param string $method
+     * @return bool
+     * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function setPassword($password, $method = 'pbkdf2')
+    {
+        $key = '';
+
+        switch ($method) {
+            case 'bcrypt':
+                $func_args = func_get_args();
+
+                if (!isset($func_args[2])) {
+                    return false;
+                }
+
+                $salt = $func_args[2];
+
+                $rounds = isset($func_args[3]) ? $func_args[3] : 16;
+                $keylen = isset($func_args[4]) ? $func_args[4] : $this->key_length;
+
+                $bf = new Blowfish();
+                $key = $bf->bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds);
+                if (!$key) {
+                    return false;
+                }
+
+                $this->setKey(substr($key, 0, $keylen));
+                $this->setIV(substr($key, $keylen));
+
+                return true;
+            default: // 'pbkdf2' or 'pbkdf1'
+                $func_args = func_get_args();
+
+                // Hash function
+                $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
+
+                // WPA and WPA2 use the SSID as the salt
+                $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
+
+                // RFC2898#section-4.2 uses 1,000 iterations by default
+                // WPA and WPA2 use 4,096.
+                $count = isset($func_args[4]) ? $func_args[4] : 1000;
+
+                // Keylength
+                if (isset($func_args[5])) {
+                    $dkLen = $func_args[5];
+                } else {
+                    $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
+                }
+
+                switch (true) {
+                    case $method == 'pbkdf1':
+                        $hashObj = new Hash();
+                        $hashObj->setHash($hash);
+                        if ($dkLen > $hashObj->getLength()) {
+                            user_error('Derived key too long');
+                            return false;
+                        }
+                        $t = $password . $salt;
+                        for ($i = 0; $i < $count; ++$i) {
+                            $t = $hashObj->hash($t);
+                        }
+                        $key = substr($t, 0, $dkLen);
+
+                        $this->setKey(substr($key, 0, $dkLen >> 1));
+                        $this->setIV(substr($key, $dkLen >> 1));
+
+                        return true;
+                    // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
+                    case !function_exists('hash_pbkdf2'):
+                    case !function_exists('hash_algos'):
+                    case !in_array($hash, hash_algos()):
+                        $i = 1;
+                        $hmac = new Hash();
+                        $hmac->setHash($hash);
+                        $hmac->setKey($password);
+                        while (strlen($key) < $dkLen) {
+                            $f = $u = $hmac->hash($salt . pack('N', $i++));
+                            for ($j = 2; $j <= $count; ++$j) {
+                                $u = $hmac->hash($u);
+                                $f^= $u;
+                            }
+                            $key.= $f;
+                        }
+                        $key = substr($key, 0, $dkLen);
+                        break;
+                    default:
+                        $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
+                }
+        }
+
+        $this->setKey($key);
+
+        return true;
+    }
+
+    /**
+     * Encrypts a message.
+     *
+     * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher
+     * implementations may or may not pad in the same manner.  Other common approaches to padding and the reasons why it's
+     * necessary are discussed in the following
+     * URL:
+     *
+     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
+     *
+     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.
+     * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
+     * length.
+     *
+     * @see self::decrypt()
+     * @access public
+     * @param string $plaintext
+     * @return string $ciphertext
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function encrypt($plaintext)
+    {
+        if ($this->paddable) {
+            $plaintext = $this->_pad($plaintext);
+        }
+
+        if ($this->engine === self::ENGINE_OPENSSL) {
+            if ($this->changed) {
+                $this->_clearBuffers();
+                $this->changed = false;
+            }
+            switch ($this->mode) {
+                case self::MODE_STREAM:
+                    return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                case self::MODE_ECB:
+                    $result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                    return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
+                case self::MODE_CBC:
+                    $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
+                    if (!defined('OPENSSL_RAW_DATA')) {
+                        $result = substr($result, 0, -$this->block_size);
+                    }
+                    if ($this->continuousBuffer) {
+                        $this->encryptIV = substr($result, -$this->block_size);
+                    }
+                    return $result;
+                case self::MODE_CTR:
+                    return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer);
+                case self::MODE_CFB:
+                    // cfb loosely routines inspired by openssl's:
+                    // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+                    $ciphertext = '';
+                    if ($this->continuousBuffer) {
+                        $iv = &$this->encryptIV;
+                        $pos = &$this->enbuffer['pos'];
+                    } else {
+                        $iv = $this->encryptIV;
+                        $pos = 0;
+                    }
+                    $len = strlen($plaintext);
+                    $i = 0;
+                    if ($pos) {
+                        $orig_pos = $pos;
+                        $max = $this->block_size - $pos;
+                        if ($len >= $max) {
+                            $i = $max;
+                            $len-= $max;
+                            $pos = 0;
+                        } else {
+                            $i = $len;
+                            $pos+= $len;
+                            $len = 0;
+                        }
+                        // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+                        $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+                        $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+                        $plaintext = substr($plaintext, $i);
+                    }
+
+                    $overflow = $len % $this->block_size;
+
+                    if ($overflow) {
+                        $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $iv = $this->_string_pop($ciphertext, $this->block_size);
+
+                        $size = $len - $overflow;
+                        $block = $iv ^ substr($plaintext, -$overflow);
+                        $iv = substr_replace($iv, $block, 0, $overflow);
+                        $ciphertext.= $block;
+                        $pos = $overflow;
+                    } elseif ($len) {
+                        $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $iv = substr($ciphertext, -$this->block_size);
+                    }
+
+                    return $ciphertext;
+                case self::MODE_CFB8:
+                    $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
+                    if ($this->continuousBuffer) {
+                        if (($len = strlen($ciphertext)) >= $this->block_size) {
+                            $this->encryptIV = substr($ciphertext, -$this->block_size);
+                        } else {
+                            $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
+                        }
+                    }
+                    return $ciphertext;
+                case self::MODE_OFB8:
+                    // OpenSSL has built in support for cfb8 but not ofb8
+                    $ciphertext = '';
+                    $len = strlen($plaintext);
+                    $iv = $this->encryptIV;
+
+                    for ($i = 0; $i < $len; ++$i) {
+                        $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV);
+                        $ciphertext.= $plaintext[$i] ^ $xor;
+                        $iv = substr($iv, 1) . $xor[0];
+                    }
+
+                    if ($this->continuousBuffer) {
+                        $this->encryptIV = $iv;
+                    }
+                    break;
+                case self::MODE_OFB:
+                    return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
+            }
+        }
+
+        if ($this->engine === self::ENGINE_MCRYPT) {
+            set_error_handler(array($this, 'do_nothing'));
+
+            if ($this->changed) {
+                $this->_setupMcrypt();
+                $this->changed = false;
+            }
+            if ($this->enchanged) {
+                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+                $this->enchanged = false;
+            }
+
+            // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
+            // using mcrypt's default handing of CFB the above would output two different things.  using phpseclib's
+            // rewritten CFB implementation the above outputs the same thing twice.
+            if ($this->mode == self::MODE_CFB && $this->continuousBuffer) {
+                $block_size = $this->block_size;
+                $iv = &$this->encryptIV;
+                $pos = &$this->enbuffer['pos'];
+                $len = strlen($plaintext);
+                $ciphertext = '';
+                $i = 0;
+                if ($pos) {
+                    $orig_pos = $pos;
+                    $max = $block_size - $pos;
+                    if ($len >= $max) {
+                        $i = $max;
+                        $len-= $max;
+                        $pos = 0;
+                    } else {
+                        $i = $len;
+                        $pos+= $len;
+                        $len = 0;
+                    }
+                    $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+                    $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+                    $this->enbuffer['enmcrypt_init'] = true;
+                }
+                if ($len >= $block_size) {
+                    if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
+                        if ($this->enbuffer['enmcrypt_init'] === true) {
+                            mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
+                            $this->enbuffer['enmcrypt_init'] = false;
+                        }
+                        $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
+                        $iv = substr($ciphertext, -$block_size);
+                        $len%= $block_size;
+                    } else {
+                        while ($len >= $block_size) {
+                            $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
+                            $ciphertext.= $iv;
+                            $len-= $block_size;
+                            $i+= $block_size;
+                        }
+                    }
+                }
+
+                if ($len) {
+                    $iv = mcrypt_generic($this->ecb, $iv);
+                    $block = $iv ^ substr($plaintext, -$len);
+                    $iv = substr_replace($iv, $block, 0, $len);
+                    $ciphertext.= $block;
+                    $pos = $len;
+                }
+
+                restore_error_handler();
+
+                return $ciphertext;
+            }
+
+            $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
+
+            if (!$this->continuousBuffer) {
+                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+            }
+
+            restore_error_handler();
+
+            return $ciphertext;
+        }
+
+        if ($this->changed) {
+            $this->_setup();
+            $this->changed = false;
+        }
+        if ($this->use_inline_crypt) {
+            $inline = $this->inline_crypt;
+            return $inline('encrypt', $this, $plaintext);
+        }
+
+        $buffer = &$this->enbuffer;
+        $block_size = $this->block_size;
+        $ciphertext = '';
+        switch ($this->mode) {
+            case self::MODE_ECB:
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
+                }
+                break;
+            case self::MODE_CBC:
+                $xor = $this->encryptIV;
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    $block = $this->_encryptBlock($block ^ $xor);
+                    $xor = $block;
+                    $ciphertext.= $block;
+                }
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $xor;
+                }
+                break;
+            case self::MODE_CTR:
+                $xor = $this->encryptIV;
+                if (strlen($buffer['ciphertext'])) {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $block = substr($plaintext, $i, $block_size);
+                        if (strlen($block) > strlen($buffer['ciphertext'])) {
+                            $buffer['ciphertext'].= $this->_encryptBlock($xor);
+                            $this->_increment_str($xor);
+                        }
+                        $key = $this->_string_shift($buffer['ciphertext'], $block_size);
+                        $ciphertext.= $block ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $block = substr($plaintext, $i, $block_size);
+                        $key = $this->_encryptBlock($xor);
+                        $this->_increment_str($xor);
+                        $ciphertext.= $block ^ $key;
+                    }
+                }
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $xor;
+                    if ($start = strlen($plaintext) % $block_size) {
+                        $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+                    }
+                }
+                break;
+            case self::MODE_CFB:
+                // cfb loosely routines inspired by openssl's:
+                // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+                if ($this->continuousBuffer) {
+                    $iv = &$this->encryptIV;
+                    $pos = &$buffer['pos'];
+                } else {
+                    $iv = $this->encryptIV;
+                    $pos = 0;
+                }
+                $len = strlen($plaintext);
+                $i = 0;
+                if ($pos) {
+                    $orig_pos = $pos;
+                    $max = $block_size - $pos;
+                    if ($len >= $max) {
+                        $i = $max;
+                        $len-= $max;
+                        $pos = 0;
+                    } else {
+                        $i = $len;
+                        $pos+= $len;
+                        $len = 0;
+                    }
+                    // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+                    $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+                    $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+                }
+                while ($len >= $block_size) {
+                    $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
+                    $ciphertext.= $iv;
+                    $len-= $block_size;
+                    $i+= $block_size;
+                }
+                if ($len) {
+                    $iv = $this->_encryptBlock($iv);
+                    $block = $iv ^ substr($plaintext, $i);
+                    $iv = substr_replace($iv, $block, 0, $len);
+                    $ciphertext.= $block;
+                    $pos = $len;
+                }
+                break;
+            case self::MODE_CFB8:
+                // compared to regular CFB, which encrypts a block at a time,
+                // here, we're encrypting a byte at a time
+                $ciphertext = '';
+                $len = strlen($plaintext);
+                $iv = $this->encryptIV;
+
+                for ($i = 0; $i < $len; ++$i) {
+                    $ciphertext.= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv));
+                    $iv = substr($iv, 1) . $c;
+                }
+
+                if ($this->continuousBuffer) {
+                    if ($len >= $block_size) {
+                        $this->encryptIV = substr($ciphertext, -$block_size);
+                    } else {
+                        $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len);
+                    }
+                }
+                break;
+            case self::MODE_OFB8:
+                $ciphertext = '';
+                $len = strlen($plaintext);
+                $iv = $this->encryptIV;
+
+                for ($i = 0; $i < $len; ++$i) {
+                    $xor = $this->_encryptBlock($iv);
+                    $ciphertext.= $plaintext[$i] ^ $xor;
+                    $iv = substr($iv, 1) . $xor[0];
+                }
+
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $iv;
+                }
+                break;
+            case self::MODE_OFB:
+                $xor = $this->encryptIV;
+                if (strlen($buffer['xor'])) {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $block = substr($plaintext, $i, $block_size);
+                        if (strlen($block) > strlen($buffer['xor'])) {
+                            $xor = $this->_encryptBlock($xor);
+                            $buffer['xor'].= $xor;
+                        }
+                        $key = $this->_string_shift($buffer['xor'], $block_size);
+                        $ciphertext.= $block ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                        $xor = $this->_encryptBlock($xor);
+                        $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
+                    }
+                    $key = $xor;
+                }
+                if ($this->continuousBuffer) {
+                    $this->encryptIV = $xor;
+                    if ($start = strlen($plaintext) % $block_size) {
+                        $buffer['xor'] = substr($key, $start) . $buffer['xor'];
+                    }
+                }
+                break;
+            case self::MODE_STREAM:
+                $ciphertext = $this->_encryptBlock($plaintext);
+                break;
+        }
+
+        return $ciphertext;
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
+     * it is.
+     *
+     * @see self::encrypt()
+     * @access public
+     * @param string $ciphertext
+     * @return string $plaintext
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function decrypt($ciphertext)
+    {
+        if ($this->paddable) {
+            // we pad with chr(0) since that's what mcrypt_generic does.  to quote from {@link http://www.php.net/function.mcrypt-generic}:
+            // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
+            $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
+        }
+
+        if ($this->engine === self::ENGINE_OPENSSL) {
+            if ($this->changed) {
+                $this->_clearBuffers();
+                $this->changed = false;
+            }
+            switch ($this->mode) {
+                case self::MODE_STREAM:
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                    break;
+                case self::MODE_ECB:
+                    if (!defined('OPENSSL_RAW_DATA')) {
+                        $ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
+                    }
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+                    break;
+                case self::MODE_CBC:
+                    if (!defined('OPENSSL_RAW_DATA')) {
+                        $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
+                        $ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
+                        $offset = 2 * $this->block_size;
+                    } else {
+                        $offset = $this->block_size;
+                    }
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
+                    if ($this->continuousBuffer) {
+                        $this->decryptIV = substr($ciphertext, -$offset, $this->block_size);
+                    }
+                    break;
+                case self::MODE_CTR:
+                    $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer);
+                    break;
+                case self::MODE_CFB:
+                    // cfb loosely routines inspired by openssl's:
+                    // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+                    $plaintext = '';
+                    if ($this->continuousBuffer) {
+                        $iv = &$this->decryptIV;
+                        $pos = &$this->debuffer['pos'];
+                    } else {
+                        $iv = $this->decryptIV;
+                        $pos = 0;
+                    }
+                    $len = strlen($ciphertext);
+                    $i = 0;
+                    if ($pos) {
+                        $orig_pos = $pos;
+                        $max = $this->block_size - $pos;
+                        if ($len >= $max) {
+                            $i = $max;
+                            $len-= $max;
+                            $pos = 0;
+                        } else {
+                            $i = $len;
+                            $pos+= $len;
+                            $len = 0;
+                        }
+                        // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize
+                        $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+                        $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+                        $ciphertext = substr($ciphertext, $i);
+                    }
+                    $overflow = $len % $this->block_size;
+                    if ($overflow) {
+                        $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        if ($len - $overflow) {
+                            $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow);
+                        }
+                        $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $plaintext.= $iv ^ substr($ciphertext, -$overflow);
+                        $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
+                        $pos = $overflow;
+                    } elseif ($len) {
+                        $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+                        $iv = substr($ciphertext, -$this->block_size);
+                    }
+                    break;
+                case self::MODE_CFB8:
+                    $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
+                    if ($this->continuousBuffer) {
+                        if (($len = strlen($ciphertext)) >= $this->block_size) {
+                            $this->decryptIV = substr($ciphertext, -$this->block_size);
+                        } else {
+                            $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
+                        }
+                    }
+                    break;
+                case self::MODE_OFB8:
+                    $plaintext = '';
+                    $len = strlen($ciphertext);
+                    $iv = $this->decryptIV;
+
+                    for ($i = 0; $i < $len; ++$i) {
+                        $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV);
+                        $plaintext.= $ciphertext[$i] ^ $xor;
+                        $iv = substr($iv, 1) . $xor[0];
+                    }
+
+                    if ($this->continuousBuffer) {
+                        $this->decryptIV = $iv;
+                    }
+                    break;
+                case self::MODE_OFB:
+                    $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
+            }
+
+            return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+        }
+
+        if ($this->engine === self::ENGINE_MCRYPT) {
+            set_error_handler(array($this, 'do_nothing'));
+            $block_size = $this->block_size;
+            if ($this->changed) {
+                $this->_setupMcrypt();
+                $this->changed = false;
+            }
+            if ($this->dechanged) {
+                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+                $this->dechanged = false;
+            }
+
+            if ($this->mode == self::MODE_CFB && $this->continuousBuffer) {
+                $iv = &$this->decryptIV;
+                $pos = &$this->debuffer['pos'];
+                $len = strlen($ciphertext);
+                $plaintext = '';
+                $i = 0;
+                if ($pos) {
+                    $orig_pos = $pos;
+                    $max = $block_size - $pos;
+                    if ($len >= $max) {
+                        $i = $max;
+                        $len-= $max;
+                        $pos = 0;
+                    } else {
+                        $i = $len;
+                        $pos+= $len;
+                        $len = 0;
+                    }
+                    // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+                    $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+                    $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+                }
+                if ($len >= $block_size) {
+                    $cb = substr($ciphertext, $i, $len - $len % $block_size);
+                    $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
+                    $iv = substr($cb, -$block_size);
+                    $len%= $block_size;
+                }
+                if ($len) {
+                    $iv = mcrypt_generic($this->ecb, $iv);
+                    $plaintext.= $iv ^ substr($ciphertext, -$len);
+                    $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
+                    $pos = $len;
+                }
+
+                restore_error_handler();
+
+                return $plaintext;
+            }
+
+            $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
+
+            if (!$this->continuousBuffer) {
+                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+            }
+
+            restore_error_handler();
+
+            return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+        }
+
+        if ($this->changed) {
+            $this->_setup();
+            $this->changed = false;
+        }
+        if ($this->use_inline_crypt) {
+            $inline = $this->inline_crypt;
+            return $inline('decrypt', $this, $ciphertext);
+        }
+
+        $block_size = $this->block_size;
+
+        $buffer = &$this->debuffer;
+        $plaintext = '';
+        switch ($this->mode) {
+            case self::MODE_ECB:
+                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                    $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
+                }
+                break;
+            case self::MODE_CBC:
+                $xor = $this->decryptIV;
+                for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                    $block = substr($ciphertext, $i, $block_size);
+                    $plaintext.= $this->_decryptBlock($block) ^ $xor;
+                    $xor = $block;
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $xor;
+                }
+                break;
+            case self::MODE_CTR:
+                $xor = $this->decryptIV;
+                if (strlen($buffer['ciphertext'])) {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $block = substr($ciphertext, $i, $block_size);
+                        if (strlen($block) > strlen($buffer['ciphertext'])) {
+                            $buffer['ciphertext'].= $this->_encryptBlock($xor);
+                            $this->_increment_str($xor);
+                        }
+                        $key = $this->_string_shift($buffer['ciphertext'], $block_size);
+                        $plaintext.= $block ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $block = substr($ciphertext, $i, $block_size);
+                        $key = $this->_encryptBlock($xor);
+                        $this->_increment_str($xor);
+                        $plaintext.= $block ^ $key;
+                    }
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $xor;
+                    if ($start = strlen($ciphertext) % $block_size) {
+                        $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+                    }
+                }
+                break;
+            case self::MODE_CFB:
+                if ($this->continuousBuffer) {
+                    $iv = &$this->decryptIV;
+                    $pos = &$buffer['pos'];
+                } else {
+                    $iv = $this->decryptIV;
+                    $pos = 0;
+                }
+                $len = strlen($ciphertext);
+                $i = 0;
+                if ($pos) {
+                    $orig_pos = $pos;
+                    $max = $block_size - $pos;
+                    if ($len >= $max) {
+                        $i = $max;
+                        $len-= $max;
+                        $pos = 0;
+                    } else {
+                        $i = $len;
+                        $pos+= $len;
+                        $len = 0;
+                    }
+                    // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+                    $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+                    $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+                }
+                while ($len >= $block_size) {
+                    $iv = $this->_encryptBlock($iv);
+                    $cb = substr($ciphertext, $i, $block_size);
+                    $plaintext.= $iv ^ $cb;
+                    $iv = $cb;
+                    $len-= $block_size;
+                    $i+= $block_size;
+                }
+                if ($len) {
+                    $iv = $this->_encryptBlock($iv);
+                    $plaintext.= $iv ^ substr($ciphertext, $i);
+                    $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
+                    $pos = $len;
+                }
+                break;
+            case self::MODE_CFB8:
+                $plaintext = '';
+                $len = strlen($ciphertext);
+                $iv = $this->decryptIV;
+
+                for ($i = 0; $i < $len; ++$i) {
+                    $plaintext.= $ciphertext[$i] ^ $this->_encryptBlock($iv);
+                    $iv = substr($iv, 1) . $ciphertext[$i];
+                }
+
+                if ($this->continuousBuffer) {
+                    if ($len >= $block_size) {
+                        $this->decryptIV = substr($ciphertext, -$block_size);
+                    } else {
+                        $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len);
+                    }
+                }
+                break;
+            case self::MODE_OFB8:
+                $plaintext = '';
+                $len = strlen($ciphertext);
+                $iv = $this->decryptIV;
+
+                for ($i = 0; $i < $len; ++$i) {
+                    $xor = $this->_encryptBlock($iv);
+                    $plaintext.= $ciphertext[$i] ^ $xor;
+                    $iv = substr($iv, 1) . $xor[0];
+                }
+
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $iv;
+                }
+                break;
+            case self::MODE_OFB:
+                $xor = $this->decryptIV;
+                if (strlen($buffer['xor'])) {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $block = substr($ciphertext, $i, $block_size);
+                        if (strlen($block) > strlen($buffer['xor'])) {
+                            $xor = $this->_encryptBlock($xor);
+                            $buffer['xor'].= $xor;
+                        }
+                        $key = $this->_string_shift($buffer['xor'], $block_size);
+                        $plaintext.= $block ^ $key;
+                    }
+                } else {
+                    for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+                        $xor = $this->_encryptBlock($xor);
+                        $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
+                    }
+                    $key = $xor;
+                }
+                if ($this->continuousBuffer) {
+                    $this->decryptIV = $xor;
+                    if ($start = strlen($ciphertext) % $block_size) {
+                        $buffer['xor'] = substr($key, $start) . $buffer['xor'];
+                    }
+                }
+                break;
+            case self::MODE_STREAM:
+                $plaintext = $this->_decryptBlock($ciphertext);
+                break;
+        }
+        return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+    }
+
+    /**
+     * OpenSSL CTR Processor
+     *
+     * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
+     * for CTR is the same for both encrypting and decrypting this function is re-used by both Base::encrypt()
+     * and Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this
+     * function will emulate CTR with ECB when necessary.
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @param string $plaintext
+     * @param string $encryptIV
+     * @param array $buffer
+     * @return string
+     * @access private
+     */
+    function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer)
+    {
+        $ciphertext = '';
+
+        $block_size = $this->block_size;
+        $key = $this->key;
+
+        if ($this->openssl_emulate_ctr) {
+            $xor = $encryptIV;
+            if (strlen($buffer['ciphertext'])) {
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    if (strlen($block) > strlen($buffer['ciphertext'])) {
+                        $result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+                        $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
+                        $buffer['ciphertext'].= $result;
+                    }
+                    $this->_increment_str($xor);
+                    $otp = $this->_string_shift($buffer['ciphertext'], $block_size);
+                    $ciphertext.= $block ^ $otp;
+                }
+            } else {
+                for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+                    $block = substr($plaintext, $i, $block_size);
+                    $otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+                    $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
+                    $this->_increment_str($xor);
+                    $ciphertext.= $block ^ $otp;
+                }
+            }
+            if ($this->continuousBuffer) {
+                $encryptIV = $xor;
+                if ($start = strlen($plaintext) % $block_size) {
+                    $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+                }
+            }
+
+            return $ciphertext;
+        }
+
+        if (strlen($buffer['ciphertext'])) {
+            $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext));
+            $plaintext = substr($plaintext, strlen($ciphertext));
+
+            if (!strlen($plaintext)) {
+                return $ciphertext;
+            }
+        }
+
+        $overflow = strlen($plaintext) % $block_size;
+        if ($overflow) {
+            $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2
+            $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+            $temp = $this->_string_pop($encrypted, $block_size);
+            $ciphertext.= $encrypted . ($plaintext2 ^ $temp);
+            if ($this->continuousBuffer) {
+                $buffer['ciphertext'] = substr($temp, $overflow);
+                $encryptIV = $temp;
+            }
+        } elseif (!strlen($buffer['ciphertext'])) {
+            $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+            $temp = $this->_string_pop($ciphertext, $block_size);
+            if ($this->continuousBuffer) {
+                $encryptIV = $temp;
+            }
+        }
+        if ($this->continuousBuffer) {
+            if (!defined('OPENSSL_RAW_DATA')) {
+                $encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+            }
+            $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+            if ($overflow) {
+                $this->_increment_str($encryptIV);
+            }
+        }
+
+        return $ciphertext;
+    }
+
+    /**
+     * OpenSSL OFB Processor
+     *
+     * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
+     * for OFB is the same for both encrypting and decrypting this function is re-used by both Base::encrypt()
+     * and Base::decrypt().
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @param string $plaintext
+     * @param string $encryptIV
+     * @param array $buffer
+     * @return string
+     * @access private
+     */
+    function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer)
+    {
+        if (strlen($buffer['xor'])) {
+            $ciphertext = $plaintext ^ $buffer['xor'];
+            $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
+            $plaintext = substr($plaintext, strlen($ciphertext));
+        } else {
+            $ciphertext = '';
+        }
+
+        $block_size = $this->block_size;
+
+        $len = strlen($plaintext);
+        $key = $this->key;
+        $overflow = $len % $block_size;
+
+        if (strlen($plaintext)) {
+            if ($overflow) {
+                $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+                $xor = $this->_string_pop($ciphertext, $block_size);
+                if ($this->continuousBuffer) {
+                    $encryptIV = $xor;
+                }
+                $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow);
+                if ($this->continuousBuffer) {
+                    $buffer['xor'] = $xor;
+                }
+            } else {
+                $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+                if ($this->continuousBuffer) {
+                    $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size);
+                }
+            }
+        }
+
+        return $ciphertext;
+    }
+
+    /**
+     * phpseclib <-> OpenSSL Mode Mapper
+     *
+     * May need to be overwritten by classes extending this one in some cases
+     *
+     * @return int
+     * @access private
+     */
+    function _openssl_translate_mode()
+    {
+        switch ($this->mode) {
+            case self::MODE_ECB:
+                return 'ecb';
+            case self::MODE_CBC:
+                return 'cbc';
+            case self::MODE_CTR:
+                return 'ctr';
+            case self::MODE_CFB:
+                return 'cfb';
+            case self::MODE_CFB8:
+                return 'cfb8';
+            case self::MODE_OFB:
+                return 'ofb';
+        }
+    }
+
+    /**
+     * Pad "packets".
+     *
+     * Block ciphers working by encrypting between their specified [$this->]block_size at a time
+     * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
+     * pad the input so that it is of the proper length.
+     *
+     * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH,
+     * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping
+     * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
+     * transmitted separately)
+     *
+     * @see self::disablePadding()
+     * @access public
+     */
+    function enablePadding()
+    {
+        $this->padding = true;
+    }
+
+    /**
+     * Do not pad packets.
+     *
+     * @see self::enablePadding()
+     * @access public
+     */
+    function disablePadding()
+    {
+        $this->padding = false;
+    }
+
+    /**
+     * Treat consecutive "packets" as if they are a continuous buffer.
+     *
+     * Say you have a 32-byte plaintext $plaintext.  Using the default behavior, the two following code snippets
+     * will yield different outputs:
+     *
+     * <code>
+     *    echo $rijndael->encrypt(substr($plaintext,  0, 16));
+     *    echo $rijndael->encrypt(substr($plaintext, 16, 16));
+     * </code>
+     * <code>
+     *    echo $rijndael->encrypt($plaintext);
+     * </code>
+     *
+     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates
+     * another, as demonstrated with the following:
+     *
+     * <code>
+     *    $rijndael->encrypt(substr($plaintext, 0, 16));
+     *    echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
+     * </code>
+     * <code>
+     *    echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
+     * </code>
+     *
+     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different
+     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /
+     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.
+     *
+     * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\*() object changes after each
+     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that
+     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),
+     * however, they are also less intuitive and more likely to cause you problems.
+     *
+     * @see self::disableContinuousBuffer()
+     * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function enableContinuousBuffer()
+    {
+        if ($this->mode == self::MODE_ECB) {
+            return;
+        }
+
+        $this->continuousBuffer = true;
+
+        $this->_setEngine();
+    }
+
+    /**
+     * Treat consecutive packets as if they are a discontinuous buffer.
+     *
+     * The default behavior.
+     *
+     * @see self::enableContinuousBuffer()
+     * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function disableContinuousBuffer()
+    {
+        if ($this->mode == self::MODE_ECB) {
+            return;
+        }
+        if (!$this->continuousBuffer) {
+            return;
+        }
+
+        $this->continuousBuffer = false;
+        $this->changed = true;
+
+        $this->_setEngine();
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * @see self::__construct()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        switch ($engine) {
+            case self::ENGINE_OPENSSL:
+                if ($this->mode == self::MODE_STREAM && $this->continuousBuffer) {
+                    return false;
+                }
+                $this->openssl_emulate_ctr = false;
+                $result = $this->cipher_name_openssl &&
+                          extension_loaded('openssl') &&
+                          // PHP 5.3.0 - 5.3.2 did not let you set IV's
+                          version_compare(PHP_VERSION, '5.3.3', '>=');
+                if (!$result) {
+                    return false;
+                }
+
+                // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer
+                // $options openssl_encrypt expected a boolean $raw_data.
+                if (!defined('OPENSSL_RAW_DATA')) {
+                    $this->openssl_options = true;
+                } else {
+                    $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
+                }
+
+                $methods = openssl_get_cipher_methods();
+                if (in_array($this->cipher_name_openssl, $methods)) {
+                    return true;
+                }
+                // not all of openssl's symmetric cipher's support ctr. for those
+                // that don't we'll emulate it
+                switch ($this->mode) {
+                    case self::MODE_CTR:
+                        if (in_array($this->cipher_name_openssl_ecb, $methods)) {
+                            $this->openssl_emulate_ctr = true;
+                            return true;
+                        }
+                }
+                return false;
+            case self::ENGINE_MCRYPT:
+                set_error_handler(array($this, 'do_nothing'));
+                $result = $this->cipher_name_mcrypt &&
+                       extension_loaded('mcrypt') &&
+                       in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms());
+                restore_error_handler();
+                return $result;
+            case self::ENGINE_INTERNAL:
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Sets the preferred crypt engine
+     *
+     * Currently, $engine could be:
+     *
+     * - \phpseclib\Crypt\Base::ENGINE_OPENSSL  [very fast]
+     *
+     * - \phpseclib\Crypt\Base::ENGINE_MCRYPT   [fast]
+     *
+     * - \phpseclib\Crypt\Base::ENGINE_INTERNAL [slow]
+     *
+     * If the preferred crypt engine is not available the fastest available one will be used
+     *
+     * @see self::__construct()
+     * @param int $engine
+     * @access public
+     */
+    function setPreferredEngine($engine)
+    {
+        switch ($engine) {
+            //case self::ENGINE_OPENSSL;
+            case self::ENGINE_MCRYPT:
+            case self::ENGINE_INTERNAL:
+                $this->preferredEngine = $engine;
+                break;
+            default:
+                $this->preferredEngine = self::ENGINE_OPENSSL;
+        }
+
+        $this->_setEngine();
+    }
+
+    /**
+     * Returns the engine currently being utilized
+     *
+     * @see self::_setEngine()
+     * @access public
+     */
+    function getEngine()
+    {
+        return $this->engine;
+    }
+
+    /**
+     * Sets the engine as appropriate
+     *
+     * @see self::__construct()
+     * @access private
+     */
+    function _setEngine()
+    {
+        $this->engine = null;
+
+        $candidateEngines = array(
+            $this->preferredEngine,
+            self::ENGINE_OPENSSL,
+            self::ENGINE_MCRYPT
+        );
+        foreach ($candidateEngines as $engine) {
+            if ($this->isValidEngine($engine)) {
+                $this->engine = $engine;
+                break;
+            }
+        }
+        if (!$this->engine) {
+            $this->engine = self::ENGINE_INTERNAL;
+        }
+
+        if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) {
+            set_error_handler(array($this, 'do_nothing'));
+            // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
+            // (re)open them with the module named in $this->cipher_name_mcrypt
+            mcrypt_module_close($this->enmcrypt);
+            mcrypt_module_close($this->demcrypt);
+            $this->enmcrypt = null;
+            $this->demcrypt = null;
+
+            if ($this->ecb) {
+                mcrypt_module_close($this->ecb);
+                $this->ecb = null;
+            }
+            restore_error_handler();
+        }
+
+        $this->changed = true;
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * Note: Must be extended by the child \phpseclib\Crypt\* class
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    abstract function _encryptBlock($in);
+
+    /**
+     * Decrypts a block
+     *
+     * Note: Must be extended by the child \phpseclib\Crypt\* class
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    abstract function _decryptBlock($in);
+
+    /**
+     * Setup the key (expansion)
+     *
+     * Only used if $engine == self::ENGINE_INTERNAL
+     *
+     * Note: Must extend by the child \phpseclib\Crypt\* class
+     *
+     * @see self::_setup()
+     * @access private
+     */
+    abstract function _setupKey();
+
+    /**
+     * Setup the self::ENGINE_INTERNAL $engine
+     *
+     * (re)init, if necessary, the internal cipher $engine and flush all $buffers
+     * Used (only) if $engine == self::ENGINE_INTERNAL
+     *
+     * _setup() will be called each time if $changed === true
+     * typically this happens when using one or more of following public methods:
+     *
+     * - setKey()
+     *
+     * - setIV()
+     *
+     * - disableContinuousBuffer()
+     *
+     * - First run of encrypt() / decrypt() with no init-settings
+     *
+     * @see self::setKey()
+     * @see self::setIV()
+     * @see self::disableContinuousBuffer()
+     * @access private
+     * @internal _setup() is always called before en/decryption.
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function _setup()
+    {
+        $this->_clearBuffers();
+        $this->_setupKey();
+
+        if ($this->use_inline_crypt) {
+            $this->_setupInlineCrypt();
+        }
+    }
+
+    /**
+     * Setup the self::ENGINE_MCRYPT $engine
+     *
+     * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
+     * Used (only) if $engine = self::ENGINE_MCRYPT
+     *
+     * _setupMcrypt() will be called each time if $changed === true
+     * typically this happens when using one or more of following public methods:
+     *
+     * - setKey()
+     *
+     * - setIV()
+     *
+     * - disableContinuousBuffer()
+     *
+     * - First run of encrypt() / decrypt()
+     *
+     * @see self::setKey()
+     * @see self::setIV()
+     * @see self::disableContinuousBuffer()
+     * @access private
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function _setupMcrypt()
+    {
+        $this->_clearBuffers();
+        $this->enchanged = $this->dechanged = true;
+
+        if (!isset($this->enmcrypt)) {
+            static $mcrypt_modes = array(
+                self::MODE_CTR    => 'ctr',
+                self::MODE_ECB    => MCRYPT_MODE_ECB,
+                self::MODE_CBC    => MCRYPT_MODE_CBC,
+                self::MODE_CFB    => 'ncfb',
+                self::MODE_CFB8   => MCRYPT_MODE_CFB,
+                self::MODE_OFB    => MCRYPT_MODE_NOFB,
+                self::MODE_OFB8   => MCRYPT_MODE_OFB,
+                self::MODE_STREAM => MCRYPT_MODE_STREAM,
+            );
+
+            $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+            $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+
+            // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
+            // to workaround mcrypt's broken ncfb implementation in buffered mode
+            // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
+            if ($this->mode == self::MODE_CFB) {
+                $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
+            }
+        } // else should mcrypt_generic_deinit be called?
+
+        if ($this->mode == self::MODE_CFB) {
+            mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
+        }
+    }
+
+    /**
+     * Pads a string
+     *
+     * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
+     * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to
+     * chr($this->block_size - (strlen($text) % $this->block_size)
+     *
+     * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
+     * and padding will, hence forth, be enabled.
+     *
+     * @see self::_unpad()
+     * @param string $text
+     * @access private
+     * @return string
+     */
+    function _pad($text)
+    {
+        $length = strlen($text);
+
+        if (!$this->padding) {
+            if ($length % $this->block_size == 0) {
+                return $text;
+            } else {
+                user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
+                $this->padding = true;
+            }
+        }
+
+        $pad = $this->block_size - ($length % $this->block_size);
+
+        return str_pad($text, $length + $pad, chr($pad));
+    }
+
+    /**
+     * Unpads a string.
+     *
+     * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
+     * and false will be returned.
+     *
+     * @see self::_pad()
+     * @param string $text
+     * @access private
+     * @return string
+     */
+    function _unpad($text)
+    {
+        if (!$this->padding) {
+            return $text;
+        }
+
+        $length = ord($text[strlen($text) - 1]);
+
+        if (!$length || $length > $this->block_size) {
+            return false;
+        }
+
+        return substr($text, 0, -$length);
+    }
+
+    /**
+     * Clears internal buffers
+     *
+     * Clearing/resetting the internal buffers is done everytime
+     * after disableContinuousBuffer() or on cipher $engine (re)init
+     * ie after setKey() or setIV()
+     *
+     * @access public
+     * @internal Could, but not must, extend by the child Crypt_* class
+     */
+    function _clearBuffers()
+    {
+        $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
+
+        // mcrypt's handling of invalid's $iv:
+        // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
+        $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
+
+        if (!$this->skip_key_adjustment) {
+            $this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");
+        }
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @access private
+     * @return string
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+
+    /**
+     * String Pop
+     *
+     * Inspired by array_pop
+     *
+     * @param string $string
+     * @param int $index
+     * @access private
+     * @return string
+     */
+    function _string_pop(&$string, $index = 1)
+    {
+        $substr = substr($string, -$index);
+        $string = substr($string, 0, -$index);
+        return $substr;
+    }
+
+    /**
+     * Increment the current string
+     *
+     * @see self::decrypt()
+     * @see self::encrypt()
+     * @param string $var
+     * @access private
+     */
+    function _increment_str(&$var)
+    {
+        if (function_exists('sodium_increment')) {
+            $var = strrev($var);
+            sodium_increment($var);
+            $var = strrev($var);
+            return;
+        }
+
+        for ($i = 4; $i <= strlen($var); $i+= 4) {
+            $temp = substr($var, -$i, 4);
+            switch ($temp) {
+                case "\xFF\xFF\xFF\xFF":
+                    $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4);
+                    break;
+                case "\x7F\xFF\xFF\xFF":
+                    $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4);
+                    return;
+                default:
+                    $temp = unpack('Nnum', $temp);
+                    $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4);
+                    return;
+            }
+        }
+
+        $remainder = strlen($var) % 4;
+
+        if ($remainder == 0) {
+            return;
+        }
+
+        $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT));
+        $temp = substr(pack('N', $temp['num'] + 1), -$remainder);
+        $var = substr_replace($var, $temp, 0, $remainder);
+    }
+
+    /**
+     * Setup the performance-optimized function for de/encrypt()
+     *
+     * Stores the created (or existing) callback function-name
+     * in $this->inline_crypt
+     *
+     * Internally for phpseclib developers:
+     *
+     *     _setupInlineCrypt() would be called only if:
+     *
+     *     - $engine == self::ENGINE_INTERNAL and
+     *
+     *     - $use_inline_crypt === true
+     *
+     *     - each time on _setup(), after(!) _setupKey()
+     *
+     *
+     *     This ensures that _setupInlineCrypt() has always a
+     *     full ready2go initializated internal cipher $engine state
+     *     where, for example, the keys allready expanded,
+     *     keys/block_size calculated and such.
+     *
+     *     It is, each time if called, the responsibility of _setupInlineCrypt():
+     *
+     *     - to set $this->inline_crypt to a valid and fully working callback function
+     *       as a (faster) replacement for encrypt() / decrypt()
+     *
+     *     - NOT to create unlimited callback functions (for memory reasons!)
+     *       no matter how often _setupInlineCrypt() would be called. At some
+     *       point of amount they must be generic re-useable.
+     *
+     *     - the code of _setupInlineCrypt() it self,
+     *       and the generated callback code,
+     *       must be, in following order:
+     *       - 100% safe
+     *       - 100% compatible to encrypt()/decrypt()
+     *       - using only php5+ features/lang-constructs/php-extensions if
+     *         compatibility (down to php4) or fallback is provided
+     *       - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-)
+     *       - >= 10% faster than encrypt()/decrypt() [which is, by the way,
+     *         the reason for the existence of _setupInlineCrypt() :-)]
+     *       - memory-nice
+     *       - short (as good as possible)
+     *
+     * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code.
+     *       - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib\Crypt\* class.
+     *       - The following variable names are reserved:
+     *         - $_*  (all variable names prefixed with an underscore)
+     *         - $self (object reference to it self. Do not use $this, but $self instead)
+     *         - $in (the content of $in has to en/decrypt by the generated code)
+     *       - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
+     *
+     *
+     * @see self::_setup()
+     * @see self::_createInlineCryptFunction()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @access private
+     * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
+     */
+    function _setupInlineCrypt()
+    {
+        // If, for any reason, an extending \phpseclib\Crypt\Base() \phpseclib\Crypt\* class
+        // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
+        // ie in the class var declaration of $use_inline_crypt in general for the \phpseclib\Crypt\* class,
+        // in the constructor at object instance-time
+        // or, if it's runtime-specific, at runtime
+
+        $this->use_inline_crypt = false;
+    }
+
+    /**
+     * Creates the performance-optimized function for en/decrypt()
+     *
+     * Internally for phpseclib developers:
+     *
+     *    _createInlineCryptFunction():
+     *
+     *    - merge the $cipher_code [setup'ed by _setupInlineCrypt()]
+     *      with the current [$this->]mode of operation code
+     *
+     *    - create the $inline function, which called by encrypt() / decrypt()
+     *      as its replacement to speed up the en/decryption operations.
+     *
+     *    - return the name of the created $inline callback function
+     *
+     *    - used to speed up en/decryption
+     *
+     *
+     *
+     *    The main reason why can speed up things [up to 50%] this way are:
+     *
+     *    - using variables more effective then regular.
+     *      (ie no use of expensive arrays but integers $k_0, $k_1 ...
+     *      or even, for example, the pure $key[] values hardcoded)
+     *
+     *    - avoiding 1000's of function calls of ie _encryptBlock()
+     *      but inlining the crypt operations.
+     *      in the mode of operation for() loop.
+     *
+     *    - full loop unroll the (sometimes key-dependent) rounds
+     *      avoiding this way ++$i counters and runtime-if's etc...
+     *
+     *    The basic code architectur of the generated $inline en/decrypt()
+     *    lambda function, in pseudo php, is:
+     *
+     *    <code>
+     *    +----------------------------------------------------------------------------------------------+
+     *    | callback $inline = create_function:                                                          |
+     *    | lambda_function_0001_crypt_ECB($action, $text)                                               |
+     *    | {                                                                                            |
+     *    |     INSERT PHP CODE OF:                                                                      |
+     *    |     $cipher_code['init_crypt'];                  // general init code.                       |
+     *    |                                                  // ie: $sbox'es declarations used for       |
+     *    |                                                  //     encrypt and decrypt'ing.             |
+     *    |                                                                                              |
+     *    |     switch ($action) {                                                                       |
+     *    |         case 'encrypt':                                                                      |
+     *    |             INSERT PHP CODE OF:                                                              |
+     *    |             $cipher_code['init_encrypt'];       // encrypt sepcific init code.               |
+     *    |                                                    ie: specified $key or $box                |
+     *    |                                                        declarations for encrypt'ing.         |
+     *    |                                                                                              |
+     *    |             foreach ($ciphertext) {                                                          |
+     *    |                 $in = $block_size of $ciphertext;                                            |
+     *    |                                                                                              |
+     *    |                 INSERT PHP CODE OF:                                                          |
+     *    |                 $cipher_code['encrypt_block'];  // encrypt's (string) $in, which is always:  |
+     *    |                                                 // strlen($in) == $this->block_size          |
+     *    |                                                 // here comes the cipher algorithm in action |
+     *    |                                                 // for encryption.                           |
+     *    |                                                 // $cipher_code['encrypt_block'] has to      |
+     *    |                                                 // encrypt the content of the $in variable   |
+     *    |                                                                                              |
+     *    |                 $plaintext .= $in;                                                           |
+     *    |             }                                                                                |
+     *    |             return $plaintext;                                                               |
+     *    |                                                                                              |
+     *    |         case 'decrypt':                                                                      |
+     *    |             INSERT PHP CODE OF:                                                              |
+     *    |             $cipher_code['init_decrypt'];       // decrypt sepcific init code                |
+     *    |                                                    ie: specified $key or $box                |
+     *    |                                                        declarations for decrypt'ing.         |
+     *    |             foreach ($plaintext) {                                                           |
+     *    |                 $in = $block_size of $plaintext;                                             |
+     *    |                                                                                              |
+     *    |                 INSERT PHP CODE OF:                                                          |
+     *    |                 $cipher_code['decrypt_block'];  // decrypt's (string) $in, which is always   |
+     *    |                                                 // strlen($in) == $this->block_size          |
+     *    |                                                 // here comes the cipher algorithm in action |
+     *    |                                                 // for decryption.                           |
+     *    |                                                 // $cipher_code['decrypt_block'] has to      |
+     *    |                                                 // decrypt the content of the $in variable   |
+     *    |                 $ciphertext .= $in;                                                          |
+     *    |             }                                                                                |
+     *    |             return $ciphertext;                                                              |
+     *    |     }                                                                                        |
+     *    | }                                                                                            |
+     *    +----------------------------------------------------------------------------------------------+
+     *    </code>
+     *
+     *    See also the \phpseclib\Crypt\*::_setupInlineCrypt()'s for
+     *    productive inline $cipher_code's how they works.
+     *
+     *    Structure of:
+     *    <code>
+     *    $cipher_code = array(
+     *        'init_crypt'    => (string) '', // optional
+     *        'init_encrypt'  => (string) '', // optional
+     *        'init_decrypt'  => (string) '', // optional
+     *        'encrypt_block' => (string) '', // required
+     *        'decrypt_block' => (string) ''  // required
+     *    );
+     *    </code>
+     *
+     * @see self::_setupInlineCrypt()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @param array $cipher_code
+     * @access private
+     * @return string (the name of the created callback function)
+     */
+    function _createInlineCryptFunction($cipher_code)
+    {
+        $block_size = $this->block_size;
+
+        // optional
+        $init_crypt    = isset($cipher_code['init_crypt'])    ? $cipher_code['init_crypt']    : '';
+        $init_encrypt  = isset($cipher_code['init_encrypt'])  ? $cipher_code['init_encrypt']  : '';
+        $init_decrypt  = isset($cipher_code['init_decrypt'])  ? $cipher_code['init_decrypt']  : '';
+        // required
+        $encrypt_block = $cipher_code['encrypt_block'];
+        $decrypt_block = $cipher_code['decrypt_block'];
+
+        // Generating mode of operation inline code,
+        // merged with the $cipher_code algorithm
+        // for encrypt- and decryption.
+        switch ($this->mode) {
+            case self::MODE_ECB:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_plaintext_len = strlen($_text);
+
+                    for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+                        $in = substr($_text, $_i, '.$block_size.');
+                        '.$encrypt_block.'
+                        $_ciphertext.= $in;
+                    }
+
+                    return $_ciphertext;
+                    ';
+
+                $decrypt = $init_decrypt . '
+                    $_plaintext = "";
+                    $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
+                    $_ciphertext_len = strlen($_text);
+
+                    for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+                        $in = substr($_text, $_i, '.$block_size.');
+                        '.$decrypt_block.'
+                        $_plaintext.= $in;
+                    }
+
+                    return $self->_unpad($_plaintext);
+                    ';
+                break;
+            case self::MODE_CTR:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_plaintext_len = strlen($_text);
+                    $_xor = $self->encryptIV;
+                    $_buffer = &$self->enbuffer;
+                    if (strlen($_buffer["ciphertext"])) {
+                        for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+                            $_block = substr($_text, $_i, '.$block_size.');
+                            if (strlen($_block) > strlen($_buffer["ciphertext"])) {
+                                $in = $_xor;
+                                '.$encrypt_block.'
+                                $self->_increment_str($_xor);
+                                $_buffer["ciphertext"].= $in;
+                            }
+                            $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
+                            $_ciphertext.= $_block ^ $_key;
+                        }
+                    } else {
+                        for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+                            $_block = substr($_text, $_i, '.$block_size.');
+                            $in = $_xor;
+                            '.$encrypt_block.'
+                            $self->_increment_str($_xor);
+                            $_key = $in;
+                            $_ciphertext.= $_block ^ $_key;
+                        }
+                    }
+                    if ($self->continuousBuffer) {
+                        $self->encryptIV = $_xor;
+                        if ($_start = $_plaintext_len % '.$block_size.') {
+                            $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
+                        }
+                    }
+
+                    return $_ciphertext;
+                ';
+
+                $decrypt = $init_encrypt . '
+                    $_plaintext = "";
+                    $_ciphertext_len = strlen($_text);
+                    $_xor = $self->decryptIV;
+                    $_buffer = &$self->debuffer;
+
+                    if (strlen($_buffer["ciphertext"])) {
+                        for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+                            $_block = substr($_text, $_i, '.$block_size.');
+                            if (strlen($_block) > strlen($_buffer["ciphertext"])) {
+                                $in = $_xor;
+                                '.$encrypt_block.'
+                                $self->_increment_str($_xor);
+                                $_buffer["ciphertext"].= $in;
+                            }
+                            $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
+                            $_plaintext.= $_block ^ $_key;
+                        }
+                    } else {
+                        for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+                            $_block = substr($_text, $_i, '.$block_size.');
+                            $in = $_xor;
+                            '.$encrypt_block.'
+                            $self->_increment_str($_xor);
+                            $_key = $in;
+                            $_plaintext.= $_block ^ $_key;
+                        }
+                    }
+                    if ($self->continuousBuffer) {
+                        $self->decryptIV = $_xor;
+                        if ($_start = $_ciphertext_len % '.$block_size.') {
+                            $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
+                        }
+                    }
+
+                    return $_plaintext;
+                    ';
+                break;
+            case self::MODE_CFB:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_buffer = &$self->enbuffer;
+
+                    if ($self->continuousBuffer) {
+                        $_iv = &$self->encryptIV;
+                        $_pos = &$_buffer["pos"];
+                    } else {
+                        $_iv = $self->encryptIV;
+                        $_pos = 0;
+                    }
+                    $_len = strlen($_text);
+                    $_i = 0;
+                    if ($_pos) {
+                        $_orig_pos = $_pos;
+                        $_max = '.$block_size.' - $_pos;
+                        if ($_len >= $_max) {
+                            $_i = $_max;
+                            $_len-= $_max;
+                            $_pos = 0;
+                        } else {
+                            $_i = $_len;
+                            $_pos+= $_len;
+                            $_len = 0;
+                        }
+                        $_ciphertext = substr($_iv, $_orig_pos) ^ $_text;
+                        $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i);
+                    }
+                    while ($_len >= '.$block_size.') {
+                        $in = $_iv;
+                        '.$encrypt_block.';
+                        $_iv = $in ^ substr($_text, $_i, '.$block_size.');
+                        $_ciphertext.= $_iv;
+                        $_len-= '.$block_size.';
+                        $_i+= '.$block_size.';
+                    }
+                    if ($_len) {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_iv = $in;
+                        $_block = $_iv ^ substr($_text, $_i);
+                        $_iv = substr_replace($_iv, $_block, 0, $_len);
+                        $_ciphertext.= $_block;
+                        $_pos = $_len;
+                    }
+                    return $_ciphertext;
+                ';
+
+                $decrypt = $init_encrypt . '
+                    $_plaintext = "";
+                    $_buffer = &$self->debuffer;
+
+                    if ($self->continuousBuffer) {
+                        $_iv = &$self->decryptIV;
+                        $_pos = &$_buffer["pos"];
+                    } else {
+                        $_iv = $self->decryptIV;
+                        $_pos = 0;
+                    }
+                    $_len = strlen($_text);
+                    $_i = 0;
+                    if ($_pos) {
+                        $_orig_pos = $_pos;
+                        $_max = '.$block_size.' - $_pos;
+                        if ($_len >= $_max) {
+                            $_i = $_max;
+                            $_len-= $_max;
+                            $_pos = 0;
+                        } else {
+                            $_i = $_len;
+                            $_pos+= $_len;
+                            $_len = 0;
+                        }
+                        $_plaintext = substr($_iv, $_orig_pos) ^ $_text;
+                        $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i);
+                    }
+                    while ($_len >= '.$block_size.') {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_iv = $in;
+                        $cb = substr($_text, $_i, '.$block_size.');
+                        $_plaintext.= $_iv ^ $cb;
+                        $_iv = $cb;
+                        $_len-= '.$block_size.';
+                        $_i+= '.$block_size.';
+                    }
+                    if ($_len) {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_iv = $in;
+                        $_plaintext.= $_iv ^ substr($_text, $_i);
+                        $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len);
+                        $_pos = $_len;
+                    }
+
+                    return $_plaintext;
+                    ';
+                break;
+            case self::MODE_CFB8:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_len = strlen($_text);
+                    $_iv = $self->encryptIV;
+
+                    for ($_i = 0; $_i < $_len; ++$_i) {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_ciphertext.= ($_c = $_text[$_i] ^ $in);
+                        $_iv = substr($_iv, 1) . $_c;
+                    }
+
+                    if ($self->continuousBuffer) {
+                        if ($_len >= '.$block_size.') {
+                            $self->encryptIV = substr($_ciphertext, -'.$block_size.');
+                        } else {
+                            $self->encryptIV = substr($self->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len);
+                        }
+                    }
+
+                    return $_ciphertext;
+                    ';
+                $decrypt = $init_encrypt . '
+                    $_plaintext = "";
+                    $_len = strlen($_text);
+                    $_iv = $self->decryptIV;
+
+                    for ($_i = 0; $_i < $_len; ++$_i) {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_plaintext.= $_text[$_i] ^ $in;
+                        $_iv = substr($_iv, 1) . $_text[$_i];
+                    }
+
+                    if ($self->continuousBuffer) {
+                        if ($_len >= '.$block_size.') {
+                            $self->decryptIV = substr($_text, -'.$block_size.');
+                        } else {
+                            $self->decryptIV = substr($self->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len);
+                        }
+                    }
+
+                    return $_plaintext;
+                    ';
+                break;
+            case self::MODE_OFB8:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_len = strlen($_text);
+                    $_iv = $self->encryptIV;
+
+                    for ($_i = 0; $_i < $_len; ++$_i) {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_ciphertext.= $_text[$_i] ^ $in;
+                        $_iv = substr($_iv, 1) . $in[0];
+                    }
+
+                    if ($self->continuousBuffer) {
+                        $self->encryptIV = $_iv;
+                    }
+
+                    return $_ciphertext;
+                    ';
+                $decrypt = $init_encrypt . '
+                    $_plaintext = "";
+                    $_len = strlen($_text);
+                    $_iv = $self->decryptIV;
+
+                    for ($_i = 0; $_i < $_len; ++$_i) {
+                        $in = $_iv;
+                        '.$encrypt_block.'
+                        $_plaintext.= $_text[$_i] ^ $in;
+                        $_iv = substr($_iv, 1) . $in[0];
+                    }
+
+                    if ($self->continuousBuffer) {
+                        $self->decryptIV = $_iv;
+                    }
+
+                    return $_plaintext;
+                    ';
+                break;
+            case self::MODE_OFB:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_plaintext_len = strlen($_text);
+                    $_xor = $self->encryptIV;
+                    $_buffer = &$self->enbuffer;
+
+                    if (strlen($_buffer["xor"])) {
+                        for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+                            $_block = substr($_text, $_i, '.$block_size.');
+                            if (strlen($_block) > strlen($_buffer["xor"])) {
+                                $in = $_xor;
+                                '.$encrypt_block.'
+                                $_xor = $in;
+                                $_buffer["xor"].= $_xor;
+                            }
+                            $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
+                            $_ciphertext.= $_block ^ $_key;
+                        }
+                    } else {
+                        for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+                            $in = $_xor;
+                            '.$encrypt_block.'
+                            $_xor = $in;
+                            $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
+                        }
+                        $_key = $_xor;
+                    }
+                    if ($self->continuousBuffer) {
+                        $self->encryptIV = $_xor;
+                        if ($_start = $_plaintext_len % '.$block_size.') {
+                             $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
+                        }
+                    }
+                    return $_ciphertext;
+                    ';
+
+                $decrypt = $init_encrypt . '
+                    $_plaintext = "";
+                    $_ciphertext_len = strlen($_text);
+                    $_xor = $self->decryptIV;
+                    $_buffer = &$self->debuffer;
+
+                    if (strlen($_buffer["xor"])) {
+                        for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+                            $_block = substr($_text, $_i, '.$block_size.');
+                            if (strlen($_block) > strlen($_buffer["xor"])) {
+                                $in = $_xor;
+                                '.$encrypt_block.'
+                                $_xor = $in;
+                                $_buffer["xor"].= $_xor;
+                            }
+                            $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
+                            $_plaintext.= $_block ^ $_key;
+                        }
+                    } else {
+                        for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+                            $in = $_xor;
+                            '.$encrypt_block.'
+                            $_xor = $in;
+                            $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
+                        }
+                        $_key = $_xor;
+                    }
+                    if ($self->continuousBuffer) {
+                        $self->decryptIV = $_xor;
+                        if ($_start = $_ciphertext_len % '.$block_size.') {
+                             $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
+                        }
+                    }
+                    return $_plaintext;
+                    ';
+                break;
+            case self::MODE_STREAM:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    '.$encrypt_block.'
+                    return $_ciphertext;
+                    ';
+                $decrypt = $init_decrypt . '
+                    $_plaintext = "";
+                    '.$decrypt_block.'
+                    return $_plaintext;
+                    ';
+                break;
+            // case self::MODE_CBC:
+            default:
+                $encrypt = $init_encrypt . '
+                    $_ciphertext = "";
+                    $_plaintext_len = strlen($_text);
+
+                    $in = $self->encryptIV;
+
+                    for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+                        $in = substr($_text, $_i, '.$block_size.') ^ $in;
+                        '.$encrypt_block.'
+                        $_ciphertext.= $in;
+                    }
+
+                    if ($self->continuousBuffer) {
+                        $self->encryptIV = $in;
+                    }
+
+                    return $_ciphertext;
+                    ';
+
+                $decrypt = $init_decrypt . '
+                    $_plaintext = "";
+                    $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
+                    $_ciphertext_len = strlen($_text);
+
+                    $_iv = $self->decryptIV;
+
+                    for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+                        $in = $_block = substr($_text, $_i, '.$block_size.');
+                        '.$decrypt_block.'
+                        $_plaintext.= $in ^ $_iv;
+                        $_iv = $_block;
+                    }
+
+                    if ($self->continuousBuffer) {
+                        $self->decryptIV = $_iv;
+                    }
+
+                    return $self->_unpad($_plaintext);
+                    ';
+                break;
+        }
+
+        // Create the $inline function and return its name as string. Ready to run!
+        eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };');
+        return $func;
+    }
+
+    /**
+     * Holds the lambda_functions table (classwide)
+     *
+     * Each name of the lambda function, created from
+     * _setupInlineCrypt() && _createInlineCryptFunction()
+     * is stored, classwide (!), here for reusing.
+     *
+     * The string-based index of $function is a classwide
+     * unique value representing, at least, the $mode of
+     * operation (or more... depends of the optimizing level)
+     * for which $mode the lambda function was created.
+     *
+     * @access private
+     * @return array &$functions
+     */
+    function &_getLambdaFunctions()
+    {
+        static $functions = array();
+        return $functions;
+    }
+
+    /**
+     * Generates a digest from $bytes
+     *
+     * @see self::_setupInlineCrypt()
+     * @access private
+     * @param string $bytes
+     * @return string
+     */
+    function _hashInlineCryptFunction($bytes)
+    {
+        if (!isset(self::$WHIRLPOOL_AVAILABLE)) {
+            self::$WHIRLPOOL_AVAILABLE = extension_loaded('hash') && in_array('whirlpool', hash_algos());
+        }
+
+        $result = '';
+        $hash = $bytes;
+
+        switch (true) {
+            case self::$WHIRLPOOL_AVAILABLE:
+                foreach (str_split($bytes, 64) as $t) {
+                    $hash = hash('whirlpool', $hash, true);
+                    $result .= $t ^ $hash;
+                }
+                return $result . hash('whirlpool', $hash, true);
+            default:
+                $len = strlen($bytes);
+                for ($i = 0; $i < $len; $i+=20) {
+                    $t = substr($bytes, $i, 20);
+                    $hash = pack('H*', sha1($hash));
+                    $result .= $t ^ $hash;
+                }
+                return $result . pack('H*', sha1($hash));
+        }
+    }
+
+    /**
+     * Convert float to int
+     *
+     * On ARM CPUs converting floats to ints doesn't always work
+     *
+     * @access private
+     * @param string $x
+     * @return int
+     */
+    function safe_intval($x)
+    {
+        if (is_int($x)) {
+            return $x;
+        }
+        return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
+            ((fmod(floor($x / 0x80000000), 2) & 1) << 31);
+    }
+
+    /**
+     * eval()'able string for in-line float to int
+     *
+     * @access private
+     * @return string
+     */
+    function safe_intval_inline()
+    {
+        if (CRYPT_BASE_USE_REG_INTVAL) {
+            return PHP_INT_SIZE == 4 ? 'intval(%s)' : '%s';
+        }
+
+        $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
+        return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
+    }
+
+    /**
+     * Dummy error handler to suppress mcrypt errors
+     *
+     * @access private
+     */
+    function do_nothing()
+    {
+    }
+
+    /**
+     * Is the continuous buffer enabled?
+     *
+     * @access public
+     * @return boolean
+     */
+    function continuousBufferEnabled()
+    {
+        return $this->continuousBuffer;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
new file mode 100644
index 00000000..94552f94
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
@@ -0,0 +1,992 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Blowfish.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ *  - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
+ *
+ * # An overview of bcrypt vs Blowfish
+ *
+ * OpenSSH private keys use a customized version of bcrypt. Specifically, instead of
+ * encrypting OrpheanBeholderScryDoubt 64 times OpenSSH's bcrypt variant encrypts
+ * OxychromaticBlowfishSwatDynamite 64 times. so we can't use crypt().
+ *
+ * bcrypt is basically Blowfish but instead of performing the key expansion once it performs
+ * the expansion 129 times for each round, with the first key expansion interleaving the salt
+ * and password. This renders OpenSSL unusable and forces us to use a pure-PHP implementation
+ * of blowfish.
+ *
+ * # phpseclib's four different _encryptBlock() implementations
+ *
+ * When using Blowfish as an encryption algorithm, _encryptBlock() is called 9 + 512 +
+ * (the number of blocks in the plaintext) times.
+ *
+ * Each of the first 9 calls to _encryptBlock() modify the P-array. Each of the next 512
+ * calls modify the S-boxes. The remaining _encryptBlock() calls operate on the plaintext to
+ * produce the ciphertext. In the pure-PHP implementation of Blowfish these remaining
+ * _encryptBlock() calls are highly optimized through the use of eval(). Among other things,
+ * P-array lookups are eliminated by hard-coding the key-dependent P-array values, and thus we
+ * have explained 2 of the 4 different _encryptBlock() implementations.
+ *
+ * With bcrypt things are a bit different. _encryptBlock() is called 1,079,296 times,
+ * assuming 16 rounds (which is what OpenSSH's bcrypt defaults to). The eval()-optimized
+ * _encryptBlock() isn't as beneficial because the P-array values are not constant. Well, they
+ * are constant, but only for, at most, 777 _encryptBlock() calls, which is equivalent to ~6KB
+ * of data. The average length of back to back _encryptBlock() calls with a fixed P-array is
+ * 514.12, which is ~4KB of data. Creating an eval()-optimized _encryptBlock() has an upfront
+ * cost, which is CPU dependent and is probably not going to be worth it for just ~4KB of
+ * data. Conseqeuently, bcrypt does not benefit from the eval()-optimized _encryptBlock().
+ *
+ * The regular _encryptBlock() does unpack() and pack() on every call, as well, and that can
+ * begin to add up after one million function calls.
+ *
+ * In theory, one might think that it might be beneficial to rewrite all block ciphers so
+ * that, instead of passing strings to _encryptBlock(), you convert the string to an array of
+ * integers and then pass successive subarrays of that array to _encryptBlock. This, however,
+ * kills PHP's memory use. Like let's say you have a 1MB long string. After doing
+ * $in = str_repeat('a', 1024 * 1024); PHP's memory utilization jumps up by ~1MB. After doing
+ * $blocks = str_split($in, 4); it jumps up by an additional ~16MB. After
+ * $blocks = array_map(fn($x) => unpack('N*', $x), $blocks); it jumps up by an additional
+ * ~90MB, yielding a 106x increase in memory usage. Consequently, it bcrypt calls a different
+ * _encryptBlock() then the regular Blowfish does. That said, the Blowfish _encryptBlock() is
+ * basically just a thin wrapper around the bcrypt _encryptBlock(), so there's that.
+ *
+ * This explains 3 of the 4 _encryptBlock() implementations. the last _encryptBlock()
+ * implementation can best be understood by doing Ctrl + F and searching for where
+ * CRYPT_BASE_USE_REG_INTVAL is defined.
+ *
+ * # phpseclib's three different _setupKey() implementations
+ *
+ * Every bcrypt round is the equivalent of encrypting 512KB of data. Since OpenSSH uses 16
+ * rounds by default that's ~8MB of data that's essentially being encrypted whenever
+ * you use bcrypt. That's a lot of data, however, bcrypt operates within tighter constraints
+ * than regular Blowfish, so we can use that to our advantage. In particular, whereas Blowfish
+ * supports variable length keys, in bcrypt, the initial "key" is the sha512 hash of the
+ * password. sha512 hashes are 512 bits or 64 bytes long and thus the bcrypt keys are of a
+ * fixed length whereas Blowfish keys are not of a fixed length.
+ *
+ * bcrypt actually has two different key expansion steps. The first one (expandstate) is
+ * constantly XOR'ing every _encryptBlock() parameter against the salt prior _encryptBlock()'s
+ * being called. The second one (expand0state) is more similar to Blowfish's _setupKey()
+ * but it can still use the fixed length key optimization discussed above and can do away with
+ * the pack() / unpack() calls.
+ *
+ * I suppose _setupKey() could be made to be a thin wrapper around expandstate() but idk it's
+ * just a lot of work for very marginal benefits as _setupKey() is only called once for
+ * regular Blowfish vs the 128 times it's called --per round-- with bcrypt.
+ *
+ * # blowfish + bcrypt in the same class
+ *
+ * Altho there's a lot of Blowfish code that bcrypt doesn't re-use, bcrypt does re-use the
+ * initial S-boxes, the initial P-array and the int-only _encryptBlock() implementation.
+ *
+ * # Credit
+ *
+ * phpseclib's bcrypt implementation is based losely off of OpenSSH's implementation:
+ *
+ * https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $blowfish = new \phpseclib\Crypt\Blowfish();
+ *
+ *    $blowfish->setKey('12345678901234567890123456789012');
+ *
+ *    $plaintext = str_repeat('a', 1024);
+ *
+ *    echo $blowfish->decrypt($blowfish->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   Blowfish
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @author    Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Blowfish.
+ *
+ * @package Blowfish
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @access  public
+ */
+class Blowfish extends Base
+{
+    /**
+     * Block Length of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::block_size
+     * @var int
+     * @access private
+     */
+    var $block_size = 8;
+
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'blowfish';
+
+    /**
+     * Optimizing value while CFB-encrypting
+     *
+     * @see \phpseclib\Crypt\Base::cfb_init_len
+     * @var int
+     * @access private
+     */
+    var $cfb_init_len = 500;
+
+    /**
+     * SHA512 Object
+     *
+     * @see self::bcrypt_pbkdf
+     * @var object
+     * @access private
+     */
+    var $sha512;
+
+    /**
+     * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
+     *
+     * S-Box 0
+     *
+     * @access private
+     * @var    array
+     */
+    var $sbox0 = array(
+        0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+        0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+        0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+        0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+        0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+        0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+        0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+        0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+        0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+        0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+        0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+        0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+        0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+        0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+        0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+        0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+        0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+        0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+        0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+        0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+        0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+        0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+        0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+        0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+        0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+        0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+        0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+        0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+        0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+        0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+        0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+        0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+    );
+
+    /**
+     * S-Box 1
+     *
+     * @access private
+     * @var    array
+     */
+    var $sbox1 = array(
+        0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+        0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+        0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+        0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+        0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+        0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+        0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+        0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+        0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+        0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+        0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+        0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+        0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+        0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+        0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+        0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+        0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+        0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+        0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+        0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+        0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+        0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+        0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+        0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+        0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+        0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+        0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+        0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+        0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+        0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+        0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+        0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+    );
+
+    /**
+     * S-Box 2
+     *
+     * @access private
+     * @var    array
+     */
+    var $sbox2 = array(
+        0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+        0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+        0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+        0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+        0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+        0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+        0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+        0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+        0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+        0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+        0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+        0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+        0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+        0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+        0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+        0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+        0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+        0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+        0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+        0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+        0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+        0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+        0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+        0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+        0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+        0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+        0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+        0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+        0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+        0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+        0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+        0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+    );
+
+    /**
+     * S-Box 3
+     *
+     * @access private
+     * @var    array
+     */
+    var $sbox3 = array(
+        0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+        0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+        0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+        0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+        0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+        0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+        0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+        0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+        0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+        0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+        0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+        0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+        0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+        0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+        0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+        0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+        0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+        0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+        0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+        0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+        0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+        0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+        0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+        0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+        0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+        0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+        0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+        0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+        0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+        0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+        0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+        0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+    );
+
+    /**
+     * P-Array consists of 18 32-bit subkeys
+     *
+     * @var array
+     * @access private
+     */
+    var $parray = array(
+        0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
+        0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+        0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
+    );
+
+    /**
+     * The BCTX-working Array
+     *
+     * Holds the expanded key [p] and the key-depended s-boxes [sb]
+     *
+     * @var array
+     * @access private
+     */
+    var $bctx;
+
+    /**
+     * Holds the last used key
+     *
+     * @var array
+     * @access private
+     */
+    var $kl;
+
+    /**
+     * The Key Length (in bytes)
+     *
+     * @see \phpseclib\Crypt\Base::setKeyLength()
+     * @var int
+     * @access private
+     * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16.  Exists in conjunction with $Nk
+     *    because the encryption / decryption / key schedule creation requires this number and not $key_length.  We could
+     *    derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    of that, we'll just precompute it once.
+     */
+    var $key_length = 16;
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.
+     *
+     * $mode could be:
+     *
+     * - CRYPT_MODE_ECB
+     *
+     * - CRYPT_MODE_CBC
+     *
+     * - CRYPT_MODE_CTR
+     *
+     * - CRYPT_MODE_CFB
+     *
+     * - CRYPT_MODE_OFB
+     *
+     * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
+     *
+     * If not explicitly set, CRYPT_MODE_CBC will be used.
+     *
+     * @param int $mode
+     * @access public
+     */
+    function __construct($mode = self::MODE_CBC)
+    {
+        parent::__construct($mode);
+
+        $this->sbox0 = array_map('intval', $this->sbox0);
+        $this->sbox1 = array_map('intval', $this->sbox1);
+        $this->sbox2 = array_map('intval', $this->sbox2);
+        $this->sbox3 = array_map('intval', $this->sbox3);
+        $this->parray = array_map('intval', $this->parray);
+    }
+
+    /**
+     * Sets the key length.
+     *
+     * Key lengths can be between 32 and 448 bits.
+     *
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        if ($length < 32) {
+            $this->key_length = 4;
+        } elseif ($length > 448) {
+            $this->key_length = 56;
+        } else {
+            $this->key_length = $length >> 3;
+        }
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+     *
+     * @see \phpseclib\Crypt\Base::isValidEngine()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($engine == self::ENGINE_OPENSSL) {
+            // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+            // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+            // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+            if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+                return false;
+            }
+            if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) {
+                return false;
+            }
+            if ($this->key_length < 16) {
+                return false;
+            }
+            $this->cipher_name_openssl_ecb = 'bf-ecb';
+            $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
+    /**
+     * Setup the key (expansion)
+     *
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
+            // already expanded
+            return;
+        }
+        $this->kl = array('key' => $this->key);
+
+        /* key-expanding p[] and S-Box building sb[] */
+        $this->bctx = array(
+            'p'  => array(),
+            'sb' => array(
+                $this->sbox0,
+                $this->sbox1,
+                $this->sbox2,
+                $this->sbox3
+            )
+        );
+
+        // unpack binary string in unsigned chars
+        $key  = array_values(unpack('C*', $this->key));
+        $keyl = count($key);
+        // with bcrypt $keyl will always be 16 (because the key is the sha512 of the key you provide)
+        for ($j = 0, $i = 0; $i < 18; ++$i) {
+            // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
+            for ($data = 0, $k = 0; $k < 4; ++$k) {
+                $data = ($data << 8) | $key[$j];
+                if (++$j >= $keyl) {
+                    $j = 0;
+                }
+            }
+            $this->bctx['p'][] = $this->parray[$i] ^ intval($data);
+        }
+
+        // encrypt the zero-string, replace P1 and P2 with the encrypted data,
+        // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
+        $data = "\0\0\0\0\0\0\0\0";
+        for ($i = 0; $i < 18; $i += 2) {
+            list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
+            $this->bctx['p'][$i    ] = $l;
+            $this->bctx['p'][$i + 1] = $r;
+        }
+        for ($i = 0; $i < 4; ++$i) {
+            for ($j = 0; $j < 256; $j += 2) {
+                list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
+                $this->bctx['sb'][$i][$j    ] = $l;
+                $this->bctx['sb'][$i][$j + 1] = $r;
+            }
+        }
+    }
+
+    /**
+     * bcrypt
+     *
+     * @param string $sha2pass
+     * @param string $sha2salt
+     * @access private
+     * @return string
+     */
+    function _bcrypt_hash($sha2pass, $sha2salt)
+    {
+        $p = $this->parray;
+        $sbox0 = $this->sbox0;
+        $sbox1 = $this->sbox1;
+        $sbox2 = $this->sbox2;
+        $sbox3 = $this->sbox3;
+
+        $cdata = array_values(unpack('N*', 'OxychromaticBlowfishSwatDynamite'));
+        $sha2pass = array_values(unpack('N*', $sha2pass));
+        $sha2salt = array_values(unpack('N*', $sha2salt));
+
+        $this->_expandstate($sha2salt, $sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 0; $i < 64; $i++) {
+            $this->_expand0state($sha2salt, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+            $this->_expand0state($sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        for ($i = 0; $i < 64; $i++) {
+            for ($j = 0; $j < 8; $j+= 2) { // count($cdata) == 8
+                list($cdata[$j], $cdata[$j + 1]) = $this->_encryptBlockHelperFast($cdata[$j], $cdata[$j + 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+            }
+        }
+
+        $output = '';
+        for ($i = 0; $i < count($cdata); $i++) {
+            $output.= pack('L*', $cdata[$i]);
+        }
+        return $output;
+    }
+
+    /**
+     * Performs OpenSSH-style bcrypt
+     *
+     * @param string $pass
+     * @param string $salt
+     * @param int $keylen
+     * @param int $rounds
+     * @access public
+     * @return false|string
+     */
+    function bcrypt_pbkdf($pass, $salt, $keylen, $rounds)
+    {
+        if (PHP_INT_SIZE == 4) {
+            user_error('bcrypt is far too slow to be practical on 32-bit versions of PHP');
+            return false;
+        }
+
+        if (!isset($this->sha512)) {
+            $this->sha512 = new Hash('sha512');
+        }
+
+        $sha2pass = $this->sha512->hash($pass);
+        $results = array();
+        $count = 1;
+        while (32 * count($results) < $keylen) {
+            $countsalt = $salt . pack('N', $count++);
+            $sha2salt = $this->sha512->hash($countsalt);
+            $out = $tmpout = $this->_bcrypt_hash($sha2pass, $sha2salt);
+            for ($i = 1; $i < $rounds; $i++) {
+                $sha2salt = $this->sha512->hash($tmpout);
+                $tmpout = $this->_bcrypt_hash($sha2pass, $sha2salt);
+                $out^= $tmpout;
+            }
+            $results[] = $out;
+        }
+        $output = '';
+        for ($i = 0; $i < 32; $i++) {
+            foreach ($results as $result) {
+                $output.= $result[$i];
+            }
+        }
+        return substr($output, 0, $keylen);
+    }
+
+    /**
+     * Key expansion without salt
+     *
+     * @access private
+     * @param int[] $key
+     * @param int[] $sbox0
+     * @param int[] $sbox1
+     * @param int[] $sbox2
+     * @param int[] $sbox3
+     * @param int[] $p
+     * @see self::_bcrypt_hash()
+     */
+    function _expand0state($key, &$sbox0, &$sbox1, &$sbox2, &$sbox3, &$p)
+    {
+        // expand0state is basically the same thing as this:
+        //return $this->_expandstate(array_fill(0, 16, 0), $key);
+        // but this separate function eliminates a bunch of XORs and array lookups
+
+        $p = array(
+            $p[0] ^ $key[0],
+            $p[1] ^ $key[1],
+            $p[2] ^ $key[2],
+            $p[3] ^ $key[3],
+            $p[4] ^ $key[4],
+            $p[5] ^ $key[5],
+            $p[6] ^ $key[6],
+            $p[7] ^ $key[7],
+            $p[8] ^ $key[8],
+            $p[9] ^ $key[9],
+            $p[10] ^ $key[10],
+            $p[11] ^ $key[11],
+            $p[12] ^ $key[12],
+            $p[13] ^ $key[13],
+            $p[14] ^ $key[14],
+            $p[15] ^ $key[15],
+            $p[16] ^ $key[0],
+            $p[17] ^ $key[1]
+        );
+
+        // @codingStandardsIgnoreStart
+        list( $p[0],  $p[1]) = $this->_encryptBlockHelperFast(     0,      0, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[2],  $p[3]) = $this->_encryptBlockHelperFast($p[ 0], $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[4],  $p[5]) = $this->_encryptBlockHelperFast($p[ 2], $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[6],  $p[7]) = $this->_encryptBlockHelperFast($p[ 4], $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[8],  $p[9]) = $this->_encryptBlockHelperFast($p[ 6], $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[10], $p[11]) = $this->_encryptBlockHelperFast($p[ 8], $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[12], $p[13]) = $this->_encryptBlockHelperFast($p[10], $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[14], $p[15]) = $this->_encryptBlockHelperFast($p[12], $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[16], $p[17]) = $this->_encryptBlockHelperFast($p[14], $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        // @codingStandardsIgnoreEnd
+
+        list($sbox0[0], $sbox0[1]) = $this->_encryptBlockHelperFast($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2; $i < 256; $i+= 2) {
+            list($sbox0[$i], $sbox0[$i + 1]) = $this->_encryptBlockHelperFast($sbox0[$i - 2], $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        list($sbox1[0], $sbox1[1]) = $this->_encryptBlockHelperFast($sbox0[254], $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2; $i < 256; $i+= 2) {
+            list($sbox1[$i], $sbox1[$i + 1]) = $this->_encryptBlockHelperFast($sbox1[$i - 2], $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        list($sbox2[0], $sbox2[1]) = $this->_encryptBlockHelperFast($sbox1[254], $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2; $i < 256; $i+= 2) {
+            list($sbox2[$i], $sbox2[$i + 1]) = $this->_encryptBlockHelperFast($sbox2[$i - 2], $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        list($sbox3[0], $sbox3[1]) = $this->_encryptBlockHelperFast($sbox2[254], $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2; $i < 256; $i+= 2) {
+            list($sbox3[$i], $sbox3[$i + 1]) = $this->_encryptBlockHelperFast($sbox3[$i - 2], $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+    }
+
+    /**
+     * Key expansion with salt
+     *
+     * @access private
+     * @param int[] $data
+     * @param int[] $key
+     * @param int[] $sbox0
+     * @param int[] $sbox1
+     * @param int[] $sbox2
+     * @param int[] $sbox3
+     * @param int[] $p
+     * @see self::_bcrypt_hash()
+     */
+    function _expandstate($data, $key, &$sbox0, &$sbox1, &$sbox2, &$sbox3, &$p)
+    {
+        $p = array(
+            $p[0] ^ $key[0],
+            $p[1] ^ $key[1],
+            $p[2] ^ $key[2],
+            $p[3] ^ $key[3],
+            $p[4] ^ $key[4],
+            $p[5] ^ $key[5],
+            $p[6] ^ $key[6],
+            $p[7] ^ $key[7],
+            $p[8] ^ $key[8],
+            $p[9] ^ $key[9],
+            $p[10] ^ $key[10],
+            $p[11] ^ $key[11],
+            $p[12] ^ $key[12],
+            $p[13] ^ $key[13],
+            $p[14] ^ $key[14],
+            $p[15] ^ $key[15],
+            $p[16] ^ $key[0],
+            $p[17] ^ $key[1]
+        );
+
+        // @codingStandardsIgnoreStart
+        list( $p[0],  $p[1]) = $this->_encryptBlockHelperFast($data[ 0]         , $data[ 1]         , $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[2],  $p[3]) = $this->_encryptBlockHelperFast($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[4],  $p[5]) = $this->_encryptBlockHelperFast($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[6],  $p[7]) = $this->_encryptBlockHelperFast($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list( $p[8],  $p[9]) = $this->_encryptBlockHelperFast($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[10], $p[11]) = $this->_encryptBlockHelperFast($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[12], $p[13]) = $this->_encryptBlockHelperFast($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[14], $p[15]) = $this->_encryptBlockHelperFast($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        list($p[16], $p[17]) = $this->_encryptBlockHelperFast($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        // @codingStandardsIgnoreEnd
+
+        list($sbox0[0], $sbox0[1]) = $this->_encryptBlockHelperFast($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better?
+            list($sbox0[$i], $sbox0[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox0[$i - 2], $data[$j + 1] ^ $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        list($sbox1[0], $sbox1[1]) = $this->_encryptBlockHelperFast($data[2] ^ $sbox0[254], $data[3] ^ $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) {
+            list($sbox1[$i], $sbox1[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox1[$i - 2], $data[$j + 1] ^ $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        list($sbox2[0], $sbox2[1]) = $this->_encryptBlockHelperFast($data[2] ^ $sbox1[254], $data[3] ^ $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) {
+            list($sbox2[$i], $sbox2[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox2[$i - 2], $data[$j + 1] ^ $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+
+        list($sbox3[0], $sbox3[1]) = $this->_encryptBlockHelperFast($data[2] ^ $sbox2[254], $data[3] ^ $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) {
+            list($sbox3[$i], $sbox3[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox3[$i - 2], $data[$j + 1] ^ $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+        }
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _encryptBlock($in)
+    {
+        $p = $this->bctx["p"];
+        // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
+        $sb_0 = $this->bctx["sb"][0];
+        $sb_1 = $this->bctx["sb"][1];
+        $sb_2 = $this->bctx["sb"][2];
+        $sb_3 = $this->bctx["sb"][3];
+
+        $in = unpack("N*", $in);
+        $l = $in[1];
+        $r = $in[2];
+
+        list($r, $l) = CRYPT_BASE_USE_REG_INTVAL ?
+            $this->_encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) :
+            $this->_encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p);
+
+        return pack("N*", $r, $l);
+    }
+
+    /**
+     * Fast helper function for block encryption
+     *
+     * @access private
+     * @param int $x0
+     * @param int $x1
+     * @param int[] $sbox0
+     * @param int[] $sbox1
+     * @param int[] $sbox2
+     * @param int[] $sbox3
+     * @param int[] $p
+     * @return int[]
+     */
+    function _encryptBlockHelperFast($x0, $x1, $sbox0, $sbox1, $sbox2, $sbox3, $p)
+    {
+        $x0 ^= $p[0];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14];
+        $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15];
+        $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16];
+
+        return array($x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF);
+    }
+
+    /**
+     * Slow helper function for block encryption
+     *
+     * @access private
+     * @param int $x0
+     * @param int $x1
+     * @param int[] $sbox0
+     * @param int[] $sbox1
+     * @param int[] $sbox2
+     * @param int[] $sbox3
+     * @param int[] $p
+     * @return int[]
+     */
+    function _encryptBlockHelperSlow($x0, $x1, $sbox0, $sbox1, $sbox2, $sbox3, $p)
+    {
+        $x0^= $p[0];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14];
+        $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15];
+        $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16];
+
+        return array($x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF);
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _decryptBlock($in)
+    {
+        $p = $this->bctx["p"];
+        $sb_0 = $this->bctx["sb"][0];
+        $sb_1 = $this->bctx["sb"][1];
+        $sb_2 = $this->bctx["sb"][2];
+        $sb_3 = $this->bctx["sb"][3];
+
+        $in = unpack("N*", $in);
+        $l = $in[1];
+        $r = $in[2];
+
+        for ($i = 17; $i > 2; $i-= 2) {
+            $l^= $p[$i];
+            $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
+                  $sb_2[$l >>  8 & 0xff]) +
+                  $sb_3[$l       & 0xff]);
+
+            $r^= $p[$i - 1];
+            $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
+                  $sb_2[$r >>  8 & 0xff]) +
+                  $sb_3[$r       & 0xff]);
+        }
+        return pack("N*", $r ^ $p[0], $l ^ $p[1]);
+    }
+
+    /**
+     * Setup the performance-optimized function for de/encrypt()
+     *
+     * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+     * @access private
+     */
+    function _setupInlineCrypt()
+    {
+        $lambda_functions =& self::_getLambdaFunctions();
+
+        // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+        // (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
+        // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_Blowfish, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
+
+        $safeint = $this->safe_intval_inline();
+
+        if (!isset($lambda_functions[$code_hash])) {
+            switch (true) {
+                case $gen_hi_opt_code:
+                    $p = $this->bctx['p'];
+                    $init_crypt = '
+                        static $sb_0, $sb_1, $sb_2, $sb_3;
+                        if (!$sb_0) {
+                            $sb_0 = $self->bctx["sb"][0];
+                            $sb_1 = $self->bctx["sb"][1];
+                            $sb_2 = $self->bctx["sb"][2];
+                            $sb_3 = $self->bctx["sb"][3];
+                        }
+                    ';
+                    break;
+                default:
+                    $p   = array();
+                    for ($i = 0; $i < 18; ++$i) {
+                        $p[] = '$p_' . $i;
+                    }
+                    $init_crypt = '
+                        list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
+                        list(' . implode(',', $p) . ') = $self->bctx["p"];
+
+                    ';
+            }
+
+            // Generating encrypt code:
+            $encrypt_block = '
+                $in = unpack("N*", $in);
+                $l = $in[1];
+                $r = $in[2];
+            ';
+            for ($i = 0; $i < 16; $i+= 2) {
+                $encrypt_block.= '
+                    $l^= ' . $p[$i] . ';
+                    $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
+                          $sb_2[$l >>  8 & 0xff]) +
+                          $sb_3[$l       & 0xff]') . ';
+
+                    $r^= ' . $p[$i + 1] . ';
+                    $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . '  ^
+                          $sb_2[$r >>  8 & 0xff]) +
+                          $sb_3[$r       & 0xff]') . ';
+                ';
+            }
+            $encrypt_block.= '
+                $in = pack("N*",
+                    $r ^ ' . $p[17] . ',
+                    $l ^ ' . $p[16] . '
+                );
+            ';
+
+            // Generating decrypt code:
+            $decrypt_block = '
+                $in = unpack("N*", $in);
+                $l = $in[1];
+                $r = $in[2];
+            ';
+
+            for ($i = 17; $i > 2; $i-= 2) {
+                $decrypt_block.= '
+                    $l^= ' . $p[$i] . ';
+                    $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
+                          $sb_2[$l >>  8 & 0xff]) +
+                          $sb_3[$l       & 0xff]') . ';
+
+                    $r^= ' . $p[$i - 1] . ';
+                    $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
+                          $sb_2[$r >>  8 & 0xff]) +
+                          $sb_3[$r       & 0xff]') . ';
+                ';
+            }
+
+            $decrypt_block.= '
+                $in = pack("N*",
+                    $r ^ ' . $p[0] . ',
+                    $l ^ ' . $p[1] . '
+                );
+            ';
+
+            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+                array(
+                   'init_crypt'    => $init_crypt,
+                   'init_encrypt'  => '',
+                   'init_decrypt'  => '',
+                   'encrypt_block' => $encrypt_block,
+                   'decrypt_block' => $decrypt_block
+                )
+            );
+        }
+        $this->inline_crypt = $lambda_functions[$code_hash];
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
new file mode 100644
index 00000000..d9244b51
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
@@ -0,0 +1,1449 @@
+<?php
+
+/**
+ * Pure-PHP implementation of DES.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ *  - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
+ *  - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
+ *  - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $des = new \phpseclib\Crypt\DES();
+ *
+ *    $des->setKey('abcdefgh');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $des->decrypt($des->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   DES
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of DES.
+ *
+ * @package DES
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class DES extends Base
+{
+    /**#@+
+     * @access private
+     * @see \phpseclib\Crypt\DES::_setupKey()
+     * @see \phpseclib\Crypt\DES::_processBlock()
+     */
+    /**
+     * Contains $keys[self::ENCRYPT]
+     */
+    const ENCRYPT = 0;
+    /**
+     * Contains $keys[self::DECRYPT]
+     */
+    const DECRYPT = 1;
+    /**#@-*/
+
+    /**
+     * Block Length of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::block_size
+     * @var int
+     * @access private
+     */
+    var $block_size = 8;
+
+    /**
+     * Key Length (in bytes)
+     *
+     * @see \phpseclib\Crypt\Base::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 8;
+
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'des';
+
+    /**
+     * The OpenSSL names of the cipher / modes
+     *
+     * @see \phpseclib\Crypt\Base::openssl_mode_names
+     * @var array
+     * @access private
+     */
+    var $openssl_mode_names = array(
+        self::MODE_ECB => 'des-ecb',
+        self::MODE_CBC => 'des-cbc',
+        self::MODE_CFB => 'des-cfb',
+        self::MODE_OFB => 'des-ofb'
+        // self::MODE_CTR is undefined for DES
+    );
+
+    /**
+     * Optimizing value while CFB-encrypting
+     *
+     * @see \phpseclib\Crypt\Base::cfb_init_len
+     * @var int
+     * @access private
+     */
+    var $cfb_init_len = 500;
+
+    /**
+     * Switch for DES/3DES encryption
+     *
+     * Used only if $engine == self::ENGINE_INTERNAL
+     *
+     * @see self::_setupKey()
+     * @see self::_processBlock()
+     * @var int
+     * @access private
+     */
+    var $des_rounds = 1;
+
+    /**
+     * max possible size of $key
+     *
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $key_length_max = 8;
+
+    /**
+     * The Key Schedule
+     *
+     * @see self::_setupKey()
+     * @var array
+     * @access private
+     */
+    var $keys;
+
+    /**
+     * Shuffle table.
+     *
+     * For each byte value index, the entry holds an 8-byte string
+     * with each byte containing all bits in the same state as the
+     * corresponding bit in the index value.
+     *
+     * @see self::_processBlock()
+     * @see self::_setupKey()
+     * @var array
+     * @access private
+     */
+    var $shuffle = array(
+        "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
+        "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
+        "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
+        "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
+        "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
+        "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
+        "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
+        "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
+        "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
+        "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
+        "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
+        "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
+        "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
+        "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
+        "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
+        "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
+        "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
+        "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
+        "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
+        "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
+        "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
+        "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
+        "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
+        "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
+        "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
+        "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
+        "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
+        "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
+        "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
+        "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
+        "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
+        "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
+        "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
+        "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
+        "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
+        "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
+        "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
+        "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
+        "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
+        "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
+        "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
+        "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
+        "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
+        "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
+        "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
+        "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
+        "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
+        "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
+        "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
+        "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
+        "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
+        "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
+        "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
+        "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
+        "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
+        "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
+        "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
+        "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
+        "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
+        "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
+        "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
+        "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
+        "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
+        "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+        "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
+        "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
+        "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
+        "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
+        "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
+        "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
+        "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
+        "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
+        "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
+        "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
+        "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
+        "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
+        "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
+        "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
+        "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
+        "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
+        "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
+        "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
+        "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
+        "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
+        "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
+        "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
+        "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
+        "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
+        "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
+        "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
+        "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
+        "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
+        "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
+        "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
+        "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
+        "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
+        "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
+        "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
+        "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
+        "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
+        "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
+        "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
+        "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
+        "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
+        "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
+        "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
+        "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
+        "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
+        "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
+        "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
+        "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
+        "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
+        "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
+        "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
+        "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
+        "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
+        "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
+        "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
+        "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
+        "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
+        "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
+        "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
+        "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
+        "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
+        "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
+        "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
+        "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
+        "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+    );
+
+    /**
+     * IP mapping helper table.
+     *
+     * Indexing this table with each source byte performs the initial bit permutation.
+     *
+     * @var array
+     * @access private
+     */
+    var $ipmap = array(
+        0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
+        0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
+        0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
+        0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
+        0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
+        0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
+        0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
+        0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
+        0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
+        0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
+        0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
+        0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
+        0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
+        0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
+        0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
+        0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
+        0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
+        0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
+        0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
+        0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
+        0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
+        0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+        0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
+        0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+        0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
+        0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
+        0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
+        0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
+        0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
+        0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
+        0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
+        0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
+    );
+
+    /**
+     * Inverse IP mapping helper table.
+     * Indexing this table with a byte value reverses the bit order.
+     *
+     * @var array
+     * @access private
+     */
+    var $invipmap = array(
+        0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+        0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+        0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+        0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+        0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+        0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+        0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+        0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+        0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+        0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+        0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+        0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+        0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+        0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+        0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+        0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+        0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+        0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+        0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+        0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+        0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+        0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+        0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+        0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+        0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+        0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+        0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+        0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+        0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+        0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+        0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+        0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+    );
+
+    /**
+     * Pre-permuted S-box1
+     *
+     * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
+     * P table: concatenation can then be replaced by exclusive ORs.
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox1 = array(
+        0x00808200, 0x00000000, 0x00008000, 0x00808202,
+        0x00808002, 0x00008202, 0x00000002, 0x00008000,
+        0x00000200, 0x00808200, 0x00808202, 0x00000200,
+        0x00800202, 0x00808002, 0x00800000, 0x00000002,
+        0x00000202, 0x00800200, 0x00800200, 0x00008200,
+        0x00008200, 0x00808000, 0x00808000, 0x00800202,
+        0x00008002, 0x00800002, 0x00800002, 0x00008002,
+        0x00000000, 0x00000202, 0x00008202, 0x00800000,
+        0x00008000, 0x00808202, 0x00000002, 0x00808000,
+        0x00808200, 0x00800000, 0x00800000, 0x00000200,
+        0x00808002, 0x00008000, 0x00008200, 0x00800002,
+        0x00000200, 0x00000002, 0x00800202, 0x00008202,
+        0x00808202, 0x00008002, 0x00808000, 0x00800202,
+        0x00800002, 0x00000202, 0x00008202, 0x00808200,
+        0x00000202, 0x00800200, 0x00800200, 0x00000000,
+        0x00008002, 0x00008200, 0x00000000, 0x00808002
+    );
+
+    /**
+     * Pre-permuted S-box2
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox2 = array(
+        0x40084010, 0x40004000, 0x00004000, 0x00084010,
+        0x00080000, 0x00000010, 0x40080010, 0x40004010,
+        0x40000010, 0x40084010, 0x40084000, 0x40000000,
+        0x40004000, 0x00080000, 0x00000010, 0x40080010,
+        0x00084000, 0x00080010, 0x40004010, 0x00000000,
+        0x40000000, 0x00004000, 0x00084010, 0x40080000,
+        0x00080010, 0x40000010, 0x00000000, 0x00084000,
+        0x00004010, 0x40084000, 0x40080000, 0x00004010,
+        0x00000000, 0x00084010, 0x40080010, 0x00080000,
+        0x40004010, 0x40080000, 0x40084000, 0x00004000,
+        0x40080000, 0x40004000, 0x00000010, 0x40084010,
+        0x00084010, 0x00000010, 0x00004000, 0x40000000,
+        0x00004010, 0x40084000, 0x00080000, 0x40000010,
+        0x00080010, 0x40004010, 0x40000010, 0x00080010,
+        0x00084000, 0x00000000, 0x40004000, 0x00004010,
+        0x40000000, 0x40080010, 0x40084010, 0x00084000
+    );
+
+    /**
+     * Pre-permuted S-box3
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox3 = array(
+        0x00000104, 0x04010100, 0x00000000, 0x04010004,
+        0x04000100, 0x00000000, 0x00010104, 0x04000100,
+        0x00010004, 0x04000004, 0x04000004, 0x00010000,
+        0x04010104, 0x00010004, 0x04010000, 0x00000104,
+        0x04000000, 0x00000004, 0x04010100, 0x00000100,
+        0x00010100, 0x04010000, 0x04010004, 0x00010104,
+        0x04000104, 0x00010100, 0x00010000, 0x04000104,
+        0x00000004, 0x04010104, 0x00000100, 0x04000000,
+        0x04010100, 0x04000000, 0x00010004, 0x00000104,
+        0x00010000, 0x04010100, 0x04000100, 0x00000000,
+        0x00000100, 0x00010004, 0x04010104, 0x04000100,
+        0x04000004, 0x00000100, 0x00000000, 0x04010004,
+        0x04000104, 0x00010000, 0x04000000, 0x04010104,
+        0x00000004, 0x00010104, 0x00010100, 0x04000004,
+        0x04010000, 0x04000104, 0x00000104, 0x04010000,
+        0x00010104, 0x00000004, 0x04010004, 0x00010100
+    );
+
+    /**
+     * Pre-permuted S-box4
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox4 = array(
+        0x80401000, 0x80001040, 0x80001040, 0x00000040,
+        0x00401040, 0x80400040, 0x80400000, 0x80001000,
+        0x00000000, 0x00401000, 0x00401000, 0x80401040,
+        0x80000040, 0x00000000, 0x00400040, 0x80400000,
+        0x80000000, 0x00001000, 0x00400000, 0x80401000,
+        0x00000040, 0x00400000, 0x80001000, 0x00001040,
+        0x80400040, 0x80000000, 0x00001040, 0x00400040,
+        0x00001000, 0x00401040, 0x80401040, 0x80000040,
+        0x00400040, 0x80400000, 0x00401000, 0x80401040,
+        0x80000040, 0x00000000, 0x00000000, 0x00401000,
+        0x00001040, 0x00400040, 0x80400040, 0x80000000,
+        0x80401000, 0x80001040, 0x80001040, 0x00000040,
+        0x80401040, 0x80000040, 0x80000000, 0x00001000,
+        0x80400000, 0x80001000, 0x00401040, 0x80400040,
+        0x80001000, 0x00001040, 0x00400000, 0x80401000,
+        0x00000040, 0x00400000, 0x00001000, 0x00401040
+    );
+
+    /**
+     * Pre-permuted S-box5
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox5 = array(
+        0x00000080, 0x01040080, 0x01040000, 0x21000080,
+        0x00040000, 0x00000080, 0x20000000, 0x01040000,
+        0x20040080, 0x00040000, 0x01000080, 0x20040080,
+        0x21000080, 0x21040000, 0x00040080, 0x20000000,
+        0x01000000, 0x20040000, 0x20040000, 0x00000000,
+        0x20000080, 0x21040080, 0x21040080, 0x01000080,
+        0x21040000, 0x20000080, 0x00000000, 0x21000000,
+        0x01040080, 0x01000000, 0x21000000, 0x00040080,
+        0x00040000, 0x21000080, 0x00000080, 0x01000000,
+        0x20000000, 0x01040000, 0x21000080, 0x20040080,
+        0x01000080, 0x20000000, 0x21040000, 0x01040080,
+        0x20040080, 0x00000080, 0x01000000, 0x21040000,
+        0x21040080, 0x00040080, 0x21000000, 0x21040080,
+        0x01040000, 0x00000000, 0x20040000, 0x21000000,
+        0x00040080, 0x01000080, 0x20000080, 0x00040000,
+        0x00000000, 0x20040000, 0x01040080, 0x20000080
+    );
+
+    /**
+     * Pre-permuted S-box6
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox6 = array(
+        0x10000008, 0x10200000, 0x00002000, 0x10202008,
+        0x10200000, 0x00000008, 0x10202008, 0x00200000,
+        0x10002000, 0x00202008, 0x00200000, 0x10000008,
+        0x00200008, 0x10002000, 0x10000000, 0x00002008,
+        0x00000000, 0x00200008, 0x10002008, 0x00002000,
+        0x00202000, 0x10002008, 0x00000008, 0x10200008,
+        0x10200008, 0x00000000, 0x00202008, 0x10202000,
+        0x00002008, 0x00202000, 0x10202000, 0x10000000,
+        0x10002000, 0x00000008, 0x10200008, 0x00202000,
+        0x10202008, 0x00200000, 0x00002008, 0x10000008,
+        0x00200000, 0x10002000, 0x10000000, 0x00002008,
+        0x10000008, 0x10202008, 0x00202000, 0x10200000,
+        0x00202008, 0x10202000, 0x00000000, 0x10200008,
+        0x00000008, 0x00002000, 0x10200000, 0x00202008,
+        0x00002000, 0x00200008, 0x10002008, 0x00000000,
+        0x10202000, 0x10000000, 0x00200008, 0x10002008
+    );
+
+    /**
+     * Pre-permuted S-box7
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox7 = array(
+        0x00100000, 0x02100001, 0x02000401, 0x00000000,
+        0x00000400, 0x02000401, 0x00100401, 0x02100400,
+        0x02100401, 0x00100000, 0x00000000, 0x02000001,
+        0x00000001, 0x02000000, 0x02100001, 0x00000401,
+        0x02000400, 0x00100401, 0x00100001, 0x02000400,
+        0x02000001, 0x02100000, 0x02100400, 0x00100001,
+        0x02100000, 0x00000400, 0x00000401, 0x02100401,
+        0x00100400, 0x00000001, 0x02000000, 0x00100400,
+        0x02000000, 0x00100400, 0x00100000, 0x02000401,
+        0x02000401, 0x02100001, 0x02100001, 0x00000001,
+        0x00100001, 0x02000000, 0x02000400, 0x00100000,
+        0x02100400, 0x00000401, 0x00100401, 0x02100400,
+        0x00000401, 0x02000001, 0x02100401, 0x02100000,
+        0x00100400, 0x00000000, 0x00000001, 0x02100401,
+        0x00000000, 0x00100401, 0x02100000, 0x00000400,
+        0x02000001, 0x02000400, 0x00000400, 0x00100001
+    );
+
+    /**
+     * Pre-permuted S-box8
+     *
+     * @var array
+     * @access private
+     */
+    var $sbox8 = array(
+        0x08000820, 0x00000800, 0x00020000, 0x08020820,
+        0x08000000, 0x08000820, 0x00000020, 0x08000000,
+        0x00020020, 0x08020000, 0x08020820, 0x00020800,
+        0x08020800, 0x00020820, 0x00000800, 0x00000020,
+        0x08020000, 0x08000020, 0x08000800, 0x00000820,
+        0x00020800, 0x00020020, 0x08020020, 0x08020800,
+        0x00000820, 0x00000000, 0x00000000, 0x08020020,
+        0x08000020, 0x08000800, 0x00020820, 0x00020000,
+        0x00020820, 0x00020000, 0x08020800, 0x00000800,
+        0x00000020, 0x08020020, 0x00000800, 0x00020820,
+        0x08000800, 0x00000020, 0x08000020, 0x08020000,
+        0x08020020, 0x08000000, 0x00020000, 0x08000820,
+        0x00000000, 0x08020820, 0x00020020, 0x08000020,
+        0x08020000, 0x08000800, 0x08000820, 0x00000000,
+        0x08020820, 0x00020800, 0x00020800, 0x00000820,
+        0x00000820, 0x00020020, 0x08000000, 0x08020800
+    );
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+     *
+     * @see \phpseclib\Crypt\Base::isValidEngine()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($this->key_length_max == 8) {
+            if ($engine == self::ENGINE_OPENSSL) {
+                // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+                // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+                // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+                if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+                    return false;
+                }
+                $this->cipher_name_openssl_ecb = 'des-ecb';
+                $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
+            }
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
+    /**
+     * Sets the key.
+     *
+     * Keys can be of any length.  DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
+     * only use the first eight, if $key has more then eight characters in it, and pad $key with the
+     * null byte if it is less then eight characters long.
+     *
+     * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
+     *
+     * If the key is not explicitly set, it'll be assumed to be all zero's.
+     *
+     * @see \phpseclib\Crypt\Base::setKey()
+     * @access public
+     * @param string $key
+     */
+    function setKey($key)
+    {
+        // We check/cut here only up to max length of the key.
+        // Key padding to the proper length will be done in _setupKey()
+        if (strlen($key) > $this->key_length_max) {
+            $key = substr($key, 0, $this->key_length_max);
+        }
+
+        // Sets the key
+        parent::setKey($key);
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @see \phpseclib\Crypt\Base::_encryptBlock()
+     * @see \phpseclib\Crypt\Base::encrypt()
+     * @see self::encrypt()
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _encryptBlock($in)
+    {
+        return $this->_processBlock($in, self::ENCRYPT);
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @see \phpseclib\Crypt\Base::_decryptBlock()
+     * @see \phpseclib\Crypt\Base::decrypt()
+     * @see self::decrypt()
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _decryptBlock($in)
+    {
+        return $this->_processBlock($in, self::DECRYPT);
+    }
+
+    /**
+     * Encrypts or decrypts a 64-bit block
+     *
+     * $mode should be either self::ENCRYPT or self::DECRYPT.  See
+     * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
+     * idea of what this function does.
+     *
+     * @see self::_encryptBlock()
+     * @see self::_decryptBlock()
+     * @access private
+     * @param string $block
+     * @param int $mode
+     * @return string
+     */
+    function _processBlock($block, $mode)
+    {
+        static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
+        if (!$sbox1) {
+            $sbox1 = array_map("intval", $this->sbox1);
+            $sbox2 = array_map("intval", $this->sbox2);
+            $sbox3 = array_map("intval", $this->sbox3);
+            $sbox4 = array_map("intval", $this->sbox4);
+            $sbox5 = array_map("intval", $this->sbox5);
+            $sbox6 = array_map("intval", $this->sbox6);
+            $sbox7 = array_map("intval", $this->sbox7);
+            $sbox8 = array_map("intval", $this->sbox8);
+            /* Merge $shuffle with $[inv]ipmap */
+            for ($i = 0; $i < 256; ++$i) {
+                $shuffleip[]    =  $this->shuffle[$this->ipmap[$i]];
+                $shuffleinvip[] =  $this->shuffle[$this->invipmap[$i]];
+            }
+        }
+
+        $keys  = $this->keys[$mode];
+        $ki    = -1;
+
+        // Do the initial IP permutation.
+        $t = unpack('Nl/Nr', $block);
+        list($l, $r) = array($t['l'], $t['r']);
+        $block = ($shuffleip[ $r        & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+                 ($shuffleip[($r >>  8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+                 ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+                 ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+                 ($shuffleip[ $l        & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+                 ($shuffleip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+                 ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+                 ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+
+        // Extract L0 and R0.
+        $t = unpack('Nl/Nr', $block);
+        list($l, $r) = array($t['l'], $t['r']);
+
+        for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
+            // Perform the 16 steps.
+            for ($i = 0; $i < 16; $i++) {
+                // start of "the Feistel (F) function" - see the following URL:
+                // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
+                // Merge key schedule.
+                $b1 = (($r >>  3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki];
+                $b2 = (($r >> 31) & 0x00000001) ^ ($r <<  1) ^ $keys[++$ki];
+
+                // S-box indexing.
+                $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
+                     $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
+                     $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^
+                     $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ $l;
+                // end of "the Feistel (F) function"
+
+                $l = $r;
+                $r = $t;
+            }
+
+            // Last step should not permute L & R.
+            $t = $l;
+            $l = $r;
+            $r = $t;
+        }
+
+        // Perform the inverse IP permutation.
+        return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+               ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+               ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+               ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+               ($shuffleinvip[($r >>  8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+               ($shuffleinvip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+               ($shuffleinvip[ $r        & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+               ($shuffleinvip[ $l        & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+    }
+
+    /**
+     * Creates the key schedule
+     *
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) {
+            // already expanded
+            return;
+        }
+        $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds);
+
+        static $shifts = array( // number of key bits shifted per round
+            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+        );
+
+        static $pc1map = array(
+            0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
+            0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
+            0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
+            0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
+            0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
+            0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
+            0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
+            0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
+            0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
+            0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
+            0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
+            0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
+            0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
+            0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
+            0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
+            0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
+            0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
+            0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
+            0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
+            0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
+            0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
+            0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
+            0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
+            0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
+            0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
+            0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
+            0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
+            0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
+            0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
+            0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
+            0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
+            0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
+        );
+
+        // Mapping tables for the PC-2 transformation.
+        static $pc2mapc1 = array(
+            0x00000000, 0x00000400, 0x00200000, 0x00200400,
+            0x00000001, 0x00000401, 0x00200001, 0x00200401,
+            0x02000000, 0x02000400, 0x02200000, 0x02200400,
+            0x02000001, 0x02000401, 0x02200001, 0x02200401
+        );
+        static $pc2mapc2 = array(
+            0x00000000, 0x00000800, 0x08000000, 0x08000800,
+            0x00010000, 0x00010800, 0x08010000, 0x08010800,
+            0x00000000, 0x00000800, 0x08000000, 0x08000800,
+            0x00010000, 0x00010800, 0x08010000, 0x08010800,
+            0x00000100, 0x00000900, 0x08000100, 0x08000900,
+            0x00010100, 0x00010900, 0x08010100, 0x08010900,
+            0x00000100, 0x00000900, 0x08000100, 0x08000900,
+            0x00010100, 0x00010900, 0x08010100, 0x08010900,
+            0x00000010, 0x00000810, 0x08000010, 0x08000810,
+            0x00010010, 0x00010810, 0x08010010, 0x08010810,
+            0x00000010, 0x00000810, 0x08000010, 0x08000810,
+            0x00010010, 0x00010810, 0x08010010, 0x08010810,
+            0x00000110, 0x00000910, 0x08000110, 0x08000910,
+            0x00010110, 0x00010910, 0x08010110, 0x08010910,
+            0x00000110, 0x00000910, 0x08000110, 0x08000910,
+            0x00010110, 0x00010910, 0x08010110, 0x08010910,
+            0x00040000, 0x00040800, 0x08040000, 0x08040800,
+            0x00050000, 0x00050800, 0x08050000, 0x08050800,
+            0x00040000, 0x00040800, 0x08040000, 0x08040800,
+            0x00050000, 0x00050800, 0x08050000, 0x08050800,
+            0x00040100, 0x00040900, 0x08040100, 0x08040900,
+            0x00050100, 0x00050900, 0x08050100, 0x08050900,
+            0x00040100, 0x00040900, 0x08040100, 0x08040900,
+            0x00050100, 0x00050900, 0x08050100, 0x08050900,
+            0x00040010, 0x00040810, 0x08040010, 0x08040810,
+            0x00050010, 0x00050810, 0x08050010, 0x08050810,
+            0x00040010, 0x00040810, 0x08040010, 0x08040810,
+            0x00050010, 0x00050810, 0x08050010, 0x08050810,
+            0x00040110, 0x00040910, 0x08040110, 0x08040910,
+            0x00050110, 0x00050910, 0x08050110, 0x08050910,
+            0x00040110, 0x00040910, 0x08040110, 0x08040910,
+            0x00050110, 0x00050910, 0x08050110, 0x08050910,
+            0x01000000, 0x01000800, 0x09000000, 0x09000800,
+            0x01010000, 0x01010800, 0x09010000, 0x09010800,
+            0x01000000, 0x01000800, 0x09000000, 0x09000800,
+            0x01010000, 0x01010800, 0x09010000, 0x09010800,
+            0x01000100, 0x01000900, 0x09000100, 0x09000900,
+            0x01010100, 0x01010900, 0x09010100, 0x09010900,
+            0x01000100, 0x01000900, 0x09000100, 0x09000900,
+            0x01010100, 0x01010900, 0x09010100, 0x09010900,
+            0x01000010, 0x01000810, 0x09000010, 0x09000810,
+            0x01010010, 0x01010810, 0x09010010, 0x09010810,
+            0x01000010, 0x01000810, 0x09000010, 0x09000810,
+            0x01010010, 0x01010810, 0x09010010, 0x09010810,
+            0x01000110, 0x01000910, 0x09000110, 0x09000910,
+            0x01010110, 0x01010910, 0x09010110, 0x09010910,
+            0x01000110, 0x01000910, 0x09000110, 0x09000910,
+            0x01010110, 0x01010910, 0x09010110, 0x09010910,
+            0x01040000, 0x01040800, 0x09040000, 0x09040800,
+            0x01050000, 0x01050800, 0x09050000, 0x09050800,
+            0x01040000, 0x01040800, 0x09040000, 0x09040800,
+            0x01050000, 0x01050800, 0x09050000, 0x09050800,
+            0x01040100, 0x01040900, 0x09040100, 0x09040900,
+            0x01050100, 0x01050900, 0x09050100, 0x09050900,
+            0x01040100, 0x01040900, 0x09040100, 0x09040900,
+            0x01050100, 0x01050900, 0x09050100, 0x09050900,
+            0x01040010, 0x01040810, 0x09040010, 0x09040810,
+            0x01050010, 0x01050810, 0x09050010, 0x09050810,
+            0x01040010, 0x01040810, 0x09040010, 0x09040810,
+            0x01050010, 0x01050810, 0x09050010, 0x09050810,
+            0x01040110, 0x01040910, 0x09040110, 0x09040910,
+            0x01050110, 0x01050910, 0x09050110, 0x09050910,
+            0x01040110, 0x01040910, 0x09040110, 0x09040910,
+            0x01050110, 0x01050910, 0x09050110, 0x09050910
+        );
+        static $pc2mapc3 = array(
+            0x00000000, 0x00000004, 0x00001000, 0x00001004,
+            0x00000000, 0x00000004, 0x00001000, 0x00001004,
+            0x10000000, 0x10000004, 0x10001000, 0x10001004,
+            0x10000000, 0x10000004, 0x10001000, 0x10001004,
+            0x00000020, 0x00000024, 0x00001020, 0x00001024,
+            0x00000020, 0x00000024, 0x00001020, 0x00001024,
+            0x10000020, 0x10000024, 0x10001020, 0x10001024,
+            0x10000020, 0x10000024, 0x10001020, 0x10001024,
+            0x00080000, 0x00080004, 0x00081000, 0x00081004,
+            0x00080000, 0x00080004, 0x00081000, 0x00081004,
+            0x10080000, 0x10080004, 0x10081000, 0x10081004,
+            0x10080000, 0x10080004, 0x10081000, 0x10081004,
+            0x00080020, 0x00080024, 0x00081020, 0x00081024,
+            0x00080020, 0x00080024, 0x00081020, 0x00081024,
+            0x10080020, 0x10080024, 0x10081020, 0x10081024,
+            0x10080020, 0x10080024, 0x10081020, 0x10081024,
+            0x20000000, 0x20000004, 0x20001000, 0x20001004,
+            0x20000000, 0x20000004, 0x20001000, 0x20001004,
+            0x30000000, 0x30000004, 0x30001000, 0x30001004,
+            0x30000000, 0x30000004, 0x30001000, 0x30001004,
+            0x20000020, 0x20000024, 0x20001020, 0x20001024,
+            0x20000020, 0x20000024, 0x20001020, 0x20001024,
+            0x30000020, 0x30000024, 0x30001020, 0x30001024,
+            0x30000020, 0x30000024, 0x30001020, 0x30001024,
+            0x20080000, 0x20080004, 0x20081000, 0x20081004,
+            0x20080000, 0x20080004, 0x20081000, 0x20081004,
+            0x30080000, 0x30080004, 0x30081000, 0x30081004,
+            0x30080000, 0x30080004, 0x30081000, 0x30081004,
+            0x20080020, 0x20080024, 0x20081020, 0x20081024,
+            0x20080020, 0x20080024, 0x20081020, 0x20081024,
+            0x30080020, 0x30080024, 0x30081020, 0x30081024,
+            0x30080020, 0x30080024, 0x30081020, 0x30081024,
+            0x00000002, 0x00000006, 0x00001002, 0x00001006,
+            0x00000002, 0x00000006, 0x00001002, 0x00001006,
+            0x10000002, 0x10000006, 0x10001002, 0x10001006,
+            0x10000002, 0x10000006, 0x10001002, 0x10001006,
+            0x00000022, 0x00000026, 0x00001022, 0x00001026,
+            0x00000022, 0x00000026, 0x00001022, 0x00001026,
+            0x10000022, 0x10000026, 0x10001022, 0x10001026,
+            0x10000022, 0x10000026, 0x10001022, 0x10001026,
+            0x00080002, 0x00080006, 0x00081002, 0x00081006,
+            0x00080002, 0x00080006, 0x00081002, 0x00081006,
+            0x10080002, 0x10080006, 0x10081002, 0x10081006,
+            0x10080002, 0x10080006, 0x10081002, 0x10081006,
+            0x00080022, 0x00080026, 0x00081022, 0x00081026,
+            0x00080022, 0x00080026, 0x00081022, 0x00081026,
+            0x10080022, 0x10080026, 0x10081022, 0x10081026,
+            0x10080022, 0x10080026, 0x10081022, 0x10081026,
+            0x20000002, 0x20000006, 0x20001002, 0x20001006,
+            0x20000002, 0x20000006, 0x20001002, 0x20001006,
+            0x30000002, 0x30000006, 0x30001002, 0x30001006,
+            0x30000002, 0x30000006, 0x30001002, 0x30001006,
+            0x20000022, 0x20000026, 0x20001022, 0x20001026,
+            0x20000022, 0x20000026, 0x20001022, 0x20001026,
+            0x30000022, 0x30000026, 0x30001022, 0x30001026,
+            0x30000022, 0x30000026, 0x30001022, 0x30001026,
+            0x20080002, 0x20080006, 0x20081002, 0x20081006,
+            0x20080002, 0x20080006, 0x20081002, 0x20081006,
+            0x30080002, 0x30080006, 0x30081002, 0x30081006,
+            0x30080002, 0x30080006, 0x30081002, 0x30081006,
+            0x20080022, 0x20080026, 0x20081022, 0x20081026,
+            0x20080022, 0x20080026, 0x20081022, 0x20081026,
+            0x30080022, 0x30080026, 0x30081022, 0x30081026,
+            0x30080022, 0x30080026, 0x30081022, 0x30081026
+        );
+        static $pc2mapc4 = array(
+            0x00000000, 0x00100000, 0x00000008, 0x00100008,
+            0x00000200, 0x00100200, 0x00000208, 0x00100208,
+            0x00000000, 0x00100000, 0x00000008, 0x00100008,
+            0x00000200, 0x00100200, 0x00000208, 0x00100208,
+            0x04000000, 0x04100000, 0x04000008, 0x04100008,
+            0x04000200, 0x04100200, 0x04000208, 0x04100208,
+            0x04000000, 0x04100000, 0x04000008, 0x04100008,
+            0x04000200, 0x04100200, 0x04000208, 0x04100208,
+            0x00002000, 0x00102000, 0x00002008, 0x00102008,
+            0x00002200, 0x00102200, 0x00002208, 0x00102208,
+            0x00002000, 0x00102000, 0x00002008, 0x00102008,
+            0x00002200, 0x00102200, 0x00002208, 0x00102208,
+            0x04002000, 0x04102000, 0x04002008, 0x04102008,
+            0x04002200, 0x04102200, 0x04002208, 0x04102208,
+            0x04002000, 0x04102000, 0x04002008, 0x04102008,
+            0x04002200, 0x04102200, 0x04002208, 0x04102208,
+            0x00000000, 0x00100000, 0x00000008, 0x00100008,
+            0x00000200, 0x00100200, 0x00000208, 0x00100208,
+            0x00000000, 0x00100000, 0x00000008, 0x00100008,
+            0x00000200, 0x00100200, 0x00000208, 0x00100208,
+            0x04000000, 0x04100000, 0x04000008, 0x04100008,
+            0x04000200, 0x04100200, 0x04000208, 0x04100208,
+            0x04000000, 0x04100000, 0x04000008, 0x04100008,
+            0x04000200, 0x04100200, 0x04000208, 0x04100208,
+            0x00002000, 0x00102000, 0x00002008, 0x00102008,
+            0x00002200, 0x00102200, 0x00002208, 0x00102208,
+            0x00002000, 0x00102000, 0x00002008, 0x00102008,
+            0x00002200, 0x00102200, 0x00002208, 0x00102208,
+            0x04002000, 0x04102000, 0x04002008, 0x04102008,
+            0x04002200, 0x04102200, 0x04002208, 0x04102208,
+            0x04002000, 0x04102000, 0x04002008, 0x04102008,
+            0x04002200, 0x04102200, 0x04002208, 0x04102208,
+            0x00020000, 0x00120000, 0x00020008, 0x00120008,
+            0x00020200, 0x00120200, 0x00020208, 0x00120208,
+            0x00020000, 0x00120000, 0x00020008, 0x00120008,
+            0x00020200, 0x00120200, 0x00020208, 0x00120208,
+            0x04020000, 0x04120000, 0x04020008, 0x04120008,
+            0x04020200, 0x04120200, 0x04020208, 0x04120208,
+            0x04020000, 0x04120000, 0x04020008, 0x04120008,
+            0x04020200, 0x04120200, 0x04020208, 0x04120208,
+            0x00022000, 0x00122000, 0x00022008, 0x00122008,
+            0x00022200, 0x00122200, 0x00022208, 0x00122208,
+            0x00022000, 0x00122000, 0x00022008, 0x00122008,
+            0x00022200, 0x00122200, 0x00022208, 0x00122208,
+            0x04022000, 0x04122000, 0x04022008, 0x04122008,
+            0x04022200, 0x04122200, 0x04022208, 0x04122208,
+            0x04022000, 0x04122000, 0x04022008, 0x04122008,
+            0x04022200, 0x04122200, 0x04022208, 0x04122208,
+            0x00020000, 0x00120000, 0x00020008, 0x00120008,
+            0x00020200, 0x00120200, 0x00020208, 0x00120208,
+            0x00020000, 0x00120000, 0x00020008, 0x00120008,
+            0x00020200, 0x00120200, 0x00020208, 0x00120208,
+            0x04020000, 0x04120000, 0x04020008, 0x04120008,
+            0x04020200, 0x04120200, 0x04020208, 0x04120208,
+            0x04020000, 0x04120000, 0x04020008, 0x04120008,
+            0x04020200, 0x04120200, 0x04020208, 0x04120208,
+            0x00022000, 0x00122000, 0x00022008, 0x00122008,
+            0x00022200, 0x00122200, 0x00022208, 0x00122208,
+            0x00022000, 0x00122000, 0x00022008, 0x00122008,
+            0x00022200, 0x00122200, 0x00022208, 0x00122208,
+            0x04022000, 0x04122000, 0x04022008, 0x04122008,
+            0x04022200, 0x04122200, 0x04022208, 0x04122208,
+            0x04022000, 0x04122000, 0x04022008, 0x04122008,
+            0x04022200, 0x04122200, 0x04022208, 0x04122208
+        );
+        static $pc2mapd1 = array(
+            0x00000000, 0x00000001, 0x08000000, 0x08000001,
+            0x00200000, 0x00200001, 0x08200000, 0x08200001,
+            0x00000002, 0x00000003, 0x08000002, 0x08000003,
+            0x00200002, 0x00200003, 0x08200002, 0x08200003
+        );
+        static $pc2mapd2 = array(
+            0x00000000, 0x00100000, 0x00000800, 0x00100800,
+            0x00000000, 0x00100000, 0x00000800, 0x00100800,
+            0x04000000, 0x04100000, 0x04000800, 0x04100800,
+            0x04000000, 0x04100000, 0x04000800, 0x04100800,
+            0x00000004, 0x00100004, 0x00000804, 0x00100804,
+            0x00000004, 0x00100004, 0x00000804, 0x00100804,
+            0x04000004, 0x04100004, 0x04000804, 0x04100804,
+            0x04000004, 0x04100004, 0x04000804, 0x04100804,
+            0x00000000, 0x00100000, 0x00000800, 0x00100800,
+            0x00000000, 0x00100000, 0x00000800, 0x00100800,
+            0x04000000, 0x04100000, 0x04000800, 0x04100800,
+            0x04000000, 0x04100000, 0x04000800, 0x04100800,
+            0x00000004, 0x00100004, 0x00000804, 0x00100804,
+            0x00000004, 0x00100004, 0x00000804, 0x00100804,
+            0x04000004, 0x04100004, 0x04000804, 0x04100804,
+            0x04000004, 0x04100004, 0x04000804, 0x04100804,
+            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+            0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+            0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+            0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+            0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+            0x00020000, 0x00120000, 0x00020800, 0x00120800,
+            0x00020000, 0x00120000, 0x00020800, 0x00120800,
+            0x04020000, 0x04120000, 0x04020800, 0x04120800,
+            0x04020000, 0x04120000, 0x04020800, 0x04120800,
+            0x00020004, 0x00120004, 0x00020804, 0x00120804,
+            0x00020004, 0x00120004, 0x00020804, 0x00120804,
+            0x04020004, 0x04120004, 0x04020804, 0x04120804,
+            0x04020004, 0x04120004, 0x04020804, 0x04120804,
+            0x00020000, 0x00120000, 0x00020800, 0x00120800,
+            0x00020000, 0x00120000, 0x00020800, 0x00120800,
+            0x04020000, 0x04120000, 0x04020800, 0x04120800,
+            0x04020000, 0x04120000, 0x04020800, 0x04120800,
+            0x00020004, 0x00120004, 0x00020804, 0x00120804,
+            0x00020004, 0x00120004, 0x00020804, 0x00120804,
+            0x04020004, 0x04120004, 0x04020804, 0x04120804,
+            0x04020004, 0x04120004, 0x04020804, 0x04120804,
+            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+            0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
+            0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
+            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+            0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+            0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+            0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+            0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
+            0x04020204, 0x04120204, 0x04020A04, 0x04120A04
+        );
+        static $pc2mapd3 = array(
+            0x00000000, 0x00010000, 0x02000000, 0x02010000,
+            0x00000020, 0x00010020, 0x02000020, 0x02010020,
+            0x00040000, 0x00050000, 0x02040000, 0x02050000,
+            0x00040020, 0x00050020, 0x02040020, 0x02050020,
+            0x00002000, 0x00012000, 0x02002000, 0x02012000,
+            0x00002020, 0x00012020, 0x02002020, 0x02012020,
+            0x00042000, 0x00052000, 0x02042000, 0x02052000,
+            0x00042020, 0x00052020, 0x02042020, 0x02052020,
+            0x00000000, 0x00010000, 0x02000000, 0x02010000,
+            0x00000020, 0x00010020, 0x02000020, 0x02010020,
+            0x00040000, 0x00050000, 0x02040000, 0x02050000,
+            0x00040020, 0x00050020, 0x02040020, 0x02050020,
+            0x00002000, 0x00012000, 0x02002000, 0x02012000,
+            0x00002020, 0x00012020, 0x02002020, 0x02012020,
+            0x00042000, 0x00052000, 0x02042000, 0x02052000,
+            0x00042020, 0x00052020, 0x02042020, 0x02052020,
+            0x00000010, 0x00010010, 0x02000010, 0x02010010,
+            0x00000030, 0x00010030, 0x02000030, 0x02010030,
+            0x00040010, 0x00050010, 0x02040010, 0x02050010,
+            0x00040030, 0x00050030, 0x02040030, 0x02050030,
+            0x00002010, 0x00012010, 0x02002010, 0x02012010,
+            0x00002030, 0x00012030, 0x02002030, 0x02012030,
+            0x00042010, 0x00052010, 0x02042010, 0x02052010,
+            0x00042030, 0x00052030, 0x02042030, 0x02052030,
+            0x00000010, 0x00010010, 0x02000010, 0x02010010,
+            0x00000030, 0x00010030, 0x02000030, 0x02010030,
+            0x00040010, 0x00050010, 0x02040010, 0x02050010,
+            0x00040030, 0x00050030, 0x02040030, 0x02050030,
+            0x00002010, 0x00012010, 0x02002010, 0x02012010,
+            0x00002030, 0x00012030, 0x02002030, 0x02012030,
+            0x00042010, 0x00052010, 0x02042010, 0x02052010,
+            0x00042030, 0x00052030, 0x02042030, 0x02052030,
+            0x20000000, 0x20010000, 0x22000000, 0x22010000,
+            0x20000020, 0x20010020, 0x22000020, 0x22010020,
+            0x20040000, 0x20050000, 0x22040000, 0x22050000,
+            0x20040020, 0x20050020, 0x22040020, 0x22050020,
+            0x20002000, 0x20012000, 0x22002000, 0x22012000,
+            0x20002020, 0x20012020, 0x22002020, 0x22012020,
+            0x20042000, 0x20052000, 0x22042000, 0x22052000,
+            0x20042020, 0x20052020, 0x22042020, 0x22052020,
+            0x20000000, 0x20010000, 0x22000000, 0x22010000,
+            0x20000020, 0x20010020, 0x22000020, 0x22010020,
+            0x20040000, 0x20050000, 0x22040000, 0x22050000,
+            0x20040020, 0x20050020, 0x22040020, 0x22050020,
+            0x20002000, 0x20012000, 0x22002000, 0x22012000,
+            0x20002020, 0x20012020, 0x22002020, 0x22012020,
+            0x20042000, 0x20052000, 0x22042000, 0x22052000,
+            0x20042020, 0x20052020, 0x22042020, 0x22052020,
+            0x20000010, 0x20010010, 0x22000010, 0x22010010,
+            0x20000030, 0x20010030, 0x22000030, 0x22010030,
+            0x20040010, 0x20050010, 0x22040010, 0x22050010,
+            0x20040030, 0x20050030, 0x22040030, 0x22050030,
+            0x20002010, 0x20012010, 0x22002010, 0x22012010,
+            0x20002030, 0x20012030, 0x22002030, 0x22012030,
+            0x20042010, 0x20052010, 0x22042010, 0x22052010,
+            0x20042030, 0x20052030, 0x22042030, 0x22052030,
+            0x20000010, 0x20010010, 0x22000010, 0x22010010,
+            0x20000030, 0x20010030, 0x22000030, 0x22010030,
+            0x20040010, 0x20050010, 0x22040010, 0x22050010,
+            0x20040030, 0x20050030, 0x22040030, 0x22050030,
+            0x20002010, 0x20012010, 0x22002010, 0x22012010,
+            0x20002030, 0x20012030, 0x22002030, 0x22012030,
+            0x20042010, 0x20052010, 0x22042010, 0x22052010,
+            0x20042030, 0x20052030, 0x22042030, 0x22052030
+        );
+        static $pc2mapd4 = array(
+            0x00000000, 0x00000400, 0x01000000, 0x01000400,
+            0x00000000, 0x00000400, 0x01000000, 0x01000400,
+            0x00000100, 0x00000500, 0x01000100, 0x01000500,
+            0x00000100, 0x00000500, 0x01000100, 0x01000500,
+            0x10000000, 0x10000400, 0x11000000, 0x11000400,
+            0x10000000, 0x10000400, 0x11000000, 0x11000400,
+            0x10000100, 0x10000500, 0x11000100, 0x11000500,
+            0x10000100, 0x10000500, 0x11000100, 0x11000500,
+            0x00080000, 0x00080400, 0x01080000, 0x01080400,
+            0x00080000, 0x00080400, 0x01080000, 0x01080400,
+            0x00080100, 0x00080500, 0x01080100, 0x01080500,
+            0x00080100, 0x00080500, 0x01080100, 0x01080500,
+            0x10080000, 0x10080400, 0x11080000, 0x11080400,
+            0x10080000, 0x10080400, 0x11080000, 0x11080400,
+            0x10080100, 0x10080500, 0x11080100, 0x11080500,
+            0x10080100, 0x10080500, 0x11080100, 0x11080500,
+            0x00000008, 0x00000408, 0x01000008, 0x01000408,
+            0x00000008, 0x00000408, 0x01000008, 0x01000408,
+            0x00000108, 0x00000508, 0x01000108, 0x01000508,
+            0x00000108, 0x00000508, 0x01000108, 0x01000508,
+            0x10000008, 0x10000408, 0x11000008, 0x11000408,
+            0x10000008, 0x10000408, 0x11000008, 0x11000408,
+            0x10000108, 0x10000508, 0x11000108, 0x11000508,
+            0x10000108, 0x10000508, 0x11000108, 0x11000508,
+            0x00080008, 0x00080408, 0x01080008, 0x01080408,
+            0x00080008, 0x00080408, 0x01080008, 0x01080408,
+            0x00080108, 0x00080508, 0x01080108, 0x01080508,
+            0x00080108, 0x00080508, 0x01080108, 0x01080508,
+            0x10080008, 0x10080408, 0x11080008, 0x11080408,
+            0x10080008, 0x10080408, 0x11080008, 0x11080408,
+            0x10080108, 0x10080508, 0x11080108, 0x11080508,
+            0x10080108, 0x10080508, 0x11080108, 0x11080508,
+            0x00001000, 0x00001400, 0x01001000, 0x01001400,
+            0x00001000, 0x00001400, 0x01001000, 0x01001400,
+            0x00001100, 0x00001500, 0x01001100, 0x01001500,
+            0x00001100, 0x00001500, 0x01001100, 0x01001500,
+            0x10001000, 0x10001400, 0x11001000, 0x11001400,
+            0x10001000, 0x10001400, 0x11001000, 0x11001400,
+            0x10001100, 0x10001500, 0x11001100, 0x11001500,
+            0x10001100, 0x10001500, 0x11001100, 0x11001500,
+            0x00081000, 0x00081400, 0x01081000, 0x01081400,
+            0x00081000, 0x00081400, 0x01081000, 0x01081400,
+            0x00081100, 0x00081500, 0x01081100, 0x01081500,
+            0x00081100, 0x00081500, 0x01081100, 0x01081500,
+            0x10081000, 0x10081400, 0x11081000, 0x11081400,
+            0x10081000, 0x10081400, 0x11081000, 0x11081400,
+            0x10081100, 0x10081500, 0x11081100, 0x11081500,
+            0x10081100, 0x10081500, 0x11081100, 0x11081500,
+            0x00001008, 0x00001408, 0x01001008, 0x01001408,
+            0x00001008, 0x00001408, 0x01001008, 0x01001408,
+            0x00001108, 0x00001508, 0x01001108, 0x01001508,
+            0x00001108, 0x00001508, 0x01001108, 0x01001508,
+            0x10001008, 0x10001408, 0x11001008, 0x11001408,
+            0x10001008, 0x10001408, 0x11001008, 0x11001408,
+            0x10001108, 0x10001508, 0x11001108, 0x11001508,
+            0x10001108, 0x10001508, 0x11001108, 0x11001508,
+            0x00081008, 0x00081408, 0x01081008, 0x01081408,
+            0x00081008, 0x00081408, 0x01081008, 0x01081408,
+            0x00081108, 0x00081508, 0x01081108, 0x01081508,
+            0x00081108, 0x00081508, 0x01081108, 0x01081508,
+            0x10081008, 0x10081408, 0x11081008, 0x11081408,
+            0x10081008, 0x10081408, 0x11081008, 0x11081408,
+            0x10081108, 0x10081508, 0x11081108, 0x11081508,
+            0x10081108, 0x10081508, 0x11081108, 0x11081508
+        );
+
+        $keys = array();
+        for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
+            // pad the key and remove extra characters as appropriate.
+            $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0");
+
+            // Perform the PC/1 transformation and compute C and D.
+            $t = unpack('Nl/Nr', $key);
+            list($l, $r) = array($t['l'], $t['r']);
+            $key = ($this->shuffle[$pc1map[ $r        & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
+                   ($this->shuffle[$pc1map[($r >>  8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
+                   ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
+                   ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
+                   ($this->shuffle[$pc1map[ $l        & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
+                   ($this->shuffle[$pc1map[($l >>  8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
+                   ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
+                   ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
+            $key = unpack('Nc/Nd', $key);
+            $c = ( $key['c'] >> 4) & 0x0FFFFFFF;
+            $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
+
+            $keys[$des_round] = array(
+                self::ENCRYPT => array(),
+                self::DECRYPT => array_fill(0, 32, 0)
+            );
+            for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
+                $c <<= $shifts[$i];
+                $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
+                $d <<= $shifts[$i];
+                $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
+
+                // Perform the PC-2 transformation.
+                $cp = $pc2mapc1[ $c >> 24        ] | $pc2mapc2[($c >> 16) & 0xFF] |
+                      $pc2mapc3[($c >>  8) & 0xFF] | $pc2mapc4[ $c        & 0xFF];
+                $dp = $pc2mapd1[ $d >> 24        ] | $pc2mapd2[($d >> 16) & 0xFF] |
+                      $pc2mapd3[($d >>  8) & 0xFF] | $pc2mapd4[ $d        & 0xFF];
+
+                // Reorder: odd bytes/even bytes. Push the result in key schedule.
+                $val1 = ( $cp        & intval(0xFF000000)) | (($cp <<  8) & 0x00FF0000) |
+                        (($dp >> 16) & 0x0000FF00) | (($dp >>  8) & 0x000000FF);
+                $val2 = (($cp <<  8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) |
+                        (($dp >>  8) & 0x0000FF00) | ( $dp        & 0x000000FF);
+                $keys[$des_round][self::ENCRYPT][       ] = $val1;
+                $keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
+                $keys[$des_round][self::ENCRYPT][       ] = $val2;
+                $keys[$des_round][self::DECRYPT][$ki    ] = $val2;
+            }
+        }
+
+        switch ($this->des_rounds) {
+            case 3: // 3DES keys
+                $this->keys = array(
+                    self::ENCRYPT => array_merge(
+                        $keys[0][self::ENCRYPT],
+                        $keys[1][self::DECRYPT],
+                        $keys[2][self::ENCRYPT]
+                    ),
+                    self::DECRYPT => array_merge(
+                        $keys[2][self::DECRYPT],
+                        $keys[1][self::ENCRYPT],
+                        $keys[0][self::DECRYPT]
+                    )
+                );
+                break;
+            // case 1: // DES keys
+            default:
+                $this->keys = array(
+                    self::ENCRYPT => $keys[0][self::ENCRYPT],
+                    self::DECRYPT => $keys[0][self::DECRYPT]
+                );
+        }
+    }
+
+    /**
+     * Setup the performance-optimized function for de/encrypt()
+     *
+     * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+     * @access private
+     */
+    function _setupInlineCrypt()
+    {
+        $lambda_functions =& self::_getLambdaFunctions();
+
+        // Engine configuration for:
+        // -  DES ($des_rounds == 1) or
+        // - 3DES ($des_rounds == 3)
+        $des_rounds = $this->des_rounds;
+
+        // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+        // (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
+        // (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
+        // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
+        $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
+
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            // For hi-optimized code, we create for each combination of
+            // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
+            // After max 10 hi-optimized functions, we create generic
+            // (still very fast.. but not ultra) functions for each $mode/$des_rounds
+            // Currently 2 * 5 generic functions will be then max. possible.
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
+
+        // Is there a re-usable $lambda_functions in there? If not, we have to create it.
+        if (!isset($lambda_functions[$code_hash])) {
+            // Init code for both, encrypt and decrypt.
+            $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
+                if (!$sbox1) {
+                    $sbox1 = array_map("intval", $self->sbox1);
+                    $sbox2 = array_map("intval", $self->sbox2);
+                    $sbox3 = array_map("intval", $self->sbox3);
+                    $sbox4 = array_map("intval", $self->sbox4);
+                    $sbox5 = array_map("intval", $self->sbox5);
+                    $sbox6 = array_map("intval", $self->sbox6);
+                    $sbox7 = array_map("intval", $self->sbox7);
+                    $sbox8 = array_map("intval", $self->sbox8);'
+                    /* Merge $shuffle with $[inv]ipmap */ . '
+                    for ($i = 0; $i < 256; ++$i) {
+                        $shuffleip[]    =  $self->shuffle[$self->ipmap[$i]];
+                        $shuffleinvip[] =  $self->shuffle[$self->invipmap[$i]];
+                    }
+                }
+            ';
+
+            switch (true) {
+                case $gen_hi_opt_code:
+                    // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
+                    // No futher initialisation of the $keys schedule is necessary.
+                    // That is the extra performance boost.
+                    $k = array(
+                        self::ENCRYPT => $this->keys[self::ENCRYPT],
+                        self::DECRYPT => $this->keys[self::DECRYPT]
+                    );
+                    $init_encrypt = '';
+                    $init_decrypt = '';
+                    break;
+                default:
+                    // In generic optimized code mode, we have to use, as the best compromise [currently],
+                    // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
+                    $k = array(
+                        self::ENCRYPT => array(),
+                        self::DECRYPT => array()
+                    );
+                    for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) {
+                        $k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
+                        $k[self::DECRYPT][$i] = '$kd[' . $i . ']';
+                    }
+                    $init_encrypt = '$ke = $self->keys[$self::ENCRYPT];';
+                    $init_decrypt = '$kd = $self->keys[$self::DECRYPT];';
+                    break;
+            }
+
+            // Creating code for en- and decryption.
+            $crypt_block = array();
+            foreach (array(self::ENCRYPT, self::DECRYPT) as $c) {
+                /* Do the initial IP permutation. */
+                $crypt_block[$c] = '
+                    $in = unpack("N*", $in);
+                    $l  = $in[1];
+                    $r  = $in[2];
+                    $in = unpack("N*",
+                        ($shuffleip[ $r        & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+                        ($shuffleip[($r >>  8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+                        ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+                        ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+                        ($shuffleip[ $l        & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+                        ($shuffleip[($l >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+                        ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+                        ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
+                    );
+                    ' . /* Extract L0 and R0 */ '
+                    $l = $in[1];
+                    $r = $in[2];
+                ';
+
+                $l = '$l';
+                $r = '$r';
+
+                // Perform DES or 3DES.
+                for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
+                    // Perform the 16 steps.
+                    for ($i = 0; $i < 16; ++$i) {
+                        // start of "the Feistel (F) function" - see the following URL:
+                        // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
+                        // Merge key schedule.
+                        $crypt_block[$c].= '
+                            $b1 = ((' . $r . ' >>  3) & 0x1FFFFFFF)  ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
+                            $b2 = ((' . $r . ' >> 31) & 0x00000001)  ^ (' . $r . ' <<  1) ^ ' . $k[$c][++$ki] . ';' .
+                            /* S-box indexing. */
+                            $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
+                                     $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
+                                     $sbox5[($b1 >>  8) & 0x3F] ^ $sbox6[($b2 >>  8) & 0x3F] ^
+                                     $sbox7[ $b1        & 0x3F] ^ $sbox8[ $b2        & 0x3F] ^ ' . $l . ';
+                        ';
+                        // end of "the Feistel (F) function"
+
+                        // swap L & R
+                        list($l, $r) = array($r, $l);
+                    }
+                    list($l, $r) = array($r, $l);
+                }
+
+                // Perform the inverse IP permutation.
+                $crypt_block[$c].= '$in =
+                    ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+                    ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+                    ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+                    ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+                    ($shuffleinvip[($l >>  8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+                    ($shuffleinvip[($r >>  8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+                    ($shuffleinvip[ $l        & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+                    ($shuffleinvip[ $r        & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+                ';
+            }
+
+            // Creates the inline-crypt function
+            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+                array(
+                   'init_crypt'    => $init_crypt,
+                   'init_encrypt'  => $init_encrypt,
+                   'init_decrypt'  => $init_decrypt,
+                   'encrypt_block' => $crypt_block[self::ENCRYPT],
+                   'decrypt_block' => $crypt_block[self::DECRYPT]
+                )
+            );
+        }
+
+        // Set the inline-crypt function as callback in: $this->inline_crypt
+        $this->inline_crypt = $lambda_functions[$code_hash];
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
new file mode 100644
index 00000000..248b65ef
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
@@ -0,0 +1,893 @@
+<?php
+
+/**
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
+ *
+ * Uses hash() or mhash() if available and an internal implementation, otherwise.  Currently supports the following:
+ *
+ * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
+ *
+ * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
+ * the hash.  If no valid algorithm is provided, sha1 will be used.
+ *
+ * PHP version 5
+ *
+ * {@internal The variable names are the same as those in
+ * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $hash = new \phpseclib\Crypt\Hash('sha1');
+ *
+ *    $hash->setKey('abcdefg');
+ *
+ *    echo base64_encode($hash->hash('abcdefg'));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   Hash
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+use phpseclib\Math\BigInteger;
+
+/**
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
+ *
+ * @package Hash
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class Hash
+{
+    /**#@+
+     * @access private
+     * @see \phpseclib\Crypt\Hash::__construct()
+     */
+    /**
+     * Toggles the internal implementation
+     */
+    const MODE_INTERNAL = 1;
+    /**
+     * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
+     */
+    const MODE_MHASH = 2;
+    /**
+     * Toggles the hash() implementation, which works on PHP 5.1.2+.
+     */
+    const MODE_HASH = 3;
+    /**#@-*/
+
+    /**
+     * Hash Parameter
+     *
+     * @see self::setHash()
+     * @var int
+     * @access private
+     */
+    var $hashParam;
+
+    /**
+     * Byte-length of compression blocks / key (Internal HMAC)
+     *
+     * @see self::setAlgorithm()
+     * @var int
+     * @access private
+     */
+    var $b;
+
+    /**
+     * Byte-length of hash output (Internal HMAC)
+     *
+     * @see self::setHash()
+     * @var int
+     * @access private
+     */
+    var $l = false;
+
+    /**
+     * Hash Algorithm
+     *
+     * @see self::setHash()
+     * @var string
+     * @access private
+     */
+    var $hash;
+
+    /**
+     * Key
+     *
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $key = false;
+
+    /**
+     * Computed Key
+     *
+     * @see self::_computeKey()
+     * @var string
+     * @access private
+     */
+    var $computedKey = false;
+
+    /**
+     * Outer XOR (Internal HMAC)
+     *
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $opad;
+
+    /**
+     * Inner XOR (Internal HMAC)
+     *
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $ipad;
+
+    /**
+     * Engine
+     *
+     * @see self::setHash()
+     * @var string
+     * @access private
+     */
+    var $engine;
+
+    /**
+     * Default Constructor.
+     *
+     * @param string $hash
+     * @return \phpseclib\Crypt\Hash
+     * @access public
+     */
+    function __construct($hash = 'sha1')
+    {
+        if (!defined('CRYPT_HASH_MODE')) {
+            switch (true) {
+                case extension_loaded('hash'):
+                    define('CRYPT_HASH_MODE', self::MODE_HASH);
+                    break;
+                case extension_loaded('mhash'):
+                    define('CRYPT_HASH_MODE', self::MODE_MHASH);
+                    break;
+                default:
+                    define('CRYPT_HASH_MODE', self::MODE_INTERNAL);
+            }
+        }
+
+        $this->setHash($hash);
+    }
+
+    /**
+     * Sets the key for HMACs
+     *
+     * Keys can be of any length.
+     *
+     * @access public
+     * @param string $key
+     */
+    function setKey($key = false)
+    {
+        $this->key = $key;
+        $this->_computeKey();
+    }
+
+    /**
+     * Pre-compute the key used by the HMAC
+     *
+     * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
+     * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
+     *
+     * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
+     * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
+     * every call
+     *
+     * @access private
+     */
+    function _computeKey()
+    {
+        if ($this->key === false) {
+            $this->computedKey = false;
+            return;
+        }
+
+        if (strlen($this->key) <= $this->b) {
+            $this->computedKey = $this->key;
+            return;
+        }
+
+        switch ($this->engine) {
+            case self::MODE_MHASH:
+                $this->computedKey = mhash($this->hash, $this->key);
+                break;
+            case self::MODE_HASH:
+                $this->computedKey = hash($this->hash, $this->key, true);
+                break;
+            case self::MODE_INTERNAL:
+                $this->computedKey = call_user_func($this->hash, $this->key);
+        }
+    }
+
+    /**
+     * Gets the hash function.
+     *
+     * As set by the constructor or by the setHash() method.
+     *
+     * @access public
+     * @return string
+     */
+    function getHash()
+    {
+        return $this->hashParam;
+    }
+
+    /**
+     * Sets the hash function.
+     *
+     * @access public
+     * @param string $hash
+     */
+    function setHash($hash)
+    {
+        $this->hashParam = $hash = strtolower($hash);
+        switch ($hash) {
+            case 'md5-96':
+            case 'sha1-96':
+            case 'sha256-96':
+            case 'sha512-96':
+                $hash = substr($hash, 0, -3);
+                $this->l = 12; // 96 / 8 = 12
+                break;
+            case 'md2':
+            case 'md5':
+                $this->l = 16;
+                break;
+            case 'sha1':
+                $this->l = 20;
+                break;
+            case 'sha256':
+                $this->l = 32;
+                break;
+            case 'sha384':
+                $this->l = 48;
+                break;
+            case 'sha512':
+                $this->l = 64;
+        }
+
+        switch ($hash) {
+            case 'md2-96':
+            case 'md2':
+                $this->b = 16;
+            case 'md5-96':
+            case 'sha1-96':
+            case 'sha224-96':
+            case 'sha256-96':
+            case 'md2':
+            case 'md5':
+            case 'sha1':
+            case 'sha224':
+            case 'sha256':
+                $this->b = 64;
+                break;
+            default:
+                $this->b = 128;
+        }
+
+        switch ($hash) {
+            case 'md2':
+                $this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
+                    self::MODE_HASH : self::MODE_INTERNAL;
+                break;
+            case 'sha384':
+            case 'sha512':
+                $this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
+                break;
+            default:
+                $this->engine = CRYPT_HASH_MODE;
+        }
+
+        switch ($this->engine) {
+            case self::MODE_MHASH:
+                switch ($hash) {
+                    case 'md5':
+                        $this->hash = MHASH_MD5;
+                        break;
+                    case 'sha256':
+                        $this->hash = MHASH_SHA256;
+                        break;
+                    case 'sha1':
+                    default:
+                        $this->hash = MHASH_SHA1;
+                }
+                $this->_computeKey(self::MODE_MHASH);
+                return;
+            case self::MODE_HASH:
+                switch ($hash) {
+                    case 'md5':
+                        $this->hash = 'md5';
+                        return;
+                    case 'md2':
+                    case 'sha256':
+                    case 'sha384':
+                    case 'sha512':
+                        $this->hash = $hash;
+                        return;
+                    case 'sha1':
+                    default:
+                        $this->hash = 'sha1';
+                }
+                $this->_computeKey(self::MODE_HASH);
+                return;
+        }
+
+        switch ($hash) {
+            case 'md2':
+                $this->hash = array($this, '_md2');
+                break;
+            case 'md5':
+                $this->hash = array($this, '_md5');
+                break;
+            case 'sha256':
+                $this->hash = array($this, '_sha256');
+                break;
+            case 'sha384':
+            case 'sha512':
+                $this->hash = array($this, '_sha512');
+                break;
+            case 'sha1':
+            default:
+                $this->hash = array($this, '_sha1');
+        }
+
+        $this->ipad = str_repeat(chr(0x36), $this->b);
+        $this->opad = str_repeat(chr(0x5C), $this->b);
+
+        $this->_computeKey(self::MODE_INTERNAL);
+    }
+
+    /**
+     * Compute the HMAC.
+     *
+     * @access public
+     * @param string $text
+     * @return string
+     */
+    function hash($text)
+    {
+        if (!empty($this->key) || is_string($this->key)) {
+            switch ($this->engine) {
+                case self::MODE_MHASH:
+                    $output = mhash($this->hash, $text, $this->computedKey);
+                    break;
+                case self::MODE_HASH:
+                    $output = hash_hmac($this->hash, $text, $this->computedKey, true);
+                    break;
+                case self::MODE_INTERNAL:
+                    $key    = str_pad($this->computedKey, $this->b, chr(0)); // step 1
+                    $temp   = $this->ipad ^ $key;                            // step 2
+                    $temp  .= $text;                                         // step 3
+                    $temp   = call_user_func($this->hash, $temp);            // step 4
+                    $output = $this->opad ^ $key;                            // step 5
+                    $output.= $temp;                                         // step 6
+                    $output = call_user_func($this->hash, $output);          // step 7
+            }
+        } else {
+            switch ($this->engine) {
+                case self::MODE_MHASH:
+                    $output = mhash($this->hash, $text);
+                    break;
+                case self::MODE_HASH:
+                    $output = hash($this->hash, $text, true);
+                    break;
+                case self::MODE_INTERNAL:
+                    $output = call_user_func($this->hash, $text);
+            }
+        }
+
+        return substr($output, 0, $this->l);
+    }
+
+    /**
+     * Returns the hash length (in bytes)
+     *
+     * @access public
+     * @return int
+     */
+    function getLength()
+    {
+        return $this->l;
+    }
+
+    /**
+     * Wrapper for MD5
+     *
+     * @access private
+     * @param string $m
+     */
+    function _md5($m)
+    {
+        return pack('H*', md5($m));
+    }
+
+    /**
+     * Wrapper for SHA1
+     *
+     * @access private
+     * @param string $m
+     */
+    function _sha1($m)
+    {
+        return pack('H*', sha1($m));
+    }
+
+    /**
+     * Pure-PHP implementation of MD2
+     *
+     * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
+     *
+     * @access private
+     * @param string $m
+     */
+    function _md2($m)
+    {
+        static $s = array(
+             41,  46,  67, 201, 162, 216, 124,   1,  61,  54,  84, 161, 236, 240, 6,
+             19,  98, 167,   5, 243, 192, 199, 115, 140, 152, 147,  43, 217, 188,
+             76, 130, 202,  30, 155,  87,  60, 253, 212, 224,  22, 103,  66, 111, 24,
+            138,  23, 229,  18, 190,  78, 196, 214, 218, 158, 222,  73, 160, 251,
+            245, 142, 187,  47, 238, 122, 169, 104, 121, 145,  21, 178,   7,  63,
+            148, 194,  16, 137,  11,  34,  95,  33, 128, 127,  93, 154,  90, 144, 50,
+             39,  53,  62, 204, 231, 191, 247, 151,   3, 255,  25,  48, 179,  72, 165,
+            181, 209, 215,  94, 146,  42, 172,  86, 170, 198,  79, 184,  56, 210,
+            150, 164, 125, 182, 118, 252, 107, 226, 156, 116,   4, 241,  69, 157,
+            112,  89, 100, 113, 135,  32, 134,  91, 207, 101, 230,  45, 168,   2, 27,
+             96,  37, 173, 174, 176, 185, 246,  28,  70,  97, 105,  52,  64, 126, 15,
+             85,  71, 163,  35, 221,  81, 175,  58, 195,  92, 249, 206, 186, 197,
+            234,  38,  44,  83,  13, 110, 133,  40, 132,   9, 211, 223, 205, 244, 65,
+            129,  77,  82, 106, 220,  55, 200, 108, 193, 171, 250,  36, 225, 123,
+              8,  12, 189, 177,  74, 120, 136, 149, 139, 227,  99, 232, 109, 233,
+            203, 213, 254,  59,   0,  29,  57, 242, 239, 183,  14, 102,  88, 208, 228,
+            166, 119, 114, 248, 235, 117,  75,  10,  49,  68,  80, 180, 143, 237,
+             31,  26, 219, 153, 141,  51, 159,  17, 131, 20
+        );
+
+        // Step 1. Append Padding Bytes
+        $pad = 16 - (strlen($m) & 0xF);
+        $m.= str_repeat(chr($pad), $pad);
+
+        $length = strlen($m);
+
+        // Step 2. Append Checksum
+        $c = str_repeat(chr(0), 16);
+        $l = chr(0);
+        for ($i = 0; $i < $length; $i+= 16) {
+            for ($j = 0; $j < 16; $j++) {
+                // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
+                //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
+                // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
+                $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
+                $l = $c[$j];
+            }
+        }
+        $m.= $c;
+
+        $length+= 16;
+
+        // Step 3. Initialize MD Buffer
+        $x = str_repeat(chr(0), 48);
+
+        // Step 4. Process Message in 16-Byte Blocks
+        for ($i = 0; $i < $length; $i+= 16) {
+            for ($j = 0; $j < 16; $j++) {
+                $x[$j + 16] = $m[$i + $j];
+                $x[$j + 32] = $x[$j + 16] ^ $x[$j];
+            }
+            $t = chr(0);
+            for ($j = 0; $j < 18; $j++) {
+                for ($k = 0; $k < 48; $k++) {
+                    $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
+                    //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
+                }
+                $t = chr(ord($t) + $j);
+            }
+        }
+
+        // Step 5. Output
+        return substr($x, 0, 16);
+    }
+
+    /**
+     * Pure-PHP implementation of SHA256
+     *
+     * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
+     *
+     * @access private
+     * @param string $m
+     */
+    function _sha256($m)
+    {
+        if (extension_loaded('suhosin')) {
+            return pack('H*', sha256($m));
+        }
+
+        // Initialize variables
+        $hash = array(
+            0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+        );
+        // Initialize table of round constants
+        // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
+        static $k = array(
+            0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+            0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+            0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+            0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+            0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+            0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+            0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+            0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+        );
+
+        // Pre-processing
+        $length = strlen($m);
+        // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
+        $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
+        $m[$length] = chr(0x80);
+        // we don't support hashing strings 512MB long
+        $m.= pack('N2', 0, $length << 3);
+
+        // Process the message in successive 512-bit chunks
+        $chunks = str_split($m, 64);
+        foreach ($chunks as $chunk) {
+            $w = array();
+            for ($i = 0; $i < 16; $i++) {
+                extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
+                $w[] = $temp;
+            }
+
+            // Extend the sixteen 32-bit words into sixty-four 32-bit words
+            for ($i = 16; $i < 64; $i++) {
+                // @codingStandardsIgnoreStart
+                $s0 = $this->_rightRotate($w[$i - 15],  7) ^
+                      $this->_rightRotate($w[$i - 15], 18) ^
+                      $this->_rightShift( $w[$i - 15],  3);
+                $s1 = $this->_rightRotate($w[$i - 2], 17) ^
+                      $this->_rightRotate($w[$i - 2], 19) ^
+                      $this->_rightShift( $w[$i - 2], 10);
+                // @codingStandardsIgnoreEnd
+                $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
+            }
+
+            // Initialize hash value for this chunk
+            list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
+
+            // Main loop
+            for ($i = 0; $i < 64; $i++) {
+                $s0 = $this->_rightRotate($a,  2) ^
+                      $this->_rightRotate($a, 13) ^
+                      $this->_rightRotate($a, 22);
+                $maj = ($a & $b) ^
+                       ($a & $c) ^
+                       ($b & $c);
+                $t2 = $this->_add($s0, $maj);
+
+                $s1 = $this->_rightRotate($e,  6) ^
+                      $this->_rightRotate($e, 11) ^
+                      $this->_rightRotate($e, 25);
+                $ch = ($e & $f) ^
+                      ($this->_not($e) & $g);
+                $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
+
+                $h = $g;
+                $g = $f;
+                $f = $e;
+                $e = $this->_add($d, $t1);
+                $d = $c;
+                $c = $b;
+                $b = $a;
+                $a = $this->_add($t1, $t2);
+            }
+
+            // Add this chunk's hash to result so far
+            $hash = array(
+                $this->_add($hash[0], $a),
+                $this->_add($hash[1], $b),
+                $this->_add($hash[2], $c),
+                $this->_add($hash[3], $d),
+                $this->_add($hash[4], $e),
+                $this->_add($hash[5], $f),
+                $this->_add($hash[6], $g),
+                $this->_add($hash[7], $h)
+            );
+        }
+
+        // Produce the final hash value (big-endian)
+        return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
+    }
+
+    /**
+     * Pure-PHP implementation of SHA384 and SHA512
+     *
+     * @access private
+     * @param string $m
+     */
+    function _sha512($m)
+    {
+        static $init384, $init512, $k;
+
+        if (!isset($k)) {
+            // Initialize variables
+            $init384 = array( // initial values for SHA384
+                'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
+                '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
+            );
+            $init512 = array( // initial values for SHA512
+                '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
+                '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
+            );
+
+            for ($i = 0; $i < 8; $i++) {
+                $init384[$i] = new BigInteger($init384[$i], 16);
+                $init384[$i]->setPrecision(64);
+                $init512[$i] = new BigInteger($init512[$i], 16);
+                $init512[$i]->setPrecision(64);
+            }
+
+            // Initialize table of round constants
+            // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
+            $k = array(
+                '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
+                '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
+                'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
+                '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
+                'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
+                '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
+                '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
+                'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
+                '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
+                '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
+                'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
+                'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
+                '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
+                '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
+                '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
+                '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
+                'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
+                '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
+                '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
+                '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
+            );
+
+            for ($i = 0; $i < 80; $i++) {
+                $k[$i] = new BigInteger($k[$i], 16);
+            }
+        }
+
+        $hash = $this->l == 48 ? $init384 : $init512;
+
+        // Pre-processing
+        $length = strlen($m);
+        // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
+        $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
+        $m[$length] = chr(0x80);
+        // we don't support hashing strings 512MB long
+        $m.= pack('N4', 0, 0, 0, $length << 3);
+
+        // Process the message in successive 1024-bit chunks
+        $chunks = str_split($m, 128);
+        foreach ($chunks as $chunk) {
+            $w = array();
+            for ($i = 0; $i < 16; $i++) {
+                $temp = new BigInteger($this->_string_shift($chunk, 8), 256);
+                $temp->setPrecision(64);
+                $w[] = $temp;
+            }
+
+            // Extend the sixteen 32-bit words into eighty 32-bit words
+            for ($i = 16; $i < 80; $i++) {
+                $temp = array(
+                          $w[$i - 15]->bitwise_rightRotate(1),
+                          $w[$i - 15]->bitwise_rightRotate(8),
+                          $w[$i - 15]->bitwise_rightShift(7)
+                );
+                $s0 = $temp[0]->bitwise_xor($temp[1]);
+                $s0 = $s0->bitwise_xor($temp[2]);
+                $temp = array(
+                          $w[$i - 2]->bitwise_rightRotate(19),
+                          $w[$i - 2]->bitwise_rightRotate(61),
+                          $w[$i - 2]->bitwise_rightShift(6)
+                );
+                $s1 = $temp[0]->bitwise_xor($temp[1]);
+                $s1 = $s1->bitwise_xor($temp[2]);
+                $w[$i] = $w[$i - 16]->copy();
+                $w[$i] = $w[$i]->add($s0);
+                $w[$i] = $w[$i]->add($w[$i - 7]);
+                $w[$i] = $w[$i]->add($s1);
+            }
+
+            // Initialize hash value for this chunk
+            $a = $hash[0]->copy();
+            $b = $hash[1]->copy();
+            $c = $hash[2]->copy();
+            $d = $hash[3]->copy();
+            $e = $hash[4]->copy();
+            $f = $hash[5]->copy();
+            $g = $hash[6]->copy();
+            $h = $hash[7]->copy();
+
+            // Main loop
+            for ($i = 0; $i < 80; $i++) {
+                $temp = array(
+                    $a->bitwise_rightRotate(28),
+                    $a->bitwise_rightRotate(34),
+                    $a->bitwise_rightRotate(39)
+                );
+                $s0 = $temp[0]->bitwise_xor($temp[1]);
+                $s0 = $s0->bitwise_xor($temp[2]);
+                $temp = array(
+                    $a->bitwise_and($b),
+                    $a->bitwise_and($c),
+                    $b->bitwise_and($c)
+                );
+                $maj = $temp[0]->bitwise_xor($temp[1]);
+                $maj = $maj->bitwise_xor($temp[2]);
+                $t2 = $s0->add($maj);
+
+                $temp = array(
+                    $e->bitwise_rightRotate(14),
+                    $e->bitwise_rightRotate(18),
+                    $e->bitwise_rightRotate(41)
+                );
+                $s1 = $temp[0]->bitwise_xor($temp[1]);
+                $s1 = $s1->bitwise_xor($temp[2]);
+                $temp = array(
+                    $e->bitwise_and($f),
+                    $g->bitwise_and($e->bitwise_not())
+                );
+                $ch = $temp[0]->bitwise_xor($temp[1]);
+                $t1 = $h->add($s1);
+                $t1 = $t1->add($ch);
+                $t1 = $t1->add($k[$i]);
+                $t1 = $t1->add($w[$i]);
+
+                $h = $g->copy();
+                $g = $f->copy();
+                $f = $e->copy();
+                $e = $d->add($t1);
+                $d = $c->copy();
+                $c = $b->copy();
+                $b = $a->copy();
+                $a = $t1->add($t2);
+            }
+
+            // Add this chunk's hash to result so far
+            $hash = array(
+                $hash[0]->add($a),
+                $hash[1]->add($b),
+                $hash[2]->add($c),
+                $hash[3]->add($d),
+                $hash[4]->add($e),
+                $hash[5]->add($f),
+                $hash[6]->add($g),
+                $hash[7]->add($h)
+            );
+        }
+
+        // Produce the final hash value (big-endian)
+        // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs.  as such, we trim the output here)
+        $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
+                $hash[4]->toBytes() . $hash[5]->toBytes();
+        if ($this->l != 48) {
+            $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
+        }
+
+        return $temp;
+    }
+
+    /**
+     * Right Rotate
+     *
+     * @access private
+     * @param int $int
+     * @param int $amt
+     * @see self::_sha256()
+     * @return int
+     */
+    function _rightRotate($int, $amt)
+    {
+        $invamt = 32 - $amt;
+        $mask = (1 << $invamt) - 1;
+        return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
+    }
+
+    /**
+     * Right Shift
+     *
+     * @access private
+     * @param int $int
+     * @param int $amt
+     * @see self::_sha256()
+     * @return int
+     */
+    function _rightShift($int, $amt)
+    {
+        $mask = (1 << (32 - $amt)) - 1;
+        return ($int >> $amt) & $mask;
+    }
+
+    /**
+     * Not
+     *
+     * @access private
+     * @param int $int
+     * @see self::_sha256()
+     * @return int
+     */
+    function _not($int)
+    {
+        return ~$int & 0xFFFFFFFF;
+    }
+
+    /**
+     * Add
+     *
+     * _sha256() adds multiple unsigned 32-bit integers.  Since PHP doesn't support unsigned integers and since the
+     * possibility of overflow exists, care has to be taken.  BigInteger could be used but this should be faster.
+     *
+     * @return int
+     * @see self::_sha256()
+     * @access private
+     */
+    function _add()
+    {
+        static $mod;
+        if (!isset($mod)) {
+            $mod = pow(2, 32);
+        }
+
+        $result = 0;
+        $arguments = func_get_args();
+        foreach ($arguments as $argument) {
+            $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
+        }
+
+        if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
+            return fmod($result, $mod);
+        }
+
+        return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
+            ((fmod(floor($result / 0x80000000), 2) & 1) << 31);
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @return string
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
new file mode 100644
index 00000000..72a15d35
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
@@ -0,0 +1,694 @@
+<?php
+
+/**
+ * Pure-PHP implementation of RC2.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ *  - {@link http://tools.ietf.org/html/rfc2268}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $rc2 = new \phpseclib\Crypt\RC2();
+ *
+ *    $rc2->setKey('abcdefgh');
+ *
+ *    $plaintext = str_repeat('a', 1024);
+ *
+ *    echo $rc2->decrypt($rc2->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package  RC2
+ * @author   Patrick Monnerat <pm@datasphere.ch>
+ * @license  http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link     http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of RC2.
+ *
+ * @package RC2
+ * @access  public
+ */
+class RC2 extends Base
+{
+    /**
+     * Block Length of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::block_size
+     * @var int
+     * @access private
+     */
+    var $block_size = 8;
+
+    /**
+     * The Key
+     *
+     * @see \phpseclib\Crypt\Base::key
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $key;
+
+    /**
+     * The Original (unpadded) Key
+     *
+     * @see \phpseclib\Crypt\Base::key
+     * @see self::setKey()
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @var string
+     * @access private
+     */
+    var $orig_key = '';
+
+    /**
+     * Don't truncate / null pad key
+     *
+     * @see \phpseclib\Crypt\Base::_clearBuffers()
+     * @var bool
+     * @access private
+     */
+    var $skip_key_adjustment = true;
+
+    /**
+     * Key Length (in bytes)
+     *
+     * @see \phpseclib\Crypt\RC2::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 16; // = 128 bits
+
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'rc2';
+
+    /**
+     * Optimizing value while CFB-encrypting
+     *
+     * @see \phpseclib\Crypt\Base::cfb_init_len
+     * @var int
+     * @access private
+     */
+    var $cfb_init_len = 500;
+
+    /**
+     * The key length in bits.
+     *
+     * @see self::setKeyLength()
+     * @see self::setKey()
+     * @var int
+     * @access private
+     * @internal Should be in range [1..1024].
+     * @internal Changing this value after setting the key has no effect.
+     */
+    var $default_key_length = 1024;
+
+    /**
+     * The key length in bits.
+     *
+     * @see self::isValidEnine()
+     * @see self::setKey()
+     * @var int
+     * @access private
+     * @internal Should be in range [1..1024].
+     */
+    var $current_key_length;
+
+    /**
+     * The Key Schedule
+     *
+     * @see self::_setupKey()
+     * @var array
+     * @access private
+     */
+    var $keys;
+
+    /**
+     * Key expansion randomization table.
+     * Twice the same 256-value sequence to save a modulus in key expansion.
+     *
+     * @see self::setKey()
+     * @var array
+     * @access private
+     */
+    var $pitable = array(
+        0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
+        0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
+        0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
+        0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
+        0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
+        0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
+        0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
+        0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
+        0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
+        0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
+        0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
+        0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
+        0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
+        0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
+        0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
+        0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
+        0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
+        0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
+        0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
+        0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
+        0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
+        0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
+        0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
+        0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
+        0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
+        0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
+        0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
+        0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
+        0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
+        0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
+        0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
+        0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
+        0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
+        0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
+        0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
+        0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
+        0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
+        0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
+        0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
+        0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
+        0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
+        0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
+        0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
+        0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
+        0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
+        0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
+        0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
+        0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
+        0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
+        0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
+        0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
+        0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
+        0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
+        0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
+        0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
+        0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
+        0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
+        0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
+        0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
+        0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
+        0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
+        0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
+        0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
+        0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
+    );
+
+    /**
+     * Inverse key expansion randomization table.
+     *
+     * @see self::setKey()
+     * @var array
+     * @access private
+     */
+    var $invpitable = array(
+        0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
+        0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
+        0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
+        0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
+        0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
+        0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
+        0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
+        0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
+        0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
+        0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
+        0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
+        0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
+        0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
+        0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
+        0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
+        0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
+        0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
+        0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
+        0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
+        0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
+        0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
+        0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
+        0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
+        0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
+        0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
+        0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
+        0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
+        0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
+        0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
+        0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
+        0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
+        0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
+    );
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+     *
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        switch ($engine) {
+            case self::ENGINE_OPENSSL:
+                // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+                // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+                // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+                if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+                    return false;
+                }
+                if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
+                    return false;
+                }
+                $this->cipher_name_openssl_ecb = 'rc2-ecb';
+                $this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
+    /**
+     * Sets the key length.
+     *
+     * Valid key lengths are 8 to 1024.
+     * Calling this function after setting the key has no effect until the next
+     *  \phpseclib\Crypt\RC2::setKey() call.
+     *
+     * @access public
+     * @param int $length in bits
+     */
+    function setKeyLength($length)
+    {
+        if ($length < 8) {
+            $this->default_key_length = 1;
+        } elseif ($length > 1024) {
+            $this->default_key_length = 128;
+        } else {
+            $this->default_key_length = $length;
+        }
+        $this->current_key_length = $this->default_key_length;
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Returns the current key length
+     *
+     * @access public
+     * @return int
+     */
+    function getKeyLength()
+    {
+        return $this->current_key_length;
+    }
+
+    /**
+     * Sets the key.
+     *
+     * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
+     * strlen($key) <= 128), however, we only use the first 128 bytes if $key
+     * has more then 128 bytes in it, and set $key to a single null byte if
+     * it is empty.
+     *
+     * If the key is not explicitly set, it'll be assumed to be a single
+     * null byte.
+     *
+     * @see \phpseclib\Crypt\Base::setKey()
+     * @access public
+     * @param string $key
+     * @param int $t1 optional Effective key length in bits.
+     */
+    function setKey($key, $t1 = 0)
+    {
+        $this->orig_key = $key;
+
+        if ($t1 <= 0) {
+            $t1 = $this->default_key_length;
+        } elseif ($t1 > 1024) {
+            $t1 = 1024;
+        }
+        $this->current_key_length = $t1;
+        // Key byte count should be 1..128.
+        $key = strlen($key) ? substr($key, 0, 128) : "\x00";
+        $t = strlen($key);
+
+        // The mcrypt RC2 implementation only supports effective key length
+        // of 1024 bits. It is however possible to handle effective key
+        // lengths in range 1..1024 by expanding the key and applying
+        // inverse pitable mapping to the first byte before submitting it
+        // to mcrypt.
+
+        // Key expansion.
+        $l = array_values(unpack('C*', $key));
+        $t8 = ($t1 + 7) >> 3;
+        $tm = 0xFF >> (8 * $t8 - $t1);
+
+        // Expand key.
+        $pitable = $this->pitable;
+        for ($i = $t; $i < 128; $i++) {
+            $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
+        }
+        $i = 128 - $t8;
+        $l[$i] = $pitable[$l[$i] & $tm];
+        while ($i--) {
+            $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
+        }
+
+        // Prepare the key for mcrypt.
+        $l[0] = $this->invpitable[$l[0]];
+        array_unshift($l, 'C*');
+
+        parent::setKey(call_user_func_array('pack', $l));
+    }
+
+    /**
+     * Encrypts a message.
+     *
+     * Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code
+     *
+     * @see self::decrypt()
+     * @access public
+     * @param string $plaintext
+     * @return string $ciphertext
+     */
+    function encrypt($plaintext)
+    {
+        if ($this->engine == self::ENGINE_OPENSSL) {
+            $temp = $this->key;
+            $this->key = $this->orig_key;
+            $result = parent::encrypt($plaintext);
+            $this->key = $temp;
+            return $result;
+        }
+
+        return parent::encrypt($plaintext);
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code
+     *
+     * @see self::encrypt()
+     * @access public
+     * @param string $ciphertext
+     * @return string $plaintext
+     */
+    function decrypt($ciphertext)
+    {
+        if ($this->engine == self::ENGINE_OPENSSL) {
+            $temp = $this->key;
+            $this->key = $this->orig_key;
+            $result = parent::decrypt($ciphertext);
+            $this->key = $temp;
+            return $result;
+        }
+
+        return parent::decrypt($ciphertext);
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @see \phpseclib\Crypt\Base::_encryptBlock()
+     * @see \phpseclib\Crypt\Base::encrypt()
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _encryptBlock($in)
+    {
+        list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
+        $keys = $this->keys;
+        $limit = 20;
+        $actions = array($limit => 44, 44 => 64);
+        $j = 0;
+
+        for (;;) {
+            // Mixing round.
+            $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
+            $r0 |= $r0 >> 16;
+            $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
+            $r1 |= $r1 >> 16;
+            $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
+            $r2 |= $r2 >> 16;
+            $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
+            $r3 |= $r3 >> 16;
+
+            if ($j === $limit) {
+                if ($limit === 64) {
+                    break;
+                }
+
+                // Mashing round.
+                $r0 += $keys[$r3 & 0x3F];
+                $r1 += $keys[$r0 & 0x3F];
+                $r2 += $keys[$r1 & 0x3F];
+                $r3 += $keys[$r2 & 0x3F];
+                $limit = $actions[$limit];
+            }
+        }
+
+        return pack('vvvv', $r0, $r1, $r2, $r3);
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @see \phpseclib\Crypt\Base::_decryptBlock()
+     * @see \phpseclib\Crypt\Base::decrypt()
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _decryptBlock($in)
+    {
+        list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
+        $keys = $this->keys;
+        $limit = 44;
+        $actions = array($limit => 20, 20 => 0);
+        $j = 64;
+
+        for (;;) {
+            // R-mixing round.
+            $r3 = ($r3 | ($r3 << 16)) >> 5;
+            $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
+            $r2 = ($r2 | ($r2 << 16)) >> 3;
+            $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
+            $r1 = ($r1 | ($r1 << 16)) >> 2;
+            $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
+            $r0 = ($r0 | ($r0 << 16)) >> 1;
+            $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
+
+            if ($j === $limit) {
+                if ($limit === 0) {
+                    break;
+                }
+
+                // R-mashing round.
+                $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
+                $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
+                $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
+                $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
+                $limit = $actions[$limit];
+            }
+        }
+
+        return pack('vvvv', $r0, $r1, $r2, $r3);
+    }
+
+    /**
+     * Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
+     *
+     * @see \phpseclib\Crypt\Base::_setupMcrypt()
+     * @access private
+     */
+    function _setupMcrypt()
+    {
+        if (!isset($this->key)) {
+            $this->setKey('');
+        }
+
+        parent::_setupMcrypt();
+    }
+
+    /**
+     * Creates the key schedule
+     *
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        if (!isset($this->key)) {
+            $this->setKey('');
+        }
+
+        // Key has already been expanded in \phpseclib\Crypt\RC2::setKey():
+        // Only the first value must be altered.
+        $l = unpack('Ca/Cb/v*', $this->key);
+        array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
+        unset($l['a']);
+        unset($l['b']);
+        $this->keys = $l;
+    }
+
+    /**
+     * Setup the performance-optimized function for de/encrypt()
+     *
+     * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+     * @access private
+     */
+    function _setupInlineCrypt()
+    {
+        $lambda_functions =& self::_getLambdaFunctions();
+
+        // The first 10 generated $lambda_functions will use the $keys hardcoded as integers
+        // for the mixing rounds, for better inline crypt performance [~20% faster].
+        // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
+        // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_RC2, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
+
+        // Is there a re-usable $lambda_functions in there?
+        // If not, we have to create it.
+        if (!isset($lambda_functions[$code_hash])) {
+            // Init code for both, encrypt and decrypt.
+            $init_crypt = '$keys = $self->keys;';
+
+            switch (true) {
+                case $gen_hi_opt_code:
+                    $keys = $this->keys;
+                default:
+                    $keys = array();
+                    foreach ($this->keys as $k => $v) {
+                        $keys[$k] = '$keys[' . $k . ']';
+                    }
+            }
+
+            // $in is the current 8 bytes block which has to be en/decrypt
+            $encrypt_block = $decrypt_block = '
+                $in = unpack("v4", $in);
+                $r0 = $in[1];
+                $r1 = $in[2];
+                $r2 = $in[3];
+                $r3 = $in[4];
+            ';
+
+            // Create code for encryption.
+            $limit = 20;
+            $actions = array($limit => 44, 44 => 64);
+            $j = 0;
+
+            for (;;) {
+                // Mixing round.
+                $encrypt_block .= '
+                    $r0 = (($r0 + ' . $keys[$j++] . ' +
+                           ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
+                    $r0 |= $r0 >> 16;
+                    $r1 = (($r1 + ' . $keys[$j++] . ' +
+                           ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
+                    $r1 |= $r1 >> 16;
+                    $r2 = (($r2 + ' . $keys[$j++] . ' +
+                           ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
+                    $r2 |= $r2 >> 16;
+                    $r3 = (($r3 + ' . $keys[$j++] . ' +
+                           ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
+                    $r3 |= $r3 >> 16;';
+
+                if ($j === $limit) {
+                    if ($limit === 64) {
+                        break;
+                    }
+
+                    // Mashing round.
+                    $encrypt_block .= '
+                        $r0 += $keys[$r3 & 0x3F];
+                        $r1 += $keys[$r0 & 0x3F];
+                        $r2 += $keys[$r1 & 0x3F];
+                        $r3 += $keys[$r2 & 0x3F];';
+                    $limit = $actions[$limit];
+                }
+            }
+
+            $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
+
+            // Create code for decryption.
+            $limit = 44;
+            $actions = array($limit => 20, 20 => 0);
+            $j = 64;
+
+            for (;;) {
+                // R-mixing round.
+                $decrypt_block .= '
+                    $r3 = ($r3 | ($r3 << 16)) >> 5;
+                    $r3 = ($r3 - ' . $keys[--$j] . ' -
+                           ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
+                    $r2 = ($r2 | ($r2 << 16)) >> 3;
+                    $r2 = ($r2 - ' . $keys[--$j] . ' -
+                           ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
+                    $r1 = ($r1 | ($r1 << 16)) >> 2;
+                    $r1 = ($r1 - ' . $keys[--$j] . ' -
+                           ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
+                    $r0 = ($r0 | ($r0 << 16)) >> 1;
+                    $r0 = ($r0 - ' . $keys[--$j] . ' -
+                           ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
+
+                if ($j === $limit) {
+                    if ($limit === 0) {
+                        break;
+                    }
+
+                    // R-mashing round.
+                    $decrypt_block .= '
+                        $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
+                        $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
+                        $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
+                        $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
+                    $limit = $actions[$limit];
+                }
+            }
+
+            $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
+
+            // Creates the inline-crypt function
+            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+                array(
+                   'init_crypt'    => $init_crypt,
+                   'encrypt_block' => $encrypt_block,
+                   'decrypt_block' => $decrypt_block
+                )
+            );
+        }
+
+        // Set the inline-crypt function as callback in: $this->inline_crypt
+        $this->inline_crypt = $lambda_functions[$code_hash];
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
new file mode 100644
index 00000000..195d97ee
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
@@ -0,0 +1,348 @@
+<?php
+
+/**
+ * Pure-PHP implementation of RC4.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ *  - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
+ *  - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
+ *
+ * RC4 is also known as ARCFOUR or ARC4.  The reason is elaborated upon at Wikipedia.  This class is named RC4 and not
+ * ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $rc4 = new \phpseclib\Crypt\RC4();
+ *
+ *    $rc4->setKey('abcdefgh');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $rc4->decrypt($rc4->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   RC4
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of RC4.
+ *
+ * @package RC4
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class RC4 extends Base
+{
+    /**#@+
+     * @access private
+     * @see \phpseclib\Crypt\RC4::_crypt()
+    */
+    const ENCRYPT = 0;
+    const DECRYPT = 1;
+    /**#@-*/
+
+    /**
+     * Block Length of the cipher
+     *
+     * RC4 is a stream cipher
+     * so we the block_size to 0
+     *
+     * @see \phpseclib\Crypt\Base::block_size
+     * @var int
+     * @access private
+     */
+    var $block_size = 0;
+
+    /**
+     * Key Length (in bytes)
+     *
+     * @see \phpseclib\Crypt\RC4::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 128; // = 1024 bits
+
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'arcfour';
+
+    /**
+     * Holds whether performance-optimized $inline_crypt() can/should be used.
+     *
+     * @see \phpseclib\Crypt\Base::inline_crypt
+     * @var mixed
+     * @access private
+     */
+    var $use_inline_crypt = false; // currently not available
+
+    /**
+     * The Key
+     *
+     * @see self::setKey()
+     * @var string
+     * @access private
+     */
+    var $key;
+
+    /**
+     * The Key Stream for decryption and encryption
+     *
+     * @see self::setKey()
+     * @var array
+     * @access private
+     */
+    var $stream;
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.
+     *
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @return \phpseclib\Crypt\RC4
+     * @access public
+     */
+    function __construct()
+    {
+        parent::__construct(Base::MODE_STREAM);
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+     *
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($engine == self::ENGINE_OPENSSL) {
+            // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+            // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+            // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+            if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+                return false;
+            }
+            if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
+                $this->cipher_name_openssl = 'rc4-40';
+            } else {
+                switch (strlen($this->key)) {
+                    case 5:
+                        $this->cipher_name_openssl = 'rc4-40';
+                        break;
+                    case 8:
+                        $this->cipher_name_openssl = 'rc4-64';
+                        break;
+                    case 16:
+                        $this->cipher_name_openssl = 'rc4';
+                        break;
+                    default:
+                        return false;
+                }
+            }
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
+    /**
+     * Dummy function.
+     *
+     * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
+     * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
+     * calling setKey().
+     *
+     * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way.  Since, in that protocol,
+     * the IV's are relatively easy to predict, an attack described by
+     * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
+     * can be used to quickly guess at the rest of the key.  The following links elaborate:
+     *
+     * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
+     * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
+     *
+     * @param string $iv
+     * @see self::setKey()
+     * @access public
+     */
+    function setIV($iv)
+    {
+    }
+
+    /**
+     * Sets the key length
+     *
+     * Keys can be between 1 and 256 bytes long.
+     *
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        if ($length < 8) {
+            $this->key_length = 1;
+        } elseif ($length > 2048) {
+            $this->key_length = 256;
+        } else {
+            $this->key_length = $length >> 3;
+        }
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Encrypts a message.
+     *
+     * @see \phpseclib\Crypt\Base::decrypt()
+     * @see self::_crypt()
+     * @access public
+     * @param string $plaintext
+     * @return string $ciphertext
+     */
+    function encrypt($plaintext)
+    {
+        if ($this->engine != self::ENGINE_INTERNAL) {
+            return parent::encrypt($plaintext);
+        }
+        return $this->_crypt($plaintext, self::ENCRYPT);
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
+     * At least if the continuous buffer is disabled.
+     *
+     * @see \phpseclib\Crypt\Base::encrypt()
+     * @see self::_crypt()
+     * @access public
+     * @param string $ciphertext
+     * @return string $plaintext
+     */
+    function decrypt($ciphertext)
+    {
+        if ($this->engine != self::ENGINE_INTERNAL) {
+            return parent::decrypt($ciphertext);
+        }
+        return $this->_crypt($ciphertext, self::DECRYPT);
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @access private
+     * @param string $in
+     */
+    function _encryptBlock($in)
+    {
+        // RC4 does not utilize this method
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @access private
+     * @param string $in
+     */
+    function _decryptBlock($in)
+    {
+        // RC4 does not utilize this method
+    }
+
+    /**
+     * Setup the key (expansion)
+     *
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        $key = $this->key;
+        $keyLength = strlen($key);
+        $keyStream = range(0, 255);
+        $j = 0;
+        for ($i = 0; $i < 256; $i++) {
+            $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
+            $temp = $keyStream[$i];
+            $keyStream[$i] = $keyStream[$j];
+            $keyStream[$j] = $temp;
+        }
+
+        $this->stream = array();
+        $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array(
+            0, // index $i
+            0, // index $j
+            $keyStream
+        );
+    }
+
+    /**
+     * Encrypts or decrypts a message.
+     *
+     * @see self::encrypt()
+     * @see self::decrypt()
+     * @access private
+     * @param string $text
+     * @param int $mode
+     * @return string $text
+     */
+    function _crypt($text, $mode)
+    {
+        if ($this->changed) {
+            $this->_setup();
+            $this->changed = false;
+        }
+
+        $stream = &$this->stream[$mode];
+        if ($this->continuousBuffer) {
+            $i = &$stream[0];
+            $j = &$stream[1];
+            $keyStream = &$stream[2];
+        } else {
+            $i = $stream[0];
+            $j = $stream[1];
+            $keyStream = $stream[2];
+        }
+
+        $len = strlen($text);
+        for ($k = 0; $k < $len; ++$k) {
+            $i = ($i + 1) & 255;
+            $ksi = $keyStream[$i];
+            $j = ($j + $ksi) & 255;
+            $ksj = $keyStream[$j];
+
+            $keyStream[$i] = $ksj;
+            $keyStream[$j] = $ksi;
+            $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
+        }
+
+        return $text;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
new file mode 100644
index 00000000..a8fa2315
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
@@ -0,0 +1,3342 @@
+<?php
+
+/**
+ * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
+ *
+ * PHP version 5
+ *
+ * Here's an example of how to encrypt and decrypt text with this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $rsa = new \phpseclib\Crypt\RSA();
+ *    extract($rsa->createKey());
+ *
+ *    $plaintext = 'terrafrost';
+ *
+ *    $rsa->loadKey($privatekey);
+ *    $ciphertext = $rsa->encrypt($plaintext);
+ *
+ *    $rsa->loadKey($publickey);
+ *    echo $rsa->decrypt($ciphertext);
+ * ?>
+ * </code>
+ *
+ * Here's an example of how to create signatures and verify signatures with this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $rsa = new \phpseclib\Crypt\RSA();
+ *    extract($rsa->createKey());
+ *
+ *    $plaintext = 'terrafrost';
+ *
+ *    $rsa->loadKey($privatekey);
+ *    $signature = $rsa->sign($plaintext);
+ *
+ *    $rsa->loadKey($publickey);
+ *    echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   RSA
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2009 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+use phpseclib\Math\BigInteger;
+
+/**
+ * Pure-PHP PKCS#1 compliant implementation of RSA.
+ *
+ * @package RSA
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class RSA
+{
+    /**#@+
+     * @access public
+     * @see self::encrypt()
+     * @see self::decrypt()
+     */
+    /**
+     * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
+     * (OAEP) for encryption / decryption.
+     *
+     * Uses sha1 by default.
+     *
+     * @see self::setHash()
+     * @see self::setMGFHash()
+     */
+    const ENCRYPTION_OAEP = 1;
+    /**
+     * Use PKCS#1 padding.
+     *
+     * Although self::ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
+     * compatibility with protocols (like SSH-1) written before OAEP's introduction.
+     */
+    const ENCRYPTION_PKCS1 = 2;
+    /**
+     * Do not use any padding
+     *
+     * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy
+     * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc.
+     */
+    const ENCRYPTION_NONE = 3;
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see self::sign()
+     * @see self::verify()
+     * @see self::setHash()
+    */
+    /**
+     * Use the Probabilistic Signature Scheme for signing
+     *
+     * Uses sha1 by default.
+     *
+     * @see self::setSaltLength()
+     * @see self::setMGFHash()
+     */
+    const SIGNATURE_PSS = 1;
+    /**
+     * Use the PKCS#1 scheme by default.
+     *
+     * Although self::SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
+     * compatibility with protocols (like SSH-2) written before PSS's introduction.
+     */
+    const SIGNATURE_PKCS1 = 2;
+    /**#@-*/
+
+    /**#@+
+     * @access private
+     * @see \phpseclib\Crypt\RSA::createKey()
+    */
+    /**
+     * ASN1 Integer
+     */
+    const ASN1_INTEGER = 2;
+    /**
+     * ASN1 Bit String
+     */
+    const ASN1_BITSTRING = 3;
+    /**
+     * ASN1 Octet String
+     */
+    const ASN1_OCTETSTRING = 4;
+    /**
+     * ASN1 Object Identifier
+     */
+    const ASN1_OBJECT = 6;
+    /**
+     * ASN1 Sequence (with the constucted bit set)
+     */
+    const ASN1_SEQUENCE = 48;
+    /**#@-*/
+
+    /**#@+
+     * @access private
+     * @see \phpseclib\Crypt\RSA::__construct()
+    */
+    /**
+     * To use the pure-PHP implementation
+     */
+    const MODE_INTERNAL = 1;
+    /**
+     * To use the OpenSSL library
+     *
+     * (if enabled; otherwise, the internal implementation will be used)
+     */
+    const MODE_OPENSSL = 2;
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Crypt\RSA::createKey()
+     * @see \phpseclib\Crypt\RSA::setPrivateKeyFormat()
+    */
+    /**
+     * PKCS#1 formatted private key
+     *
+     * Used by OpenSSH
+     */
+    const PRIVATE_FORMAT_PKCS1 = 0;
+    /**
+     * PuTTY formatted private key
+     */
+    const PRIVATE_FORMAT_PUTTY = 1;
+    /**
+     * XML formatted private key
+     */
+    const PRIVATE_FORMAT_XML = 2;
+    /**
+     * PKCS#8 formatted private key
+     */
+    const PRIVATE_FORMAT_PKCS8 = 8;
+    /**
+     * OpenSSH formatted private key
+     */
+    const PRIVATE_FORMAT_OPENSSH = 9;
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Crypt\RSA::createKey()
+     * @see \phpseclib\Crypt\RSA::setPublicKeyFormat()
+    */
+    /**
+     * Raw public key
+     *
+     * An array containing two \phpseclib\Math\BigInteger objects.
+     *
+     * The exponent can be indexed with any of the following:
+     *
+     * 0, e, exponent, publicExponent
+     *
+     * The modulus can be indexed with any of the following:
+     *
+     * 1, n, modulo, modulus
+     */
+    const PUBLIC_FORMAT_RAW = 3;
+    /**
+     * PKCS#1 formatted public key (raw)
+     *
+     * Used by File/X509.php
+     *
+     * Has the following header:
+     *
+     * -----BEGIN RSA PUBLIC KEY-----
+     *
+     * Analogous to ssh-keygen's pem format (as specified by -m)
+     */
+    const PUBLIC_FORMAT_PKCS1 = 4;
+    const PUBLIC_FORMAT_PKCS1_RAW = 4;
+    /**
+     * XML formatted public key
+     */
+    const PUBLIC_FORMAT_XML = 5;
+    /**
+     * OpenSSH formatted public key
+     *
+     * Place in $HOME/.ssh/authorized_keys
+     */
+    const PUBLIC_FORMAT_OPENSSH = 6;
+    /**
+     * PKCS#1 formatted public key (encapsulated)
+     *
+     * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
+     *
+     * Has the following header:
+     *
+     * -----BEGIN PUBLIC KEY-----
+     *
+     * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
+     * is specific to private keys it's basically creating a DER-encoded wrapper
+     * for keys. This just extends that same concept to public keys (much like ssh-keygen)
+     */
+    const PUBLIC_FORMAT_PKCS8 = 7;
+    /**#@-*/
+
+    /**
+     * Precomputed Zero
+     *
+     * @var \phpseclib\Math\BigInteger
+     * @access private
+     */
+    var $zero;
+
+    /**
+     * Precomputed One
+     *
+     * @var \phpseclib\Math\BigInteger
+     * @access private
+     */
+    var $one;
+
+    /**
+     * Private Key Format
+     *
+     * @var int
+     * @access private
+     */
+    var $privateKeyFormat = self::PRIVATE_FORMAT_PKCS1;
+
+    /**
+     * Public Key Format
+     *
+     * @var int
+     * @access public
+     */
+    var $publicKeyFormat = self::PUBLIC_FORMAT_PKCS8;
+
+    /**
+     * Modulus (ie. n)
+     *
+     * @var \phpseclib\Math\BigInteger
+     * @access private
+     */
+    var $modulus;
+
+    /**
+     * Modulus length
+     *
+     * @var \phpseclib\Math\BigInteger
+     * @access private
+     */
+    var $k;
+
+    /**
+     * Exponent (ie. e or d)
+     *
+     * @var \phpseclib\Math\BigInteger
+     * @access private
+     */
+    var $exponent;
+
+    /**
+     * Primes for Chinese Remainder Theorem (ie. p and q)
+     *
+     * @var array
+     * @access private
+     */
+    var $primes;
+
+    /**
+     * Exponents for Chinese Remainder Theorem (ie. dP and dQ)
+     *
+     * @var array
+     * @access private
+     */
+    var $exponents;
+
+    /**
+     * Coefficients for Chinese Remainder Theorem (ie. qInv)
+     *
+     * @var array
+     * @access private
+     */
+    var $coefficients;
+
+    /**
+     * Hash name
+     *
+     * @var string
+     * @access private
+     */
+    var $hashName;
+
+    /**
+     * Hash function
+     *
+     * @var \phpseclib\Crypt\Hash
+     * @access private
+     */
+    var $hash;
+
+    /**
+     * Length of hash function output
+     *
+     * @var int
+     * @access private
+     */
+    var $hLen;
+
+    /**
+     * Length of salt
+     *
+     * @var int
+     * @access private
+     */
+    var $sLen;
+
+    /**
+     * Hash function for the Mask Generation Function
+     *
+     * @var \phpseclib\Crypt\Hash
+     * @access private
+     */
+    var $mgfHash;
+
+    /**
+     * Length of MGF hash function output
+     *
+     * @var int
+     * @access private
+     */
+    var $mgfHLen;
+
+    /**
+     * Encryption mode
+     *
+     * @var int
+     * @access private
+     */
+    var $encryptionMode = self::ENCRYPTION_OAEP;
+
+    /**
+     * Signature mode
+     *
+     * @var int
+     * @access private
+     */
+    var $signatureMode = self::SIGNATURE_PSS;
+
+    /**
+     * Public Exponent
+     *
+     * @var mixed
+     * @access private
+     */
+    var $publicExponent = false;
+
+    /**
+     * Password
+     *
+     * @var string
+     * @access private
+     */
+    var $password = false;
+
+    /**
+     * Components
+     *
+     * For use with parsing XML formatted keys.  PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
+     * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
+     *
+     * @see self::_start_element_handler()
+     * @var array
+     * @access private
+     */
+    var $components = array();
+
+    /**
+     * Current String
+     *
+     * For use with parsing XML formatted keys.
+     *
+     * @see self::_character_handler()
+     * @see self::_stop_element_handler()
+     * @var mixed
+     * @access private
+     */
+    var $current;
+
+    /**
+     * OpenSSL configuration file name.
+     *
+     * Set to null to use system configuration file.
+     * @see self::createKey()
+     * @var mixed
+     * @Access public
+     */
+    var $configFile;
+
+    /**
+     * Public key comment field.
+     *
+     * @var string
+     * @access private
+     */
+    var $comment = 'phpseclib-generated-key';
+
+    /**
+     * The constructor
+     *
+     * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself.  The reason
+     * \phpseclib\Crypt\RSA doesn't do it is because OpenSSL doesn't fail gracefully.  openssl_pkey_new(), in particular, requires
+     * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
+     *
+     * @return \phpseclib\Crypt\RSA
+     * @access public
+     */
+    function __construct()
+    {
+        $this->configFile = dirname(__FILE__) . '/../openssl.cnf';
+
+        if (!defined('CRYPT_RSA_MODE')) {
+            switch (true) {
+                // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
+                // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
+                // can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
+                case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'):
+                    define('CRYPT_RSA_MODE', self::MODE_INTERNAL);
+                    break;
+                case function_exists('phpinfo') && extension_loaded('openssl') && file_exists($this->configFile):
+                    // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
+                    $versions = array();
+
+                    // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
+                    if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
+                        ob_start();
+                        @phpinfo();
+                        $content = ob_get_contents();
+                        ob_end_clean();
+
+                        preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
+
+                        if (!empty($matches[1])) {
+                            for ($i = 0; $i < count($matches[1]); $i++) {
+                                $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
+
+                                // Remove letter part in OpenSSL version
+                                if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
+                                    $versions[$matches[1][$i]] = $fullVersion;
+                                } else {
+                                    $versions[$matches[1][$i]] = $m[0];
+                                }
+                            }
+                        }
+                    }
+
+                    // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
+                    switch (true) {
+                        case !isset($versions['Header']):
+                        case !isset($versions['Library']):
+                        case $versions['Header'] == $versions['Library']:
+                        case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
+                            define('CRYPT_RSA_MODE', self::MODE_OPENSSL);
+                            break;
+                        default:
+                            define('CRYPT_RSA_MODE', self::MODE_INTERNAL);
+                            define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
+                    }
+                    break;
+                default:
+                    define('CRYPT_RSA_MODE', self::MODE_INTERNAL);
+            }
+        }
+
+        $this->zero = new BigInteger();
+        $this->one = new BigInteger(1);
+
+        $this->hash = new Hash('sha1');
+        $this->hLen = $this->hash->getLength();
+        $this->hashName = 'sha1';
+        $this->mgfHash = new Hash('sha1');
+        $this->mgfHLen = $this->mgfHash->getLength();
+    }
+
+    /**
+     * Create public / private key pair
+     *
+     * Returns an array with the following three elements:
+     *  - 'privatekey': The private key.
+     *  - 'publickey':  The public key.
+     *  - 'partialkey': A partially computed key (if the execution time exceeded $timeout).
+     *                  Will need to be passed back to \phpseclib\Crypt\RSA::createKey() as the third parameter for further processing.
+     *
+     * @access public
+     * @param int $bits
+     * @param int $timeout
+     * @param array $partial
+     */
+    function createKey($bits = 1024, $timeout = false, $partial = array())
+    {
+        if (!defined('CRYPT_RSA_EXPONENT')) {
+            // http://en.wikipedia.org/wiki/65537_%28number%29
+            define('CRYPT_RSA_EXPONENT', '65537');
+        }
+        // per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
+        // than 256 bits. as a consequence if the key you're trying to create is 1024 bits and you've set CRYPT_RSA_SMALLEST_PRIME
+        // to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). at least if
+        // CRYPT_RSA_MODE is set to self::MODE_INTERNAL. if CRYPT_RSA_MODE is set to self::MODE_OPENSSL then
+        // CRYPT_RSA_SMALLEST_PRIME is ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key
+        // generation when there's a chance neither gmp nor OpenSSL are installed)
+        if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {
+            define('CRYPT_RSA_SMALLEST_PRIME', 4096);
+        }
+
+        // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
+        if (CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
+            $config = array();
+            if (isset($this->configFile)) {
+                $config['config'] = $this->configFile;
+            }
+            $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config);
+            openssl_pkey_export($rsa, $privatekey, null, $config);
+            $publickey = openssl_pkey_get_details($rsa);
+            $publickey = $publickey['key'];
+
+            $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, self::PRIVATE_FORMAT_PKCS1)));
+            $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1)));
+
+            // clear the buffer of error strings stemming from a minimalistic openssl.cnf
+            while (openssl_error_string() !== false) {
+            }
+
+            return array(
+                'privatekey' => $privatekey,
+                'publickey' => $publickey,
+                'partialkey' => false
+            );
+        }
+
+        static $e;
+        if (!isset($e)) {
+            $e = new BigInteger(CRYPT_RSA_EXPONENT);
+        }
+
+        extract($this->_generateMinMax($bits));
+        $absoluteMin = $min;
+        $temp = $bits >> 1; // divide by two to see how many bits P and Q would be
+        if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
+            $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
+            $temp = CRYPT_RSA_SMALLEST_PRIME;
+        } else {
+            $num_primes = 2;
+        }
+        extract($this->_generateMinMax($temp + $bits % $temp));
+        $finalMax = $max;
+        extract($this->_generateMinMax($temp));
+
+        $generator = new BigInteger();
+
+        $n = $this->one->copy();
+        if (!empty($partial)) {
+            extract(unserialize($partial));
+        } else {
+            $exponents = $coefficients = $primes = array();
+            $lcm = array(
+                'top' => $this->one->copy(),
+                'bottom' => false
+            );
+        }
+
+        $start = time();
+        $i0 = count($primes) + 1;
+
+        do {
+            for ($i = $i0; $i <= $num_primes; $i++) {
+                if ($timeout !== false) {
+                    $timeout-= time() - $start;
+                    $start = time();
+                    if ($timeout <= 0) {
+                        return array(
+                            'privatekey' => '',
+                            'publickey'  => '',
+                            'partialkey' => serialize(array(
+                                'primes' => $primes,
+                                'coefficients' => $coefficients,
+                                'lcm' => $lcm,
+                                'exponents' => $exponents
+                            ))
+                        );
+                    }
+                }
+
+                if ($i == $num_primes) {
+                    list($min, $temp) = $absoluteMin->divide($n);
+                    if (!$temp->equals($this->zero)) {
+                        $min = $min->add($this->one); // ie. ceil()
+                    }
+                    $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);
+                } else {
+                    $primes[$i] = $generator->randomPrime($min, $max, $timeout);
+                }
+
+                if ($primes[$i] === false) { // if we've reached the timeout
+                    if (count($primes) > 1) {
+                        $partialkey = '';
+                    } else {
+                        array_pop($primes);
+                        $partialkey = serialize(array(
+                            'primes' => $primes,
+                            'coefficients' => $coefficients,
+                            'lcm' => $lcm,
+                            'exponents' => $exponents
+                        ));
+                    }
+
+                    return array(
+                        'privatekey' => '',
+                        'publickey'  => '',
+                        'partialkey' => $partialkey
+                    );
+                }
+
+                // the first coefficient is calculated differently from the rest
+                // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
+                if ($i > 2) {
+                    $coefficients[$i] = $n->modInverse($primes[$i]);
+                }
+
+                $n = $n->multiply($primes[$i]);
+
+                $temp = $primes[$i]->subtract($this->one);
+
+                // textbook RSA implementations use Euler's totient function instead of the least common multiple.
+                // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
+                $lcm['top'] = $lcm['top']->multiply($temp);
+                $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
+
+                $exponents[$i] = $e->modInverse($temp);
+            }
+
+            list($temp) = $lcm['top']->divide($lcm['bottom']);
+            $gcd = $temp->gcd($e);
+            $i0 = 1;
+        } while (!$gcd->equals($this->one));
+
+        $d = $e->modInverse($temp);
+
+        $coefficients[2] = $primes[2]->modInverse($primes[1]);
+
+        // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
+        // RSAPrivateKey ::= SEQUENCE {
+        //     version           Version,
+        //     modulus           INTEGER,  -- n
+        //     publicExponent    INTEGER,  -- e
+        //     privateExponent   INTEGER,  -- d
+        //     prime1            INTEGER,  -- p
+        //     prime2            INTEGER,  -- q
+        //     exponent1         INTEGER,  -- d mod (p-1)
+        //     exponent2         INTEGER,  -- d mod (q-1)
+        //     coefficient       INTEGER,  -- (inverse of q) mod p
+        //     otherPrimeInfos   OtherPrimeInfos OPTIONAL
+        // }
+
+        return array(
+            'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),
+            'publickey'  => $this->_convertPublicKey($n, $e),
+            'partialkey' => false
+        );
+    }
+
+    /**
+     * Convert a private key to the appropriate format.
+     *
+     * @access private
+     * @see self::setPrivateKeyFormat()
+     * @param Math_BigInteger $n
+     * @param Math_BigInteger $e
+     * @param Math_BigInteger $d
+     * @param array<int,Math_BigInteger> $primes
+     * @param array<int,Math_BigInteger> $exponents
+     * @param array<int,Math_BigInteger> $coefficients
+     * @return string
+     */
+    function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
+    {
+        $signed = $this->privateKeyFormat != self::PRIVATE_FORMAT_XML;
+        $num_primes = count($primes);
+        $raw = array(
+            'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
+            'modulus' => $n->toBytes($signed),
+            'publicExponent' => $e->toBytes($signed),
+            'privateExponent' => $d->toBytes($signed),
+            'prime1' => $primes[1]->toBytes($signed),
+            'prime2' => $primes[2]->toBytes($signed),
+            'exponent1' => $exponents[1]->toBytes($signed),
+            'exponent2' => $exponents[2]->toBytes($signed),
+            'coefficient' => $coefficients[2]->toBytes($signed)
+        );
+
+        // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
+        // call _convertPublicKey() instead.
+        switch ($this->privateKeyFormat) {
+            case self::PRIVATE_FORMAT_XML:
+                if ($num_primes != 2) {
+                    return false;
+                }
+                return "<RSAKeyValue>\r\n" .
+                       '  <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" .
+                       '  <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" .
+                       '  <P>' . base64_encode($raw['prime1']) . "</P>\r\n" .
+                       '  <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" .
+                       '  <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" .
+                       '  <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" .
+                       '  <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" .
+                       '  <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" .
+                       '</RSAKeyValue>';
+                break;
+            case self::PRIVATE_FORMAT_PUTTY:
+                if ($num_primes != 2) {
+                    return false;
+                }
+                $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
+                $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
+                $key.= $encryption;
+                $key.= "\r\nComment: " . $this->comment . "\r\n";
+                $public = pack(
+                    'Na*Na*Na*',
+                    strlen('ssh-rsa'),
+                    'ssh-rsa',
+                    strlen($raw['publicExponent']),
+                    $raw['publicExponent'],
+                    strlen($raw['modulus']),
+                    $raw['modulus']
+                );
+                $source = pack(
+                    'Na*Na*Na*Na*',
+                    strlen('ssh-rsa'),
+                    'ssh-rsa',
+                    strlen($encryption),
+                    $encryption,
+                    strlen($this->comment),
+                    $this->comment,
+                    strlen($public),
+                    $public
+                );
+                $public = base64_encode($public);
+                $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
+                $key.= chunk_split($public, 64);
+                $private = pack(
+                    'Na*Na*Na*Na*',
+                    strlen($raw['privateExponent']),
+                    $raw['privateExponent'],
+                    strlen($raw['prime1']),
+                    $raw['prime1'],
+                    strlen($raw['prime2']),
+                    $raw['prime2'],
+                    strlen($raw['coefficient']),
+                    $raw['coefficient']
+                );
+                if (empty($this->password) && !is_string($this->password)) {
+                    $source.= pack('Na*', strlen($private), $private);
+                    $hashkey = 'putty-private-key-file-mac-key';
+                } else {
+                    $private.= Random::string(16 - (strlen($private) & 15));
+                    $source.= pack('Na*', strlen($private), $private);
+                    $sequence = 0;
+                    $symkey = '';
+                    while (strlen($symkey) < 32) {
+                        $temp = pack('Na*', $sequence++, $this->password);
+                        $symkey.= pack('H*', sha1($temp));
+                    }
+                    $symkey = substr($symkey, 0, 32);
+                    $crypto = new AES();
+
+                    $crypto->setKey($symkey);
+                    $crypto->disablePadding();
+                    $private = $crypto->encrypt($private);
+                    $hashkey = 'putty-private-key-file-mac-key' . $this->password;
+                }
+
+                $private = base64_encode($private);
+                $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
+                $key.= chunk_split($private, 64);
+                $hash = new Hash('sha1');
+                $hash->setKey(pack('H*', sha1($hashkey)));
+                $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
+
+                return $key;
+            case self::PRIVATE_FORMAT_OPENSSH:
+                if ($num_primes != 2) {
+                    return false;
+                }
+                $publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']);
+                $privateKey = pack(
+                    'Na*Na*Na*Na*Na*Na*Na*',
+                    strlen('ssh-rsa'),
+                    'ssh-rsa',
+                    strlen($raw['modulus']),
+                    $raw['modulus'],
+                    strlen($raw['publicExponent']),
+                    $raw['publicExponent'],
+                    strlen($raw['privateExponent']),
+                    $raw['privateExponent'],
+                    strlen($raw['coefficient']),
+                    $raw['coefficient'],
+                    strlen($raw['prime1']),
+                    $raw['prime1'],
+                    strlen($raw['prime2']),
+                    $raw['prime2']
+                );
+                $checkint = Random::string(4);
+                $paddedKey = pack(
+                    'a*Na*',
+                    $checkint . $checkint . $privateKey,
+                    strlen($this->comment),
+                    $this->comment
+                );
+                $paddingLength = (7 * strlen($paddedKey)) % 8;
+                for ($i = 1; $i <= $paddingLength; $i++) {
+                    $paddedKey.= chr($i);
+                }
+                $key = pack(
+                    'Na*Na*Na*NNa*Na*',
+                    strlen('none'),
+                    'none',
+                    strlen('none'),
+                    'none',
+                    0,
+                    '',
+                    1,
+                    strlen($publicKey),
+                    $publicKey,
+                    strlen($paddedKey),
+                    $paddedKey
+                );
+                $key = "openssh-key-v1\0$key";
+
+                return "-----BEGIN OPENSSH PRIVATE KEY-----\n" .
+                       chunk_split(base64_encode($key), 70, "\n") .
+                       "-----END OPENSSH PRIVATE KEY-----\n";
+            default: // eg. self::PRIVATE_FORMAT_PKCS1
+                $components = array();
+                foreach ($raw as $name => $value) {
+                    $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
+                }
+
+                $RSAPrivateKey = implode('', $components);
+
+                if ($num_primes > 2) {
+                    $OtherPrimeInfos = '';
+                    for ($i = 3; $i <= $num_primes; $i++) {
+                        // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
+                        //
+                        // OtherPrimeInfo ::= SEQUENCE {
+                        //     prime             INTEGER,  -- ri
+                        //     exponent          INTEGER,  -- di
+                        //     coefficient       INTEGER   -- ti
+                        // }
+                        $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
+                        $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
+                        $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
+                        $OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
+                    }
+                    $RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
+                }
+
+                $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
+
+                if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) {
+                    $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+                    $RSAPrivateKey = pack(
+                        'Ca*a*Ca*a*',
+                        self::ASN1_INTEGER,
+                        "\01\00",
+                        $rsaOID,
+                        4,
+                        $this->_encodeLength(strlen($RSAPrivateKey)),
+                        $RSAPrivateKey
+                    );
+                    $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
+                    if (!empty($this->password) || is_string($this->password)) {
+                        $salt = Random::string(8);
+                        $iterationCount = 2048;
+
+                        $crypto = new DES();
+                        $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
+                        $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
+
+                        $parameters = pack(
+                            'Ca*a*Ca*N',
+                            self::ASN1_OCTETSTRING,
+                            $this->_encodeLength(strlen($salt)),
+                            $salt,
+                            self::ASN1_INTEGER,
+                            $this->_encodeLength(4),
+                            $iterationCount
+                        );
+                        $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
+
+                        $encryptionAlgorithm = pack(
+                            'Ca*a*Ca*a*',
+                            self::ASN1_OBJECT,
+                            $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
+                            $pbeWithMD5AndDES_CBC,
+                            self::ASN1_SEQUENCE,
+                            $this->_encodeLength(strlen($parameters)),
+                            $parameters
+                        );
+
+                        $RSAPrivateKey = pack(
+                            'Ca*a*Ca*a*',
+                            self::ASN1_SEQUENCE,
+                            $this->_encodeLength(strlen($encryptionAlgorithm)),
+                            $encryptionAlgorithm,
+                            self::ASN1_OCTETSTRING,
+                            $this->_encodeLength(strlen($RSAPrivateKey)),
+                            $RSAPrivateKey
+                        );
+
+                        $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
+
+                        $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
+                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
+                                         '-----END ENCRYPTED PRIVATE KEY-----';
+                    } else {
+                        $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
+                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
+                                         '-----END PRIVATE KEY-----';
+                    }
+                    return $RSAPrivateKey;
+                }
+
+                if (!empty($this->password) || is_string($this->password)) {
+                    $iv = Random::string(8);
+                    $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
+                    $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
+                    $des = new TripleDES();
+                    $des->setKey($symkey);
+                    $des->setIV($iv);
+                    $iv = strtoupper(bin2hex($iv));
+                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
+                                     "Proc-Type: 4,ENCRYPTED\r\n" .
+                                     "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
+                                     "\r\n" .
+                                     chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
+                                     '-----END RSA PRIVATE KEY-----';
+                } else {
+                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
+                                     chunk_split(base64_encode($RSAPrivateKey), 64) .
+                                     '-----END RSA PRIVATE KEY-----';
+                }
+
+                return $RSAPrivateKey;
+        }
+    }
+
+    /**
+     * Convert a public key to the appropriate format
+     *
+     * @access private
+     * @see self::setPublicKeyFormat()
+     * @param Math_BigInteger $n
+     * @param Math_BigInteger $e
+     * @return string|array<string,Math_BigInteger>
+     */
+    function _convertPublicKey($n, $e)
+    {
+        $signed = $this->publicKeyFormat != self::PUBLIC_FORMAT_XML;
+
+        $modulus = $n->toBytes($signed);
+        $publicExponent = $e->toBytes($signed);
+
+        switch ($this->publicKeyFormat) {
+            case self::PUBLIC_FORMAT_RAW:
+                return array('e' => $e->copy(), 'n' => $n->copy());
+            case self::PUBLIC_FORMAT_XML:
+                return "<RSAKeyValue>\r\n" .
+                       '  <Modulus>' . base64_encode($modulus) . "</Modulus>\r\n" .
+                       '  <Exponent>' . base64_encode($publicExponent) . "</Exponent>\r\n" .
+                       '</RSAKeyValue>';
+                break;
+            case self::PUBLIC_FORMAT_OPENSSH:
+                // from <http://tools.ietf.org/html/rfc4253#page-15>:
+                // string    "ssh-rsa"
+                // mpint     e
+                // mpint     n
+                $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
+                $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment;
+
+                return $RSAPublicKey;
+            default: // eg. self::PUBLIC_FORMAT_PKCS1_RAW or self::PUBLIC_FORMAT_PKCS1
+                // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
+                // RSAPublicKey ::= SEQUENCE {
+                //     modulus           INTEGER,  -- n
+                //     publicExponent    INTEGER   -- e
+                // }
+                $components = array(
+                    'modulus' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
+                    'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
+                );
+
+                $RSAPublicKey = pack(
+                    'Ca*a*a*',
+                    self::ASN1_SEQUENCE,
+                    $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
+                    $components['modulus'],
+                    $components['publicExponent']
+                );
+
+                if ($this->publicKeyFormat == self::PUBLIC_FORMAT_PKCS1_RAW) {
+                    $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
+                                    chunk_split(base64_encode($RSAPublicKey), 64) .
+                                    '-----END RSA PUBLIC KEY-----';
+                } else {
+                    // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
+                    $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+                    $RSAPublicKey = chr(0) . $RSAPublicKey;
+                    $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
+
+                    $RSAPublicKey = pack(
+                        'Ca*a*',
+                        self::ASN1_SEQUENCE,
+                        $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)),
+                        $rsaOID . $RSAPublicKey
+                    );
+
+                    $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
+                                     chunk_split(base64_encode($RSAPublicKey), 64) .
+                                     '-----END PUBLIC KEY-----';
+                }
+
+                return $RSAPublicKey;
+        }
+    }
+
+    /**
+     * Break a public or private key down into its constituant components
+     *
+     * @access private
+     * @see self::_convertPublicKey()
+     * @see self::_convertPrivateKey()
+     * @param string|array $key
+     * @param int $type
+     * @return array|bool
+     */
+    function _parseKey($key, $type)
+    {
+        if ($type != self::PUBLIC_FORMAT_RAW && !is_string($key)) {
+            return false;
+        }
+
+        switch ($type) {
+            case self::PUBLIC_FORMAT_RAW:
+                if (!is_array($key)) {
+                    return false;
+                }
+                $components = array();
+                switch (true) {
+                    case isset($key['e']):
+                        $components['publicExponent'] = $key['e']->copy();
+                        break;
+                    case isset($key['exponent']):
+                        $components['publicExponent'] = $key['exponent']->copy();
+                        break;
+                    case isset($key['publicExponent']):
+                        $components['publicExponent'] = $key['publicExponent']->copy();
+                        break;
+                    case isset($key[0]):
+                        $components['publicExponent'] = $key[0]->copy();
+                }
+                switch (true) {
+                    case isset($key['n']):
+                        $components['modulus'] = $key['n']->copy();
+                        break;
+                    case isset($key['modulo']):
+                        $components['modulus'] = $key['modulo']->copy();
+                        break;
+                    case isset($key['modulus']):
+                        $components['modulus'] = $key['modulus']->copy();
+                        break;
+                    case isset($key[1]):
+                        $components['modulus'] = $key[1]->copy();
+                }
+                return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
+            case self::PRIVATE_FORMAT_PKCS1:
+            case self::PRIVATE_FORMAT_PKCS8:
+            case self::PUBLIC_FORMAT_PKCS1:
+                /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
+                   "outside the scope" of PKCS#1.  PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
+                   protect private keys, however, that's not what OpenSSL* does.  OpenSSL protects private keys by adding
+                   two new "fields" to the key - DEK-Info and Proc-Type.  These fields are discussed here:
+
+                   http://tools.ietf.org/html/rfc1421#section-4.6.1.1
+                   http://tools.ietf.org/html/rfc1421#section-4.6.1.3
+
+                   DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
+                   DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
+                   function.  As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
+                   own implementation.  ie. the implementation *is* the standard and any bugs that may exist in that
+                   implementation are part of the standard, as well.
+
+                   * OpenSSL is the de facto standard.  It's utilized by OpenSSH and other projects */
+                if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
+                    $iv = pack('H*', trim($matches[2]));
+                    $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
+                    $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
+                    // remove the Proc-Type / DEK-Info sections as they're no longer needed
+                    $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
+                    $ciphertext = $this->_extractBER($key);
+                    if ($ciphertext === false) {
+                        $ciphertext = $key;
+                    }
+                    switch ($matches[1]) {
+                        case 'AES-256-CBC':
+                            $crypto = new AES();
+                            break;
+                        case 'AES-128-CBC':
+                            $symkey = substr($symkey, 0, 16);
+                            $crypto = new AES();
+                            break;
+                        case 'DES-EDE3-CFB':
+                            $crypto = new TripleDES(Base::MODE_CFB);
+                            break;
+                        case 'DES-EDE3-CBC':
+                            $symkey = substr($symkey, 0, 24);
+                            $crypto = new TripleDES();
+                            break;
+                        case 'DES-CBC':
+                            $crypto = new DES();
+                            break;
+                        default:
+                            return false;
+                    }
+                    $crypto->setKey($symkey);
+                    $crypto->setIV($iv);
+                    $decoded = $crypto->decrypt($ciphertext);
+                } else {
+                    $decoded = $this->_extractBER($key);
+                }
+
+                if ($decoded !== false) {
+                    $key = $decoded;
+                }
+
+                $components = array();
+
+                if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+                    return false;
+                }
+                if ($this->_decodeLength($key) != strlen($key)) {
+                    return false;
+                }
+
+                $tag = ord($this->_string_shift($key));
+                /* intended for keys for which OpenSSL's asn1parse returns the following:
+
+                    0:d=0  hl=4 l= 631 cons: SEQUENCE
+                    4:d=1  hl=2 l=   1 prim:  INTEGER           :00
+                    7:d=1  hl=2 l=  13 cons:  SEQUENCE
+                    9:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
+                   20:d=2  hl=2 l=   0 prim:   NULL
+                   22:d=1  hl=4 l= 609 prim:  OCTET STRING
+
+                   ie. PKCS8 keys*/
+
+                if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
+                    $this->_string_shift($key, 3);
+                    $tag = self::ASN1_SEQUENCE;
+                }
+
+                if ($tag == self::ASN1_SEQUENCE) {
+                    $temp = $this->_string_shift($key, $this->_decodeLength($key));
+                    if (ord($this->_string_shift($temp)) != self::ASN1_OBJECT) {
+                        return false;
+                    }
+                    $length = $this->_decodeLength($temp);
+                    switch ($this->_string_shift($temp, $length)) {
+                        case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
+                        case "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A": // rsaPSS
+                            break;
+                        case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
+                            /*
+                               PBEParameter ::= SEQUENCE {
+                                   salt OCTET STRING (SIZE(8)),
+                                   iterationCount INTEGER }
+                            */
+                            if (ord($this->_string_shift($temp)) != self::ASN1_SEQUENCE) {
+                                return false;
+                            }
+                            if ($this->_decodeLength($temp) != strlen($temp)) {
+                                return false;
+                            }
+                            $this->_string_shift($temp); // assume it's an octet string
+                            $salt = $this->_string_shift($temp, $this->_decodeLength($temp));
+                            if (ord($this->_string_shift($temp)) != self::ASN1_INTEGER) {
+                                return false;
+                            }
+                            $this->_decodeLength($temp);
+                            list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
+                            $this->_string_shift($key); // assume it's an octet string
+                            $length = $this->_decodeLength($key);
+                            if (strlen($key) != $length) {
+                                return false;
+                            }
+
+                            $crypto = new DES();
+                            $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
+                            $key = $crypto->decrypt($key);
+                            if ($key === false) {
+                                return false;
+                            }
+                            return $this->_parseKey($key, self::PRIVATE_FORMAT_PKCS1);
+                        default:
+                            return false;
+                    }
+                    /* intended for keys for which OpenSSL's asn1parse returns the following:
+
+                        0:d=0  hl=4 l= 290 cons: SEQUENCE
+                        4:d=1  hl=2 l=  13 cons:  SEQUENCE
+                        6:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
+                       17:d=2  hl=2 l=   0 prim:   NULL
+                       19:d=1  hl=4 l= 271 prim:  BIT STRING */
+                    $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
+                    $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
+                    // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
+                    //  unused bits in the final subsequent octet. The number shall be in the range zero to seven."
+                    //  -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
+                    if ($tag == self::ASN1_BITSTRING) {
+                        $this->_string_shift($key);
+                    }
+                    if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+                        return false;
+                    }
+                    if ($this->_decodeLength($key) != strlen($key)) {
+                        return false;
+                    }
+                    $tag = ord($this->_string_shift($key));
+                }
+                if ($tag != self::ASN1_INTEGER) {
+                    return false;
+                }
+
+                $length = $this->_decodeLength($key);
+                $temp = $this->_string_shift($key, $length);
+                if (strlen($temp) != 1 || ord($temp) > 2) {
+                    $components['modulus'] = new BigInteger($temp, 256);
+                    $this->_string_shift($key); // skip over self::ASN1_INTEGER
+                    $length = $this->_decodeLength($key);
+                    $components[$type == self::PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256);
+
+                    return $components;
+                }
+                if (ord($this->_string_shift($key)) != self::ASN1_INTEGER) {
+                    return false;
+                }
+                $length = $this->_decodeLength($key);
+                $components['modulus'] = new BigInteger($this->_string_shift($key, $length), 256);
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['publicExponent'] = new BigInteger($this->_string_shift($key, $length), 256);
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256);
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['primes'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256));
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256);
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['exponents'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256));
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256);
+                $this->_string_shift($key);
+                $length = $this->_decodeLength($key);
+                $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($key, $length), 256));
+
+                if (!empty($key)) {
+                    if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+                        return false;
+                    }
+                    $this->_decodeLength($key);
+                    while (!empty($key)) {
+                        if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+                            return false;
+                        }
+                        $this->_decodeLength($key);
+                        $key = substr($key, 1);
+                        $length = $this->_decodeLength($key);
+                        $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256);
+                        $this->_string_shift($key);
+                        $length = $this->_decodeLength($key);
+                        $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256);
+                        $this->_string_shift($key);
+                        $length = $this->_decodeLength($key);
+                        $components['coefficients'][] = new BigInteger($this->_string_shift($key, $length), 256);
+                    }
+                }
+
+                return $components;
+            case self::PUBLIC_FORMAT_OPENSSH:
+                $parts = explode(' ', $key, 3);
+
+                $key = isset($parts[1]) ? base64_decode($parts[1]) : false;
+                if ($key === false) {
+                    return false;
+                }
+
+                $comment = isset($parts[2]) ? $parts[2] : false;
+
+                $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
+
+                if (strlen($key) <= 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($key, 4)));
+                $publicExponent = new BigInteger($this->_string_shift($key, $length), -256);
+                if (strlen($key) <= 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($key, 4)));
+                $modulus = new BigInteger($this->_string_shift($key, $length), -256);
+
+                if ($cleanup && strlen($key)) {
+                    if (strlen($key) <= 4) {
+                        return false;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($key, 4)));
+                    $realModulus = new BigInteger($this->_string_shift($key, $length), -256);
+                    return strlen($key) ? false : array(
+                        'modulus' => $realModulus,
+                        'publicExponent' => $modulus,
+                        'comment' => $comment
+                    );
+                } else {
+                    return strlen($key) ? false : array(
+                        'modulus' => $modulus,
+                        'publicExponent' => $publicExponent,
+                        'comment' => $comment
+                    );
+                }
+            // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
+            // http://en.wikipedia.org/wiki/XML_Signature
+            case self::PRIVATE_FORMAT_XML:
+            case self::PUBLIC_FORMAT_XML:
+                if (!extension_loaded('xml')) {
+                    return false;
+                }
+
+                $this->components = array();
+
+                $xml = xml_parser_create('UTF-8');
+                xml_set_object($xml, $this);
+                xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
+                xml_set_character_data_handler($xml, '_data_handler');
+                // add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
+                if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
+                    xml_parser_free($xml);
+                    unset($xml);
+                    return false;
+                }
+
+                xml_parser_free($xml);
+                unset($xml);
+
+                return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
+            // see PuTTY's SSHPUBK.C and https://tartarus.org/~simon/putty-snapshots/htmldoc/AppendixC.html
+            case self::PRIVATE_FORMAT_PUTTY:
+                $components = array();
+                $key = preg_split('#\r\n|\r|\n#', $key);
+                if ($this->_string_shift($key[0], strlen('PuTTY-User-Key-File-')) != 'PuTTY-User-Key-File-') {
+                    return false;
+                }
+                $version = (int) $this->_string_shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting
+                if ($version != 2 && $version != 3) {
+                    return false;
+                }
+                $type = rtrim($key[0]);
+                if ($type != 'ssh-rsa') {
+                    return false;
+                }
+                $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
+                $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
+
+                $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
+                $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
+                $public = substr($public, 11);
+                extract(unpack('Nlength', $this->_string_shift($public, 4)));
+                $components['publicExponent'] = new BigInteger($this->_string_shift($public, $length), -256);
+                extract(unpack('Nlength', $this->_string_shift($public, 4)));
+                $components['modulus'] = new BigInteger($this->_string_shift($public, $length), -256);
+
+                $offset = $publicLength + 4;
+                switch ($encryption) {
+                    case 'aes256-cbc':
+                        $crypto = new AES();
+                        switch ($version) {
+                            case 3:
+                                if (!function_exists('sodium_crypto_pwhash')) {
+                                    return false;
+                                }
+                                $flavour = trim(preg_replace('#Key-Derivation: (.*)#', '$1', $key[$offset++]));
+                                switch ($flavour) {
+                                    case 'Argon2i':
+                                        $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13;
+                                        break;
+                                    case 'Argon2id':
+                                        $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13;
+                                        break;
+                                    default:
+                                        return false;
+                                }
+                                $memory = trim(preg_replace('#Argon2-Memory: (\d+)#', '$1', $key[$offset++]));
+                                $passes = trim(preg_replace('#Argon2-Passes: (\d+)#', '$1', $key[$offset++]));
+                                $parallelism = trim(preg_replace('#Argon2-Parallelism: (\d+)#', '$1', $key[$offset++]));
+                                $salt = pack('H*', trim(preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++])));
+
+                                $length = 80; // keylen + ivlen + mac_keylen
+                                $temp = sodium_crypto_pwhash($length, $this->password, $salt, $passes, $memory << 10, $flavour);
+
+                                $symkey = substr($temp, 0, 32);
+                                $symiv = substr($temp, 32, 16);
+                                break;
+                            case 2:
+                                $symkey = '';
+                                $sequence = 0;
+                                while (strlen($symkey) < 32) {
+                                    $temp = pack('Na*', $sequence++, $this->password);
+                                    $symkey.= pack('H*', sha1($temp));
+                                }
+                                $symkey = substr($symkey, 0, 32);
+                                $symiv = str_repeat("\0", 16);
+                        }
+                }
+
+                $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$offset++]));
+                $private = base64_decode(implode('', array_map('trim', array_slice($key, $offset, $privateLength))));
+
+                if ($encryption != 'none') {
+                    $crypto->setKey($symkey);
+                    $crypto->setIV($symiv);
+                    $crypto->disablePadding();
+                    $private = $crypto->decrypt($private);
+                    if ($private === false) {
+                        return false;
+                    }
+                }
+
+                extract(unpack('Nlength', $this->_string_shift($private, 4)));
+                if (strlen($private) < $length) {
+                    return false;
+                }
+                $components['privateExponent'] = new BigInteger($this->_string_shift($private, $length), -256);
+                extract(unpack('Nlength', $this->_string_shift($private, 4)));
+                if (strlen($private) < $length) {
+                    return false;
+                }
+                $components['primes'] = array(1 => new BigInteger($this->_string_shift($private, $length), -256));
+                extract(unpack('Nlength', $this->_string_shift($private, 4)));
+                if (strlen($private) < $length) {
+                    return false;
+                }
+                $components['primes'][] = new BigInteger($this->_string_shift($private, $length), -256);
+
+                $temp = $components['primes'][1]->subtract($this->one);
+                $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
+                $temp = $components['primes'][2]->subtract($this->one);
+                $components['exponents'][] = $components['publicExponent']->modInverse($temp);
+
+                extract(unpack('Nlength', $this->_string_shift($private, 4)));
+                if (strlen($private) < $length) {
+                    return false;
+                }
+                $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($private, $length), -256));
+
+                return $components;
+            case self::PRIVATE_FORMAT_OPENSSH:
+                $components = array();
+                $decoded = $this->_extractBER($key);
+                $magic = $this->_string_shift($decoded, 15);
+                if ($magic !== "openssh-key-v1\0") {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+                if (strlen($decoded) < $length) {
+                    return false;
+                }
+                $ciphername = $this->_string_shift($decoded, $length);
+                extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+                if (strlen($decoded) < $length) {
+                    return false;
+                }
+                $kdfname = $this->_string_shift($decoded, $length);
+                extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+                if (strlen($decoded) < $length) {
+                    return false;
+                }
+                $kdfoptions = $this->_string_shift($decoded, $length);
+                extract(unpack('Nnumkeys', $this->_string_shift($decoded, 4)));
+                if ($numkeys != 1 || ($ciphername != 'none' && $kdfname != 'bcrypt')) {
+                    return false;
+                }
+                switch ($ciphername) {
+                    case 'none':
+                        break;
+                    case 'aes256-ctr':
+                        extract(unpack('Nlength', $this->_string_shift($kdfoptions, 4)));
+                        if (strlen($kdfoptions) < $length) {
+                            return false;
+                        }
+                        $salt = $this->_string_shift($kdfoptions, $length);
+                        extract(unpack('Nrounds', $this->_string_shift($kdfoptions, 4)));
+                        $crypto = new AES(AES::MODE_CTR);
+                        $crypto->disablePadding();
+                        if (!$crypto->setPassword($this->password, 'bcrypt', $salt, $rounds, 32)) {
+                            return false;
+                        }
+                        break;
+                    default:
+                        return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+                if (strlen($decoded) < $length) {
+                    return false;
+                }
+                $publicKey = $this->_string_shift($decoded, $length);
+                extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+                if (strlen($decoded) < $length) {
+                    return false;
+                }
+
+                if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") {
+                    return false;
+                }
+
+                $paddedKey = $this->_string_shift($decoded, $length);
+                if (isset($crypto)) {
+                    $paddedKey = $crypto->decrypt($paddedKey);
+                }
+
+                $checkint1 = $this->_string_shift($paddedKey, 4);
+                $checkint2 = $this->_string_shift($paddedKey, 4);
+                if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) {
+                    return false;
+                }
+
+                if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") {
+                    return false;
+                }
+
+                $values = array(
+                    &$components['modulus'],
+                    &$components['publicExponent'],
+                    &$components['privateExponent'],
+                    &$components['coefficients'][2],
+                    &$components['primes'][1],
+                    &$components['primes'][2]
+                );
+
+                foreach ($values as &$value) {
+                    extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
+                    if (strlen($paddedKey) < $length) {
+                        return false;
+                    }
+                    $value = new BigInteger($this->_string_shift($paddedKey, $length), -256);
+                }
+
+                extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
+                if (strlen($paddedKey) < $length) {
+                    return false;
+                }
+                $components['comment'] = $this->_string_shift($decoded, $length);
+
+                $temp = $components['primes'][1]->subtract($this->one);
+                $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
+                $temp = $components['primes'][2]->subtract($this->one);
+                $components['exponents'][] = $components['publicExponent']->modInverse($temp);
+
+                return $components;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the key size
+     *
+     * More specifically, this returns the size of the modulo in bits.
+     *
+     * @access public
+     * @return int
+     */
+    function getSize()
+    {
+        return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits());
+    }
+
+    /**
+     * Start Element Handler
+     *
+     * Called by xml_set_element_handler()
+     *
+     * @access private
+     * @param resource $parser
+     * @param string $name
+     * @param array $attribs
+     */
+    function _start_element_handler($parser, $name, $attribs)
+    {
+        //$name = strtoupper($name);
+        switch ($name) {
+            case 'MODULUS':
+                $this->current = &$this->components['modulus'];
+                break;
+            case 'EXPONENT':
+                $this->current = &$this->components['publicExponent'];
+                break;
+            case 'P':
+                $this->current = &$this->components['primes'][1];
+                break;
+            case 'Q':
+                $this->current = &$this->components['primes'][2];
+                break;
+            case 'DP':
+                $this->current = &$this->components['exponents'][1];
+                break;
+            case 'DQ':
+                $this->current = &$this->components['exponents'][2];
+                break;
+            case 'INVERSEQ':
+                $this->current = &$this->components['coefficients'][2];
+                break;
+            case 'D':
+                $this->current = &$this->components['privateExponent'];
+        }
+        $this->current = '';
+    }
+
+    /**
+     * Stop Element Handler
+     *
+     * Called by xml_set_element_handler()
+     *
+     * @access private
+     * @param resource $parser
+     * @param string $name
+     */
+    function _stop_element_handler($parser, $name)
+    {
+        if (isset($this->current)) {
+            $this->current = new BigInteger(base64_decode($this->current), 256);
+            unset($this->current);
+        }
+    }
+
+    /**
+     * Data Handler
+     *
+     * Called by xml_set_character_data_handler()
+     *
+     * @access private
+     * @param resource $parser
+     * @param string $data
+     */
+    function _data_handler($parser, $data)
+    {
+        if (!isset($this->current) || is_object($this->current)) {
+            return;
+        }
+        $this->current.= trim($data);
+    }
+
+    /**
+     * Loads a public or private key
+     *
+     * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
+     *
+     * @access public
+     * @param string|RSA|array $key
+     * @param bool|int $type optional
+     * @return bool
+     */
+    function loadKey($key, $type = false)
+    {
+        if ($key instanceof RSA) {
+            $this->privateKeyFormat = $key->privateKeyFormat;
+            $this->publicKeyFormat = $key->publicKeyFormat;
+            $this->k = $key->k;
+            $this->hLen = $key->hLen;
+            $this->sLen = $key->sLen;
+            $this->mgfHLen = $key->mgfHLen;
+            $this->encryptionMode = $key->encryptionMode;
+            $this->signatureMode = $key->signatureMode;
+            $this->password = $key->password;
+            $this->configFile = $key->configFile;
+            $this->comment = $key->comment;
+
+            if (is_object($key->hash)) {
+                $this->hash = new Hash($key->hash->getHash());
+            }
+            if (is_object($key->mgfHash)) {
+                $this->mgfHash = new Hash($key->mgfHash->getHash());
+            }
+
+            if (is_object($key->modulus)) {
+                $this->modulus = $key->modulus->copy();
+            }
+            if (is_object($key->exponent)) {
+                $this->exponent = $key->exponent->copy();
+            }
+            if (is_object($key->publicExponent)) {
+                $this->publicExponent = $key->publicExponent->copy();
+            }
+
+            $this->primes = array();
+            $this->exponents = array();
+            $this->coefficients = array();
+
+            foreach ($this->primes as $prime) {
+                $this->primes[] = $prime->copy();
+            }
+            foreach ($this->exponents as $exponent) {
+                $this->exponents[] = $exponent->copy();
+            }
+            foreach ($this->coefficients as $coefficient) {
+                $this->coefficients[] = $coefficient->copy();
+            }
+
+            return true;
+        }
+
+        if ($type === false) {
+            $types = array(
+                self::PUBLIC_FORMAT_RAW,
+                self::PRIVATE_FORMAT_PKCS1,
+                self::PRIVATE_FORMAT_XML,
+                self::PRIVATE_FORMAT_PUTTY,
+                self::PUBLIC_FORMAT_OPENSSH,
+                self::PRIVATE_FORMAT_OPENSSH
+            );
+            foreach ($types as $type) {
+                $components = $this->_parseKey($key, $type);
+                if ($components !== false) {
+                    break;
+                }
+            }
+        } else {
+            $components = $this->_parseKey($key, $type);
+        }
+
+        if ($components === false) {
+            $this->comment = null;
+            $this->modulus = null;
+            $this->k = null;
+            $this->exponent = null;
+            $this->primes = null;
+            $this->exponents = null;
+            $this->coefficients = null;
+            $this->publicExponent = null;
+
+            return false;
+        }
+
+        if (isset($components['comment']) && $components['comment'] !== false) {
+            $this->comment = $components['comment'];
+        }
+        $this->modulus = $components['modulus'];
+        $this->k = strlen($this->modulus->toBytes());
+        $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
+        if (isset($components['primes'])) {
+            $this->primes = $components['primes'];
+            $this->exponents = $components['exponents'];
+            $this->coefficients = $components['coefficients'];
+            $this->publicExponent = $components['publicExponent'];
+        } else {
+            $this->primes = array();
+            $this->exponents = array();
+            $this->coefficients = array();
+            $this->publicExponent = false;
+        }
+
+        switch ($type) {
+            case self::PUBLIC_FORMAT_OPENSSH:
+            case self::PUBLIC_FORMAT_RAW:
+                $this->setPublicKey();
+                break;
+            case self::PRIVATE_FORMAT_PKCS1:
+                switch (true) {
+                    case strpos($key, '-BEGIN PUBLIC KEY-') !== false:
+                    case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false:
+                        $this->setPublicKey();
+                }
+        }
+
+        return true;
+    }
+
+    /**
+     * Sets the password
+     *
+     * Private keys can be encrypted with a password.  To unset the password, pass in the empty string or false.
+     * Or rather, pass in $password such that empty($password) && !is_string($password) is true.
+     *
+     * @see self::createKey()
+     * @see self::loadKey()
+     * @access public
+     * @param string $password
+     */
+    function setPassword($password = false)
+    {
+        $this->password = $password;
+    }
+
+    /**
+     * Defines the public key
+     *
+     * Some private key formats define the public exponent and some don't.  Those that don't define it are problematic when
+     * used in certain contexts.  For example, in SSH-2, RSA authentication works by sending the public key along with a
+     * message signed by the private key to the server.  The SSH-2 server looks the public key up in an index of public keys
+     * and if it's present then proceeds to verify the signature.  Problem is, if your private key doesn't include the public
+     * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used
+     * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being
+     * public.
+     *
+     * Do note that when a new key is loaded the index will be cleared.
+     *
+     * Returns true on success, false on failure
+     *
+     * @see self::getPublicKey()
+     * @access public
+     * @param string $key optional
+     * @param int $type optional
+     * @return bool
+     */
+    function setPublicKey($key = false, $type = false)
+    {
+        // if a public key has already been loaded return false
+        if (!empty($this->publicExponent)) {
+            return false;
+        }
+
+        if ($key === false && !empty($this->modulus)) {
+            $this->publicExponent = $this->exponent;
+            return true;
+        }
+
+        if ($type === false) {
+            $types = array(
+                self::PUBLIC_FORMAT_RAW,
+                self::PUBLIC_FORMAT_PKCS1,
+                self::PUBLIC_FORMAT_XML,
+                self::PUBLIC_FORMAT_OPENSSH
+            );
+            foreach ($types as $type) {
+                $components = $this->_parseKey($key, $type);
+                if ($components !== false) {
+                    break;
+                }
+            }
+        } else {
+            $components = $this->_parseKey($key, $type);
+        }
+
+        if ($components === false) {
+            return false;
+        }
+
+        if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {
+            $this->modulus = $components['modulus'];
+            $this->exponent = $this->publicExponent = $components['publicExponent'];
+            return true;
+        }
+
+        $this->publicExponent = $components['publicExponent'];
+
+        return true;
+    }
+
+    /**
+     * Defines the private key
+     *
+     * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force
+     * phpseclib to treat the key as a private key. This function will do that.
+     *
+     * Do note that when a new key is loaded the index will be cleared.
+     *
+     * Returns true on success, false on failure
+     *
+     * @see self::getPublicKey()
+     * @access public
+     * @param string $key optional
+     * @param int $type optional
+     * @return bool
+     */
+    function setPrivateKey($key = false, $type = false)
+    {
+        if ($key === false && !empty($this->publicExponent)) {
+            $this->publicExponent = false;
+            return true;
+        }
+
+        $rsa = new RSA();
+        if (!$rsa->loadKey($key, $type)) {
+            return false;
+        }
+        $rsa->publicExponent = false;
+
+        // don't overwrite the old key if the new key is invalid
+        $this->loadKey($rsa);
+        return true;
+    }
+
+    /**
+     * Returns the public key
+     *
+     * The public key is only returned under two circumstances - if the private key had the public key embedded within it
+     * or if the public key was set via setPublicKey().  If the currently loaded key is supposed to be the public key this
+     * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
+     *
+     * @see self::getPublicKey()
+     * @access public
+     * @param int $type optional
+     */
+    function getPublicKey($type = self::PUBLIC_FORMAT_PKCS8)
+    {
+        if (empty($this->modulus) || empty($this->publicExponent)) {
+            return false;
+        }
+
+        $oldFormat = $this->publicKeyFormat;
+        $this->publicKeyFormat = $type;
+        $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);
+        $this->publicKeyFormat = $oldFormat;
+        return $temp;
+    }
+
+    /**
+     * Returns the public key's fingerprint
+     *
+     * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is
+     * no public key currently loaded, false is returned.
+     * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716)
+     *
+     * @access public
+     * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned
+     * for invalid values.
+     * @return mixed
+     */
+    function getPublicKeyFingerprint($algorithm = 'md5')
+    {
+        if (empty($this->modulus) || empty($this->publicExponent)) {
+            return false;
+        }
+
+        $modulus = $this->modulus->toBytes(true);
+        $publicExponent = $this->publicExponent->toBytes(true);
+
+        $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
+
+        switch ($algorithm) {
+            case 'sha256':
+                $hash = new Hash('sha256');
+                $base = base64_encode($hash->hash($RSAPublicKey));
+                return substr($base, 0, strlen($base) - 1);
+            case 'md5':
+                return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1);
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Returns the private key
+     *
+     * The private key is only returned if the currently loaded key contains the constituent prime numbers.
+     *
+     * @see self::getPublicKey()
+     * @access public
+     * @param int $type optional
+     * @return mixed
+     */
+    function getPrivateKey($type = self::PUBLIC_FORMAT_PKCS1)
+    {
+        if (empty($this->primes)) {
+            return false;
+        }
+
+        $oldFormat = $this->privateKeyFormat;
+        $this->privateKeyFormat = $type;
+        $temp = $this->_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients);
+        $this->privateKeyFormat = $oldFormat;
+        return $temp;
+    }
+
+    /**
+     * Returns a minimalistic private key
+     *
+     * Returns the private key without the prime number constituants.  Structurally identical to a public key that
+     * hasn't been set as the public key
+     *
+     * @see self::getPrivateKey()
+     * @access private
+     * @param int $mode optional
+     */
+    function _getPrivatePublicKey($mode = self::PUBLIC_FORMAT_PKCS8)
+    {
+        if (empty($this->modulus) || empty($this->exponent)) {
+            return false;
+        }
+
+        $oldFormat = $this->publicKeyFormat;
+        $this->publicKeyFormat = $mode;
+        $temp = $this->_convertPublicKey($this->modulus, $this->exponent);
+        $this->publicKeyFormat = $oldFormat;
+        return $temp;
+    }
+
+    /**
+     *  __toString() magic method
+     *
+     * @access public
+     * @return string
+     */
+    function __toString()
+    {
+        $key = $this->getPrivateKey($this->privateKeyFormat);
+        if ($key !== false) {
+            return $key;
+        }
+        $key = $this->_getPrivatePublicKey($this->publicKeyFormat);
+        return $key !== false ? $key : '';
+    }
+
+    /**
+     *  __clone() magic method
+     *
+     * @access public
+     * @return Crypt_RSA
+     */
+    function __clone()
+    {
+        $key = new RSA();
+        $key->loadKey($this);
+        return $key;
+    }
+
+    /**
+     * Generates the smallest and largest numbers requiring $bits bits
+     *
+     * @access private
+     * @param int $bits
+     * @return array
+     */
+    function _generateMinMax($bits)
+    {
+        $bytes = $bits >> 3;
+        $min = str_repeat(chr(0), $bytes);
+        $max = str_repeat(chr(0xFF), $bytes);
+        $msb = $bits & 7;
+        if ($msb) {
+            $min = chr(1 << ($msb - 1)) . $min;
+            $max = chr((1 << $msb) - 1) . $max;
+        } else {
+            $min[0] = chr(0x80);
+        }
+
+        return array(
+            'min' => new BigInteger($min, 256),
+            'max' => new BigInteger($max, 256)
+        );
+    }
+
+    /**
+     * DER-decode the length
+     *
+     * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4.  See
+     * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+     *
+     * @access private
+     * @param string $string
+     * @return int
+     */
+    function _decodeLength(&$string)
+    {
+        $length = ord($this->_string_shift($string));
+        if ($length & 0x80) { // definite length, long form
+            $length&= 0x7F;
+            $temp = $this->_string_shift($string, $length);
+            list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
+        }
+        return $length;
+    }
+
+    /**
+     * DER-encode the length
+     *
+     * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4.  See
+     * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+     *
+     * @access private
+     * @param int $length
+     * @return string
+     */
+    function _encodeLength($length)
+    {
+        if ($length <= 0x7F) {
+            return chr($length);
+        }
+
+        $temp = ltrim(pack('N', $length), chr(0));
+        return pack('Ca*', 0x80 | strlen($temp), $temp);
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @return string
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+
+    /**
+     * Determines the private key format
+     *
+     * @see self::createKey()
+     * @access public
+     * @param int $format
+     */
+    function setPrivateKeyFormat($format)
+    {
+        $this->privateKeyFormat = $format;
+    }
+
+    /**
+     * Determines the public key format
+     *
+     * @see self::createKey()
+     * @access public
+     * @param int $format
+     */
+    function setPublicKeyFormat($format)
+    {
+        $this->publicKeyFormat = $format;
+    }
+
+    /**
+     * Determines which hashing function should be used
+     *
+     * Used with signature production / verification and (if the encryption mode is self::ENCRYPTION_OAEP) encryption and
+     * decryption.  If $hash isn't supported, sha1 is used.
+     *
+     * @access public
+     * @param string $hash
+     */
+    function setHash($hash)
+    {
+        // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
+        switch ($hash) {
+            case 'md2':
+            case 'md5':
+            case 'sha1':
+            case 'sha256':
+            case 'sha384':
+            case 'sha512':
+                $this->hash = new Hash($hash);
+                $this->hashName = $hash;
+                break;
+            default:
+                $this->hash = new Hash('sha1');
+                $this->hashName = 'sha1';
+        }
+        $this->hLen = $this->hash->getLength();
+    }
+
+    /**
+     * Determines which hashing function should be used for the mask generation function
+     *
+     * The mask generation function is used by self::ENCRYPTION_OAEP and self::SIGNATURE_PSS and although it's
+     * best if Hash and MGFHash are set to the same thing this is not a requirement.
+     *
+     * @access public
+     * @param string $hash
+     */
+    function setMGFHash($hash)
+    {
+        // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support.  md5-96 and sha1-96, for example.
+        switch ($hash) {
+            case 'md2':
+            case 'md5':
+            case 'sha1':
+            case 'sha256':
+            case 'sha384':
+            case 'sha512':
+                $this->mgfHash = new Hash($hash);
+                break;
+            default:
+                $this->mgfHash = new Hash('sha1');
+        }
+        $this->mgfHLen = $this->mgfHash->getLength();
+    }
+
+    /**
+     * Determines the salt length
+     *
+     * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
+     *
+     *    Typical salt lengths in octets are hLen (the length of the output
+     *    of the hash function Hash) and 0.
+     *
+     * @access public
+     * @param int $sLen
+     */
+    function setSaltLength($sLen)
+    {
+        $this->sLen = $sLen;
+    }
+
+    /**
+     * Integer-to-Octet-String primitive
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $x
+     * @param int $xLen
+     * @return string
+     */
+    function _i2osp($x, $xLen)
+    {
+        $x = $x->toBytes();
+        if (strlen($x) > $xLen) {
+            user_error('Integer too large');
+            return false;
+        }
+        return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
+    }
+
+    /**
+     * Octet-String-to-Integer primitive
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
+     *
+     * @access private
+     * @param int|string|resource $x
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _os2ip($x)
+    {
+        return new BigInteger($x, 256);
+    }
+
+    /**
+     * Exponentiate with or without Chinese Remainder Theorem
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $x
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _exponentiate($x)
+    {
+        switch (true) {
+            case empty($this->primes):
+            case $this->primes[1]->equals($this->zero):
+            case empty($this->coefficients):
+            case $this->coefficients[2]->equals($this->zero):
+            case empty($this->exponents):
+            case $this->exponents[1]->equals($this->zero):
+                return $x->modPow($this->exponent, $this->modulus);
+        }
+
+        $num_primes = count($this->primes);
+
+        if (defined('CRYPT_RSA_DISABLE_BLINDING')) {
+            $m_i = array(
+                1 => $x->modPow($this->exponents[1], $this->primes[1]),
+                2 => $x->modPow($this->exponents[2], $this->primes[2])
+            );
+            $h = $m_i[1]->subtract($m_i[2]);
+            $h = $h->multiply($this->coefficients[2]);
+            list(, $h) = $h->divide($this->primes[1]);
+            $m = $m_i[2]->add($h->multiply($this->primes[2]));
+
+            $r = $this->primes[1];
+            for ($i = 3; $i <= $num_primes; $i++) {
+                $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
+
+                $r = $r->multiply($this->primes[$i - 1]);
+
+                $h = $m_i->subtract($m);
+                $h = $h->multiply($this->coefficients[$i]);
+                list(, $h) = $h->divide($this->primes[$i]);
+
+                $m = $m->add($r->multiply($h));
+            }
+        } else {
+            $smallest = $this->primes[1];
+            for ($i = 2; $i <= $num_primes; $i++) {
+                if ($smallest->compare($this->primes[$i]) > 0) {
+                    $smallest = $this->primes[$i];
+                }
+            }
+
+            $one = new BigInteger(1);
+
+            $r = $one->random($one, $smallest->subtract($one));
+
+            $m_i = array(
+                1 => $this->_blind($x, $r, 1),
+                2 => $this->_blind($x, $r, 2)
+            );
+            $h = $m_i[1]->subtract($m_i[2]);
+            $h = $h->multiply($this->coefficients[2]);
+            list(, $h) = $h->divide($this->primes[1]);
+            $m = $m_i[2]->add($h->multiply($this->primes[2]));
+
+            $r = $this->primes[1];
+            for ($i = 3; $i <= $num_primes; $i++) {
+                $m_i = $this->_blind($x, $r, $i);
+
+                $r = $r->multiply($this->primes[$i - 1]);
+
+                $h = $m_i->subtract($m);
+                $h = $h->multiply($this->coefficients[$i]);
+                list(, $h) = $h->divide($this->primes[$i]);
+
+                $m = $m->add($r->multiply($h));
+            }
+        }
+
+        return $m;
+    }
+
+    /**
+     * Performs RSA Blinding
+     *
+     * Protects against timing attacks by employing RSA Blinding.
+     * Returns $x->modPow($this->exponents[$i], $this->primes[$i])
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $x
+     * @param \phpseclib\Math\BigInteger $r
+     * @param int $i
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _blind($x, $r, $i)
+    {
+        $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i]));
+        $x = $x->modPow($this->exponents[$i], $this->primes[$i]);
+
+        $r = $r->modInverse($this->primes[$i]);
+        $x = $x->multiply($r);
+        list(, $x) = $x->divide($this->primes[$i]);
+
+        return $x;
+    }
+
+    /**
+     * Performs blinded RSA equality testing
+     *
+     * Protects against a particular type of timing attack described.
+     *
+     * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)}
+     *
+     * Thanks for the heads up singpolyma!
+     *
+     * @access private
+     * @param string $x
+     * @param string $y
+     * @return bool
+     */
+    function _equals($x, $y)
+    {
+        if (function_exists('hash_equals')) {
+            return hash_equals($x, $y);
+        }
+
+        if (strlen($x) != strlen($y)) {
+            return false;
+        }
+
+        $result = "\0";
+        $x^= $y;
+        for ($i = 0; $i < strlen($x); $i++) {
+            $result|= $x[$i];
+        }
+
+        return $result === "\0";
+    }
+
+    /**
+     * RSAEP
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $m
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _rsaep($m)
+    {
+        if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
+            user_error('Message representative out of range');
+            return false;
+        }
+        return $this->_exponentiate($m);
+    }
+
+    /**
+     * RSADP
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $c
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _rsadp($c)
+    {
+        if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
+            user_error('Ciphertext representative out of range');
+            return false;
+        }
+        return $this->_exponentiate($c);
+    }
+
+    /**
+     * RSASP1
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $m
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _rsasp1($m)
+    {
+        if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
+            user_error('Message representative out of range');
+            return false;
+        }
+        return $this->_exponentiate($m);
+    }
+
+    /**
+     * RSAVP1
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
+     *
+     * @access private
+     * @param \phpseclib\Math\BigInteger $s
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _rsavp1($s)
+    {
+        if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
+            user_error('Signature representative out of range');
+            return false;
+        }
+        return $this->_exponentiate($s);
+    }
+
+    /**
+     * MGF1
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
+     *
+     * @access private
+     * @param string $mgfSeed
+     * @param int $maskLen
+     * @return string
+     */
+    function _mgf1($mgfSeed, $maskLen)
+    {
+        // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
+
+        $t = '';
+        $count = ceil($maskLen / $this->mgfHLen);
+        for ($i = 0; $i < $count; $i++) {
+            $c = pack('N', $i);
+            $t.= $this->mgfHash->hash($mgfSeed . $c);
+        }
+
+        return substr($t, 0, $maskLen);
+    }
+
+    /**
+     * RSAES-OAEP-ENCRYPT
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
+     * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
+     *
+     * @access private
+     * @param string $m
+     * @param string $l
+     * @return string
+     */
+    function _rsaes_oaep_encrypt($m, $l = '')
+    {
+        $mLen = strlen($m);
+
+        // Length checking
+
+        // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+        // be output.
+
+        if ($mLen > $this->k - 2 * $this->hLen - 2) {
+            user_error('Message too long');
+            return false;
+        }
+
+        // EME-OAEP encoding
+
+        $lHash = $this->hash->hash($l);
+        $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
+        $db = $lHash . $ps . chr(1) . $m;
+        $seed = Random::string($this->hLen);
+        $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
+        $maskedDB = $db ^ $dbMask;
+        $seedMask = $this->_mgf1($maskedDB, $this->hLen);
+        $maskedSeed = $seed ^ $seedMask;
+        $em = chr(0) . $maskedSeed . $maskedDB;
+
+        // RSA encryption
+
+        $m = $this->_os2ip($em);
+        $c = $this->_rsaep($m);
+        $c = $this->_i2osp($c, $this->k);
+
+        // Output the ciphertext C
+
+        return $c;
+    }
+
+    /**
+     * RSAES-OAEP-DECRYPT
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}.  The fact that the error
+     * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:
+     *
+     *    Note.  Care must be taken to ensure that an opponent cannot
+     *    distinguish the different error conditions in Step 3.g, whether by
+     *    error message or timing, or, more generally, learn partial
+     *    information about the encoded message EM.  Otherwise an opponent may
+     *    be able to obtain useful information about the decryption of the
+     *    ciphertext C, leading to a chosen-ciphertext attack such as the one
+     *    observed by Manger [36].
+     *
+     * As for $l...  to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
+     *
+     *    Both the encryption and the decryption operations of RSAES-OAEP take
+     *    the value of a label L as input.  In this version of PKCS #1, L is
+     *    the empty string; other uses of the label are outside the scope of
+     *    this document.
+     *
+     * @access private
+     * @param string $c
+     * @param string $l
+     * @return string
+     */
+    function _rsaes_oaep_decrypt($c, $l = '')
+    {
+        // Length checking
+
+        // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+        // be output.
+
+        if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
+            user_error('Decryption error');
+            return false;
+        }
+
+        // RSA decryption
+
+        $c = $this->_os2ip($c);
+        $m = $this->_rsadp($c);
+        if ($m === false) {
+            user_error('Decryption error');
+            return false;
+        }
+        $em = $this->_i2osp($m, $this->k);
+
+        // EME-OAEP decoding
+
+        $lHash = $this->hash->hash($l);
+        $y = ord($em[0]);
+        $maskedSeed = substr($em, 1, $this->hLen);
+        $maskedDB = substr($em, $this->hLen + 1);
+        $seedMask = $this->_mgf1($maskedDB, $this->hLen);
+        $seed = $maskedSeed ^ $seedMask;
+        $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
+        $db = $maskedDB ^ $dbMask;
+        $lHash2 = substr($db, 0, $this->hLen);
+        $m = substr($db, $this->hLen);
+        $hashesMatch = $this->_equals($lHash, $lHash2);
+        $leadingZeros = 1;
+        $patternMatch = 0;
+        $offset = 0;
+        for ($i = 0; $i < strlen($m); $i++) {
+            $patternMatch|= $leadingZeros & ($m[$i] === "\1");
+            $leadingZeros&= $m[$i] === "\0";
+            $offset+= $patternMatch ? 0 : 1;
+        }
+
+        // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
+        // to protect against timing attacks
+        if (!$hashesMatch | !$patternMatch) {
+            user_error('Decryption error');
+            return false;
+        }
+
+        // Output the message M
+
+        return substr($m, $offset + 1);
+    }
+
+    /**
+     * Raw Encryption / Decryption
+     *
+     * Doesn't use padding and is not recommended.
+     *
+     * @access private
+     * @param string $m
+     * @return string
+     */
+    function _raw_encrypt($m)
+    {
+        $temp = $this->_os2ip($m);
+        $temp = $this->_rsaep($temp);
+        return  $this->_i2osp($temp, $this->k);
+    }
+
+    /**
+     * RSAES-PKCS1-V1_5-ENCRYPT
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
+     *
+     * @access private
+     * @param string $m
+     * @return string
+     */
+    function _rsaes_pkcs1_v1_5_encrypt($m)
+    {
+        $mLen = strlen($m);
+
+        // Length checking
+
+        if ($mLen > $this->k - 11) {
+            user_error('Message too long');
+            return false;
+        }
+
+        // EME-PKCS1-v1_5 encoding
+
+        $psLen = $this->k - $mLen - 3;
+        $ps = '';
+        while (strlen($ps) != $psLen) {
+            $temp = Random::string($psLen - strlen($ps));
+            $temp = str_replace("\x00", '', $temp);
+            $ps.= $temp;
+        }
+        $type = 2;
+        // see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done
+        if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) {
+            $type = 1;
+            // "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF"
+            $ps = str_repeat("\xFF", $psLen);
+        }
+        $em = chr(0) . chr($type) . $ps . chr(0) . $m;
+
+        // RSA encryption
+        $m = $this->_os2ip($em);
+        $c = $this->_rsaep($m);
+        $c = $this->_i2osp($c, $this->k);
+
+        // Output the ciphertext C
+
+        return $c;
+    }
+
+    /**
+     * RSAES-PKCS1-V1_5-DECRYPT
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.
+     *
+     * For compatibility purposes, this function departs slightly from the description given in RFC3447.
+     * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the
+     * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the
+     * public key should have the second byte set to 2.  In RFC3447 (PKCS#1 v2.1), the second byte is supposed
+     * to be 2 regardless of which key is used.  For compatibility purposes, we'll just check to make sure the
+     * second byte is 2 or less.  If it is, we'll accept the decrypted string as valid.
+     *
+     * As a consequence of this, a private key encrypted ciphertext produced with \phpseclib\Crypt\RSA may not decrypt
+     * with a strictly PKCS#1 v1.5 compliant RSA implementation.  Public key encrypted ciphertext's should but
+     * not private key encrypted ciphertext's.
+     *
+     * @access private
+     * @param string $c
+     * @return string
+     */
+    function _rsaes_pkcs1_v1_5_decrypt($c)
+    {
+        // Length checking
+
+        if (strlen($c) != $this->k) { // or if k < 11
+            user_error('Decryption error');
+            return false;
+        }
+
+        // RSA decryption
+
+        $c = $this->_os2ip($c);
+        $m = $this->_rsadp($c);
+
+        if ($m === false) {
+            user_error('Decryption error');
+            return false;
+        }
+        $em = $this->_i2osp($m, $this->k);
+
+        // EME-PKCS1-v1_5 decoding
+
+        if (ord($em[0]) != 0 || ord($em[1]) > 2) {
+            user_error('Decryption error');
+            return false;
+        }
+
+        $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
+        $m = substr($em, strlen($ps) + 3);
+
+        if (strlen($ps) < 8) {
+            user_error('Decryption error');
+            return false;
+        }
+
+        // Output M
+
+        return $m;
+    }
+
+    /**
+     * EMSA-PSS-ENCODE
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
+     *
+     * @access private
+     * @param string $m
+     * @param int $emBits
+     */
+    function _emsa_pss_encode($m, $emBits)
+    {
+        // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+        // be output.
+
+        $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
+        $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
+
+        $mHash = $this->hash->hash($m);
+        if ($emLen < $this->hLen + $sLen + 2) {
+            user_error('Encoding error');
+            return false;
+        }
+
+        $salt = Random::string($sLen);
+        $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
+        $h = $this->hash->hash($m2);
+        $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2);
+        $db = $ps . chr(1) . $salt;
+        $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
+        $maskedDB = $db ^ $dbMask;
+        $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
+        $em = $maskedDB . $h . chr(0xBC);
+
+        return $em;
+    }
+
+    /**
+     * EMSA-PSS-VERIFY
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.
+     *
+     * @access private
+     * @param string $m
+     * @param string $em
+     * @param int $emBits
+     * @return string
+     */
+    function _emsa_pss_verify($m, $em, $emBits)
+    {
+        // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+        // be output.
+
+        $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8);
+        $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
+
+        $mHash = $this->hash->hash($m);
+        if ($emLen < $this->hLen + $sLen + 2) {
+            return false;
+        }
+
+        if ($em[strlen($em) - 1] != chr(0xBC)) {
+            return false;
+        }
+
+        $maskedDB = substr($em, 0, -$this->hLen - 1);
+        $h = substr($em, -$this->hLen - 1, $this->hLen);
+        $temp = chr(0xFF << ($emBits & 7));
+        if ((~$maskedDB[0] & $temp) != $temp) {
+            return false;
+        }
+        $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
+        $db = $maskedDB ^ $dbMask;
+        $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
+        $temp = $emLen - $this->hLen - $sLen - 2;
+        if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
+            return false;
+        }
+        $salt = substr($db, $temp + 1); // should be $sLen long
+        $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
+        $h2 = $this->hash->hash($m2);
+        return $this->_equals($h, $h2);
+    }
+
+    /**
+     * RSASSA-PSS-SIGN
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.
+     *
+     * @access private
+     * @param string $m
+     * @return string
+     */
+    function _rsassa_pss_sign($m)
+    {
+        // EMSA-PSS encoding
+
+        $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1);
+
+        // RSA signature
+
+        $m = $this->_os2ip($em);
+        $s = $this->_rsasp1($m);
+        $s = $this->_i2osp($s, $this->k);
+
+        // Output the signature S
+
+        return $s;
+    }
+
+    /**
+     * RSASSA-PSS-VERIFY
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.
+     *
+     * @access private
+     * @param string $m
+     * @param string $s
+     * @return string
+     */
+    function _rsassa_pss_verify($m, $s)
+    {
+        // Length checking
+
+        if (strlen($s) != $this->k) {
+            user_error('Invalid signature');
+            return false;
+        }
+
+        // RSA verification
+
+        $modBits = strlen($this->modulus->toBits());
+
+        $s2 = $this->_os2ip($s);
+        $m2 = $this->_rsavp1($s2);
+        if ($m2 === false) {
+            user_error('Invalid signature');
+            return false;
+        }
+        $em = $this->_i2osp($m2, $this->k);
+        if ($em === false) {
+            user_error('Invalid signature');
+            return false;
+        }
+
+        // EMSA-PSS verification
+
+        return $this->_emsa_pss_verify($m, $em, $modBits - 1);
+    }
+
+    /**
+     * EMSA-PKCS1-V1_5-ENCODE
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
+     *
+     * @access private
+     * @param string $m
+     * @param int $emLen
+     * @return string
+     */
+    function _emsa_pkcs1_v1_5_encode($m, $emLen)
+    {
+        $h = $this->hash->hash($m);
+        if ($h === false) {
+            return false;
+        }
+
+        // see http://tools.ietf.org/html/rfc3447#page-43
+        switch ($this->hashName) {
+            case 'md2':
+                $t = pack('H*', '3020300c06082a864886f70d020205000410');
+                break;
+            case 'md5':
+                $t = pack('H*', '3020300c06082a864886f70d020505000410');
+                break;
+            case 'sha1':
+                $t = pack('H*', '3021300906052b0e03021a05000414');
+                break;
+            case 'sha256':
+                $t = pack('H*', '3031300d060960864801650304020105000420');
+                break;
+            case 'sha384':
+                $t = pack('H*', '3041300d060960864801650304020205000430');
+                break;
+            case 'sha512':
+                $t = pack('H*', '3051300d060960864801650304020305000440');
+        }
+        $t.= $h;
+        $tLen = strlen($t);
+
+        if ($emLen < $tLen + 11) {
+            user_error('Intended encoded message length too short');
+            return false;
+        }
+
+        $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
+
+        $em = "\0\1$ps\0$t";
+
+        return $em;
+    }
+
+    /**
+     * EMSA-PKCS1-V1_5-ENCODE (without NULL)
+     *
+     * Quoting https://tools.ietf.org/html/rfc8017#page-65,
+     *
+     * "The parameters field associated with id-sha1, id-sha224, id-sha256,
+     *  id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should
+     *  generally be omitted, but if present, it shall have a value of type
+     *  NULL"
+     *
+     * @access private
+     * @param string $m
+     * @param int $emLen
+     * @return string
+     */
+    function _emsa_pkcs1_v1_5_encode_without_null($m, $emLen)
+    {
+        $h = $this->hash->hash($m);
+        if ($h === false) {
+            return false;
+        }
+
+        switch ($this->hashName) {
+            case 'sha1':
+                $t = pack('H*', '301f300706052b0e03021a0414');
+                break;
+            case 'sha256':
+                $t = pack('H*', '302f300b06096086480165030402010420');
+                break;
+            case 'sha384':
+                $t = pack('H*', '303f300b06096086480165030402020430');
+                break;
+            case 'sha512':
+                $t = pack('H*', '304f300b06096086480165030402030440');
+                break;
+            default:
+                return false;
+        }
+        $t.= $h;
+        $tLen = strlen($t);
+
+        if ($emLen < $tLen + 11) {
+            user_error('Intended encoded message length too short');
+            return false;
+        }
+
+        $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
+
+        $em = "\0\1$ps\0$t";
+
+        return $em;
+    }
+
+    /**
+     * RSASSA-PKCS1-V1_5-SIGN
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
+     *
+     * @access private
+     * @param string $m
+     * @return string
+     */
+    function _rsassa_pkcs1_v1_5_sign($m)
+    {
+        // EMSA-PKCS1-v1_5 encoding
+
+        $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
+        if ($em === false) {
+            user_error('RSA modulus too short');
+            return false;
+        }
+
+        // RSA signature
+
+        $m = $this->_os2ip($em);
+        $s = $this->_rsasp1($m);
+        $s = $this->_i2osp($s, $this->k);
+
+        // Output the signature S
+
+        return $s;
+    }
+
+    /**
+     * RSASSA-PKCS1-V1_5-VERIFY
+     *
+     * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
+     *
+     * @access private
+     * @param string $m
+     * @param string $s
+     * @return string
+     */
+    function _rsassa_pkcs1_v1_5_verify($m, $s)
+    {
+        // Length checking
+
+        if (strlen($s) != $this->k) {
+            user_error('Invalid signature');
+            return false;
+        }
+
+        // RSA verification
+
+        $s = $this->_os2ip($s);
+        $m2 = $this->_rsavp1($s);
+        if ($m2 === false) {
+            user_error('Invalid signature');
+            return false;
+        }
+        $em = $this->_i2osp($m2, $this->k);
+        if ($em === false) {
+            user_error('Invalid signature');
+            return false;
+        }
+
+        // EMSA-PKCS1-v1_5 encoding
+
+        $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
+        $em3 = $this->_emsa_pkcs1_v1_5_encode_without_null($m, $this->k);
+
+        if ($em2 === false && $em3 === false) {
+            user_error('RSA modulus too short');
+            return false;
+        }
+
+        // Compare
+
+        return ($em2 !== false && $this->_equals($em, $em2)) ||
+               ($em3 !== false && $this->_equals($em, $em3));
+    }
+
+    /**
+     * Set Encryption Mode
+     *
+     * Valid values include self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1.
+     *
+     * @access public
+     * @param int $mode
+     */
+    function setEncryptionMode($mode)
+    {
+        $this->encryptionMode = $mode;
+    }
+
+    /**
+     * Set Signature Mode
+     *
+     * Valid values include self::SIGNATURE_PSS and self::SIGNATURE_PKCS1
+     *
+     * @access public
+     * @param int $mode
+     */
+    function setSignatureMode($mode)
+    {
+        $this->signatureMode = $mode;
+    }
+
+    /**
+     * Set public key comment.
+     *
+     * @access public
+     * @param string $comment
+     */
+    function setComment($comment)
+    {
+        $this->comment = $comment;
+    }
+
+    /**
+     * Get public key comment.
+     *
+     * @access public
+     * @return string
+     */
+    function getComment()
+    {
+        return $this->comment;
+    }
+
+    /**
+     * Encryption
+     *
+     * Both self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1 both place limits on how long $plaintext can be.
+     * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will
+     * be concatenated together.
+     *
+     * @see self::decrypt()
+     * @access public
+     * @param string $plaintext
+     * @return string
+     */
+    function encrypt($plaintext)
+    {
+        switch ($this->encryptionMode) {
+            case self::ENCRYPTION_NONE:
+                $plaintext = str_split($plaintext, $this->k);
+                $ciphertext = '';
+                foreach ($plaintext as $m) {
+                    $ciphertext.= $this->_raw_encrypt($m);
+                }
+                return $ciphertext;
+            case self::ENCRYPTION_PKCS1:
+                $length = $this->k - 11;
+                if ($length <= 0) {
+                    return false;
+                }
+
+                $plaintext = str_split($plaintext, $length);
+                $ciphertext = '';
+                foreach ($plaintext as $m) {
+                    $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m);
+                }
+                return $ciphertext;
+            //case self::ENCRYPTION_OAEP:
+            default:
+                $length = $this->k - 2 * $this->hLen - 2;
+                if ($length <= 0) {
+                    return false;
+                }
+
+                $plaintext = str_split($plaintext, $length);
+                $ciphertext = '';
+                foreach ($plaintext as $m) {
+                    $ciphertext.= $this->_rsaes_oaep_encrypt($m);
+                }
+                return $ciphertext;
+        }
+    }
+
+    /**
+     * Decryption
+     *
+     * @see self::encrypt()
+     * @access public
+     * @param string $ciphertext
+     * @return string
+     */
+    function decrypt($ciphertext)
+    {
+        if ($this->k <= 0) {
+            return false;
+        }
+
+        $ciphertext = str_split($ciphertext, $this->k);
+        $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT);
+
+        $plaintext = '';
+
+        switch ($this->encryptionMode) {
+            case self::ENCRYPTION_NONE:
+                $decrypt = '_raw_encrypt';
+                break;
+            case self::ENCRYPTION_PKCS1:
+                $decrypt = '_rsaes_pkcs1_v1_5_decrypt';
+                break;
+            //case self::ENCRYPTION_OAEP:
+            default:
+                $decrypt = '_rsaes_oaep_decrypt';
+        }
+
+        foreach ($ciphertext as $c) {
+            $temp = $this->$decrypt($c);
+            if ($temp === false) {
+                return false;
+            }
+            $plaintext.= $temp;
+        }
+
+        return $plaintext;
+    }
+
+    /**
+     * Create a signature
+     *
+     * @see self::verify()
+     * @access public
+     * @param string $message
+     * @return string
+     */
+    function sign($message)
+    {
+        if (empty($this->modulus) || empty($this->exponent)) {
+            return false;
+        }
+
+        switch ($this->signatureMode) {
+            case self::SIGNATURE_PKCS1:
+                return $this->_rsassa_pkcs1_v1_5_sign($message);
+            //case self::SIGNATURE_PSS:
+            default:
+                return $this->_rsassa_pss_sign($message);
+        }
+    }
+
+    /**
+     * Verifies a signature
+     *
+     * @see self::sign()
+     * @access public
+     * @param string $message
+     * @param string $signature
+     * @return bool
+     */
+    function verify($message, $signature)
+    {
+        if (empty($this->modulus) || empty($this->exponent)) {
+            return false;
+        }
+
+        switch ($this->signatureMode) {
+            case self::SIGNATURE_PKCS1:
+                return $this->_rsassa_pkcs1_v1_5_verify($message, $signature);
+            //case self::SIGNATURE_PSS:
+            default:
+                return $this->_rsassa_pss_verify($message, $signature);
+        }
+    }
+
+    /**
+     * Extract raw BER from Base64 encoding
+     *
+     * @access private
+     * @param string $str
+     * @return string
+     */
+    function _extractBER($str)
+    {
+        /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
+         * above and beyond the ceritificate.
+         * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
+         *
+         * Bag Attributes
+         *     localKeyID: 01 00 00 00
+         * subject=/O=organization/OU=org unit/CN=common name
+         * issuer=/O=organization/CN=common name
+         */
+        $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
+        // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
+        $temp = preg_replace('#-+[^-]+-+#', '', $temp);
+        // remove new lines
+        $temp = str_replace(array("\r", "\n", ' '), '', $temp);
+        $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
+        return $temp != false ? $temp : $str;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
new file mode 100644
index 00000000..e039340c
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
@@ -0,0 +1,280 @@
+<?php
+
+/**
+ * Random Number Generator
+ *
+ * PHP version 5
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    echo bin2hex(\phpseclib\Crypt\Random::string(8));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   Random
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP Random Number Generator
+ *
+ * @package Random
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class Random
+{
+    /**
+     * Generate a random string.
+     *
+     * Although microoptimizations are generally discouraged as they impair readability this function is ripe with
+     * microoptimizations because this function has the potential of being called a huge number of times.
+     * eg. for RSA key generation.
+     *
+     * @param int $length
+     * @return string
+     */
+    static function string($length)
+    {
+        if (!$length) {
+            return '';
+        }
+
+        if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
+            try {
+                return \random_bytes($length);
+            } catch (\Throwable $e) {
+                // If a sufficient source of randomness is unavailable, random_bytes() will throw an
+                // object that implements the Throwable interface (Exception, TypeError, Error).
+                // We don't actually need to do anything here. The string() method should just continue
+                // as normal. Note, however, that if we don't have a sufficient source of randomness for
+                // random_bytes(), most of the other calls here will fail too, so we'll end up using
+                // the PHP implementation.
+            }
+        }
+
+        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+            // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
+            // ie. class_alias is a function that was introduced in PHP 5.3
+            if (extension_loaded('mcrypt') && function_exists('class_alias')) {
+                return @mcrypt_create_iv($length);
+            }
+            // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
+            // to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
+            // openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
+            // call php_win32_get_random_bytes():
+            //
+            // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
+            // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
+            //
+            // php_win32_get_random_bytes() is defined thusly:
+            //
+            // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
+            //
+            // we're calling it, all the same, in the off chance that the mcrypt extension is not available
+            if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
+                return openssl_random_pseudo_bytes($length);
+            }
+        } else {
+            // method 1. the fastest
+            if (extension_loaded('openssl')) {
+                return openssl_random_pseudo_bytes($length);
+            }
+            // method 2
+            static $fp = true;
+            if ($fp === true) {
+                // warning's will be output unles the error suppression operator is used. errors such as
+                // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
+                $fp = @fopen('/dev/urandom', 'rb');
+            }
+            if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
+                $temp = fread($fp, $length);
+                if (strlen($temp) == $length) {
+                    return $temp;
+                }
+            }
+            // method 3. pretty much does the same thing as method 2 per the following url:
+            // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
+            // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
+            // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
+            // restrictions or some such
+            if (extension_loaded('mcrypt')) {
+                return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
+            }
+        }
+        // at this point we have no choice but to use a pure-PHP CSPRNG
+
+        // cascade entropy across multiple PHP instances by fixing the session and collecting all
+        // environmental variables, including the previous session data and the current session
+        // data.
+        //
+        // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
+        // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
+        // PHP isn't low level to be able to use those as sources and on a web server there's not likely
+        // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
+        // however, a ton of people visiting the website. obviously you don't want to base your seeding
+        // soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
+        // by the user and (2) this isn't just looking at the data sent by the current user - it's based
+        // on the data sent by all users. one user requests the page and a hash of their info is saved.
+        // another user visits the page and the serialization of their data is utilized along with the
+        // server envirnment stuff and a hash of the previous http request data (which itself utilizes
+        // a hash of the session data before that). certainly an attacker should be assumed to have
+        // full control over his own http requests. he, however, is not going to have control over
+        // everyone's http requests.
+        static $crypto = false, $v;
+        if ($crypto === false) {
+            // save old session data
+            $old_session_id = session_id();
+            $old_use_cookies = ini_get('session.use_cookies');
+            $old_session_cache_limiter = session_cache_limiter();
+            $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
+            if ($old_session_id != '') {
+                session_write_close();
+            }
+
+            session_id(1);
+            ini_set('session.use_cookies', 0);
+            session_cache_limiter('');
+            session_start();
+
+            $v = $seed = $_SESSION['seed'] = pack('H*', sha1(
+                (isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') .
+                (isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
+                (isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
+                (isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
+                // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates
+                // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage
+                // for more info
+                (version_compare(PHP_VERSION, '8.1.0', '>=') ? serialize($GLOBALS) : phpseclib_safe_serialize($GLOBALS)) .
+                phpseclib_safe_serialize($_SESSION) .
+                phpseclib_safe_serialize($_OLD_SESSION)
+            ));
+            if (!isset($_SESSION['count'])) {
+                $_SESSION['count'] = 0;
+            }
+            $_SESSION['count']++;
+
+            session_write_close();
+
+            // restore old session data
+            if ($old_session_id != '') {
+                session_id($old_session_id);
+                session_start();
+                ini_set('session.use_cookies', $old_use_cookies);
+                session_cache_limiter($old_session_cache_limiter);
+            } else {
+                if ($_OLD_SESSION !== false) {
+                    $_SESSION = $_OLD_SESSION;
+                    unset($_OLD_SESSION);
+                } else {
+                    unset($_SESSION);
+                }
+            }
+
+            // in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
+            // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
+            // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
+            // original hash and the current hash. we'll be emulating that. for more info see the following URL:
+            //
+            // http://tools.ietf.org/html/rfc4253#section-7.2
+            //
+            // see the is_string($crypto) part for an example of how to expand the keys
+            $key = pack('H*', sha1($seed . 'A'));
+            $iv = pack('H*', sha1($seed . 'C'));
+
+            // ciphers are used as per the nist.gov link below. also, see this link:
+            //
+            // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
+            switch (true) {
+                case class_exists('\phpseclib\Crypt\AES'):
+                    $crypto = new AES(Base::MODE_CTR);
+                    break;
+                case class_exists('\phpseclib\Crypt\Twofish'):
+                    $crypto = new Twofish(Base::MODE_CTR);
+                    break;
+                case class_exists('\phpseclib\Crypt\Blowfish'):
+                    $crypto = new Blowfish(Base::MODE_CTR);
+                    break;
+                case class_exists('\phpseclib\Crypt\TripleDES'):
+                    $crypto = new TripleDES(Base::MODE_CTR);
+                    break;
+                case class_exists('\phpseclib\Crypt\DES'):
+                    $crypto = new DES(Base::MODE_CTR);
+                    break;
+                case class_exists('\phpseclib\Crypt\RC4'):
+                    $crypto = new RC4();
+                    break;
+                default:
+                    user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
+                    return false;
+            }
+
+            $crypto->setKey($key);
+            $crypto->setIV($iv);
+            $crypto->enableContinuousBuffer();
+        }
+
+        //return $crypto->encrypt(str_repeat("\0", $length));
+
+        // the following is based off of ANSI X9.31:
+        //
+        // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
+        //
+        // OpenSSL uses that same standard for it's random numbers:
+        //
+        // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
+        // (do a search for "ANS X9.31 A.2.4")
+        $result = '';
+        while (strlen($result) < $length) {
+            $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
+            $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
+            $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
+            $result.= $r;
+        }
+        return substr($result, 0, $length);
+    }
+}
+
+if (!function_exists('phpseclib_safe_serialize')) {
+    /**
+     * Safely serialize variables
+     *
+     * If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier.
+     * PHP 5.3 will emit a warning.
+     *
+     * @param mixed $arr
+     * @access public
+     */
+    function phpseclib_safe_serialize(&$arr)
+    {
+        if (is_object($arr)) {
+            return '';
+        }
+        if (!is_array($arr)) {
+            return serialize($arr);
+        }
+        // prevent circular array recursion
+        if (isset($arr['__phpseclib_marker'])) {
+            return '';
+        }
+        $safearr = array();
+        $arr['__phpseclib_marker'] = true;
+        foreach (array_keys($arr) as $key) {
+            // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
+            if ($key !== '__phpseclib_marker') {
+                $safearr[$key] = phpseclib_safe_serialize($arr[$key]);
+            }
+        }
+        unset($arr['__phpseclib_marker']);
+        return serialize($safearr);
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
new file mode 100644
index 00000000..7a6be2a6
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
@@ -0,0 +1,941 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Rijndael.
+ *
+ * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits.  If
+ * {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link self::setKey() setKey()}.  ie. if the key is 128-bits, the key length will be 128-bits.  If it's
+ * 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
+ * {@link self::setKey() setKey()} is called, again, at which point, it'll be recalculated.
+ *
+ * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length.  mcrypt, for example,
+ * does not.  AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
+ * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224.  Indeed, 160 and 224
+ * are first defined as valid key / block lengths in
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
+ * Extensions: Other block and Cipher Key lengths.
+ * Note: Use of 160/224-bit Keys must be explicitly set by setKeyLength(160) respectively setKeyLength(224).
+ *
+ * {@internal The variable names are the same as those in
+ * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $rijndael = new \phpseclib\Crypt\Rijndael();
+ *
+ *    $rijndael->setKey('abcdefghijklmnop');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $rijndael->decrypt($rijndael->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   Rijndael
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2008 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Rijndael.
+ *
+ * @package Rijndael
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class Rijndael extends Base
+{
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
+     * \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable
+     * or not for the current $block_size/$key_length.
+     * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
+     *
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @see \phpseclib\Crypt\Base::engine
+     * @see self::isValidEngine()
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'rijndael-128';
+
+    /**
+     * The default salt used by setPassword()
+     *
+     * @see \phpseclib\Crypt\Base::password_default_salt
+     * @see \phpseclib\Crypt\Base::setPassword()
+     * @var string
+     * @access private
+     */
+    var $password_default_salt = 'phpseclib';
+
+    /**
+     * The Key Schedule
+     *
+     * @see self::_setup()
+     * @var array
+     * @access private
+     */
+    var $w;
+
+    /**
+     * The Inverse Key Schedule
+     *
+     * @see self::_setup()
+     * @var array
+     * @access private
+     */
+    var $dw;
+
+    /**
+     * The Block Length divided by 32
+     *
+     * @see self::setBlockLength()
+     * @var int
+     * @access private
+     * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4.  Exists in conjunction with $block_size
+     *    because the encryption / decryption / key schedule creation requires this number and not $block_size.  We could
+     *    derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    of that, we'll just precompute it once.
+     */
+    var $Nb = 4;
+
+    /**
+     * The Key Length (in bytes)
+     *
+     * @see self::setKeyLength()
+     * @var int
+     * @access private
+     * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16.  Exists in conjunction with $Nk
+     *    because the encryption / decryption / key schedule creation requires this number and not $key_length.  We could
+     *    derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+     *    of that, we'll just precompute it once.
+     */
+    var $key_length = 16;
+
+    /**
+     * The Key Length divided by 32
+     *
+     * @see self::setKeyLength()
+     * @var int
+     * @access private
+     * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
+     */
+    var $Nk = 4;
+
+    /**
+     * The Number of Rounds
+     *
+     * @var int
+     * @access private
+     * @internal The max value is 14, the min value is 10.
+     */
+    var $Nr;
+
+    /**
+     * Shift offsets
+     *
+     * @var array
+     * @access private
+     */
+    var $c;
+
+    /**
+     * Holds the last used key- and block_size information
+     *
+     * @var array
+     * @access private
+     */
+    var $kl;
+
+    /**
+     * Sets the key length.
+     *
+     * Valid key lengths are 128, 160, 192, 224, and 256.  If the length is less than 128, it will be rounded up to
+     * 128.  If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
+     *
+     * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
+     *       and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
+     *       192/256 bits as, for example, mcrypt will do.
+     *
+     *       That said, if you want be compatible with other Rijndael and AES implementations,
+     *       you should not setKeyLength(160) or setKeyLength(224).
+     *
+     * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use
+     *             the mcrypt php extension, even if available.
+     *             This results then in slower encryption.
+     *
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        switch (true) {
+            case $length <= 128:
+                $this->key_length = 16;
+                break;
+            case $length <= 160:
+                $this->key_length = 20;
+                break;
+            case $length <= 192:
+                $this->key_length = 24;
+                break;
+            case $length <= 224:
+                $this->key_length = 28;
+                break;
+            default:
+                $this->key_length = 32;
+        }
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Sets the block length
+     *
+     * Valid block lengths are 128, 160, 192, 224, and 256.  If the length is less than 128, it will be rounded up to
+     * 128.  If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
+     *
+     * @access public
+     * @param int $length
+     */
+    function setBlockLength($length)
+    {
+        $length >>= 5;
+        if ($length > 8) {
+            $length = 8;
+        } elseif ($length < 4) {
+            $length = 4;
+        }
+        $this->Nb = $length;
+        $this->block_size = $length << 2;
+        $this->changed = true;
+        $this->_setEngine();
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+     *
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        switch ($engine) {
+            case self::ENGINE_OPENSSL:
+                if ($this->block_size != 16) {
+                    return false;
+                }
+                $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
+                $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
+                break;
+            case self::ENGINE_MCRYPT:
+                $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
+                if ($this->key_length % 8) { // is it a 160/224-bit key?
+                    // mcrypt is not usable for them, only for 128/192/256-bit keys
+                    return false;
+                }
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _encryptBlock($in)
+    {
+        static $tables;
+        if (empty($tables)) {
+            $tables = &$this->_getTables();
+        }
+        $t0   = $tables[0];
+        $t1   = $tables[1];
+        $t2   = $tables[2];
+        $t3   = $tables[3];
+        $sbox = $tables[4];
+
+        $state = array();
+        $words = unpack('N*', $in);
+
+        $c = $this->c;
+        $w = $this->w;
+        $Nb = $this->Nb;
+        $Nr = $this->Nr;
+
+        // addRoundKey
+        $wc = $Nb - 1;
+        foreach ($words as $word) {
+            $state[] = $word ^ $w[++$wc];
+        }
+
+        // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
+        // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
+        // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
+        // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
+        // Unfortunately, the description given there is not quite correct.  Per aes.spec.v316.pdf#page=19 [1],
+        // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
+
+        // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
+        $temp = array();
+        for ($round = 1; $round < $Nr; ++$round) {
+            $i = 0; // $c[0] == 0
+            $j = $c[1];
+            $k = $c[2];
+            $l = $c[3];
+
+            while ($i < $Nb) {
+                $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
+                            $t1[$state[$j] >> 16 & 0x000000FF] ^
+                            $t2[$state[$k] >>  8 & 0x000000FF] ^
+                            $t3[$state[$l]       & 0x000000FF] ^
+                            $w[++$wc];
+                ++$i;
+                $j = ($j + 1) % $Nb;
+                $k = ($k + 1) % $Nb;
+                $l = ($l + 1) % $Nb;
+            }
+            $state = $temp;
+        }
+
+        // subWord
+        for ($i = 0; $i < $Nb; ++$i) {
+            $state[$i] =   $sbox[$state[$i]       & 0x000000FF]        |
+                          ($sbox[$state[$i] >>  8 & 0x000000FF] <<  8) |
+                          ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
+                          ($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
+        }
+
+        // shiftRows + addRoundKey
+        $i = 0; // $c[0] == 0
+        $j = $c[1];
+        $k = $c[2];
+        $l = $c[3];
+        while ($i < $Nb) {
+            $temp[$i] = ($state[$i] & intval(0xFF000000)) ^
+                        ($state[$j] & 0x00FF0000) ^
+                        ($state[$k] & 0x0000FF00) ^
+                        ($state[$l] & 0x000000FF) ^
+                         $w[$i];
+            ++$i;
+            $j = ($j + 1) % $Nb;
+            $k = ($k + 1) % $Nb;
+            $l = ($l + 1) % $Nb;
+        }
+
+        switch ($Nb) {
+            case 8:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
+            case 7:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
+            case 6:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
+            case 5:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
+            default:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
+        }
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _decryptBlock($in)
+    {
+        static $invtables;
+        if (empty($invtables)) {
+            $invtables = &$this->_getInvTables();
+        }
+        $dt0   = $invtables[0];
+        $dt1   = $invtables[1];
+        $dt2   = $invtables[2];
+        $dt3   = $invtables[3];
+        $isbox = $invtables[4];
+
+        $state = array();
+        $words = unpack('N*', $in);
+
+        $c  = $this->c;
+        $dw = $this->dw;
+        $Nb = $this->Nb;
+        $Nr = $this->Nr;
+
+        // addRoundKey
+        $wc = $Nb - 1;
+        foreach ($words as $word) {
+            $state[] = $word ^ $dw[++$wc];
+        }
+
+        $temp = array();
+        for ($round = $Nr - 1; $round > 0; --$round) {
+            $i = 0; // $c[0] == 0
+            $j = $Nb - $c[1];
+            $k = $Nb - $c[2];
+            $l = $Nb - $c[3];
+
+            while ($i < $Nb) {
+                $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
+                            $dt1[$state[$j] >> 16 & 0x000000FF] ^
+                            $dt2[$state[$k] >>  8 & 0x000000FF] ^
+                            $dt3[$state[$l]       & 0x000000FF] ^
+                            $dw[++$wc];
+                ++$i;
+                $j = ($j + 1) % $Nb;
+                $k = ($k + 1) % $Nb;
+                $l = ($l + 1) % $Nb;
+            }
+            $state = $temp;
+        }
+
+        // invShiftRows + invSubWord + addRoundKey
+        $i = 0; // $c[0] == 0
+        $j = $Nb - $c[1];
+        $k = $Nb - $c[2];
+        $l = $Nb - $c[3];
+
+        while ($i < $Nb) {
+            $word = ($state[$i] & intval(0xFF000000)) |
+                    ($state[$j] & 0x00FF0000) |
+                    ($state[$k] & 0x0000FF00) |
+                    ($state[$l] & 0x000000FF);
+
+            $temp[$i] = $dw[$i] ^ ($isbox[$word       & 0x000000FF]        |
+                                  ($isbox[$word >>  8 & 0x000000FF] <<  8) |
+                                  ($isbox[$word >> 16 & 0x000000FF] << 16) |
+                                  ($isbox[$word >> 24 & 0x000000FF] << 24));
+            ++$i;
+            $j = ($j + 1) % $Nb;
+            $k = ($k + 1) % $Nb;
+            $l = ($l + 1) % $Nb;
+        }
+
+        switch ($Nb) {
+            case 8:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
+            case 7:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
+            case 6:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
+            case 5:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
+            default:
+                return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
+        }
+    }
+
+    /**
+     * Setup the key (expansion)
+     *
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
+        // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
+        static $rcon;
+
+        if (!isset($rcon)) {
+            $rcon = array(0,
+                0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+                0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
+                0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
+                0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
+                0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
+                0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
+            );
+            $rcon = array_map('intval', $rcon);
+        }
+
+        if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
+            // already expanded
+            return;
+        }
+        $this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
+
+        $this->Nk = $this->key_length >> 2;
+        // see Rijndael-ammended.pdf#page=44
+        $this->Nr = max($this->Nk, $this->Nb) + 6;
+
+        // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
+        //     "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
+        // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
+        //     "Table 2: Shift offsets for different block lengths"
+        switch ($this->Nb) {
+            case 4:
+            case 5:
+            case 6:
+                $this->c = array(0, 1, 2, 3);
+                break;
+            case 7:
+                $this->c = array(0, 1, 2, 4);
+                break;
+            case 8:
+                $this->c = array(0, 1, 3, 4);
+        }
+
+        $w = array_values(unpack('N*words', $this->key));
+
+        $length = $this->Nb * ($this->Nr + 1);
+        for ($i = $this->Nk; $i < $length; $i++) {
+            $temp = $w[$i - 1];
+            if ($i % $this->Nk == 0) {
+                // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
+                // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
+                // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
+                // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
+                $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord
+                $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
+            } elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
+                $temp = $this->_subWord($temp);
+            }
+            $w[$i] = $w[$i - $this->Nk] ^ $temp;
+        }
+
+        // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
+        // and generate the inverse key schedule.  more specifically,
+        // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
+        // "The key expansion for the Inverse Cipher is defined as follows:
+        //        1. Apply the Key Expansion.
+        //        2. Apply InvMixColumn to all Round Keys except the first and the last one."
+        // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
+        list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
+        $temp = $this->w = $this->dw = array();
+        for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
+            if ($col == $this->Nb) {
+                if ($row == 0) {
+                    $this->dw[0] = $this->w[0];
+                } else {
+                    // subWord + invMixColumn + invSubWord = invMixColumn
+                    $j = 0;
+                    while ($j < $this->Nb) {
+                        $dw = $this->_subWord($this->w[$row][$j]);
+                        $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
+                                    $dt1[$dw >> 16 & 0x000000FF] ^
+                                    $dt2[$dw >>  8 & 0x000000FF] ^
+                                    $dt3[$dw       & 0x000000FF];
+                        $j++;
+                    }
+                    $this->dw[$row] = $temp;
+                }
+
+                $col = 0;
+                $row++;
+            }
+            $this->w[$row][$col] = $w[$i];
+        }
+
+        $this->dw[$row] = $this->w[$row];
+
+        // Converting to 1-dim key arrays (both ascending)
+        $this->dw = array_reverse($this->dw);
+        $w  = array_pop($this->w);
+        $dw = array_pop($this->dw);
+        foreach ($this->w as $r => $wr) {
+            foreach ($wr as $c => $wc) {
+                $w[]  = $wc;
+                $dw[] = $this->dw[$r][$c];
+            }
+        }
+        $this->w  = $w;
+        $this->dw = $dw;
+    }
+
+    /**
+     * Performs S-Box substitutions
+     *
+     * @access private
+     * @param int $word
+     */
+    function _subWord($word)
+    {
+        static $sbox;
+        if (empty($sbox)) {
+            list(, , , , $sbox) = $this->_getTables();
+        }
+
+        return  $sbox[$word       & 0x000000FF]        |
+               ($sbox[$word >>  8 & 0x000000FF] <<  8) |
+               ($sbox[$word >> 16 & 0x000000FF] << 16) |
+               ($sbox[$word >> 24 & 0x000000FF] << 24);
+    }
+
+    /**
+     * Provides the mixColumns and sboxes tables
+     *
+     * @see self::_encryptBlock()
+     * @see self::_setupInlineCrypt()
+     * @see self::_subWord()
+     * @access private
+     * @return array &$tables
+     */
+    function &_getTables()
+    {
+        static $tables;
+        if (empty($tables)) {
+            // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
+            // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
+            // those are the names we'll use.
+            $t3 = array_map('intval', array(
+                // with array_map('intval', ...) we ensure we have only int's and not
+                // some slower floats converted by php automatically on high values
+                0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
+                0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
+                0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
+                0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
+                0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
+                0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
+                0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
+                0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
+                0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
+                0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
+                0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
+                0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
+                0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
+                0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
+                0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
+                0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
+                0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
+                0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
+                0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
+                0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
+                0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
+                0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
+                0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
+                0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
+                0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
+                0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
+                0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
+                0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
+                0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
+                0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
+                0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
+                0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
+            ));
+
+            foreach ($t3 as $t3i) {
+                $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >>  8) & 0x00FFFFFF);
+                $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF);
+                $t2[] = (($t3i <<  8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF);
+            }
+
+            $tables = array(
+                // The Precomputed mixColumns tables t0 - t3
+                $t0,
+                $t1,
+                $t2,
+                $t3,
+                // The SubByte S-Box
+                array(
+                    0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+                    0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+                    0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+                    0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+                    0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+                    0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+                    0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+                    0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+                    0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+                    0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+                    0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+                    0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+                    0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+                    0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+                    0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+                    0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+                )
+            );
+        }
+        return $tables;
+    }
+
+    /**
+     * Provides the inverse mixColumns and inverse sboxes tables
+     *
+     * @see self::_decryptBlock()
+     * @see self::_setupInlineCrypt()
+     * @see self::_setupKey()
+     * @access private
+     * @return array &$tables
+     */
+    function &_getInvTables()
+    {
+        static $tables;
+        if (empty($tables)) {
+            $dt3 = array_map('intval', array(
+                0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
+                0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
+                0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
+                0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
+                0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
+                0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
+                0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
+                0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
+                0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
+                0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
+                0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
+                0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
+                0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
+                0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
+                0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
+                0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
+                0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
+                0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
+                0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
+                0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
+                0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
+                0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
+                0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
+                0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
+                0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
+                0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
+                0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
+                0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
+                0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
+                0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
+                0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
+                0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
+            ));
+
+            foreach ($dt3 as $dt3i) {
+                $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >>  8) & 0x00FFFFFF);
+                $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF);
+                $dt2[] = (($dt3i <<  8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF);
+            };
+
+            $tables = array(
+                // The Precomputed inverse mixColumns tables dt0 - dt3
+                $dt0,
+                $dt1,
+                $dt2,
+                $dt3,
+                // The inverse SubByte S-Box
+                array(
+                    0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+                    0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+                    0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+                    0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+                    0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+                    0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+                    0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+                    0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+                    0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+                    0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+                    0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+                    0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+                    0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+                    0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+                    0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+                    0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+                )
+            );
+        }
+        return $tables;
+    }
+
+    /**
+     * Setup the performance-optimized function for de/encrypt()
+     *
+     * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+     * @access private
+     */
+    function _setupInlineCrypt()
+    {
+        // Note: _setupInlineCrypt() will be called only if $this->changed === true
+        // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
+        // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
+
+        $lambda_functions =& self::_getLambdaFunctions();
+
+        // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+        // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
+        // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+        // Generation of a uniqe hash for our generated code
+        $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
+
+        if (!isset($lambda_functions[$code_hash])) {
+            switch (true) {
+                case $gen_hi_opt_code:
+                    // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
+                    $w  = $this->w;
+                    $dw = $this->dw;
+                    $init_encrypt = '';
+                    $init_decrypt = '';
+                    break;
+                default:
+                    for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
+                        $w[]  = '$w['  . $i . ']';
+                        $dw[] = '$dw[' . $i . ']';
+                    }
+                    $init_encrypt = '$w  = $self->w;';
+                    $init_decrypt = '$dw = $self->dw;';
+            }
+
+            $Nr = $this->Nr;
+            $Nb = $this->Nb;
+            $c  = $this->c;
+
+            // Generating encrypt code:
+            $init_encrypt.= '
+                static $tables;
+                if (empty($tables)) {
+                    $tables = &$self->_getTables();
+                }
+                $t0   = $tables[0];
+                $t1   = $tables[1];
+                $t2   = $tables[2];
+                $t3   = $tables[3];
+                $sbox = $tables[4];
+            ';
+
+            $s  = 'e';
+            $e  = 's';
+            $wc = $Nb - 1;
+
+            // Preround: addRoundKey
+            $encrypt_block = '$in = unpack("N*", $in);'."\n";
+            for ($i = 0; $i < $Nb; ++$i) {
+                $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
+            }
+
+            // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
+            for ($round = 1; $round < $Nr; ++$round) {
+                list($s, $e) = array($e, $s);
+                for ($i = 0; $i < $Nb; ++$i) {
+                    $encrypt_block.=
+                        '$'.$e.$i.' =
+                        $t0[($'.$s.$i                  .' >> 24) & 0xff] ^
+                        $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
+                        $t2[($'.$s.(($i + $c[2]) % $Nb).' >>  8) & 0xff] ^
+                        $t3[ $'.$s.(($i + $c[3]) % $Nb).'        & 0xff] ^
+                        '.$w[++$wc].";\n";
+                }
+            }
+
+            // Finalround: subWord + shiftRows + addRoundKey
+            for ($i = 0; $i < $Nb; ++$i) {
+                $encrypt_block.=
+                    '$'.$e.$i.' =
+                     $sbox[ $'.$e.$i.'        & 0xff]        |
+                    ($sbox[($'.$e.$i.' >>  8) & 0xff] <<  8) |
+                    ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
+                    ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
+            }
+            $encrypt_block .= '$in = pack("N*"'."\n";
+            for ($i = 0; $i < $Nb; ++$i) {
+                $encrypt_block.= ',
+                    ($'.$e.$i                  .' & '.((int)0xFF000000).') ^
+                    ($'.$e.(($i + $c[1]) % $Nb).' &         0x00FF0000   ) ^
+                    ($'.$e.(($i + $c[2]) % $Nb).' &         0x0000FF00   ) ^
+                    ($'.$e.(($i + $c[3]) % $Nb).' &         0x000000FF   ) ^
+                    '.$w[$i]."\n";
+            }
+            $encrypt_block .= ');';
+
+            // Generating decrypt code:
+            $init_decrypt.= '
+                static $invtables;
+                if (empty($invtables)) {
+                    $invtables = &$self->_getInvTables();
+                }
+                $dt0   = $invtables[0];
+                $dt1   = $invtables[1];
+                $dt2   = $invtables[2];
+                $dt3   = $invtables[3];
+                $isbox = $invtables[4];
+            ';
+
+            $s  = 'e';
+            $e  = 's';
+            $wc = $Nb - 1;
+
+            // Preround: addRoundKey
+            $decrypt_block = '$in = unpack("N*", $in);'."\n";
+            for ($i = 0; $i < $Nb; ++$i) {
+                $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
+            }
+
+            // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
+            for ($round = 1; $round < $Nr; ++$round) {
+                list($s, $e) = array($e, $s);
+                for ($i = 0; $i < $Nb; ++$i) {
+                    $decrypt_block.=
+                        '$'.$e.$i.' =
+                        $dt0[($'.$s.$i                        .' >> 24) & 0xff] ^
+                        $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
+                        $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >>  8) & 0xff] ^
+                        $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).'        & 0xff] ^
+                        '.$dw[++$wc].";\n";
+                }
+            }
+
+            // Finalround: subWord + shiftRows + addRoundKey
+            for ($i = 0; $i < $Nb; ++$i) {
+                $decrypt_block.=
+                    '$'.$e.$i.' =
+                     $isbox[ $'.$e.$i.'        & 0xff]        |
+                    ($isbox[($'.$e.$i.' >>  8) & 0xff] <<  8) |
+                    ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
+                    ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
+            }
+            $decrypt_block .= '$in = pack("N*"'."\n";
+            for ($i = 0; $i < $Nb; ++$i) {
+                $decrypt_block.= ',
+                    ($'.$e.$i.                        ' & '.((int)0xFF000000).') ^
+                    ($'.$e.(($Nb + $i - $c[1]) % $Nb).' &         0x00FF0000   ) ^
+                    ($'.$e.(($Nb + $i - $c[2]) % $Nb).' &         0x0000FF00   ) ^
+                    ($'.$e.(($Nb + $i - $c[3]) % $Nb).' &         0x000000FF   ) ^
+                    '.$dw[$i]."\n";
+            }
+            $decrypt_block .= ');';
+
+            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+                array(
+                   'init_crypt'    => '',
+                   'init_encrypt'  => $init_encrypt,
+                   'init_decrypt'  => $init_decrypt,
+                   'encrypt_block' => $encrypt_block,
+                   'decrypt_block' => $decrypt_block
+                )
+            );
+        }
+        $this->inline_crypt = $lambda_functions[$code_hash];
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
new file mode 100644
index 00000000..bf2df95e
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
@@ -0,0 +1,460 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Triple DES.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.  Operates in the EDE3 mode (encrypt-decrypt-encrypt).
+ *
+ * PHP version 5
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $des = new \phpseclib\Crypt\TripleDES();
+ *
+ *    $des->setKey('abcdefghijklmnopqrstuvwx');
+ *
+ *    $size = 10 * 1024;
+ *    $plaintext = '';
+ *    for ($i = 0; $i < $size; $i++) {
+ *        $plaintext.= 'a';
+ *    }
+ *
+ *    echo $des->decrypt($des->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   TripleDES
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Triple DES.
+ *
+ * @package TripleDES
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class TripleDES extends DES
+{
+    /**
+     * Encrypt / decrypt using inner chaining
+     *
+     * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3).
+     */
+    const MODE_3CBC = -2;
+
+    /**
+     * Encrypt / decrypt using outer chaining
+     *
+     * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
+     */
+    const MODE_CBC3 = self::MODE_CBC;
+
+    /**
+     * Key Length (in bytes)
+     *
+     * @see \phpseclib\Crypt\TripleDES::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 24;
+
+    /**
+     * The default salt used by setPassword()
+     *
+     * @see \phpseclib\Crypt\Base::password_default_salt
+     * @see \phpseclib\Crypt\Base::setPassword()
+     * @var string
+     * @access private
+     */
+    var $password_default_salt = 'phpseclib';
+
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * @see \phpseclib\Crypt\DES::cipher_name_mcrypt
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'tripledes';
+
+    /**
+     * Optimizing value while CFB-encrypting
+     *
+     * @see \phpseclib\Crypt\Base::cfb_init_len
+     * @var int
+     * @access private
+     */
+    var $cfb_init_len = 750;
+
+    /**
+     * max possible size of $key
+     *
+     * @see self::setKey()
+     * @see \phpseclib\Crypt\DES::setKey()
+     * @var string
+     * @access private
+     */
+    var $key_length_max = 24;
+
+    /**
+     * Internal flag whether using self::MODE_3CBC or not
+     *
+     * @var bool
+     * @access private
+     */
+    var $mode_3cbc;
+
+    /**
+     * The \phpseclib\Crypt\DES objects
+     *
+     * Used only if $mode_3cbc === true
+     *
+     * @var array
+     * @access private
+     */
+    var $des;
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.
+     *
+     * $mode could be:
+     *
+     * - \phpseclib\Crypt\Base::MODE_ECB
+     *
+     * - \phpseclib\Crypt\Base::MODE_CBC
+     *
+     * - \phpseclib\Crypt\Base::MODE_CTR
+     *
+     * - \phpseclib\Crypt\Base::MODE_CFB
+     *
+     * - \phpseclib\Crypt\Base::MODE_OFB
+     *
+     * - \phpseclib\Crypt\TripleDES::MODE_3CBC
+     *
+     * If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
+     *
+     * @see \phpseclib\Crypt\DES::__construct()
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @param int $mode
+     * @access public
+     */
+    function __construct($mode = self::MODE_CBC)
+    {
+        switch ($mode) {
+            // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
+            // and additional flag us internally as 3CBC
+            case self::MODE_3CBC:
+                parent::__construct(self::MODE_CBC);
+                $this->mode_3cbc = true;
+
+                // This three $des'es will do the 3CBC work (if $key > 64bits)
+                $this->des = array(
+                    new DES(self::MODE_CBC),
+                    new DES(self::MODE_CBC),
+                    new DES(self::MODE_CBC),
+                );
+
+                // we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects
+                $this->des[0]->disablePadding();
+                $this->des[1]->disablePadding();
+                $this->des[2]->disablePadding();
+                break;
+            // If not 3CBC, we init as usual
+            default:
+                parent::__construct($mode);
+        }
+    }
+
+    /**
+     * Test for engine validity
+     *
+     * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+     *
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @param int $engine
+     * @access public
+     * @return bool
+     */
+    function isValidEngine($engine)
+    {
+        if ($engine == self::ENGINE_OPENSSL) {
+            $this->cipher_name_openssl_ecb = 'des-ede3';
+            $mode = $this->_openssl_translate_mode();
+            $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
+        }
+
+        return parent::isValidEngine($engine);
+    }
+
+    /**
+     * Sets the initialization vector. (optional)
+     *
+     * SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used.  If not explicitly set, it'll be assumed
+     * to be all zero's.
+     *
+     * @see \phpseclib\Crypt\Base::setIV()
+     * @access public
+     * @param string $iv
+     */
+    function setIV($iv)
+    {
+        parent::setIV($iv);
+        if ($this->mode_3cbc) {
+            $this->des[0]->setIV($iv);
+            $this->des[1]->setIV($iv);
+            $this->des[2]->setIV($iv);
+        }
+    }
+
+    /**
+     * Sets the key length.
+     *
+     * Valid key lengths are 64, 128 and 192
+     *
+     * @see \phpseclib\Crypt\Base:setKeyLength()
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        $length >>= 3;
+        switch (true) {
+            case $length <= 8:
+                $this->key_length = 8;
+                break;
+            case $length <= 16:
+                $this->key_length = 16;
+                break;
+            default:
+                $this->key_length = 24;
+        }
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Sets the key.
+     *
+     * Keys can be of any length.  Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
+     * 192-bit (eg. strlen($key) == 24) keys.  This function pads and truncates $key as appropriate.
+     *
+     * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
+     *
+     * If the key is not explicitly set, it'll be assumed to be all null bytes.
+     *
+     * @access public
+     * @see \phpseclib\Crypt\DES::setKey()
+     * @see \phpseclib\Crypt\Base::setKey()
+     * @param string $key
+     */
+    function setKey($key)
+    {
+        $length = $this->explicit_key_length ? $this->key_length : strlen($key);
+        if ($length > 8) {
+            $key = str_pad(substr($key, 0, 24), 24, chr(0));
+            // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
+            // http://php.net/function.mcrypt-encrypt#47973
+            $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
+        } else {
+            $key = str_pad($key, 8, chr(0));
+        }
+        parent::setKey($key);
+
+        // And in case of self::MODE_3CBC:
+        // if key <= 64bits we not need the 3 $des to work,
+        // because we will then act as regular DES-CBC with just a <= 64bit key.
+        // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
+        if ($this->mode_3cbc && $length > 8) {
+            $this->des[0]->setKey(substr($key,  0, 8));
+            $this->des[1]->setKey(substr($key,  8, 8));
+            $this->des[2]->setKey(substr($key, 16, 8));
+        }
+    }
+
+    /**
+     * Encrypts a message.
+     *
+     * @see \phpseclib\Crypt\Base::encrypt()
+     * @access public
+     * @param string $plaintext
+     * @return string $cipertext
+     */
+    function encrypt($plaintext)
+    {
+        // parent::en/decrypt() is able to do all the work for all modes and keylengths,
+        // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits
+
+        // if the key is smaller then 8, do what we'd normally do
+        if ($this->mode_3cbc && strlen($this->key) > 8) {
+            return $this->des[2]->encrypt(
+                $this->des[1]->decrypt(
+                    $this->des[0]->encrypt(
+                        $this->_pad($plaintext)
+                    )
+                )
+            );
+        }
+
+        return parent::encrypt($plaintext);
+    }
+
+    /**
+     * Decrypts a message.
+     *
+     * @see \phpseclib\Crypt\Base::decrypt()
+     * @access public
+     * @param string $ciphertext
+     * @return string $plaintext
+     */
+    function decrypt($ciphertext)
+    {
+        if ($this->mode_3cbc && strlen($this->key) > 8) {
+            return $this->_unpad(
+                $this->des[0]->decrypt(
+                    $this->des[1]->encrypt(
+                        $this->des[2]->decrypt(
+                            str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
+                        )
+                    )
+                )
+            );
+        }
+
+        return parent::decrypt($ciphertext);
+    }
+
+    /**
+     * Treat consecutive "packets" as if they are a continuous buffer.
+     *
+     * Say you have a 16-byte plaintext $plaintext.  Using the default behavior, the two following code snippets
+     * will yield different outputs:
+     *
+     * <code>
+     *    echo $des->encrypt(substr($plaintext, 0, 8));
+     *    echo $des->encrypt(substr($plaintext, 8, 8));
+     * </code>
+     * <code>
+     *    echo $des->encrypt($plaintext);
+     * </code>
+     *
+     * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates
+     * another, as demonstrated with the following:
+     *
+     * <code>
+     *    $des->encrypt(substr($plaintext, 0, 8));
+     *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
+     * </code>
+     * <code>
+     *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
+     * </code>
+     *
+     * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different
+     * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /
+     * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.
+     *
+     * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\DES() object changes after each
+     * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that
+     * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),
+     * however, they are also less intuitive and more likely to cause you problems.
+     *
+     * @see \phpseclib\Crypt\Base::enableContinuousBuffer()
+     * @see self::disableContinuousBuffer()
+     * @access public
+     */
+    function enableContinuousBuffer()
+    {
+        parent::enableContinuousBuffer();
+        if ($this->mode_3cbc) {
+            $this->des[0]->enableContinuousBuffer();
+            $this->des[1]->enableContinuousBuffer();
+            $this->des[2]->enableContinuousBuffer();
+        }
+    }
+
+    /**
+     * Treat consecutive packets as if they are a discontinuous buffer.
+     *
+     * The default behavior.
+     *
+     * @see \phpseclib\Crypt\Base::disableContinuousBuffer()
+     * @see self::enableContinuousBuffer()
+     * @access public
+     */
+    function disableContinuousBuffer()
+    {
+        parent::disableContinuousBuffer();
+        if ($this->mode_3cbc) {
+            $this->des[0]->disableContinuousBuffer();
+            $this->des[1]->disableContinuousBuffer();
+            $this->des[2]->disableContinuousBuffer();
+        }
+    }
+
+    /**
+     * Creates the key schedule
+     *
+     * @see \phpseclib\Crypt\DES::_setupKey()
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        switch (true) {
+            // if $key <= 64bits we configure our internal pure-php cipher engine
+            // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
+            case strlen($this->key) <= 8:
+                $this->des_rounds = 1;
+                break;
+
+            // otherwise, if $key > 64bits, we configure our engine to work as 3DES.
+            default:
+                $this->des_rounds = 3;
+
+                // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
+                if ($this->mode_3cbc) {
+                    $this->des[0]->_setupKey();
+                    $this->des[1]->_setupKey();
+                    $this->des[2]->_setupKey();
+
+                    // because $des[0-2] will, now, do all the work we can return here
+                    // not need unnecessary stress parent::_setupKey() with our, now unused, $key.
+                    return;
+                }
+        }
+        // setup our key
+        parent::_setupKey();
+    }
+
+    /**
+     * Sets the internal crypt engine
+     *
+     * @see \phpseclib\Crypt\Base::__construct()
+     * @see \phpseclib\Crypt\Base::setPreferredEngine()
+     * @param int $engine
+     * @access public
+     * @return int
+     */
+    function setPreferredEngine($engine)
+    {
+        if ($this->mode_3cbc) {
+            $this->des[0]->setPreferredEngine($engine);
+            $this->des[1]->setPreferredEngine($engine);
+            $this->des[2]->setPreferredEngine($engine);
+        }
+
+        return parent::setPreferredEngine($engine);
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
new file mode 100644
index 00000000..1c020481
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
@@ -0,0 +1,852 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Twofish.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ *  - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $twofish = new \phpseclib\Crypt\Twofish();
+ *
+ *    $twofish->setKey('12345678901234567890123456789012');
+ *
+ *    $plaintext = str_repeat('a', 1024);
+ *
+ *    echo $twofish->decrypt($twofish->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category  Crypt
+ * @package   Twofish
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @author    Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Twofish.
+ *
+ * @package Twofish
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @access  public
+ */
+class Twofish extends Base
+{
+    /**
+     * The mcrypt specific name of the cipher
+     *
+     * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+     * @var string
+     * @access private
+     */
+    var $cipher_name_mcrypt = 'twofish';
+
+    /**
+     * Optimizing value while CFB-encrypting
+     *
+     * @see \phpseclib\Crypt\Base::cfb_init_len
+     * @var int
+     * @access private
+     */
+    var $cfb_init_len = 800;
+
+    /**
+     * Q-Table
+     *
+     * @var array
+     * @access private
+     */
+    var $q0 = array(
+        0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
+        0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
+        0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+        0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
+        0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
+        0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+        0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
+        0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
+        0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+        0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
+        0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
+        0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+        0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
+        0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
+        0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+        0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
+        0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
+        0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+        0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
+        0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
+        0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+        0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
+        0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
+        0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+        0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
+        0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
+        0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+        0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
+        0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
+        0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+        0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
+        0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
+    );
+
+    /**
+     * Q-Table
+     *
+     * @var array
+     * @access private
+     */
+    var $q1 = array(
+        0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
+        0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
+        0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+        0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
+        0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
+        0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+        0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
+        0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
+        0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+        0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
+        0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
+        0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+        0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
+        0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
+        0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+        0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
+        0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
+        0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+        0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
+        0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
+        0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+        0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
+        0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
+        0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+        0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
+        0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
+        0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+        0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
+        0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
+        0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+        0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
+        0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
+    );
+
+    /**
+     * M-Table
+     *
+     * @var array
+     * @access private
+     */
+    var $m0 = array(
+        0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
+        0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
+        0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+        0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
+        0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
+        0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+        0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
+        0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
+        0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+        0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
+        0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
+        0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+        0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
+        0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
+        0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+        0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
+        0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
+        0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+        0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
+        0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
+        0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+        0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
+        0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
+        0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+        0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
+        0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
+        0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+        0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
+        0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
+        0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+        0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
+        0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
+    );
+
+    /**
+     * M-Table
+     *
+     * @var array
+     * @access private
+     */
+    var $m1 = array(
+        0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
+        0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
+        0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+        0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
+        0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
+        0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+        0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
+        0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
+        0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+        0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
+        0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
+        0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+        0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
+        0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
+        0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+        0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
+        0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
+        0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+        0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
+        0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
+        0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+        0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
+        0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
+        0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+        0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
+        0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
+        0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+        0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
+        0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
+        0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+        0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
+        0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
+    );
+
+    /**
+     * M-Table
+     *
+     * @var array
+     * @access private
+     */
+    var $m2 = array(
+        0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
+        0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
+        0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+        0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
+        0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
+        0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+        0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
+        0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
+        0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+        0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
+        0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
+        0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+        0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
+        0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
+        0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+        0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
+        0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
+        0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+        0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
+        0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
+        0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+        0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
+        0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
+        0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+        0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
+        0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
+        0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+        0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
+        0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
+        0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+        0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
+        0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
+    );
+
+    /**
+     * M-Table
+     *
+     * @var array
+     * @access private
+     */
+    var $m3 = array(
+        0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
+        0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
+        0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+        0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
+        0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
+        0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+        0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
+        0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
+        0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+        0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
+        0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
+        0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+        0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
+        0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
+        0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+        0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
+        0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
+        0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+        0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
+        0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
+        0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+        0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
+        0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
+        0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+        0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
+        0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
+        0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+        0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
+        0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
+        0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+        0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
+        0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
+    );
+
+    /**
+     * The Key Schedule Array
+     *
+     * @var array
+     * @access private
+     */
+    var $K = array();
+
+    /**
+     * The Key depended S-Table 0
+     *
+     * @var array
+     * @access private
+     */
+    var $S0 = array();
+
+    /**
+     * The Key depended S-Table 1
+     *
+     * @var array
+     * @access private
+     */
+    var $S1 = array();
+
+    /**
+     * The Key depended S-Table 2
+     *
+     * @var array
+     * @access private
+     */
+    var $S2 = array();
+
+    /**
+     * The Key depended S-Table 3
+     *
+     * @var array
+     * @access private
+     */
+    var $S3 = array();
+
+    /**
+     * Holds the last used key
+     *
+     * @var array
+     * @access private
+     */
+    var $kl;
+
+    /**
+     * The Key Length (in bytes)
+     *
+     * @see Crypt_Twofish::setKeyLength()
+     * @var int
+     * @access private
+     */
+    var $key_length = 16;
+
+    /**
+     * Default Constructor.
+     *
+     * Determines whether or not the mcrypt extension should be used.
+     *
+     * $mode could be:
+     *
+     * - CRYPT_MODE_ECB
+     *
+     * - CRYPT_MODE_CBC
+     *
+     * - CRYPT_MODE_CTR
+     *
+     * - CRYPT_MODE_CFB
+     *
+     * - CRYPT_MODE_OFB
+     *
+     * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
+     *
+     * If not explicitly set, CRYPT_MODE_CBC will be used.
+     *
+     * @param int $mode
+     * @access public
+     */
+    function __construct($mode = self::MODE_CBC)
+    {
+        parent::__construct($mode);
+
+        $this->m0 = array_map('intval', $this->m0);
+        $this->m1 = array_map('intval', $this->m1);
+        $this->m2 = array_map('intval', $this->m2);
+        $this->m3 = array_map('intval', $this->m3);
+        $this->q0 = array_map('intval', $this->q0);
+        $this->q1 = array_map('intval', $this->q1);
+    }
+
+    /**
+     * Sets the key length.
+     *
+     * Valid key lengths are 128, 192 or 256 bits
+     *
+     * @access public
+     * @param int $length
+     */
+    function setKeyLength($length)
+    {
+        switch (true) {
+            case $length <= 128:
+                $this->key_length = 16;
+                break;
+            case $length <= 192:
+                $this->key_length = 24;
+                break;
+            default:
+                $this->key_length = 32;
+        }
+
+        parent::setKeyLength($length);
+    }
+
+    /**
+     * Setup the key (expansion)
+     *
+     * @see \phpseclib\Crypt\Base::_setupKey()
+     * @access private
+     */
+    function _setupKey()
+    {
+        if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
+            // already expanded
+            return;
+        }
+        $this->kl = array('key' => $this->key);
+
+        /* Key expanding and generating the key-depended s-boxes */
+        $le_longs = unpack('V*', $this->key);
+        $key = unpack('C*', $this->key);
+        $m0 = $this->m0;
+        $m1 = $this->m1;
+        $m2 = $this->m2;
+        $m3 = $this->m3;
+        $q0 = $this->q0;
+        $q1 = $this->q1;
+
+        $K = $S0 = $S1 = $S2 = $S3 = array();
+
+        switch (strlen($this->key)) {
+            case 16:
+                list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+                list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+                for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
+                    $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
+                         $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
+                         $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
+                         $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
+                    $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
+                         $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
+                         $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
+                         $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
+                    $B = ($B << 8) | ($B >> 24 & 0xff);
+                    $A = $this->safe_intval($A + $B);
+                    $K[] = $A;
+                    $A = $this->safe_intval($A + $B);
+                    $K[] = ($A << 9 | $A >> 23 & 0x1ff);
+                }
+                for ($i = 0; $i < 256; ++$i) {
+                    $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
+                    $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
+                    $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
+                    $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
+                }
+                break;
+            case 24:
+                list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+                list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+                list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
+                for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
+                    $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
+                         $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
+                         $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
+                         $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
+                    $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
+                         $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
+                         $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
+                         $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
+                    $B = ($B << 8) | ($B >> 24 & 0xff);
+                    $A = $this->safe_intval($A + $B);
+                    $K[] = $A;
+                    $A = $this->safe_intval($A + $B);
+                    $K[] = ($A << 9 | $A >> 23 & 0x1ff);
+                }
+                for ($i = 0; $i < 256; ++$i) {
+                    $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
+                    $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
+                    $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
+                    $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
+                }
+                break;
+            default: // 32
+                list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+                list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+                list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
+                list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
+                for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
+                    $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
+                         $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
+                         $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
+                         $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
+                    $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
+                         $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
+                         $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
+                         $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
+                    $B = ($B << 8) | ($B >> 24 & 0xff);
+                    $A = $this->safe_intval($A + $B);
+                    $K[] = $A;
+                    $A = $this->safe_intval($A + $B);
+                    $K[] = ($A << 9 | $A >> 23 & 0x1ff);
+                }
+                for ($i = 0; $i < 256; ++$i) {
+                    $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
+                    $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
+                    $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
+                    $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
+                }
+        }
+
+        $this->K  = $K;
+        $this->S0 = $S0;
+        $this->S1 = $S1;
+        $this->S2 = $S2;
+        $this->S3 = $S3;
+    }
+
+    /**
+     * _mdsrem function using by the twofish cipher algorithm
+     *
+     * @access private
+     * @param string $A
+     * @param string $B
+     * @return array
+     */
+    function _mdsrem($A, $B)
+    {
+        // No gain by unrolling this loop.
+        for ($i = 0; $i < 8; ++$i) {
+            // Get most significant coefficient.
+            $t = 0xff & ($B >> 24);
+
+            // Shift the others up.
+            $B = ($B << 8) | (0xff & ($A >> 24));
+            $A<<= 8;
+
+            $u = $t << 1;
+
+            // Subtract the modular polynomial on overflow.
+            if ($t & 0x80) {
+                $u^= 0x14d;
+            }
+
+            // Remove t * (a * x^2 + 1).
+            $B ^= $t ^ ($u << 16);
+
+            // Form u = a*t + t/a = t*(a + 1/a).
+            $u^= 0x7fffffff & ($t >> 1);
+
+            // Add the modular polynomial on underflow.
+            if ($t & 0x01) {
+                $u^= 0xa6 ;
+            }
+
+            // Remove t * (a + 1/a) * (x^3 + x).
+            $B^= ($u << 24) | ($u << 8);
+        }
+
+        return array(
+            0xff & $B >> 24,
+            0xff & $B >> 16,
+            0xff & $B >>  8,
+            0xff & $B);
+    }
+
+    /**
+     * Encrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _encryptBlock($in)
+    {
+        $S0 = $this->S0;
+        $S1 = $this->S1;
+        $S2 = $this->S2;
+        $S3 = $this->S3;
+        $K  = $this->K;
+
+        $in = unpack("V4", $in);
+        $R0 = $K[0] ^ $in[1];
+        $R1 = $K[1] ^ $in[2];
+        $R2 = $K[2] ^ $in[3];
+        $R3 = $K[3] ^ $in[4];
+
+        $ki = 7;
+        while ($ki < 39) {
+            $t0 = $S0[ $R0        & 0xff] ^
+                  $S1[($R0 >>  8) & 0xff] ^
+                  $S2[($R0 >> 16) & 0xff] ^
+                  $S3[($R0 >> 24) & 0xff];
+            $t1 = $S0[($R1 >> 24) & 0xff] ^
+                  $S1[ $R1        & 0xff] ^
+                  $S2[($R1 >>  8) & 0xff] ^
+                  $S3[($R1 >> 16) & 0xff];
+            $R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
+            $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
+            $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
+
+            $t0 = $S0[ $R2        & 0xff] ^
+                  $S1[($R2 >>  8) & 0xff] ^
+                  $S2[($R2 >> 16) & 0xff] ^
+                  $S3[($R2 >> 24) & 0xff];
+            $t1 = $S0[($R3 >> 24) & 0xff] ^
+                  $S1[ $R3        & 0xff] ^
+                  $S2[($R3 >>  8) & 0xff] ^
+                  $S3[($R3 >> 16) & 0xff];
+            $R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
+            $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
+            $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
+        }
+
+        // @codingStandardsIgnoreStart
+        return pack("V4", $K[4] ^ $R2,
+                          $K[5] ^ $R3,
+                          $K[6] ^ $R0,
+                          $K[7] ^ $R1);
+        // @codingStandardsIgnoreEnd
+    }
+
+    /**
+     * Decrypts a block
+     *
+     * @access private
+     * @param string $in
+     * @return string
+     */
+    function _decryptBlock($in)
+    {
+        $S0 = $this->S0;
+        $S1 = $this->S1;
+        $S2 = $this->S2;
+        $S3 = $this->S3;
+        $K  = $this->K;
+
+        $in = unpack("V4", $in);
+        $R0 = $K[4] ^ $in[1];
+        $R1 = $K[5] ^ $in[2];
+        $R2 = $K[6] ^ $in[3];
+        $R3 = $K[7] ^ $in[4];
+
+        $ki = 40;
+        while ($ki > 8) {
+            $t0 = $S0[$R0       & 0xff] ^
+                  $S1[$R0 >>  8 & 0xff] ^
+                  $S2[$R0 >> 16 & 0xff] ^
+                  $S3[$R0 >> 24 & 0xff];
+            $t1 = $S0[$R1 >> 24 & 0xff] ^
+                  $S1[$R1       & 0xff] ^
+                  $S2[$R1 >>  8 & 0xff] ^
+                  $S3[$R1 >> 16 & 0xff];
+            $R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
+            $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
+            $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
+
+            $t0 = $S0[$R2       & 0xff] ^
+                  $S1[$R2 >>  8 & 0xff] ^
+                  $S2[$R2 >> 16 & 0xff] ^
+                  $S3[$R2 >> 24 & 0xff];
+            $t1 = $S0[$R3 >> 24 & 0xff] ^
+                  $S1[$R3       & 0xff] ^
+                  $S2[$R3 >>  8 & 0xff] ^
+                  $S3[$R3 >> 16 & 0xff];
+            $R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
+            $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
+            $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
+        }
+
+        // @codingStandardsIgnoreStart
+        return pack("V4", $K[0] ^ $R2,
+                          $K[1] ^ $R3,
+                          $K[2] ^ $R0,
+                          $K[3] ^ $R1);
+        // @codingStandardsIgnoreEnd
+    }
+
+    /**
+     * Setup the performance-optimized function for de/encrypt()
+     *
+     * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+     * @access private
+     */
+    function _setupInlineCrypt()
+    {
+        $lambda_functions =& self::_getLambdaFunctions();
+
+        // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
+        // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
+        $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+        // Generation of a unique hash for our generated code
+        $code_hash = "Crypt_Twofish, {$this->mode}";
+        if ($gen_hi_opt_code) {
+            $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+        }
+
+        $safeint = $this->safe_intval_inline();
+
+        if (!isset($lambda_functions[$code_hash])) {
+            switch (true) {
+                case $gen_hi_opt_code:
+                    $K = $this->K;
+                    $init_crypt = '
+                        static $S0, $S1, $S2, $S3;
+                        if (!$S0) {
+                            for ($i = 0; $i < 256; ++$i) {
+                                $S0[] = (int)$self->S0[$i];
+                                $S1[] = (int)$self->S1[$i];
+                                $S2[] = (int)$self->S2[$i];
+                                $S3[] = (int)$self->S3[$i];
+                            }
+                        }
+                    ';
+                    break;
+                default:
+                    $K   = array();
+                    for ($i = 0; $i < 40; ++$i) {
+                        $K[] = '$K_' . $i;
+                    }
+                    $init_crypt = '
+                        $S0 = $self->S0;
+                        $S1 = $self->S1;
+                        $S2 = $self->S2;
+                        $S3 = $self->S3;
+                        list(' . implode(',', $K) . ') = $self->K;
+                    ';
+            }
+
+            // Generating encrypt code:
+            $encrypt_block = '
+                $in = unpack("V4", $in);
+                $R0 = '.$K[0].' ^ $in[1];
+                $R1 = '.$K[1].' ^ $in[2];
+                $R2 = '.$K[2].' ^ $in[3];
+                $R3 = '.$K[3].' ^ $in[4];
+            ';
+            for ($ki = 7, $i = 0; $i < 8; ++$i) {
+                $encrypt_block.= '
+                    $t0 = $S0[ $R0        & 0xff] ^
+                          $S1[($R0 >>  8) & 0xff] ^
+                          $S2[($R0 >> 16) & 0xff] ^
+                          $S3[($R0 >> 24) & 0xff];
+                    $t1 = $S0[($R1 >> 24) & 0xff] ^
+                          $S1[ $R1        & 0xff] ^
+                          $S2[($R1 >>  8) & 0xff] ^
+                          $S3[($R1 >> 16) & 0xff];
+                    $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
+                    $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
+                    $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
+
+                    $t0 = $S0[ $R2        & 0xff] ^
+                          $S1[($R2 >>  8) & 0xff] ^
+                          $S2[($R2 >> 16) & 0xff] ^
+                          $S3[($R2 >> 24) & 0xff];
+                    $t1 = $S0[($R3 >> 24) & 0xff] ^
+                          $S1[ $R3        & 0xff] ^
+                          $S2[($R3 >>  8) & 0xff] ^
+                          $S3[($R3 >> 16) & 0xff];
+                    $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
+                    $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
+                    $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
+                ';
+            }
+            $encrypt_block.= '
+                $in = pack("V4", ' . $K[4] . ' ^ $R2,
+                                 ' . $K[5] . ' ^ $R3,
+                                 ' . $K[6] . ' ^ $R0,
+                                 ' . $K[7] . ' ^ $R1);
+            ';
+
+            // Generating decrypt code:
+            $decrypt_block = '
+                $in = unpack("V4", $in);
+                $R0 = '.$K[4].' ^ $in[1];
+                $R1 = '.$K[5].' ^ $in[2];
+                $R2 = '.$K[6].' ^ $in[3];
+                $R3 = '.$K[7].' ^ $in[4];
+            ';
+            for ($ki = 40, $i = 0; $i < 8; ++$i) {
+                $decrypt_block.= '
+                    $t0 = $S0[$R0       & 0xff] ^
+                          $S1[$R0 >>  8 & 0xff] ^
+                          $S2[$R0 >> 16 & 0xff] ^
+                          $S3[$R0 >> 24 & 0xff];
+                    $t1 = $S0[$R1 >> 24 & 0xff] ^
+                          $S1[$R1       & 0xff] ^
+                          $S2[$R1 >>  8 & 0xff] ^
+                          $S3[$R1 >> 16 & 0xff];
+                    $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
+                    $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
+                    $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
+
+                    $t0 = $S0[$R2       & 0xff] ^
+                          $S1[$R2 >>  8 & 0xff] ^
+                          $S2[$R2 >> 16 & 0xff] ^
+                          $S3[$R2 >> 24 & 0xff];
+                    $t1 = $S0[$R3 >> 24 & 0xff] ^
+                          $S1[$R3       & 0xff] ^
+                          $S2[$R3 >>  8 & 0xff] ^
+                          $S3[$R3 >> 16 & 0xff];
+                    $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
+                    $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
+                    $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
+                ';
+            }
+            $decrypt_block.= '
+                $in = pack("V4", ' . $K[0] . ' ^ $R2,
+                                 ' . $K[1] . ' ^ $R3,
+                                 ' . $K[2] . ' ^ $R0,
+                                 ' . $K[3] . ' ^ $R1);
+            ';
+
+            $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+                array(
+                   'init_crypt'    => $init_crypt,
+                   'init_encrypt'  => '',
+                   'init_decrypt'  => '',
+                   'encrypt_block' => $encrypt_block,
+                   'decrypt_block' => $decrypt_block
+                )
+            );
+        }
+        $this->inline_crypt = $lambda_functions[$code_hash];
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/msd/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
new file mode 100644
index 00000000..b6874d35
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
@@ -0,0 +1,577 @@
+<?php
+
+/**
+ * Pure-PHP ANSI Decoder
+ *
+ * PHP version 5
+ *
+ * If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
+ * They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC).  They tell a
+ * {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
+ * color to display them in, etc. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
+ *
+ * @category  File
+ * @package   ANSI
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File;
+
+/**
+ * Pure-PHP ANSI Decoder
+ *
+ * @package ANSI
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class ANSI
+{
+    /**
+     * Max Width
+     *
+     * @var int
+     * @access private
+     */
+    var $max_x;
+
+    /**
+     * Max Height
+     *
+     * @var int
+     * @access private
+     */
+    var $max_y;
+
+    /**
+     * Max History
+     *
+     * @var int
+     * @access private
+     */
+    var $max_history;
+
+    /**
+     * History
+     *
+     * @var array
+     * @access private
+     */
+    var $history;
+
+    /**
+     * History Attributes
+     *
+     * @var array
+     * @access private
+     */
+    var $history_attrs;
+
+    /**
+     * Current Column
+     *
+     * @var int
+     * @access private
+     */
+    var $x;
+
+    /**
+     * Current Row
+     *
+     * @var int
+     * @access private
+     */
+    var $y;
+
+    /**
+     * Old Column
+     *
+     * @var int
+     * @access private
+     */
+    var $old_x;
+
+    /**
+     * Old Row
+     *
+     * @var int
+     * @access private
+     */
+    var $old_y;
+
+    /**
+     * An empty attribute cell
+     *
+     * @var object
+     * @access private
+     */
+    var $base_attr_cell;
+
+    /**
+     * The current attribute cell
+     *
+     * @var object
+     * @access private
+     */
+    var $attr_cell;
+
+    /**
+     * An empty attribute row
+     *
+     * @var array
+     * @access private
+     */
+    var $attr_row;
+
+    /**
+     * The current screen text
+     *
+     * @var array
+     * @access private
+     */
+    var $screen;
+
+    /**
+     * The current screen attributes
+     *
+     * @var array
+     * @access private
+     */
+    var $attrs;
+
+    /**
+     * Current ANSI code
+     *
+     * @var string
+     * @access private
+     */
+    var $ansi;
+
+    /**
+     * Tokenization
+     *
+     * @var array
+     * @access private
+     */
+    var $tokenization;
+
+    /**
+     * Default Constructor.
+     *
+     * @return \phpseclib\File\ANSI
+     * @access public
+     */
+    function __construct()
+    {
+        $attr_cell = new \stdClass();
+        $attr_cell->bold = false;
+        $attr_cell->underline = false;
+        $attr_cell->blink = false;
+        $attr_cell->background = 'black';
+        $attr_cell->foreground = 'white';
+        $attr_cell->reverse = false;
+        $this->base_attr_cell = clone $attr_cell;
+        $this->attr_cell = clone $attr_cell;
+
+        $this->setHistory(200);
+        $this->setDimensions(80, 24);
+    }
+
+    /**
+     * Set terminal width and height
+     *
+     * Resets the screen as well
+     *
+     * @param int $x
+     * @param int $y
+     * @access public
+     */
+    function setDimensions($x, $y)
+    {
+        $this->max_x = $x - 1;
+        $this->max_y = $y - 1;
+        $this->x = $this->y = 0;
+        $this->history = $this->history_attrs = array();
+        $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell);
+        $this->screen = array_fill(0, $this->max_y + 1, '');
+        $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
+        $this->ansi = '';
+    }
+
+    /**
+     * Set the number of lines that should be logged past the terminal height
+     *
+     * @param int $history
+     * @access public
+     */
+    function setHistory($history)
+    {
+        $this->max_history = $history;
+    }
+
+    /**
+     * Load a string
+     *
+     * @param string $source
+     * @access public
+     */
+    function loadString($source)
+    {
+        $this->setDimensions($this->max_x + 1, $this->max_y + 1);
+        $this->appendString($source);
+    }
+
+    /**
+     * Appdend a string
+     *
+     * @param string $source
+     * @access public
+     */
+    function appendString($source)
+    {
+        $this->tokenization = array('');
+        for ($i = 0; $i < strlen($source); $i++) {
+            if (strlen($this->ansi)) {
+                $this->ansi.= $source[$i];
+                $chr = ord($source[$i]);
+                // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
+                // single character CSI's not currently supported
+                switch (true) {
+                    case $this->ansi == "\x1B=":
+                        $this->ansi = '';
+                        continue 2;
+                    case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
+                    case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
+                        break;
+                    default:
+                        continue 2;
+                }
+                $this->tokenization[] = $this->ansi;
+                $this->tokenization[] = '';
+                // http://ascii-table.com/ansi-escape-sequences-vt-100.php
+                switch ($this->ansi) {
+                    case "\x1B[H": // Move cursor to upper left corner
+                        $this->old_x = $this->x;
+                        $this->old_y = $this->y;
+                        $this->x = $this->y = 0;
+                        break;
+                    case "\x1B[J": // Clear screen from cursor down
+                        $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
+                        $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
+
+                        $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
+                        $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));
+
+                        if (count($this->history) == $this->max_history) {
+                            array_shift($this->history);
+                            array_shift($this->history_attrs);
+                        }
+                    case "\x1B[K": // Clear screen from cursor right
+                        $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
+
+                        array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell));
+                        break;
+                    case "\x1B[2K": // Clear entire line
+                        $this->screen[$this->y] = str_repeat(' ', $this->x);
+                        $this->attrs[$this->y] = $this->attr_row;
+                        break;
+                    case "\x1B[?1h": // set cursor key to application
+                    case "\x1B[?25h": // show the cursor
+                    case "\x1B(B": // set united states g0 character set
+                        break;
+                    case "\x1BE": // Move to next line
+                        $this->_newLine();
+                        $this->x = 0;
+                        break;
+                    default:
+                        switch (true) {
+                            case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
+                                $this->old_y = $this->y;
+                                $this->y+= $match[1];
+                                break;
+                            case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
+                                $this->old_x = $this->x;
+                                $this->old_y = $this->y;
+                                $this->x = $match[2] - 1;
+                                $this->y = $match[1] - 1;
+                                break;
+                            case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
+                                $this->old_x = $this->x;
+                                $this->x+= $match[1];
+                                break;
+                            case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
+                                $this->old_x = $this->x;
+                                $this->x-= $match[1];
+                                if ($this->x < 0) {
+                                    $this->x = 0;
+                                }
+                                break;
+                            case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
+                                break;
+                            case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
+                                $attr_cell = &$this->attr_cell;
+                                $mods = explode(';', $match[1]);
+                                foreach ($mods as $mod) {
+                                    switch ($mod) {
+                                        case '':
+                                        case '0': // Turn off character attributes
+                                            $attr_cell = clone $this->base_attr_cell;
+                                            break;
+                                        case '1': // Turn bold mode on
+                                            $attr_cell->bold = true;
+                                            break;
+                                        case '4': // Turn underline mode on
+                                            $attr_cell->underline = true;
+                                            break;
+                                        case '5': // Turn blinking mode on
+                                            $attr_cell->blink = true;
+                                            break;
+                                        case '7': // Turn reverse video on
+                                            $attr_cell->reverse = !$attr_cell->reverse;
+                                            $temp = $attr_cell->background;
+                                            $attr_cell->background = $attr_cell->foreground;
+                                            $attr_cell->foreground = $temp;
+                                            break;
+                                        default: // set colors
+                                            //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
+                                            $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
+                                            //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
+                                            $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
+                                            switch ($mod) {
+                                                // @codingStandardsIgnoreStart
+                                                case '30': $front = 'black'; break;
+                                                case '31': $front = 'red'; break;
+                                                case '32': $front = 'green'; break;
+                                                case '33': $front = 'yellow'; break;
+                                                case '34': $front = 'blue'; break;
+                                                case '35': $front = 'magenta'; break;
+                                                case '36': $front = 'cyan'; break;
+                                                case '37': $front = 'white'; break;
+
+                                                case '40': $back = 'black'; break;
+                                                case '41': $back = 'red'; break;
+                                                case '42': $back = 'green'; break;
+                                                case '43': $back = 'yellow'; break;
+                                                case '44': $back = 'blue'; break;
+                                                case '45': $back = 'magenta'; break;
+                                                case '46': $back = 'cyan'; break;
+                                                case '47': $back = 'white'; break;
+                                                // @codingStandardsIgnoreEnd
+
+                                                default:
+                                                    //user_error('Unsupported attribute: ' . $mod);
+                                                    $this->ansi = '';
+                                                    break 2;
+                                            }
+                                    }
+                                }
+                                break;
+                            default:
+                                //user_error("{$this->ansi} is unsupported\r\n");
+                        }
+                }
+                $this->ansi = '';
+                continue;
+            }
+
+            $this->tokenization[count($this->tokenization) - 1].= $source[$i];
+            switch ($source[$i]) {
+                case "\r":
+                    $this->x = 0;
+                    break;
+                case "\n":
+                    $this->_newLine();
+                    break;
+                case "\x08": // backspace
+                    if ($this->x) {
+                        $this->x--;
+                        $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell;
+                        $this->screen[$this->y] = substr_replace(
+                            $this->screen[$this->y],
+                            $source[$i],
+                            $this->x,
+                            1
+                        );
+                    }
+                    break;
+                case "\x0F": // shift
+                    break;
+                case "\x1B": // start ANSI escape code
+                    $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
+                    //if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
+                    //    array_pop($this->tokenization);
+                    //}
+                    $this->ansi.= "\x1B";
+                    break;
+                default:
+                    $this->attrs[$this->y][$this->x] = clone $this->attr_cell;
+                    if ($this->x > strlen($this->screen[$this->y])) {
+                        $this->screen[$this->y] = str_repeat(' ', $this->x);
+                    }
+                    $this->screen[$this->y] = substr_replace(
+                        $this->screen[$this->y],
+                        $source[$i],
+                        $this->x,
+                        1
+                    );
+
+                    if ($this->x > $this->max_x) {
+                        $this->x = 0;
+                        $this->_newLine();
+                    } else {
+                        $this->x++;
+                    }
+            }
+        }
+    }
+
+    /**
+     * Add a new line
+     *
+     * Also update the $this->screen and $this->history buffers
+     *
+     * @access private
+     */
+    function _newLine()
+    {
+        //if ($this->y < $this->max_y) {
+        //    $this->y++;
+        //}
+
+        while ($this->y >= $this->max_y) {
+            $this->history = array_merge($this->history, array(array_shift($this->screen)));
+            $this->screen[] = '';
+
+            $this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
+            $this->attrs[] = $this->attr_row;
+
+            if (count($this->history) >= $this->max_history) {
+                array_shift($this->history);
+                array_shift($this->history_attrs);
+            }
+
+            $this->y--;
+        }
+        $this->y++;
+    }
+
+    /**
+     * Returns the current coordinate without preformating
+     *
+     * @access private
+     * @return string
+     */
+    function _processCoordinate($last_attr, $cur_attr, $char)
+    {
+        $output = '';
+
+        if ($last_attr != $cur_attr) {
+            $close = $open = '';
+            if ($last_attr->foreground != $cur_attr->foreground) {
+                if ($cur_attr->foreground != 'white') {
+                    $open.= '<span style="color: ' . $cur_attr->foreground . '">';
+                }
+                if ($last_attr->foreground != 'white') {
+                    $close = '</span>' . $close;
+                }
+            }
+            if ($last_attr->background != $cur_attr->background) {
+                if ($cur_attr->background != 'black') {
+                    $open.= '<span style="background: ' . $cur_attr->background . '">';
+                }
+                if ($last_attr->background != 'black') {
+                    $close = '</span>' . $close;
+                }
+            }
+            if ($last_attr->bold != $cur_attr->bold) {
+                if ($cur_attr->bold) {
+                    $open.= '<b>';
+                } else {
+                    $close = '</b>' . $close;
+                }
+            }
+            if ($last_attr->underline != $cur_attr->underline) {
+                if ($cur_attr->underline) {
+                    $open.= '<u>';
+                } else {
+                    $close = '</u>' . $close;
+                }
+            }
+            if ($last_attr->blink != $cur_attr->blink) {
+                if ($cur_attr->blink) {
+                    $open.= '<blink>';
+                } else {
+                    $close = '</blink>' . $close;
+                }
+            }
+            $output.= $close . $open;
+        }
+
+        $output.= htmlspecialchars($char);
+
+        return $output;
+    }
+
+    /**
+     * Returns the current screen without preformating
+     *
+     * @access private
+     * @return string
+     */
+    function _getScreen()
+    {
+        $output = '';
+        $last_attr = $this->base_attr_cell;
+        for ($i = 0; $i <= $this->max_y; $i++) {
+            for ($j = 0; $j <= $this->max_x; $j++) {
+                $cur_attr = $this->attrs[$i][$j];
+                $output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : '');
+                $last_attr = $this->attrs[$i][$j];
+            }
+            $output.= "\r\n";
+        }
+        $output = substr($output, 0, -2);
+        // close any remaining open tags
+        $output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, '');
+        return rtrim($output);
+    }
+
+    /**
+     * Returns the current screen
+     *
+     * @access public
+     * @return string
+     */
+    function getScreen()
+    {
+        return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $this->_getScreen() . '</pre>';
+    }
+
+    /**
+     * Returns the current screen and the x previous lines
+     *
+     * @access public
+     * @return string
+     */
+    function getHistory()
+    {
+        $scrollback = '';
+        $last_attr = $this->base_attr_cell;
+        for ($i = 0; $i < count($this->history); $i++) {
+            for ($j = 0; $j <= $this->max_x + 1; $j++) {
+                $cur_attr = $this->history_attrs[$i][$j];
+                $scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : '');
+                $last_attr = $this->history_attrs[$i][$j];
+            }
+            $scrollback.= "\r\n";
+        }
+        $base_attr_cell = $this->base_attr_cell;
+        $this->base_attr_cell = $last_attr;
+        $scrollback.= $this->_getScreen();
+        $this->base_attr_cell = $base_attr_cell;
+
+        return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $scrollback . '</span></pre>';
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/msd/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
new file mode 100644
index 00000000..22e4d965
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
@@ -0,0 +1,1469 @@
+<?php
+
+/**
+ * Pure-PHP ASN.1 Parser
+ *
+ * PHP version 5
+ *
+ * ASN.1 provides the semantics for data encoded using various schemes.  The most commonly
+ * utilized scheme is DER or the "Distinguished Encoding Rules".  PEM's are base64 encoded
+ * DER blobs.
+ *
+ * \phpseclib\File\ASN1 decodes and encodes DER formatted messages and places them in a semantic context.
+ *
+ * Uses the 1988 ASN.1 syntax.
+ *
+ * @category  File
+ * @package   ASN1
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File;
+
+use phpseclib\File\ASN1\Element;
+use phpseclib\Math\BigInteger;
+use DateTime;
+use DateTimeZone;
+
+/**
+ * Pure-PHP ASN.1 Parser
+ *
+ * @package ASN1
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class ASN1
+{
+    /**#@+
+     * Tag Classes
+     *
+     * @access private
+     * @link http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12
+     */
+    const CLASS_UNIVERSAL        = 0;
+    const CLASS_APPLICATION      = 1;
+    const CLASS_CONTEXT_SPECIFIC = 2;
+    const CLASS_PRIVATE          = 3;
+    /**#@-*/
+
+    /**#@+
+     * Tag Classes
+     *
+     * @access private
+     * @link http://www.obj-sys.com/asn1tutorial/node124.html
+    */
+    const TYPE_BOOLEAN           = 1;
+    const TYPE_INTEGER           = 2;
+    const TYPE_BIT_STRING        = 3;
+    const TYPE_OCTET_STRING      = 4;
+    const TYPE_NULL              = 5;
+    const TYPE_OBJECT_IDENTIFIER = 6;
+    //const TYPE_OBJECT_DESCRIPTOR = 7;
+    //const TYPE_INSTANCE_OF       = 8; // EXTERNAL
+    const TYPE_REAL              = 9;
+    const TYPE_ENUMERATED        = 10;
+    //const TYPE_EMBEDDED          = 11;
+    const TYPE_UTF8_STRING       = 12;
+    //const TYPE_RELATIVE_OID      = 13;
+    const TYPE_SEQUENCE          = 16; // SEQUENCE OF
+    const TYPE_SET               = 17; // SET OF
+    /**#@-*/
+    /**#@+
+     * More Tag Classes
+     *
+     * @access private
+     * @link http://www.obj-sys.com/asn1tutorial/node10.html
+    */
+    const TYPE_NUMERIC_STRING   = 18;
+    const TYPE_PRINTABLE_STRING = 19;
+    const TYPE_TELETEX_STRING   = 20; // T61String
+    const TYPE_VIDEOTEX_STRING  = 21;
+    const TYPE_IA5_STRING       = 22;
+    const TYPE_UTC_TIME         = 23;
+    const TYPE_GENERALIZED_TIME = 24;
+    const TYPE_GRAPHIC_STRING   = 25;
+    const TYPE_VISIBLE_STRING   = 26; // ISO646String
+    const TYPE_GENERAL_STRING   = 27;
+    const TYPE_UNIVERSAL_STRING = 28;
+    //const TYPE_CHARACTER_STRING = 29;
+    const TYPE_BMP_STRING       = 30;
+    /**#@-*/
+
+    /**#@+
+     * Tag Aliases
+     *
+     * These tags are kinda place holders for other tags.
+     *
+     * @access private
+    */
+    const TYPE_CHOICE = -1;
+    const TYPE_ANY    = -2;
+    /**#@-*/
+
+    /**
+     * ASN.1 object identifier
+     *
+     * @var array
+     * @access private
+     * @link http://en.wikipedia.org/wiki/Object_identifier
+     */
+    var $oids = array();
+
+    /**
+     * Default date format
+     *
+     * @var string
+     * @access private
+     * @link http://php.net/class.datetime
+     */
+    var $format = 'D, d M Y H:i:s O';
+
+    /**
+     * Default date format
+     *
+     * @var array
+     * @access private
+     * @see self::setTimeFormat()
+     * @see self::asn1map()
+     * @link http://php.net/class.datetime
+     */
+    var $encoded;
+
+    /**
+     * Filters
+     *
+     * If the mapping type is self::TYPE_ANY what do we actually encode it as?
+     *
+     * @var array
+     * @access private
+     * @see self::_encode_der()
+     */
+    var $filters;
+
+    /**
+     * Current Location of most recent ASN.1 encode process
+     *
+     * Useful for debug purposes
+     *
+     * @var array
+     * @see self::encode_der()
+     */
+    var $location;
+
+    /**
+     * Type mapping table for the ANY type.
+     *
+     * Structured or unknown types are mapped to a \phpseclib\File\ASN1\Element.
+     * Unambiguous types get the direct mapping (int/real/bool).
+     * Others are mapped as a choice, with an extra indexing level.
+     *
+     * @var array
+     * @access public
+     */
+    var $ANYmap = array(
+        self::TYPE_BOOLEAN              => true,
+        self::TYPE_INTEGER              => true,
+        self::TYPE_BIT_STRING           => 'bitString',
+        self::TYPE_OCTET_STRING         => 'octetString',
+        self::TYPE_NULL                 => 'null',
+        self::TYPE_OBJECT_IDENTIFIER    => 'objectIdentifier',
+        self::TYPE_REAL                 => true,
+        self::TYPE_ENUMERATED           => 'enumerated',
+        self::TYPE_UTF8_STRING          => 'utf8String',
+        self::TYPE_NUMERIC_STRING       => 'numericString',
+        self::TYPE_PRINTABLE_STRING     => 'printableString',
+        self::TYPE_TELETEX_STRING       => 'teletexString',
+        self::TYPE_VIDEOTEX_STRING      => 'videotexString',
+        self::TYPE_IA5_STRING           => 'ia5String',
+        self::TYPE_UTC_TIME             => 'utcTime',
+        self::TYPE_GENERALIZED_TIME     => 'generalTime',
+        self::TYPE_GRAPHIC_STRING       => 'graphicString',
+        self::TYPE_VISIBLE_STRING       => 'visibleString',
+        self::TYPE_GENERAL_STRING       => 'generalString',
+        self::TYPE_UNIVERSAL_STRING     => 'universalString',
+        //self::TYPE_CHARACTER_STRING     => 'characterString',
+        self::TYPE_BMP_STRING           => 'bmpString'
+    );
+
+    /**
+     * String type to character size mapping table.
+     *
+     * Non-convertable types are absent from this table.
+     * size == 0 indicates variable length encoding.
+     *
+     * @var array
+     * @access public
+     */
+    var $stringTypeSize = array(
+        self::TYPE_UTF8_STRING      => 0,
+        self::TYPE_BMP_STRING       => 2,
+        self::TYPE_UNIVERSAL_STRING => 4,
+        self::TYPE_PRINTABLE_STRING => 1,
+        self::TYPE_TELETEX_STRING   => 1,
+        self::TYPE_IA5_STRING       => 1,
+        self::TYPE_VISIBLE_STRING   => 1,
+    );
+
+    /**
+     * Parse BER-encoding
+     *
+     * Serves a similar purpose to openssl's asn1parse
+     *
+     * @param string $encoded
+     * @return array
+     * @access public
+     */
+    function decodeBER($encoded)
+    {
+        if ($encoded instanceof Element) {
+            $encoded = $encoded->element;
+        }
+
+        $this->encoded = $encoded;
+        // encapsulate in an array for BC with the old decodeBER
+        return array($this->_decode_ber($encoded));
+    }
+
+    /**
+     * Parse BER-encoding (Helper function)
+     *
+     * Sometimes we want to get the BER encoding of a particular tag.  $start lets us do that without having to reencode.
+     * $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and
+     * self::TYPE_OCTET_STRING. In those cases, the indefinite length is used.
+     *
+     * @param string $encoded
+     * @param int $start
+     * @param int $encoded_pos
+     * @return array
+     * @access private
+     */
+    function _decode_ber($encoded, $start = 0, $encoded_pos = 0)
+    {
+        $current = array('start' => $start);
+
+        if (!isset($encoded[$encoded_pos])) {
+            return false;
+        }
+        $type = ord($encoded[$encoded_pos++]);
+        $startOffset = 1;
+
+        $constructed = ($type >> 5) & 1;
+
+        $tag = $type & 0x1F;
+        if ($tag == 0x1F) {
+            $tag = 0;
+            // process septets (since the eighth bit is ignored, it's not an octet)
+            do {
+                if (!isset($encoded[$encoded_pos])) {
+                    return false;
+                }
+                $temp = ord($encoded[$encoded_pos++]);
+                $startOffset++;
+                $loop = $temp >> 7;
+                $tag <<= 7;
+                $temp &= 0x7F;
+                // "bits 7 to 1 of the first subsequent octet shall not all be zero"
+                if ($startOffset == 2 && $temp == 0) {
+                    return false;
+                }
+                $tag |= $temp;
+            } while ($loop);
+        }
+
+        $start+= $startOffset;
+
+        // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
+        if (!isset($encoded[$encoded_pos])) {
+            return false;
+        }
+        $length = ord($encoded[$encoded_pos++]);
+        $start++;
+        if ($length == 0x80) { // indefinite length
+            // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
+            //  immediately available." -- paragraph 8.1.3.2.c
+            $length = strlen($encoded) - $encoded_pos;
+        } elseif ($length & 0x80) { // definite length, long form
+            // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
+            // support it up to four.
+            $length&= 0x7F;
+            $temp = substr($encoded, $encoded_pos, $length);
+            $encoded_pos += $length;
+            // tags of indefinte length don't really have a header length; this length includes the tag
+            $current+= array('headerlength' => $length + 2);
+            $start+= $length;
+            extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)));
+        } else {
+            $current+= array('headerlength' => 2);
+        }
+
+        if ($length > (strlen($encoded) - $encoded_pos)) {
+            return false;
+        }
+
+        $content = substr($encoded, $encoded_pos, $length);
+        $content_pos = 0;
+
+        // at this point $length can be overwritten. it's only accurate for definite length things as is
+
+        /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1
+           built-in types. It defines an application-independent data type that must be distinguishable from all other
+           data types. The other three classes are user defined. The APPLICATION class distinguishes data types that
+           have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within
+           a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the
+           alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this
+           data type; the term CONTEXT-SPECIFIC does not appear.
+
+             -- http://www.obj-sys.com/asn1tutorial/node12.html */
+        $class = ($type >> 6) & 3;
+        switch ($class) {
+            case self::CLASS_APPLICATION:
+            case self::CLASS_PRIVATE:
+            case self::CLASS_CONTEXT_SPECIFIC:
+                if (!$constructed) {
+                    return array(
+                        'type'     => $class,
+                        'constant' => $tag,
+                        'content'  => $content,
+                        'length'   => $length + $start - $current['start']
+                    );
+                }
+
+                $newcontent = array();
+                $remainingLength = $length;
+                while ($remainingLength > 0) {
+                    $temp = $this->_decode_ber($content, $start, $content_pos);
+                    if ($temp === false) {
+                        break;
+                    }
+                    $length = $temp['length'];
+                    // end-of-content octets - see paragraph 8.1.5
+                    if (substr($content, $content_pos + $length, 2) == "\0\0") {
+                        $length+= 2;
+                        $start+= $length;
+                        $newcontent[] = $temp;
+                        break;
+                    }
+                    $start+= $length;
+                    $remainingLength-= $length;
+                    $newcontent[] = $temp;
+                    $content_pos += $length;
+                }
+
+                return array(
+                    'type'     => $class,
+                    'constant' => $tag,
+                    // the array encapsulation is for BC with the old format
+                    'content'  => $newcontent,
+                    // the only time when $content['headerlength'] isn't defined is when the length is indefinite.
+                    // the absence of $content['headerlength'] is how we know if something is indefinite or not.
+                    // technically, it could be defined to be 2 and then another indicator could be used but whatever.
+                    'length'   => $start - $current['start']
+                ) + $current;
+        }
+
+        $current+= array('type' => $tag);
+
+        // decode UNIVERSAL tags
+        switch ($tag) {
+            case self::TYPE_BOOLEAN:
+                // "The contents octets shall consist of a single octet." -- paragraph 8.2.1
+                if ($constructed || strlen($content) != 1) {
+                    return false;
+                }
+                $current['content'] = (bool) ord($content[$content_pos]);
+                break;
+            case self::TYPE_INTEGER:
+            case self::TYPE_ENUMERATED:
+                if ($constructed) {
+                    return false;
+                }
+                $current['content'] = new BigInteger(substr($content, $content_pos), -256);
+                break;
+            case self::TYPE_REAL: // not currently supported
+                return false;
+            case self::TYPE_BIT_STRING:
+                // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit,
+                // the number of unused bits in the final subsequent octet. The number shall be in the range zero to
+                // seven.
+                if (!$constructed) {
+                    $current['content'] = substr($content, $content_pos);
+                } else {
+                    $temp = $this->_decode_ber($content, $start, $content_pos);
+                    if ($temp === false) {
+                        return false;
+                    }
+                    $length-= (strlen($content) - $content_pos);
+                    $last = count($temp) - 1;
+                    for ($i = 0; $i < $last; $i++) {
+                        // all subtags should be bit strings
+                        if ($temp[$i]['type'] != self::TYPE_BIT_STRING) {
+                            return false;
+                        }
+                        $current['content'].= substr($temp[$i]['content'], 1);
+                    }
+                    // all subtags should be bit strings
+                    if ($temp[$last]['type'] != self::TYPE_BIT_STRING) {
+                        return false;
+                    }
+                    $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1);
+                }
+                break;
+            case self::TYPE_OCTET_STRING:
+                if (!$constructed) {
+                    $current['content'] = substr($content, $content_pos);
+                } else {
+                    $current['content'] = '';
+                    $length = 0;
+                    while (substr($content, $content_pos, 2) != "\0\0") {
+                        $temp = $this->_decode_ber($content, $length + $start, $content_pos);
+                        if ($temp === false) {
+                            return false;
+                        }
+                        $content_pos += $temp['length'];
+                        // all subtags should be octet strings
+                        if ($temp['type'] != self::TYPE_OCTET_STRING) {
+                            return false;
+                        }
+                        $current['content'].= $temp['content'];
+                        $length+= $temp['length'];
+                    }
+                    if (substr($content, $content_pos, 2) == "\0\0") {
+                        $length+= 2; // +2 for the EOC
+                    }
+                }
+                break;
+            case self::TYPE_NULL:
+                // "The contents octets shall not contain any octets." -- paragraph 8.8.2
+                if ($constructed || strlen($content)) {
+                    return false;
+                }
+                break;
+            case self::TYPE_SEQUENCE:
+            case self::TYPE_SET:
+                if (!$constructed) {
+                    return false;
+                }
+                $offset = 0;
+                $current['content'] = array();
+                $content_len = strlen($content);
+                while ($content_pos < $content_len) {
+                    // if indefinite length construction was used and we have an end-of-content string next
+                    // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2
+                    if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") {
+                        $length = $offset + 2; // +2 for the EOC
+                        break 2;
+                    }
+                    $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
+                    if ($temp === false) {
+                        return false;
+                    }
+                    $content_pos += $temp['length'];
+                    $current['content'][] = $temp;
+                    $offset+= $temp['length'];
+                }
+                break;
+            case self::TYPE_OBJECT_IDENTIFIER:
+                if ($constructed) {
+                    return false;
+                }
+                $current['content'] = $this->_decodeOID(substr($content, $content_pos));
+                if ($current['content'] === false) {
+                    return false;
+                }
+                break;
+            /* Each character string type shall be encoded as if it had been declared:
+               [UNIVERSAL x] IMPLICIT OCTET STRING
+
+                 -- X.690-0207.pdf#page=23 (paragraph 8.21.3)
+
+               Per that, we're not going to do any validation.  If there are any illegal characters in the string,
+               we don't really care */
+            case self::TYPE_NUMERIC_STRING:
+                // 0,1,2,3,4,5,6,7,8,9, and space
+            case self::TYPE_PRINTABLE_STRING:
+                // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma,
+                // hyphen, full stop, solidus, colon, equal sign, question mark
+            case self::TYPE_TELETEX_STRING:
+                // The Teletex character set in CCITT's T61, space, and delete
+                // see http://en.wikipedia.org/wiki/Teletex#Character_sets
+            case self::TYPE_VIDEOTEX_STRING:
+                // The Videotex character set in CCITT's T.100 and T.101, space, and delete
+            case self::TYPE_VISIBLE_STRING:
+                // Printing character sets of international ASCII, and space
+            case self::TYPE_IA5_STRING:
+                // International Alphabet 5 (International ASCII)
+            case self::TYPE_GRAPHIC_STRING:
+                // All registered G sets, and space
+            case self::TYPE_GENERAL_STRING:
+                // All registered C and G sets, space and delete
+            case self::TYPE_UTF8_STRING:
+                // ????
+            case self::TYPE_BMP_STRING:
+                if ($constructed) {
+                    return false;
+                }
+                $current['content'] = substr($content, $content_pos);
+                break;
+            case self::TYPE_UTC_TIME:
+            case self::TYPE_GENERALIZED_TIME:
+                if ($constructed) {
+                    return false;
+                }
+                $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
+                break;
+            default:
+                return false;
+        }
+
+        $start+= $length;
+
+        // ie. length is the length of the full TLV encoding - it's not just the length of the value
+        return $current + array('length' => $start - $current['start']);
+    }
+
+    /**
+     * ASN.1 Map
+     *
+     * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format.
+     *
+     * "Special" mappings may be applied on a per tag-name basis via $special.
+     *
+     * @param array $decoded
+     * @param array $mapping
+     * @param array $special
+     * @return array
+     * @access public
+     */
+    function asn1map($decoded, $mapping, $special = array())
+    {
+        if (!is_array($decoded)) {
+            return false;
+        }
+
+        if (isset($mapping['explicit']) && is_array($decoded['content'])) {
+            $decoded = $decoded['content'][0];
+        }
+
+        switch (true) {
+            case $mapping['type'] == self::TYPE_ANY:
+                $intype = $decoded['type'];
+                if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || (ord($this->encoded[$decoded['start']]) & 0x20)) {
+                    return new Element(substr($this->encoded, $decoded['start'], $decoded['length']));
+                }
+                $inmap = $this->ANYmap[$intype];
+                if (is_string($inmap)) {
+                    return array($inmap => $this->asn1map($decoded, array('type' => $intype) + $mapping, $special));
+                }
+                break;
+            case $mapping['type'] == self::TYPE_CHOICE:
+                foreach ($mapping['children'] as $key => $option) {
+                    switch (true) {
+                        case isset($option['constant']) && $option['constant'] == $decoded['constant']:
+                        case !isset($option['constant']) && $option['type'] == $decoded['type']:
+                            $value = $this->asn1map($decoded, $option, $special);
+                            break;
+                        case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE:
+                            $v = $this->asn1map($decoded, $option, $special);
+                            if (isset($v)) {
+                                $value = $v;
+                            }
+                    }
+                    if (isset($value)) {
+                        if (isset($special[$key])) {
+                            $value = call_user_func($special[$key], $value);
+                        }
+                        return array($key => $value);
+                    }
+                }
+                return null;
+            case isset($mapping['implicit']):
+            case isset($mapping['explicit']):
+            case $decoded['type'] == $mapping['type']:
+                break;
+            default:
+                // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings,
+                // let it through
+                switch (true) {
+                    case $decoded['type'] < 18: // self::TYPE_NUMERIC_STRING == 18
+                    case $decoded['type'] > 30: // self::TYPE_BMP_STRING == 30
+                    case $mapping['type'] < 18:
+                    case $mapping['type'] > 30:
+                        return null;
+                }
+        }
+
+        if (isset($mapping['implicit'])) {
+            $decoded['type'] = $mapping['type'];
+        }
+
+        switch ($decoded['type']) {
+            case self::TYPE_SEQUENCE:
+                $map = array();
+
+                // ignore the min and max
+                if (isset($mapping['min']) && isset($mapping['max'])) {
+                    $child = $mapping['children'];
+                    foreach ($decoded['content'] as $content) {
+                        if (($map[] = $this->asn1map($content, $child, $special)) === null) {
+                            return null;
+                        }
+                    }
+
+                    return $map;
+                }
+
+                $n = count($decoded['content']);
+                $i = 0;
+
+                foreach ($mapping['children'] as $key => $child) {
+                    $maymatch = $i < $n; // Match only existing input.
+                    if ($maymatch) {
+                        $temp = $decoded['content'][$i];
+
+                        if ($child['type'] != self::TYPE_CHOICE) {
+                            // Get the mapping and input class & constant.
+                            $childClass = $tempClass = self::CLASS_UNIVERSAL;
+                            $constant = null;
+                            if (isset($temp['constant'])) {
+                                $tempClass = $temp['type'];
+                            }
+                            if (isset($child['class'])) {
+                                $childClass = $child['class'];
+                                $constant = $child['cast'];
+                            } elseif (isset($child['constant'])) {
+                                $childClass = self::CLASS_CONTEXT_SPECIFIC;
+                                $constant = $child['constant'];
+                            }
+
+                            if (isset($constant) && isset($temp['constant'])) {
+                                // Can only match if constants and class match.
+                                $maymatch = $constant == $temp['constant'] && $childClass == $tempClass;
+                            } else {
+                                // Can only match if no constant expected and type matches or is generic.
+                                $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false;
+                            }
+                        }
+                    }
+
+                    if ($maymatch) {
+                        // Attempt submapping.
+                        $candidate = $this->asn1map($temp, $child, $special);
+                        $maymatch = $candidate !== null;
+                    }
+
+                    if ($maymatch) {
+                        // Got the match: use it.
+                        if (isset($special[$key])) {
+                            $candidate = call_user_func($special[$key], $candidate);
+                        }
+                        $map[$key] = $candidate;
+                        $i++;
+                    } elseif (isset($child['default'])) {
+                        $map[$key] = $child['default']; // Use default.
+                    } elseif (!isset($child['optional'])) {
+                        return null; // Syntax error.
+                    }
+                }
+
+                // Fail mapping if all input items have not been consumed.
+                return $i < $n ? null: $map;
+
+            // the main diff between sets and sequences is the encapsulation of the foreach in another for loop
+            case self::TYPE_SET:
+                $map = array();
+
+                // ignore the min and max
+                if (isset($mapping['min']) && isset($mapping['max'])) {
+                    $child = $mapping['children'];
+                    foreach ($decoded['content'] as $content) {
+                        if (($map[] = $this->asn1map($content, $child, $special)) === null) {
+                            return null;
+                        }
+                    }
+
+                    return $map;
+                }
+
+                for ($i = 0; $i < count($decoded['content']); $i++) {
+                    $temp = $decoded['content'][$i];
+                    $tempClass = self::CLASS_UNIVERSAL;
+                    if (isset($temp['constant'])) {
+                        $tempClass = $temp['type'];
+                    }
+
+                    foreach ($mapping['children'] as $key => $child) {
+                        if (isset($map[$key])) {
+                            continue;
+                        }
+                        $maymatch = true;
+                        if ($child['type'] != self::TYPE_CHOICE) {
+                            $childClass = self::CLASS_UNIVERSAL;
+                            $constant = null;
+                            if (isset($child['class'])) {
+                                $childClass = $child['class'];
+                                $constant = $child['cast'];
+                            } elseif (isset($child['constant'])) {
+                                $childClass = self::CLASS_CONTEXT_SPECIFIC;
+                                $constant = $child['constant'];
+                            }
+
+                            if (isset($constant) && isset($temp['constant'])) {
+                                // Can only match if constants and class match.
+                                $maymatch = $constant == $temp['constant'] && $childClass == $tempClass;
+                            } else {
+                                // Can only match if no constant expected and type matches or is generic.
+                                $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false;
+                            }
+                        }
+
+                        if ($maymatch) {
+                            // Attempt submapping.
+                            $candidate = $this->asn1map($temp, $child, $special);
+                            $maymatch = $candidate !== null;
+                        }
+
+                        if (!$maymatch) {
+                            break;
+                        }
+
+                        // Got the match: use it.
+                        if (isset($special[$key])) {
+                            $candidate = call_user_func($special[$key], $candidate);
+                        }
+                        $map[$key] = $candidate;
+                        break;
+                    }
+                }
+
+                foreach ($mapping['children'] as $key => $child) {
+                    if (!isset($map[$key])) {
+                        if (isset($child['default'])) {
+                            $map[$key] = $child['default'];
+                        } elseif (!isset($child['optional'])) {
+                            return null;
+                        }
+                    }
+                }
+                return $map;
+            case self::TYPE_OBJECT_IDENTIFIER:
+                return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content'];
+            case self::TYPE_UTC_TIME:
+            case self::TYPE_GENERALIZED_TIME:
+                // for explicitly tagged optional stuff
+                if (is_array($decoded['content'])) {
+                    $decoded['content'] = $decoded['content'][0]['content'];
+                }
+                // for implicitly tagged optional stuff
+                // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist
+                // in the wild that OpenSSL decodes without issue so we'll support them as well
+                if (!is_object($decoded['content'])) {
+                    $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
+                }
+                return $decoded['content'] ? $decoded['content']->format($this->format) : false;
+            case self::TYPE_BIT_STRING:
+                if (isset($mapping['mapping'])) {
+                    $offset = ord($decoded['content'][0]);
+                    $size = (strlen($decoded['content']) - 1) * 8 - $offset;
+                    /*
+                       From X.680-0207.pdf#page=46 (21.7):
+
+                       "When a "NamedBitList" is used in defining a bitstring type ASN.1 encoding rules are free to add (or remove)
+                        arbitrarily any trailing 0 bits to (or from) values that are being encoded or decoded. Application designers should
+                        therefore ensure that different semantics are not associated with such values which differ only in the number of trailing
+                        0 bits."
+                    */
+                    $bits = count($mapping['mapping']) == $size ? array() : array_fill(0, count($mapping['mapping']) - $size, false);
+                    for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) {
+                        $current = ord($decoded['content'][$i]);
+                        for ($j = $offset; $j < 8; $j++) {
+                            $bits[] = (bool) ($current & (1 << $j));
+                        }
+                        $offset = 0;
+                    }
+                    $values = array();
+                    $map = array_reverse($mapping['mapping']);
+                    foreach ($map as $i => $value) {
+                        if ($bits[$i]) {
+                            $values[] = $value;
+                        }
+                    }
+                    return $values;
+                }
+            case self::TYPE_OCTET_STRING:
+                return base64_encode($decoded['content']);
+            case self::TYPE_NULL:
+                return '';
+            case self::TYPE_BOOLEAN:
+                return $decoded['content'];
+            case self::TYPE_NUMERIC_STRING:
+            case self::TYPE_PRINTABLE_STRING:
+            case self::TYPE_TELETEX_STRING:
+            case self::TYPE_VIDEOTEX_STRING:
+            case self::TYPE_IA5_STRING:
+            case self::TYPE_GRAPHIC_STRING:
+            case self::TYPE_VISIBLE_STRING:
+            case self::TYPE_GENERAL_STRING:
+            case self::TYPE_UNIVERSAL_STRING:
+            case self::TYPE_UTF8_STRING:
+            case self::TYPE_BMP_STRING:
+                return $decoded['content'];
+            case self::TYPE_INTEGER:
+            case self::TYPE_ENUMERATED:
+                $temp = $decoded['content'];
+                if (isset($mapping['implicit'])) {
+                    $temp = new BigInteger($decoded['content'], -256);
+                }
+                if (isset($mapping['mapping'])) {
+                    $temp = (int) $temp->toString();
+                    return isset($mapping['mapping'][$temp]) ?
+                        $mapping['mapping'][$temp] :
+                        false;
+                }
+                return $temp;
+        }
+    }
+
+    /**
+     * ASN.1 Encode
+     *
+     * DER-encodes an ASN.1 semantic mapping ($mapping).  Some libraries would probably call this function
+     * an ASN.1 compiler.
+     *
+     * "Special" mappings can be applied via $special.
+     *
+     * @param string $source
+     * @param string $mapping
+     * @param array $special
+     * @return string
+     * @access public
+     */
+    function encodeDER($source, $mapping, $special = array())
+    {
+        $this->location = array();
+        return $this->_encode_der($source, $mapping, null, $special);
+    }
+
+    /**
+     * ASN.1 Encode (Helper function)
+     *
+     * @param string $source
+     * @param string $mapping
+     * @param int $idx
+     * @param array $special
+     * @return string
+     * @access private
+     */
+    function _encode_der($source, $mapping, $idx = null, $special = array())
+    {
+        if ($source instanceof Element) {
+            return $source->element;
+        }
+
+        // do not encode (implicitly optional) fields with value set to default
+        if (isset($mapping['default']) && $source === $mapping['default']) {
+            return '';
+        }
+
+        if (isset($idx)) {
+            if (isset($special[$idx])) {
+                $source = call_user_func($special[$idx], $source);
+            }
+            $this->location[] = $idx;
+        }
+
+        $tag = $mapping['type'];
+
+        switch ($tag) {
+            case self::TYPE_SET:    // Children order is not important, thus process in sequence.
+            case self::TYPE_SEQUENCE:
+                $tag|= 0x20; // set the constructed bit
+
+                // ignore the min and max
+                if (isset($mapping['min']) && isset($mapping['max'])) {
+                    $value = array();
+                    $child = $mapping['children'];
+
+                    foreach ($source as $content) {
+                        $temp = $this->_encode_der($content, $child, null, $special);
+                        if ($temp === false) {
+                            return false;
+                        }
+                        $value[]= $temp;
+                    }
+                    /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared
+                        as octet strings with the shorter components being padded at their trailing end with 0-octets.
+                        NOTE - The padding octets are for comparison purposes only and do not appear in the encodings."
+
+                       -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf  */
+                    if ($mapping['type'] == self::TYPE_SET) {
+                        sort($value);
+                    }
+                    $value = implode('', $value);
+                    break;
+                }
+
+                $value = '';
+                foreach ($mapping['children'] as $key => $child) {
+                    if (!array_key_exists($key, $source)) {
+                        if (!isset($child['optional'])) {
+                            return false;
+                        }
+                        continue;
+                    }
+
+                    $temp = $this->_encode_der($source[$key], $child, $key, $special);
+                    if ($temp === false) {
+                        return false;
+                    }
+
+                    // An empty child encoding means it has been optimized out.
+                    // Else we should have at least one tag byte.
+                    if ($temp === '') {
+                        continue;
+                    }
+
+                    // if isset($child['constant']) is true then isset($child['optional']) should be true as well
+                    if (isset($child['constant'])) {
+                        /*
+                           From X.680-0207.pdf#page=58 (30.6):
+
+                           "The tagging construction specifies explicit tagging if any of the following holds:
+                            ...
+                            c) the "Tag Type" alternative is used and the value of "TagDefault" for the module is IMPLICIT TAGS or
+                            AUTOMATIC TAGS, but the type defined by "Type" is an untagged choice type, an untagged open type, or
+                            an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)."
+                         */
+                        if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
+                            $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
+                            $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp;
+                        } else {
+                            $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
+                            $temp = $subtag . substr($temp, 1);
+                        }
+                    }
+                    $value.= $temp;
+                }
+                break;
+            case self::TYPE_CHOICE:
+                $temp = false;
+
+                foreach ($mapping['children'] as $key => $child) {
+                    if (!isset($source[$key])) {
+                        continue;
+                    }
+
+                    $temp = $this->_encode_der($source[$key], $child, $key, $special);
+                    if ($temp === false) {
+                        return false;
+                    }
+
+                    // An empty child encoding means it has been optimized out.
+                    // Else we should have at least one tag byte.
+                    if ($temp === '') {
+                        continue;
+                    }
+
+                    $tag = ord($temp[0]);
+
+                    // if isset($child['constant']) is true then isset($child['optional']) should be true as well
+                    if (isset($child['constant'])) {
+                        if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
+                            $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
+                            $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp;
+                        } else {
+                            $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
+                            $temp = $subtag . substr($temp, 1);
+                        }
+                    }
+                }
+
+                if (isset($idx)) {
+                    array_pop($this->location);
+                }
+
+                if ($temp && isset($mapping['cast'])) {
+                    $temp[0] = chr(($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']);
+                }
+
+                return $temp;
+            case self::TYPE_INTEGER:
+            case self::TYPE_ENUMERATED:
+                if (!isset($mapping['mapping'])) {
+                    if (is_numeric($source)) {
+                        $source = new BigInteger($source);
+                    }
+                    $value = $source->toBytes(true);
+                } else {
+                    $value = array_search($source, $mapping['mapping']);
+                    if ($value === false) {
+                        return false;
+                    }
+                    $value = new BigInteger($value);
+                    $value = $value->toBytes(true);
+                }
+                if (!strlen($value)) {
+                    $value = chr(0);
+                }
+                break;
+            case self::TYPE_UTC_TIME:
+            case self::TYPE_GENERALIZED_TIME:
+                $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
+                $format.= 'mdHis';
+                // if $source does _not_ include timezone information within it then assume that the timezone is GMT
+                $date = new DateTime($source, new DateTimeZone('GMT'));
+                // if $source _does_ include timezone information within it then convert the time to GMT
+                $date->setTimezone(new DateTimeZone('GMT'));
+                $value = $date->format($format) . 'Z';
+                break;
+            case self::TYPE_BIT_STRING:
+                if (isset($mapping['mapping'])) {
+                    $bits = array_fill(0, count($mapping['mapping']), 0);
+                    $size = 0;
+                    for ($i = 0; $i < count($mapping['mapping']); $i++) {
+                        if (in_array($mapping['mapping'][$i], $source)) {
+                            $bits[$i] = 1;
+                            $size = $i;
+                        }
+                    }
+
+                    if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) {
+                        $size = $mapping['min'] - 1;
+                    }
+
+                    $offset = 8 - (($size + 1) & 7);
+                    $offset = $offset !== 8 ? $offset : 0;
+
+                    $value = chr($offset);
+
+                    for ($i = $size + 1; $i < count($mapping['mapping']); $i++) {
+                        unset($bits[$i]);
+                    }
+
+                    $bits = implode('', array_pad($bits, $size + $offset + 1, 0));
+                    $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' ')));
+                    foreach ($bytes as $byte) {
+                        $value.= chr(bindec($byte));
+                    }
+
+                    break;
+                }
+            case self::TYPE_OCTET_STRING:
+                /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit,
+                   the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven.
+
+                   -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */
+                $value = base64_decode($source);
+                break;
+            case self::TYPE_OBJECT_IDENTIFIER:
+                $value = $this->_encodeOID($source);
+                break;
+            case self::TYPE_ANY:
+                $loc = $this->location;
+                if (isset($idx)) {
+                    array_pop($this->location);
+                }
+
+                switch (true) {
+                    case !isset($source):
+                        return $this->_encode_der(null, array('type' => self::TYPE_NULL) + $mapping, null, $special);
+                    case is_int($source):
+                    case $source instanceof BigInteger:
+                        return $this->_encode_der($source, array('type' => self::TYPE_INTEGER) + $mapping, null, $special);
+                    case is_float($source):
+                        return $this->_encode_der($source, array('type' => self::TYPE_REAL) + $mapping, null, $special);
+                    case is_bool($source):
+                        return $this->_encode_der($source, array('type' => self::TYPE_BOOLEAN) + $mapping, null, $special);
+                    case is_array($source) && count($source) == 1:
+                        $typename = implode('', array_keys($source));
+                        $outtype = array_search($typename, $this->ANYmap, true);
+                        if ($outtype !== false) {
+                            return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, null, $special);
+                        }
+                }
+
+                $filters = $this->filters;
+                foreach ($loc as $part) {
+                    if (!isset($filters[$part])) {
+                        $filters = false;
+                        break;
+                    }
+                    $filters = $filters[$part];
+                }
+                if ($filters === false) {
+                    user_error('No filters defined for ' . implode('/', $loc));
+                    return false;
+                }
+                return $this->_encode_der($source, $filters + $mapping, null, $special);
+            case self::TYPE_NULL:
+                $value = '';
+                break;
+            case self::TYPE_NUMERIC_STRING:
+            case self::TYPE_TELETEX_STRING:
+            case self::TYPE_PRINTABLE_STRING:
+            case self::TYPE_UNIVERSAL_STRING:
+            case self::TYPE_UTF8_STRING:
+            case self::TYPE_BMP_STRING:
+            case self::TYPE_IA5_STRING:
+            case self::TYPE_VISIBLE_STRING:
+            case self::TYPE_VIDEOTEX_STRING:
+            case self::TYPE_GRAPHIC_STRING:
+            case self::TYPE_GENERAL_STRING:
+                $value = $source;
+                break;
+            case self::TYPE_BOOLEAN:
+                $value = $source ? "\xFF" : "\x00";
+                break;
+            default:
+                user_error('Mapping provides no type definition for ' . implode('/', $this->location));
+                return false;
+        }
+
+        if (isset($idx)) {
+            array_pop($this->location);
+        }
+
+        if (isset($mapping['cast'])) {
+            if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) {
+                $value = chr($tag) . $this->_encodeLength(strlen($value)) . $value;
+                $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast'];
+            } else {
+                $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast'];
+            }
+        }
+
+        return chr($tag) . $this->_encodeLength(strlen($value)) . $value;
+    }
+
+    /**
+     * DER-encode the length
+     *
+     * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4.  See
+     * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+     *
+     * @access private
+     * @param int $length
+     * @return string
+     */
+    function _encodeLength($length)
+    {
+        if ($length <= 0x7F) {
+            return chr($length);
+        }
+
+        $temp = ltrim(pack('N', $length), chr(0));
+        return pack('Ca*', 0x80 | strlen($temp), $temp);
+    }
+
+    /**
+     * BER-decode the OID
+     *
+     * Called by _decode_ber()
+     *
+     * @access private
+     * @param string $content
+     * @return string
+     */
+    function _decodeOID($content)
+    {
+        static $eighty;
+        if (!$eighty) {
+            $eighty = new BigInteger(80);
+        }
+
+        $oid = array();
+        $pos = 0;
+        $len = strlen($content);
+
+        if (ord($content[$len - 1]) & 0x80) {
+            return false;
+        }
+
+        $n = new BigInteger();
+        while ($pos < $len) {
+            $temp = ord($content[$pos++]);
+            $n = $n->bitwise_leftShift(7);
+            $n = $n->bitwise_or(new BigInteger($temp & 0x7F));
+            if (~$temp & 0x80) {
+                $oid[] = $n;
+                $n = new BigInteger();
+            }
+        }
+        $part1 = array_shift($oid);
+        $first = floor(ord($content[0]) / 40);
+        /*
+          "This packing of the first two object identifier components recognizes that only three values are allocated from the root
+           node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1."
+
+          -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22
+        */
+        if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78)
+            array_unshift($oid, ord($content[0]) % 40);
+            array_unshift($oid, $first);
+        } else {
+            array_unshift($oid, $part1->subtract($eighty));
+            array_unshift($oid, 2);
+        }
+
+        return implode('.', $oid);
+    }
+
+    /**
+     * DER-encode the OID
+     *
+     * Called by _encode_der()
+     *
+     * @access private
+     * @param string $source
+     * @return string
+     */
+    function _encodeOID($source)
+    {
+        static $mask, $zero, $forty;
+        if (!$mask) {
+            $mask = new BigInteger(0x7F);
+            $zero = new BigInteger();
+            $forty = new BigInteger(40);
+        }
+
+        $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
+        if ($oid === false) {
+            user_error('Invalid OID');
+            return false;
+        }
+        $parts = explode('.', $oid);
+        $part1 = array_shift($parts);
+        $part2 = array_shift($parts);
+
+        $first = new BigInteger($part1);
+        $first = $first->multiply($forty);
+        $first = $first->add(new BigInteger($part2));
+
+        array_unshift($parts, $first->toString());
+
+        $value = '';
+        foreach ($parts as $part) {
+            if (!$part) {
+                $temp = "\0";
+            } else {
+                $temp = '';
+                $part = new BigInteger($part);
+                while (!$part->equals($zero)) {
+                    $submask = $part->bitwise_and($mask);
+                    $submask->setPrecision(8);
+                    $temp = (chr(0x80) | $submask->toBytes()) . $temp;
+                    $part = $part->bitwise_rightShift(7);
+                }
+                $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
+            }
+            $value.= $temp;
+        }
+
+        return $value;
+    }
+
+    /**
+     * BER-decode the time
+     *
+     * Called by _decode_ber() and in the case of implicit tags asn1map().
+     *
+     * @access private
+     * @param string $content
+     * @param int $tag
+     * @return string
+     */
+    function _decodeTime($content, $tag)
+    {
+        /* UTCTime:
+           http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+           http://www.obj-sys.com/asn1tutorial/node15.html
+
+           GeneralizedTime:
+           http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
+           http://www.obj-sys.com/asn1tutorial/node14.html */
+
+        $format = 'YmdHis';
+
+        if ($tag == self::TYPE_UTC_TIME) {
+            // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
+            // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
+            // browsers parse it phpseclib ought to too
+            if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
+                $content = $matches[1] . '00' . $matches[2];
+            }
+            $prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
+            $content = $prefix . $content;
+        } elseif (strpos($content, '.') !== false) {
+            $format.= '.u';
+        }
+
+        if ($content[strlen($content) - 1] == 'Z') {
+            $content = substr($content, 0, -1) . '+0000';
+        }
+
+        if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
+            $format.= 'O';
+        }
+
+        // error supression isn't necessary as of PHP 7.0:
+        // http://php.net/manual/en/migration70.other-changes.php
+        return @DateTime::createFromFormat($format, $content);
+    }
+
+    /**
+     * Set the time format
+     *
+     * Sets the time / date format for asn1map().
+     *
+     * @access public
+     * @param string $format
+     */
+    function setTimeFormat($format)
+    {
+        $this->format = $format;
+    }
+
+    /**
+     * Load OIDs
+     *
+     * Load the relevant OIDs for a particular ASN.1 semantic mapping.
+     *
+     * @access public
+     * @param array $oids
+     */
+    function loadOIDs($oids)
+    {
+        $this->oids = $oids;
+    }
+
+    /**
+     * Load filters
+     *
+     * See \phpseclib\File\X509, etc, for an example.
+     *
+     * @access public
+     * @param array $filters
+     */
+    function loadFilters($filters)
+    {
+        $this->filters = $filters;
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @return string
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+
+    /**
+     * String type conversion
+     *
+     * This is a lazy conversion, dealing only with character size.
+     * No real conversion table is used.
+     *
+     * @param string $in
+     * @param int $from
+     * @param int $to
+     * @return string
+     * @access public
+     */
+    function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING)
+    {
+        if (!isset($this->stringTypeSize[$from]) || !isset($this->stringTypeSize[$to])) {
+            return false;
+        }
+        $insize = $this->stringTypeSize[$from];
+        $outsize = $this->stringTypeSize[$to];
+        $inlength = strlen($in);
+        $out = '';
+
+        for ($i = 0; $i < $inlength;) {
+            if ($inlength - $i < $insize) {
+                return false;
+            }
+
+            // Get an input character as a 32-bit value.
+            $c = ord($in[$i++]);
+            switch (true) {
+                case $insize == 4:
+                    $c = ($c << 8) | ord($in[$i++]);
+                    $c = ($c << 8) | ord($in[$i++]);
+                case $insize == 2:
+                    $c = ($c << 8) | ord($in[$i++]);
+                case $insize == 1:
+                    break;
+                case ($c & 0x80) == 0x00:
+                    break;
+                case ($c & 0x40) == 0x00:
+                    return false;
+                default:
+                    $bit = 6;
+                    do {
+                        if ($bit > 25 || $i >= $inlength || (ord($in[$i]) & 0xC0) != 0x80) {
+                            return false;
+                        }
+                        $c = ($c << 6) | (ord($in[$i++]) & 0x3F);
+                        $bit += 5;
+                        $mask = 1 << $bit;
+                    } while ($c & $bit);
+                    $c &= $mask - 1;
+                    break;
+            }
+
+            // Convert and append the character to output string.
+            $v = '';
+            switch (true) {
+                case $outsize == 4:
+                    $v .= chr($c & 0xFF);
+                    $c >>= 8;
+                    $v .= chr($c & 0xFF);
+                    $c >>= 8;
+                case $outsize == 2:
+                    $v .= chr($c & 0xFF);
+                    $c >>= 8;
+                case $outsize == 1:
+                    $v .= chr($c & 0xFF);
+                    $c >>= 8;
+                    if ($c) {
+                        return false;
+                    }
+                    break;
+                case ($c & 0x80000000) != 0:
+                    return false;
+                case $c >= 0x04000000:
+                    $v .= chr(0x80 | ($c & 0x3F));
+                    $c = ($c >> 6) | 0x04000000;
+                case $c >= 0x00200000:
+                    $v .= chr(0x80 | ($c & 0x3F));
+                    $c = ($c >> 6) | 0x00200000;
+                case $c >= 0x00010000:
+                    $v .= chr(0x80 | ($c & 0x3F));
+                    $c = ($c >> 6) | 0x00010000;
+                case $c >= 0x00000800:
+                    $v .= chr(0x80 | ($c & 0x3F));
+                    $c = ($c >> 6) | 0x00000800;
+                case $c >= 0x00000080:
+                    $v .= chr(0x80 | ($c & 0x3F));
+                    $c = ($c >> 6) | 0x000000C0;
+                default:
+                    $v .= chr($c);
+                    break;
+            }
+            $out .= strrev($v);
+        }
+        return $out;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/msd/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php
new file mode 100644
index 00000000..68246e2b
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Pure-PHP ASN.1 Parser
+ *
+ * PHP version 5
+ *
+ * @category  File
+ * @package   ASN1
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File\ASN1;
+
+/**
+ * ASN.1 Element
+ *
+ * Bypass normal encoding rules in phpseclib\File\ASN1::encodeDER()
+ *
+ * @package ASN1
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class Element
+{
+    /**
+     * Raw element value
+     *
+     * @var string
+     * @access private
+     */
+    var $element;
+
+    /**
+     * Constructor
+     *
+     * @param string $encoded
+     * @return \phpseclib\File\ASN1\Element
+     * @access public
+     */
+    function __construct($encoded)
+    {
+        $this->element = $encoded;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/msd/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
new file mode 100644
index 00000000..73ecd25d
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
@@ -0,0 +1,5102 @@
+<?php
+
+/**
+ * Pure-PHP X.509 Parser
+ *
+ * PHP version 5
+ *
+ * Encode and decode X.509 certificates.
+ *
+ * The extensions are from {@link http://tools.ietf.org/html/rfc5280 RFC5280} and
+ * {@link http://web.archive.org/web/19961027104704/http://www3.netscape.com/eng/security/cert-exts.html Netscape Certificate Extensions}.
+ *
+ * Note that loading an X.509 certificate and resaving it may invalidate the signature.  The reason being that the signature is based on a
+ * portion of the certificate that contains optional parameters with default values.  ie. if the parameter isn't there the default value is
+ * used.  Problem is, if the parameter is there and it just so happens to have the default value there are two ways that that parameter can
+ * be encoded.  It can be encoded explicitly or left out all together.  This would effect the signature value and thus may invalidate the
+ * the certificate all together unless the certificate is re-signed.
+ *
+ * @category  File
+ * @package   X509
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File;
+
+use phpseclib\Crypt\Hash;
+use phpseclib\Crypt\Random;
+use phpseclib\Crypt\RSA;
+use phpseclib\File\ASN1\Element;
+use phpseclib\Math\BigInteger;
+use DateTime;
+use DateTimeZone;
+
+/**
+ * Pure-PHP X.509 Parser
+ *
+ * @package X509
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class X509
+{
+    /**
+     * Flag to only accept signatures signed by certificate authorities
+     *
+     * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs
+     *
+     * @access public
+     */
+    const VALIDATE_SIGNATURE_BY_CA = 1;
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\File\X509::getDN()
+    */
+    /**
+     * Return internal array representation
+     */
+    const DN_ARRAY = 0;
+    /**
+     * Return string
+     */
+    const DN_STRING = 1;
+    /**
+     * Return ASN.1 name string
+     */
+    const DN_ASN1 = 2;
+    /**
+     * Return OpenSSL compatible array
+     */
+    const DN_OPENSSL = 3;
+    /**
+     * Return canonical ASN.1 RDNs string
+     */
+    const DN_CANON = 4;
+    /**
+     * Return name hash for file indexing
+     */
+    const DN_HASH = 5;
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\File\X509::saveX509()
+     * @see \phpseclib\File\X509::saveCSR()
+     * @see \phpseclib\File\X509::saveCRL()
+    */
+    /**
+     * Save as PEM
+     *
+     * ie. a base64-encoded PEM with a header and a footer
+     */
+    const FORMAT_PEM = 0;
+    /**
+     * Save as DER
+     */
+    const FORMAT_DER = 1;
+    /**
+     * Save as a SPKAC
+     *
+     * Only works on CSRs. Not currently supported.
+     */
+    const FORMAT_SPKAC = 2;
+    /**
+     * Auto-detect the format
+     *
+     * Used only by the load*() functions
+     */
+    const FORMAT_AUTO_DETECT = 3;
+    /**#@-*/
+
+    /**
+     * Attribute value disposition.
+     * If disposition is >= 0, this is the index of the target value.
+     */
+    const ATTR_ALL = -1; // All attribute values (array).
+    const ATTR_APPEND = -2; // Add a value.
+    const ATTR_REPLACE = -3; // Clear first, then add a value.
+
+    /**
+     * ASN.1 syntax for X.509 certificates
+     *
+     * @var array
+     * @access private
+     */
+    var $Certificate;
+
+    /**#@+
+     * ASN.1 syntax for various extensions
+     *
+     * @access private
+     */
+    var $DirectoryString;
+    var $PKCS9String;
+    var $AttributeValue;
+    var $Extensions;
+    var $KeyUsage;
+    var $ExtKeyUsageSyntax;
+    var $BasicConstraints;
+    var $KeyIdentifier;
+    var $CRLDistributionPoints;
+    var $AuthorityKeyIdentifier;
+    var $CertificatePolicies;
+    var $AuthorityInfoAccessSyntax;
+    var $SubjectInfoAccessSyntax;
+    var $SubjectAltName;
+    var $SubjectDirectoryAttributes;
+    var $PrivateKeyUsagePeriod;
+    var $IssuerAltName;
+    var $PolicyMappings;
+    var $NameConstraints;
+
+    var $CPSuri;
+    var $UserNotice;
+
+    var $netscape_cert_type;
+    var $netscape_comment;
+    var $netscape_ca_policy_url;
+
+    var $Name;
+    var $RelativeDistinguishedName;
+    var $CRLNumber;
+    var $CRLReason;
+    var $IssuingDistributionPoint;
+    var $InvalidityDate;
+    var $CertificateIssuer;
+    var $HoldInstructionCode;
+    var $SignedPublicKeyAndChallenge;
+    /**#@-*/
+
+    /**#@+
+     * ASN.1 syntax for various DN attributes
+     *
+     * @access private
+     */
+    var $PostalAddress;
+    /**#@-*/
+
+    /**
+     * ASN.1 syntax for Certificate Signing Requests (RFC2986)
+     *
+     * @var array
+     * @access private
+     */
+    var $CertificationRequest;
+
+    /**
+     * ASN.1 syntax for Certificate Revocation Lists (RFC5280)
+     *
+     * @var array
+     * @access private
+     */
+    var $CertificateList;
+
+    /**
+     * Distinguished Name
+     *
+     * @var array
+     * @access private
+     */
+    var $dn;
+
+    /**
+     * Public key
+     *
+     * @var string
+     * @access private
+     */
+    var $publicKey;
+
+    /**
+     * Private key
+     *
+     * @var string
+     * @access private
+     */
+    var $privateKey;
+
+    /**
+     * Object identifiers for X.509 certificates
+     *
+     * @var array
+     * @access private
+     * @link http://en.wikipedia.org/wiki/Object_identifier
+     */
+    var $oids;
+
+    /**
+     * The certificate authorities
+     *
+     * @var array
+     * @access private
+     */
+    var $CAs;
+
+    /**
+     * The currently loaded certificate
+     *
+     * @var array
+     * @access private
+     */
+    var $currentCert;
+
+    /**
+     * The signature subject
+     *
+     * There's no guarantee \phpseclib\File\X509 is going to re-encode an X.509 cert in the same way it was originally
+     * encoded so we take save the portion of the original cert that the signature would have made for.
+     *
+     * @var string
+     * @access private
+     */
+    var $signatureSubject;
+
+    /**
+     * Certificate Start Date
+     *
+     * @var string
+     * @access private
+     */
+    var $startDate;
+
+    /**
+     * Certificate End Date
+     *
+     * @var string
+     * @access private
+     */
+    var $endDate;
+
+    /**
+     * Serial Number
+     *
+     * @var string
+     * @access private
+     */
+    var $serialNumber;
+
+    /**
+     * Key Identifier
+     *
+     * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and
+     * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}.
+     *
+     * @var string
+     * @access private
+     */
+    var $currentKeyIdentifier;
+
+    /**
+     * CA Flag
+     *
+     * @var bool
+     * @access private
+     */
+    var $caFlag = false;
+
+    /**
+     * SPKAC Challenge
+     *
+     * @var string
+     * @access private
+     */
+    var $challenge;
+
+    /**
+     * Recursion Limit
+     *
+     * @var int
+     * @access private
+     */
+    static $recur_limit = 5;
+
+    /**
+     * URL fetch flag
+     *
+     * @var bool
+     * @access private
+     */
+    static $disable_url_fetch = false;
+
+    /**
+     * Default Constructor.
+     *
+     * @return \phpseclib\File\X509
+     * @access public
+     */
+    function __construct()
+    {
+        // Explicitly Tagged Module, 1988 Syntax
+        // http://tools.ietf.org/html/rfc5280#appendix-A.1
+
+        $this->DirectoryString = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'teletexString'   => array('type' => ASN1::TYPE_TELETEX_STRING),
+                'printableString' => array('type' => ASN1::TYPE_PRINTABLE_STRING),
+                'universalString' => array('type' => ASN1::TYPE_UNIVERSAL_STRING),
+                'utf8String'      => array('type' => ASN1::TYPE_UTF8_STRING),
+                'bmpString'       => array('type' => ASN1::TYPE_BMP_STRING)
+            )
+        );
+
+        $this->PKCS9String = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'ia5String'       => array('type' => ASN1::TYPE_IA5_STRING),
+                'directoryString' => $this->DirectoryString
+            )
+        );
+
+        $this->AttributeValue = array('type' => ASN1::TYPE_ANY);
+
+        $AttributeType = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+        $AttributeTypeAndValue = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'type' => $AttributeType,
+                'value'=> $this->AttributeValue
+            )
+        );
+
+        /*
+        In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare,
+        but they can be useful at times when either there is no unique attribute in the entry or you
+        want to ensure that the entry's DN contains some useful identifying information.
+
+        - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName
+        */
+        $this->RelativeDistinguishedName = array(
+            'type'     => ASN1::TYPE_SET,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $AttributeTypeAndValue
+        );
+
+        // http://tools.ietf.org/html/rfc5280#section-4.1.2.4
+        $RDNSequence = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            // RDNSequence does not define a min or a max, which means it doesn't have one
+            'min'      => 0,
+            'max'      => -1,
+            'children' => $this->RelativeDistinguishedName
+        );
+
+        $this->Name = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'rdnSequence' => $RDNSequence
+            )
+        );
+
+        // http://tools.ietf.org/html/rfc5280#section-4.1.1.2
+        $AlgorithmIdentifier = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'algorithm'  => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+                'parameters' => array(
+                                    'type'     => ASN1::TYPE_ANY,
+                                    'optional' => true
+                                )
+            )
+        );
+
+        /*
+           A certificate using system MUST reject the certificate if it encounters
+           a critical extension it does not recognize; however, a non-critical
+           extension may be ignored if it is not recognized.
+
+           http://tools.ietf.org/html/rfc5280#section-4.2
+        */
+        $Extension = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'extnId'   => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+                'critical' => array(
+                                  'type'     => ASN1::TYPE_BOOLEAN,
+                                  'optional' => true,
+                                  'default'  => false
+                              ),
+                'extnValue' => array('type' => ASN1::TYPE_OCTET_STRING)
+            )
+        );
+
+        $this->Extensions = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            // technically, it's MAX, but we'll assume anything < 0 is MAX
+            'max'      => -1,
+            // if 'children' isn't an array then 'min' and 'max' must be defined
+            'children' => $Extension
+        );
+
+        $SubjectPublicKeyInfo = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'algorithm'        => $AlgorithmIdentifier,
+                'subjectPublicKey' => array('type' => ASN1::TYPE_BIT_STRING)
+            )
+        );
+
+        $UniqueIdentifier = array('type' => ASN1::TYPE_BIT_STRING);
+
+        $Time = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'utcTime'     => array('type' => ASN1::TYPE_UTC_TIME),
+                'generalTime' => array('type' => ASN1::TYPE_GENERALIZED_TIME)
+            )
+        );
+
+        // http://tools.ietf.org/html/rfc5280#section-4.1.2.5
+        $Validity = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'notBefore' => $Time,
+                'notAfter'  => $Time
+            )
+        );
+
+        $CertificateSerialNumber = array('type' => ASN1::TYPE_INTEGER);
+
+        $Version = array(
+            'type'    => ASN1::TYPE_INTEGER,
+            'mapping' => array('v1', 'v2', 'v3')
+        );
+
+        // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm'])
+        $TBSCertificate = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                // technically, default implies optional, but we'll define it as being optional, none-the-less, just to
+                // reenforce that fact
+                'version'             => array(
+                                             'constant' => 0,
+                                             'optional' => true,
+                                             'explicit' => true,
+                                             'default'  => 'v1'
+                                         ) + $Version,
+                'serialNumber'         => $CertificateSerialNumber,
+                'signature'            => $AlgorithmIdentifier,
+                'issuer'               => $this->Name,
+                'validity'             => $Validity,
+                'subject'              => $this->Name,
+                'subjectPublicKeyInfo' => $SubjectPublicKeyInfo,
+                // implicit means that the T in the TLV structure is to be rewritten, regardless of the type
+                'issuerUniqueID'       => array(
+                                               'constant' => 1,
+                                               'optional' => true,
+                                               'implicit' => true
+                                           ) + $UniqueIdentifier,
+                'subjectUniqueID'       => array(
+                                               'constant' => 2,
+                                               'optional' => true,
+                                               'implicit' => true
+                                           ) + $UniqueIdentifier,
+                // <http://tools.ietf.org/html/rfc2459#page-74> doesn't use the EXPLICIT keyword but if
+                // it's not IMPLICIT, it's EXPLICIT
+                'extensions'            => array(
+                                               'constant' => 3,
+                                               'optional' => true,
+                                               'explicit' => true
+                                           ) + $this->Extensions
+            )
+        );
+
+        $this->Certificate = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                 'tbsCertificate'     => $TBSCertificate,
+                 'signatureAlgorithm' => $AlgorithmIdentifier,
+                 'signature'          => array('type' => ASN1::TYPE_BIT_STRING)
+            )
+        );
+
+        $this->KeyUsage = array(
+            'type'    => ASN1::TYPE_BIT_STRING,
+            'mapping' => array(
+                'digitalSignature',
+                'nonRepudiation',
+                'keyEncipherment',
+                'dataEncipherment',
+                'keyAgreement',
+                'keyCertSign',
+                'cRLSign',
+                'encipherOnly',
+                'decipherOnly'
+            )
+        );
+
+        $this->BasicConstraints = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'cA'                => array(
+                                                 'type'     => ASN1::TYPE_BOOLEAN,
+                                                 'optional' => true,
+                                                 'default'  => false
+                                       ),
+                'pathLenConstraint' => array(
+                                                 'type' => ASN1::TYPE_INTEGER,
+                                                 'optional' => true
+                                       )
+            )
+        );
+
+        $this->KeyIdentifier = array('type' => ASN1::TYPE_OCTET_STRING);
+
+        $OrganizationalUnitNames = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => 4, // ub-organizational-units
+            'children' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+        );
+
+        $PersonalName = array(
+            'type'     => ASN1::TYPE_SET,
+            'children' => array(
+                'surname'              => array(
+                                           'type' => ASN1::TYPE_PRINTABLE_STRING,
+                                           'constant' => 0,
+                                           'optional' => true,
+                                           'implicit' => true
+                                         ),
+                'given-name'           => array(
+                                           'type' => ASN1::TYPE_PRINTABLE_STRING,
+                                           'constant' => 1,
+                                           'optional' => true,
+                                           'implicit' => true
+                                         ),
+                'initials'             => array(
+                                           'type' => ASN1::TYPE_PRINTABLE_STRING,
+                                           'constant' => 2,
+                                           'optional' => true,
+                                           'implicit' => true
+                                         ),
+                'generation-qualifier' => array(
+                                           'type' => ASN1::TYPE_PRINTABLE_STRING,
+                                           'constant' => 3,
+                                           'optional' => true,
+                                           'implicit' => true
+                                         )
+            )
+        );
+
+        $NumericUserIdentifier = array('type' => ASN1::TYPE_NUMERIC_STRING);
+
+        $OrganizationName = array('type' => ASN1::TYPE_PRINTABLE_STRING);
+
+        $PrivateDomainName = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'numeric'   => array('type' => ASN1::TYPE_NUMERIC_STRING),
+                'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+            )
+        );
+
+        $TerminalIdentifier = array('type' => ASN1::TYPE_PRINTABLE_STRING);
+
+        $NetworkAddress = array('type' => ASN1::TYPE_NUMERIC_STRING);
+
+        $AdministrationDomainName = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or
+            // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC
+            'class'    => ASN1::CLASS_APPLICATION,
+            'cast'     => 2,
+            'children' => array(
+                'numeric'   => array('type' => ASN1::TYPE_NUMERIC_STRING),
+                'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+            )
+        );
+
+        $CountryName = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or
+            // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC
+            'class'    => ASN1::CLASS_APPLICATION,
+            'cast'     => 1,
+            'children' => array(
+                'x121-dcc-code'        => array('type' => ASN1::TYPE_NUMERIC_STRING),
+                'iso-3166-alpha2-code' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+            )
+        );
+
+        $AnotherName = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                 'type-id' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+                 'value'   => array(
+                                  'type' => ASN1::TYPE_ANY,
+                                  'constant' => 0,
+                                  'optional' => true,
+                                  'explicit' => true
+                              )
+            )
+        );
+
+        $ExtensionAttribute = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                 'extension-attribute-type'  => array(
+                                                    'type' => ASN1::TYPE_PRINTABLE_STRING,
+                                                    'constant' => 0,
+                                                    'optional' => true,
+                                                    'implicit' => true
+                                                ),
+                 'extension-attribute-value' => array(
+                                                    'type' => ASN1::TYPE_ANY,
+                                                    'constant' => 1,
+                                                    'optional' => true,
+                                                    'explicit' => true
+                                                )
+            )
+        );
+
+        $ExtensionAttributes = array(
+            'type'     => ASN1::TYPE_SET,
+            'min'      => 1,
+            'max'      => 256, // ub-extension-attributes
+            'children' => $ExtensionAttribute
+        );
+
+        $BuiltInDomainDefinedAttribute = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                 'type'  => array('type' => ASN1::TYPE_PRINTABLE_STRING),
+                 'value' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+            )
+        );
+
+        $BuiltInDomainDefinedAttributes = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => 4, // ub-domain-defined-attributes
+            'children' => $BuiltInDomainDefinedAttribute
+        );
+
+        $BuiltInStandardAttributes =  array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'country-name'               => array('optional' => true) + $CountryName,
+                'administration-domain-name' => array('optional' => true) + $AdministrationDomainName,
+                'network-address'            => array(
+                                                 'constant' => 0,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $NetworkAddress,
+                'terminal-identifier'        => array(
+                                                 'constant' => 1,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $TerminalIdentifier,
+                'private-domain-name'        => array(
+                                                 'constant' => 2,
+                                                 'optional' => true,
+                                                 'explicit' => true
+                                               ) + $PrivateDomainName,
+                'organization-name'          => array(
+                                                 'constant' => 3,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $OrganizationName,
+                'numeric-user-identifier'    => array(
+                                                 'constant' => 4,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $NumericUserIdentifier,
+                'personal-name'              => array(
+                                                 'constant' => 5,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $PersonalName,
+                'organizational-unit-names'  => array(
+                                                 'constant' => 6,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $OrganizationalUnitNames
+            )
+        );
+
+        $ORAddress = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                 'built-in-standard-attributes'       => $BuiltInStandardAttributes,
+                 'built-in-domain-defined-attributes' => array('optional' => true) + $BuiltInDomainDefinedAttributes,
+                 'extension-attributes'               => array('optional' => true) + $ExtensionAttributes
+            )
+        );
+
+        $EDIPartyName = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                 'nameAssigner' => array(
+                                    'constant' => 0,
+                                    'optional' => true,
+                                    'implicit' => true
+                                ) + $this->DirectoryString,
+                 // partyName is technically required but \phpseclib\File\ASN1 doesn't currently support non-optional constants and
+                 // setting it to optional gets the job done in any event.
+                 'partyName'    => array(
+                                    'constant' => 1,
+                                    'optional' => true,
+                                    'implicit' => true
+                                ) + $this->DirectoryString
+            )
+        );
+
+        $GeneralName = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'otherName'                 => array(
+                                                 'constant' => 0,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $AnotherName,
+                'rfc822Name'                => array(
+                                                 'type' => ASN1::TYPE_IA5_STRING,
+                                                 'constant' => 1,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ),
+                'dNSName'                   => array(
+                                                 'type' => ASN1::TYPE_IA5_STRING,
+                                                 'constant' => 2,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ),
+                'x400Address'               => array(
+                                                 'constant' => 3,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $ORAddress,
+                'directoryName'             => array(
+                                                 'constant' => 4,
+                                                 'optional' => true,
+                                                 'explicit' => true
+                                               ) + $this->Name,
+                'ediPartyName'              => array(
+                                                 'constant' => 5,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $EDIPartyName,
+                'uniformResourceIdentifier' => array(
+                                                 'type' => ASN1::TYPE_IA5_STRING,
+                                                 'constant' => 6,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ),
+                'iPAddress'                 => array(
+                                                 'type' => ASN1::TYPE_OCTET_STRING,
+                                                 'constant' => 7,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ),
+                'registeredID'              => array(
+                                                 'type' => ASN1::TYPE_OBJECT_IDENTIFIER,
+                                                 'constant' => 8,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               )
+            )
+        );
+
+        $GeneralNames = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $GeneralName
+        );
+
+        $this->IssuerAltName = $GeneralNames;
+
+        $ReasonFlags = array(
+            'type'    => ASN1::TYPE_BIT_STRING,
+            'mapping' => array(
+                'unused',
+                'keyCompromise',
+                'cACompromise',
+                'affiliationChanged',
+                'superseded',
+                'cessationOfOperation',
+                'certificateHold',
+                'privilegeWithdrawn',
+                'aACompromise'
+            )
+        );
+
+        $DistributionPointName = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'fullName'                => array(
+                                                 'constant' => 0,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                       ) + $GeneralNames,
+                'nameRelativeToCRLIssuer' => array(
+                                                 'constant' => 1,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                       ) + $this->RelativeDistinguishedName
+            )
+        );
+
+        $DistributionPoint = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'distributionPoint' => array(
+                                                 'constant' => 0,
+                                                 'optional' => true,
+                                                 'explicit' => true
+                                       ) + $DistributionPointName,
+                'reasons'           => array(
+                                                 'constant' => 1,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                       ) + $ReasonFlags,
+                'cRLIssuer'         => array(
+                                                 'constant' => 2,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                       ) + $GeneralNames
+            )
+        );
+
+        $this->CRLDistributionPoints = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $DistributionPoint
+        );
+
+        $this->AuthorityKeyIdentifier = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'keyIdentifier'             => array(
+                                                 'constant' => 0,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $this->KeyIdentifier,
+                'authorityCertIssuer'       => array(
+                                                 'constant' => 1,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $GeneralNames,
+                'authorityCertSerialNumber' => array(
+                                                 'constant' => 2,
+                                                 'optional' => true,
+                                                 'implicit' => true
+                                               ) + $CertificateSerialNumber
+            )
+        );
+
+        $PolicyQualifierId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+        $PolicyQualifierInfo = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'policyQualifierId' => $PolicyQualifierId,
+                'qualifier'         => array('type' => ASN1::TYPE_ANY)
+            )
+        );
+
+        $CertPolicyId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+        $PolicyInformation = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'policyIdentifier' => $CertPolicyId,
+                'policyQualifiers' => array(
+                                          'type'     => ASN1::TYPE_SEQUENCE,
+                                          'min'      => 0,
+                                          'max'      => -1,
+                                          'optional' => true,
+                                          'children' => $PolicyQualifierInfo
+                                      )
+            )
+        );
+
+        $this->CertificatePolicies = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $PolicyInformation
+        );
+
+        $this->PolicyMappings = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => array(
+                              'type'     => ASN1::TYPE_SEQUENCE,
+                              'children' => array(
+                                  'issuerDomainPolicy' => $CertPolicyId,
+                                  'subjectDomainPolicy' => $CertPolicyId
+                              )
+                       )
+        );
+
+        $KeyPurposeId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+        $this->ExtKeyUsageSyntax = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $KeyPurposeId
+        );
+
+        $AccessDescription = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'accessMethod'   => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+                'accessLocation' => $GeneralName
+            )
+        );
+
+        $this->AuthorityInfoAccessSyntax = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $AccessDescription
+        );
+
+        $this->SubjectInfoAccessSyntax = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $AccessDescription
+        );
+
+        $this->SubjectAltName = $GeneralNames;
+
+        $this->PrivateKeyUsagePeriod = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'notBefore' => array(
+                                                 'constant' => 0,
+                                                 'optional' => true,
+                                                 'implicit' => true,
+                                                 'type' => ASN1::TYPE_GENERALIZED_TIME),
+                'notAfter'  => array(
+                                                 'constant' => 1,
+                                                 'optional' => true,
+                                                 'implicit' => true,
+                                                 'type' => ASN1::TYPE_GENERALIZED_TIME)
+            )
+        );
+
+        $BaseDistance = array('type' => ASN1::TYPE_INTEGER);
+
+        $GeneralSubtree = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'base'    => $GeneralName,
+                'minimum' => array(
+                                 'constant' => 0,
+                                 'optional' => true,
+                                 'implicit' => true,
+                                 'default' => new BigInteger(0)
+                             ) + $BaseDistance,
+                'maximum' => array(
+                                 'constant' => 1,
+                                 'optional' => true,
+                                 'implicit' => true,
+                             ) + $BaseDistance
+            )
+        );
+
+        $GeneralSubtrees = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $GeneralSubtree
+        );
+
+        $this->NameConstraints = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'permittedSubtrees' => array(
+                                           'constant' => 0,
+                                           'optional' => true,
+                                           'implicit' => true
+                                       ) + $GeneralSubtrees,
+                'excludedSubtrees'  => array(
+                                           'constant' => 1,
+                                           'optional' => true,
+                                           'implicit' => true
+                                       ) + $GeneralSubtrees
+            )
+        );
+
+        $this->CPSuri = array('type' => ASN1::TYPE_IA5_STRING);
+
+        $DisplayText = array(
+            'type'     => ASN1::TYPE_CHOICE,
+            'children' => array(
+                'ia5String'     => array('type' => ASN1::TYPE_IA5_STRING),
+                'visibleString' => array('type' => ASN1::TYPE_VISIBLE_STRING),
+                'bmpString'     => array('type' => ASN1::TYPE_BMP_STRING),
+                'utf8String'    => array('type' => ASN1::TYPE_UTF8_STRING)
+            )
+        );
+
+        $NoticeReference = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'organization'  => $DisplayText,
+                'noticeNumbers' => array(
+                                       'type'     => ASN1::TYPE_SEQUENCE,
+                                       'min'      => 1,
+                                       'max'      => 200,
+                                       'children' => array('type' => ASN1::TYPE_INTEGER)
+                                   )
+            )
+        );
+
+        $this->UserNotice = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'noticeRef' => array(
+                                           'optional' => true,
+                                           'implicit' => true
+                                       ) + $NoticeReference,
+                'explicitText'  => array(
+                                           'optional' => true,
+                                           'implicit' => true
+                                       ) + $DisplayText
+            )
+        );
+
+        // mapping is from <http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html>
+        $this->netscape_cert_type = array(
+            'type'    => ASN1::TYPE_BIT_STRING,
+            'mapping' => array(
+                'SSLClient',
+                'SSLServer',
+                'Email',
+                'ObjectSigning',
+                'Reserved',
+                'SSLCA',
+                'EmailCA',
+                'ObjectSigningCA'
+            )
+        );
+
+        $this->netscape_comment = array('type' => ASN1::TYPE_IA5_STRING);
+        $this->netscape_ca_policy_url = array('type' => ASN1::TYPE_IA5_STRING);
+
+        // attribute is used in RFC2986 but we're using the RFC5280 definition
+
+        $Attribute = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'type' => $AttributeType,
+                'value'=> array(
+                              'type'     => ASN1::TYPE_SET,
+                              'min'      => 1,
+                              'max'      => -1,
+                              'children' => $this->AttributeValue
+                          )
+            )
+        );
+
+        $this->SubjectDirectoryAttributes = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $Attribute
+        );
+
+        // adapted from <http://tools.ietf.org/html/rfc2986>
+
+        $Attributes = array(
+            'type'     => ASN1::TYPE_SET,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $Attribute
+        );
+
+        $CertificationRequestInfo = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'version'       => array(
+                                       'type' => ASN1::TYPE_INTEGER,
+                                       'mapping' => array('v1')
+                                   ),
+                'subject'       => $this->Name,
+                'subjectPKInfo' => $SubjectPublicKeyInfo,
+                'attributes'    => array(
+                                       'constant' => 0,
+                                       'optional' => true,
+                                       'implicit' => true
+                                   ) + $Attributes,
+            )
+        );
+
+        $this->CertificationRequest = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'certificationRequestInfo' => $CertificationRequestInfo,
+                'signatureAlgorithm'       => $AlgorithmIdentifier,
+                'signature'                => array('type' => ASN1::TYPE_BIT_STRING)
+            )
+        );
+
+        $RevokedCertificate = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                              'userCertificate'    => $CertificateSerialNumber,
+                              'revocationDate'     => $Time,
+                              'crlEntryExtensions' => array(
+                                                          'optional' => true
+                                                      ) + $this->Extensions
+                          )
+        );
+
+        $TBSCertList = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'version'             => array(
+                                             'optional' => true,
+                                             'default'  => 'v1'
+                                         ) + $Version,
+                'signature'           => $AlgorithmIdentifier,
+                'issuer'              => $this->Name,
+                'thisUpdate'          => $Time,
+                'nextUpdate'          => array(
+                                             'optional' => true
+                                         ) + $Time,
+                'revokedCertificates' => array(
+                                             'type'     => ASN1::TYPE_SEQUENCE,
+                                             'optional' => true,
+                                             'min'      => 0,
+                                             'max'      => -1,
+                                             'children' => $RevokedCertificate
+                                         ),
+                'crlExtensions'       => array(
+                                             'constant' => 0,
+                                             'optional' => true,
+                                             'explicit' => true
+                                         ) + $this->Extensions
+            )
+        );
+
+        $this->CertificateList = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'tbsCertList'        => $TBSCertList,
+                'signatureAlgorithm' => $AlgorithmIdentifier,
+                'signature'          => array('type' => ASN1::TYPE_BIT_STRING)
+            )
+        );
+
+        $this->CRLNumber = array('type' => ASN1::TYPE_INTEGER);
+
+        $this->CRLReason = array('type' => ASN1::TYPE_ENUMERATED,
+           'mapping' => array(
+                            'unspecified',
+                            'keyCompromise',
+                            'cACompromise',
+                            'affiliationChanged',
+                            'superseded',
+                            'cessationOfOperation',
+                            'certificateHold',
+                            // Value 7 is not used.
+                            8 => 'removeFromCRL',
+                            'privilegeWithdrawn',
+                            'aACompromise'
+            )
+        );
+
+        $this->IssuingDistributionPoint = array('type' => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'distributionPoint'          => array(
+                                                    'constant' => 0,
+                                                    'optional' => true,
+                                                    'explicit' => true
+                                                ) + $DistributionPointName,
+                'onlyContainsUserCerts'      => array(
+                                                    'type'     => ASN1::TYPE_BOOLEAN,
+                                                    'constant' => 1,
+                                                    'optional' => true,
+                                                    'default'  => false,
+                                                    'implicit' => true
+                                                ),
+                'onlyContainsCACerts'        => array(
+                                                    'type'     => ASN1::TYPE_BOOLEAN,
+                                                    'constant' => 2,
+                                                    'optional' => true,
+                                                    'default'  => false,
+                                                    'implicit' => true
+                                                ),
+                'onlySomeReasons'           => array(
+                                                    'constant' => 3,
+                                                    'optional' => true,
+                                                    'implicit' => true
+                                                ) + $ReasonFlags,
+                'indirectCRL'               => array(
+                                                    'type'     => ASN1::TYPE_BOOLEAN,
+                                                    'constant' => 4,
+                                                    'optional' => true,
+                                                    'default'  => false,
+                                                    'implicit' => true
+                                                ),
+                'onlyContainsAttributeCerts' => array(
+                                                    'type'     => ASN1::TYPE_BOOLEAN,
+                                                    'constant' => 5,
+                                                    'optional' => true,
+                                                    'default'  => false,
+                                                    'implicit' => true
+                                                )
+                          )
+        );
+
+        $this->InvalidityDate = array('type' => ASN1::TYPE_GENERALIZED_TIME);
+
+        $this->CertificateIssuer = $GeneralNames;
+
+        $this->HoldInstructionCode = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+        $PublicKeyAndChallenge = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'spki'      => $SubjectPublicKeyInfo,
+                'challenge' => array('type' => ASN1::TYPE_IA5_STRING)
+            )
+        );
+
+        $this->SignedPublicKeyAndChallenge = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'children' => array(
+                'publicKeyAndChallenge' => $PublicKeyAndChallenge,
+                'signatureAlgorithm'    => $AlgorithmIdentifier,
+                'signature'             => array('type' => ASN1::TYPE_BIT_STRING)
+            )
+        );
+
+        $this->PostalAddress = array(
+            'type'     => ASN1::TYPE_SEQUENCE,
+            'optional' => true,
+            'min'      => 1,
+            'max'      => -1,
+            'children' => $this->DirectoryString
+        );
+
+        // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2
+        $this->oids = array(
+            '1.3.6.1.5.5.7' => 'id-pkix',
+            '1.3.6.1.5.5.7.1' => 'id-pe',
+            '1.3.6.1.5.5.7.2' => 'id-qt',
+            '1.3.6.1.5.5.7.3' => 'id-kp',
+            '1.3.6.1.5.5.7.48' => 'id-ad',
+            '1.3.6.1.5.5.7.2.1' => 'id-qt-cps',
+            '1.3.6.1.5.5.7.2.2' => 'id-qt-unotice',
+            '1.3.6.1.5.5.7.48.1' =>'id-ad-ocsp',
+            '1.3.6.1.5.5.7.48.2' => 'id-ad-caIssuers',
+            '1.3.6.1.5.5.7.48.3' => 'id-ad-timeStamping',
+            '1.3.6.1.5.5.7.48.5' => 'id-ad-caRepository',
+            '2.5.4' => 'id-at',
+            '2.5.4.41' => 'id-at-name',
+            '2.5.4.4' => 'id-at-surname',
+            '2.5.4.42' => 'id-at-givenName',
+            '2.5.4.43' => 'id-at-initials',
+            '2.5.4.44' => 'id-at-generationQualifier',
+            '2.5.4.3' => 'id-at-commonName',
+            '2.5.4.7' => 'id-at-localityName',
+            '2.5.4.8' => 'id-at-stateOrProvinceName',
+            '2.5.4.10' => 'id-at-organizationName',
+            '2.5.4.11' => 'id-at-organizationalUnitName',
+            '2.5.4.12' => 'id-at-title',
+            '2.5.4.13' => 'id-at-description',
+            '2.5.4.46' => 'id-at-dnQualifier',
+            '2.5.4.6' => 'id-at-countryName',
+            '2.5.4.5' => 'id-at-serialNumber',
+            '2.5.4.65' => 'id-at-pseudonym',
+            '2.5.4.17' => 'id-at-postalCode',
+            '2.5.4.9' => 'id-at-streetAddress',
+            '2.5.4.45' => 'id-at-uniqueIdentifier',
+            '2.5.4.72' => 'id-at-role',
+            '2.5.4.16' => 'id-at-postalAddress',
+
+            '0.9.2342.19200300.100.1.25' => 'id-domainComponent',
+            '1.2.840.113549.1.9' => 'pkcs-9',
+            '1.2.840.113549.1.9.1' => 'pkcs-9-at-emailAddress',
+            '2.5.29' => 'id-ce',
+            '2.5.29.35' => 'id-ce-authorityKeyIdentifier',
+            '2.5.29.14' => 'id-ce-subjectKeyIdentifier',
+            '2.5.29.15' => 'id-ce-keyUsage',
+            '2.5.29.16' => 'id-ce-privateKeyUsagePeriod',
+            '2.5.29.32' => 'id-ce-certificatePolicies',
+            '2.5.29.32.0' => 'anyPolicy',
+
+            '2.5.29.33' => 'id-ce-policyMappings',
+            '2.5.29.17' => 'id-ce-subjectAltName',
+            '2.5.29.18' => 'id-ce-issuerAltName',
+            '2.5.29.9' => 'id-ce-subjectDirectoryAttributes',
+            '2.5.29.19' => 'id-ce-basicConstraints',
+            '2.5.29.30' => 'id-ce-nameConstraints',
+            '2.5.29.36' => 'id-ce-policyConstraints',
+            '2.5.29.31' => 'id-ce-cRLDistributionPoints',
+            '2.5.29.37' => 'id-ce-extKeyUsage',
+            '2.5.29.37.0' => 'anyExtendedKeyUsage',
+            '1.3.6.1.5.5.7.3.1' => 'id-kp-serverAuth',
+            '1.3.6.1.5.5.7.3.2' => 'id-kp-clientAuth',
+            '1.3.6.1.5.5.7.3.3' => 'id-kp-codeSigning',
+            '1.3.6.1.5.5.7.3.4' => 'id-kp-emailProtection',
+            '1.3.6.1.5.5.7.3.8' => 'id-kp-timeStamping',
+            '1.3.6.1.5.5.7.3.9' => 'id-kp-OCSPSigning',
+            '2.5.29.54' => 'id-ce-inhibitAnyPolicy',
+            '2.5.29.46' => 'id-ce-freshestCRL',
+            '1.3.6.1.5.5.7.1.1' => 'id-pe-authorityInfoAccess',
+            '1.3.6.1.5.5.7.1.11' => 'id-pe-subjectInfoAccess',
+            '2.5.29.20' => 'id-ce-cRLNumber',
+            '2.5.29.28' => 'id-ce-issuingDistributionPoint',
+            '2.5.29.27' => 'id-ce-deltaCRLIndicator',
+            '2.5.29.21' => 'id-ce-cRLReasons',
+            '2.5.29.29' => 'id-ce-certificateIssuer',
+            '2.5.29.23' => 'id-ce-holdInstructionCode',
+            '1.2.840.10040.2' => 'holdInstruction',
+            '1.2.840.10040.2.1' => 'id-holdinstruction-none',
+            '1.2.840.10040.2.2' => 'id-holdinstruction-callissuer',
+            '1.2.840.10040.2.3' => 'id-holdinstruction-reject',
+            '2.5.29.24' => 'id-ce-invalidityDate',
+
+            '1.2.840.113549.2.2' => 'md2',
+            '1.2.840.113549.2.5' => 'md5',
+            '1.3.14.3.2.26' => 'id-sha1',
+            '1.2.840.10040.4.1' => 'id-dsa',
+            '1.2.840.10040.4.3' => 'id-dsa-with-sha1',
+            '1.2.840.113549.1.1' => 'pkcs-1',
+            '1.2.840.113549.1.1.1' => 'rsaEncryption',
+            '1.2.840.113549.1.1.2' => 'md2WithRSAEncryption',
+            '1.2.840.113549.1.1.4' => 'md5WithRSAEncryption',
+            '1.2.840.113549.1.1.5' => 'sha1WithRSAEncryption',
+            '1.2.840.10046.2.1' => 'dhpublicnumber',
+            '2.16.840.1.101.2.1.1.22' => 'id-keyExchangeAlgorithm',
+            '1.2.840.10045' => 'ansi-X9-62',
+            '1.2.840.10045.4' => 'id-ecSigType',
+            '1.2.840.10045.4.1' => 'ecdsa-with-SHA1',
+            '1.2.840.10045.1' => 'id-fieldType',
+            '1.2.840.10045.1.1' => 'prime-field',
+            '1.2.840.10045.1.2' => 'characteristic-two-field',
+            '1.2.840.10045.1.2.3' => 'id-characteristic-two-basis',
+            '1.2.840.10045.1.2.3.1' => 'gnBasis',
+            '1.2.840.10045.1.2.3.2' => 'tpBasis',
+            '1.2.840.10045.1.2.3.3' => 'ppBasis',
+            '1.2.840.10045.2' => 'id-publicKeyType',
+            '1.2.840.10045.2.1' => 'id-ecPublicKey',
+            '1.2.840.10045.3' => 'ellipticCurve',
+            '1.2.840.10045.3.0' => 'c-TwoCurve',
+            '1.2.840.10045.3.0.1' => 'c2pnb163v1',
+            '1.2.840.10045.3.0.2' => 'c2pnb163v2',
+            '1.2.840.10045.3.0.3' => 'c2pnb163v3',
+            '1.2.840.10045.3.0.4' => 'c2pnb176w1',
+            '1.2.840.10045.3.0.5' => 'c2pnb191v1',
+            '1.2.840.10045.3.0.6' => 'c2pnb191v2',
+            '1.2.840.10045.3.0.7' => 'c2pnb191v3',
+            '1.2.840.10045.3.0.8' => 'c2pnb191v4',
+            '1.2.840.10045.3.0.9' => 'c2pnb191v5',
+            '1.2.840.10045.3.0.10' => 'c2pnb208w1',
+            '1.2.840.10045.3.0.11' => 'c2pnb239v1',
+            '1.2.840.10045.3.0.12' => 'c2pnb239v2',
+            '1.2.840.10045.3.0.13' => 'c2pnb239v3',
+            '1.2.840.10045.3.0.14' => 'c2pnb239v4',
+            '1.2.840.10045.3.0.15' => 'c2pnb239v5',
+            '1.2.840.10045.3.0.16' => 'c2pnb272w1',
+            '1.2.840.10045.3.0.17' => 'c2pnb304w1',
+            '1.2.840.10045.3.0.18' => 'c2pnb359v1',
+            '1.2.840.10045.3.0.19' => 'c2pnb368w1',
+            '1.2.840.10045.3.0.20' => 'c2pnb431r1',
+            '1.2.840.10045.3.1' => 'primeCurve',
+            '1.2.840.10045.3.1.1' => 'prime192v1',
+            '1.2.840.10045.3.1.2' => 'prime192v2',
+            '1.2.840.10045.3.1.3' => 'prime192v3',
+            '1.2.840.10045.3.1.4' => 'prime239v1',
+            '1.2.840.10045.3.1.5' => 'prime239v2',
+            '1.2.840.10045.3.1.6' => 'prime239v3',
+            '1.2.840.10045.3.1.7' => 'prime256v1',
+            '1.2.840.113549.1.1.7' => 'id-RSAES-OAEP',
+            '1.2.840.113549.1.1.9' => 'id-pSpecified',
+            '1.2.840.113549.1.1.10' => 'id-RSASSA-PSS',
+            '1.2.840.113549.1.1.8' => 'id-mgf1',
+            '1.2.840.113549.1.1.14' => 'sha224WithRSAEncryption',
+            '1.2.840.113549.1.1.11' => 'sha256WithRSAEncryption',
+            '1.2.840.113549.1.1.12' => 'sha384WithRSAEncryption',
+            '1.2.840.113549.1.1.13' => 'sha512WithRSAEncryption',
+            '2.16.840.1.101.3.4.2.4' => 'id-sha224',
+            '2.16.840.1.101.3.4.2.1' => 'id-sha256',
+            '2.16.840.1.101.3.4.2.2' => 'id-sha384',
+            '2.16.840.1.101.3.4.2.3' => 'id-sha512',
+            '1.2.643.2.2.4' => 'id-GostR3411-94-with-GostR3410-94',
+            '1.2.643.2.2.3' => 'id-GostR3411-94-with-GostR3410-2001',
+            '1.2.643.2.2.20' => 'id-GostR3410-2001',
+            '1.2.643.2.2.19' => 'id-GostR3410-94',
+            // Netscape Object Identifiers from "Netscape Certificate Extensions"
+            '2.16.840.1.113730' => 'netscape',
+            '2.16.840.1.113730.1' => 'netscape-cert-extension',
+            '2.16.840.1.113730.1.1' => 'netscape-cert-type',
+            '2.16.840.1.113730.1.13' => 'netscape-comment',
+            '2.16.840.1.113730.1.8' => 'netscape-ca-policy-url',
+            // the following are X.509 extensions not supported by phpseclib
+            '1.3.6.1.5.5.7.1.12' => 'id-pe-logotype',
+            '1.2.840.113533.7.65.0' => 'entrustVersInfo',
+            '2.16.840.1.113733.1.6.9' => 'verisignPrivate',
+            // for Certificate Signing Requests
+            // see http://tools.ietf.org/html/rfc2985
+            '1.2.840.113549.1.9.2' => 'pkcs-9-at-unstructuredName', // PKCS #9 unstructured name
+            '1.2.840.113549.1.9.7' => 'pkcs-9-at-challengePassword', // Challenge password for certificate revocations
+            '1.2.840.113549.1.9.14' => 'pkcs-9-at-extensionRequest' // Certificate extension request
+        );
+    }
+
+    /**
+     * Load X.509 certificate
+     *
+     * Returns an associative array describing the X.509 cert or a false if the cert failed to load
+     *
+     * @param string $cert
+     * @param int $mode
+     * @access public
+     * @return mixed
+     */
+    function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT)
+    {
+        if (is_array($cert) && isset($cert['tbsCertificate'])) {
+            unset($this->currentCert);
+            unset($this->currentKeyIdentifier);
+            $this->dn = $cert['tbsCertificate']['subject'];
+            if (!isset($this->dn)) {
+                return false;
+            }
+            $this->currentCert = $cert;
+
+            $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier');
+            $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null;
+
+            unset($this->signatureSubject);
+
+            return $cert;
+        }
+
+        $asn1 = new ASN1();
+
+        if ($mode != self::FORMAT_DER) {
+            $newcert = $this->_extractBER($cert);
+            if ($mode == self::FORMAT_PEM && $cert == $newcert) {
+                return false;
+            }
+            $cert = $newcert;
+        }
+
+        if ($cert === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $asn1->loadOIDs($this->oids);
+        $decoded = $asn1->decodeBER($cert);
+
+        if (!empty($decoded)) {
+            $x509 = $asn1->asn1map($decoded[0], $this->Certificate);
+        }
+        if (!isset($x509) || $x509 === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+        if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) {
+            $this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
+        }
+        $this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1);
+        $this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1);
+
+        $key = &$x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'];
+        $key = $this->_reformatKey($x509['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $key);
+
+        $this->currentCert = $x509;
+        $this->dn = $x509['tbsCertificate']['subject'];
+
+        $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier');
+        $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null;
+
+        return $x509;
+    }
+
+    /**
+     * Save X.509 certificate
+     *
+     * @param array $cert
+     * @param int $format optional
+     * @access public
+     * @return string
+     */
+    function saveX509($cert, $format = self::FORMAT_PEM)
+    {
+        if (!is_array($cert) || !isset($cert['tbsCertificate'])) {
+            return false;
+        }
+
+        switch (true) {
+            // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()"
+            case !($algorithm = $this->_subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')):
+            case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']):
+                break;
+            default:
+                switch ($algorithm) {
+                    case 'rsaEncryption':
+                        $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']
+                            = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
+                        /* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier."
+                           -- https://tools.ietf.org/html/rfc3279#section-2.3.1
+
+                           given that and the fact that RSA keys appear ot be the only key type for which the parameters field can be blank,
+                           it seems like perhaps the ASN.1 description ought not say the parameters field is OPTIONAL, but whatever.
+                         */
+                        $cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = null;
+                        // https://tools.ietf.org/html/rfc3279#section-2.2.1
+                        $cert['signatureAlgorithm']['parameters'] = null;
+                        $cert['tbsCertificate']['signature']['parameters'] = null;
+                }
+        }
+
+        $asn1 = new ASN1();
+        $asn1->loadOIDs($this->oids);
+
+        $filters = array();
+        $type_utf8_string = array('type' => ASN1::TYPE_UTF8_STRING);
+        $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string;
+        $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string;
+        $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string;
+        $filters['tbsCertificate']['subject']['rdnSequence']['value'] = $type_utf8_string;
+        $filters['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = $type_utf8_string;
+        $filters['signatureAlgorithm']['parameters'] = $type_utf8_string;
+        $filters['authorityCertIssuer']['directoryName']['rdnSequence']['value'] = $type_utf8_string;
+        //$filters['policyQualifiers']['qualifier'] = $type_utf8_string;
+        $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string;
+        $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string;
+
+        /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib\File\ASN1::TYPE_IA5_STRING.
+           \phpseclib\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random
+           characters.
+         */
+        $filters['policyQualifiers']['qualifier']
+            = array('type' => ASN1::TYPE_IA5_STRING);
+
+        $asn1->loadFilters($filters);
+
+        $this->_mapOutExtensions($cert, 'tbsCertificate/extensions', $asn1);
+        $this->_mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence', $asn1);
+        $this->_mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence', $asn1);
+
+        $cert = $asn1->encodeDER($cert, $this->Certificate);
+
+        switch ($format) {
+            case self::FORMAT_DER:
+                return $cert;
+            // case self::FORMAT_PEM:
+            default:
+                return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert), 64) . '-----END CERTIFICATE-----';
+        }
+    }
+
+    /**
+     * Map extension values from octet string to extension-specific internal
+     *   format.
+     *
+     * @param array $root (by reference)
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapInExtensions(&$root, $path, $asn1)
+    {
+        $extensions = &$this->_subArrayUnchecked($root, $path);
+
+        if ($extensions) {
+            for ($i = 0; $i < count($extensions); $i++) {
+                $id = $extensions[$i]['extnId'];
+                $value = &$extensions[$i]['extnValue'];
+                $value = base64_decode($value);
+                /* [extnValue] contains the DER encoding of an ASN.1 value
+                   corresponding to the extension type identified by extnID */
+                $map = $this->_getMapping($id);
+                if (!is_bool($map)) {
+                    $decoder = $id == 'id-ce-nameConstraints' ?
+                        array($this, '_decodeNameConstraintIP') :
+                        array($this, '_decodeIP');
+                    $decoded = $asn1->decodeBER($value);
+                    $mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => $decoder));
+                    $value = $mapped === false ? $decoded[0] : $mapped;
+
+                    if ($id == 'id-ce-certificatePolicies') {
+                        for ($j = 0; $j < count($value); $j++) {
+                            if (!isset($value[$j]['policyQualifiers'])) {
+                                continue;
+                            }
+                            for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) {
+                                $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId'];
+                                $map = $this->_getMapping($subid);
+                                $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier'];
+                                if ($map !== false) {
+                                    $decoded = $asn1->decodeBER($subvalue);
+                                    $mapped = $asn1->asn1map($decoded[0], $map);
+                                    $subvalue = $mapped === false ? $decoded[0] : $mapped;
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    $value = base64_encode($value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Map extension values from extension-specific internal format to
+     *   octet string.
+     *
+     * @param array $root (by reference)
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapOutExtensions(&$root, $path, $asn1)
+    {
+        $extensions = &$this->_subArray($root, $path);
+
+        if (is_array($extensions)) {
+            $size = count($extensions);
+            for ($i = 0; $i < $size; $i++) {
+                if ($extensions[$i] instanceof Element) {
+                    continue;
+                }
+
+                $id = $extensions[$i]['extnId'];
+                $value = &$extensions[$i]['extnValue'];
+
+                switch ($id) {
+                    case 'id-ce-certificatePolicies':
+                        for ($j = 0; $j < count($value); $j++) {
+                            if (!isset($value[$j]['policyQualifiers'])) {
+                                continue;
+                            }
+                            for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) {
+                                $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId'];
+                                $map = $this->_getMapping($subid);
+                                $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier'];
+                                if ($map !== false) {
+                                    // by default \phpseclib\File\ASN1 will try to render qualifier as a \phpseclib\File\ASN1::TYPE_IA5_STRING since it's
+                                    // actual type is \phpseclib\File\ASN1::TYPE_ANY
+                                    $subvalue = new Element($asn1->encodeDER($subvalue, $map));
+                                }
+                            }
+                        }
+                        break;
+                    case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string
+                        if (isset($value['authorityCertSerialNumber'])) {
+                            if ($value['authorityCertSerialNumber']->toBytes() == '') {
+                                $temp = chr((ASN1::CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0";
+                                $value['authorityCertSerialNumber'] = new Element($temp);
+                            }
+                        }
+                }
+
+                /* [extnValue] contains the DER encoding of an ASN.1 value
+                   corresponding to the extension type identified by extnID */
+                $map = $this->_getMapping($id);
+                if (is_bool($map)) {
+                    if (!$map) {
+                        user_error($id . ' is not a currently supported extension');
+                        unset($extensions[$i]);
+                    }
+                } else {
+                    $temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP')));
+                    $value = base64_encode($temp);
+                }
+            }
+        }
+    }
+
+    /**
+     * Map attribute values from ANY type to attribute-specific internal
+     *   format.
+     *
+     * @param array $root (by reference)
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapInAttributes(&$root, $path, $asn1)
+    {
+        $attributes = &$this->_subArray($root, $path);
+
+        if (is_array($attributes)) {
+            for ($i = 0; $i < count($attributes); $i++) {
+                $id = $attributes[$i]['type'];
+                /* $value contains the DER encoding of an ASN.1 value
+                   corresponding to the attribute type identified by type */
+                $map = $this->_getMapping($id);
+                if (is_array($attributes[$i]['value'])) {
+                    $values = &$attributes[$i]['value'];
+                    for ($j = 0; $j < count($values); $j++) {
+                        $value = $asn1->encodeDER($values[$j], $this->AttributeValue);
+                        $decoded = $asn1->decodeBER($value);
+                        if (!is_bool($map)) {
+                            $mapped = $asn1->asn1map($decoded[0], $map);
+                            if ($mapped !== false) {
+                                $values[$j] = $mapped;
+                            }
+                            if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) {
+                                $this->_mapInExtensions($values, $j, $asn1);
+                            }
+                        } elseif ($map) {
+                            $values[$j] = base64_encode($value);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Map attribute values from attribute-specific internal format to
+     *   ANY type.
+     *
+     * @param array $root (by reference)
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapOutAttributes(&$root, $path, $asn1)
+    {
+        $attributes = &$this->_subArray($root, $path);
+
+        if (is_array($attributes)) {
+            $size = count($attributes);
+            for ($i = 0; $i < $size; $i++) {
+                /* [value] contains the DER encoding of an ASN.1 value
+                   corresponding to the attribute type identified by type */
+                $id = $attributes[$i]['type'];
+                $map = $this->_getMapping($id);
+                if ($map === false) {
+                    user_error($id . ' is not a currently supported attribute', E_USER_NOTICE);
+                    unset($attributes[$i]);
+                } elseif (is_array($attributes[$i]['value'])) {
+                    $values = &$attributes[$i]['value'];
+                    for ($j = 0; $j < count($values); $j++) {
+                        switch ($id) {
+                            case 'pkcs-9-at-extensionRequest':
+                                $this->_mapOutExtensions($values, $j, $asn1);
+                                break;
+                        }
+
+                        if (!is_bool($map)) {
+                            $temp = $asn1->encodeDER($values[$j], $map);
+                            $decoded = $asn1->decodeBER($temp);
+                            $values[$j] = $asn1->asn1map($decoded[0], $this->AttributeValue);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Map DN values from ANY type to DN-specific internal
+     *   format.
+     *
+     * @param array $root (by reference)
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapInDNs(&$root, $path, $asn1)
+    {
+        $dns = &$this->_subArray($root, $path);
+
+        if (is_array($dns)) {
+            for ($i = 0; $i < count($dns); $i++) {
+                for ($j = 0; $j < count($dns[$i]); $j++) {
+                    $type = $dns[$i][$j]['type'];
+                    $value = &$dns[$i][$j]['value'];
+                    if (is_object($value) && $value instanceof Element) {
+                        $map = $this->_getMapping($type);
+                        if (!is_bool($map)) {
+                            $decoded = $asn1->decodeBER($value);
+                            $value = $asn1->asn1map($decoded[0], $map);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Map DN values from DN-specific internal format to
+     *   ANY type.
+     *
+     * @param array $root (by reference)
+     * @param string $path
+     * @param object $asn1
+     * @access private
+     */
+    function _mapOutDNs(&$root, $path, $asn1)
+    {
+        $dns = &$this->_subArray($root, $path);
+
+        if (is_array($dns)) {
+            $size = count($dns);
+            for ($i = 0; $i < $size; $i++) {
+                for ($j = 0; $j < count($dns[$i]); $j++) {
+                    $type = $dns[$i][$j]['type'];
+                    $value = &$dns[$i][$j]['value'];
+                    if (is_object($value) && $value instanceof Element) {
+                        continue;
+                    }
+
+                    $map = $this->_getMapping($type);
+                    if (!is_bool($map)) {
+                        $value = new Element($asn1->encodeDER($value, $map));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Associate an extension ID to an extension mapping
+     *
+     * @param string $extnId
+     * @access private
+     * @return mixed
+     */
+    function _getMapping($extnId)
+    {
+        if (!is_string($extnId)) { // eg. if it's a \phpseclib\File\ASN1\Element object
+            return true;
+        }
+
+        switch ($extnId) {
+            case 'id-ce-keyUsage':
+                return $this->KeyUsage;
+            case 'id-ce-basicConstraints':
+                return $this->BasicConstraints;
+            case 'id-ce-subjectKeyIdentifier':
+                return $this->KeyIdentifier;
+            case 'id-ce-cRLDistributionPoints':
+                return $this->CRLDistributionPoints;
+            case 'id-ce-authorityKeyIdentifier':
+                return $this->AuthorityKeyIdentifier;
+            case 'id-ce-certificatePolicies':
+                return $this->CertificatePolicies;
+            case 'id-ce-extKeyUsage':
+                return $this->ExtKeyUsageSyntax;
+            case 'id-pe-authorityInfoAccess':
+                return $this->AuthorityInfoAccessSyntax;
+            case 'id-pe-subjectInfoAccess':
+                return $this->SubjectInfoAccessSyntax;
+            case 'id-ce-subjectAltName':
+                return $this->SubjectAltName;
+            case 'id-ce-subjectDirectoryAttributes':
+                return $this->SubjectDirectoryAttributes;
+            case 'id-ce-privateKeyUsagePeriod':
+                return $this->PrivateKeyUsagePeriod;
+            case 'id-ce-issuerAltName':
+                return $this->IssuerAltName;
+            case 'id-ce-policyMappings':
+                return $this->PolicyMappings;
+            case 'id-ce-nameConstraints':
+                return $this->NameConstraints;
+
+            case 'netscape-cert-type':
+                return $this->netscape_cert_type;
+            case 'netscape-comment':
+                return $this->netscape_comment;
+            case 'netscape-ca-policy-url':
+                return $this->netscape_ca_policy_url;
+
+            // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets
+            // back around to asn1map() and we don't want it decoded again.
+            //case 'id-qt-cps':
+            //    return $this->CPSuri;
+            case 'id-qt-unotice':
+                return $this->UserNotice;
+
+            // the following OIDs are unsupported but we don't want them to give notices when calling saveX509().
+            case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt
+            case 'entrustVersInfo':
+            // http://support.microsoft.com/kb/287547
+            case '1.3.6.1.4.1.311.20.2': // szOID_ENROLL_CERTTYPE_EXTENSION
+            case '1.3.6.1.4.1.311.21.1': // szOID_CERTSRV_CA_VERSION
+            // "SET Secure Electronic Transaction Specification"
+            // http://www.maithean.com/docs/set_bk3.pdf
+            case '2.23.42.7.0': // id-set-hashedRootKey
+            // "Certificate Transparency"
+            // https://tools.ietf.org/html/rfc6962
+            case '1.3.6.1.4.1.11129.2.4.2':
+            // "Qualified Certificate statements"
+            // https://tools.ietf.org/html/rfc3739#section-3.2.6
+            case '1.3.6.1.5.5.7.1.3':
+                return true;
+
+            // CSR attributes
+            case 'pkcs-9-at-unstructuredName':
+                return $this->PKCS9String;
+            case 'pkcs-9-at-challengePassword':
+                return $this->DirectoryString;
+            case 'pkcs-9-at-extensionRequest':
+                return $this->Extensions;
+
+            // CRL extensions.
+            case 'id-ce-cRLNumber':
+                return $this->CRLNumber;
+            case 'id-ce-deltaCRLIndicator':
+                return $this->CRLNumber;
+            case 'id-ce-issuingDistributionPoint':
+                return $this->IssuingDistributionPoint;
+            case 'id-ce-freshestCRL':
+                return $this->CRLDistributionPoints;
+            case 'id-ce-cRLReasons':
+                return $this->CRLReason;
+            case 'id-ce-invalidityDate':
+                return $this->InvalidityDate;
+            case 'id-ce-certificateIssuer':
+                return $this->CertificateIssuer;
+            case 'id-ce-holdInstructionCode':
+                return $this->HoldInstructionCode;
+            case 'id-at-postalAddress':
+                return $this->PostalAddress;
+        }
+
+        return false;
+    }
+
+    /**
+     * Load an X.509 certificate as a certificate authority
+     *
+     * @param string $cert
+     * @access public
+     * @return bool
+     */
+    function loadCA($cert)
+    {
+        $olddn = $this->dn;
+        $oldcert = $this->currentCert;
+        $oldsigsubj = $this->signatureSubject;
+        $oldkeyid = $this->currentKeyIdentifier;
+
+        $cert = $this->loadX509($cert);
+        if (!$cert) {
+            $this->dn = $olddn;
+            $this->currentCert = $oldcert;
+            $this->signatureSubject = $oldsigsubj;
+            $this->currentKeyIdentifier = $oldkeyid;
+
+            return false;
+        }
+
+        /* From RFC5280 "PKIX Certificate and CRL Profile":
+
+           If the keyUsage extension is present, then the subject public key
+           MUST NOT be used to verify signatures on certificates or CRLs unless
+           the corresponding keyCertSign or cRLSign bit is set. */
+        //$keyUsage = $this->getExtension('id-ce-keyUsage');
+        //if ($keyUsage && !in_array('keyCertSign', $keyUsage)) {
+        //    return false;
+        //}
+
+        /* From RFC5280 "PKIX Certificate and CRL Profile":
+
+           The cA boolean indicates whether the certified public key may be used
+           to verify certificate signatures.  If the cA boolean is not asserted,
+           then the keyCertSign bit in the key usage extension MUST NOT be
+           asserted.  If the basic constraints extension is not present in a
+           version 3 certificate, or the extension is present but the cA boolean
+           is not asserted, then the certified public key MUST NOT be used to
+           verify certificate signatures. */
+        //$basicConstraints = $this->getExtension('id-ce-basicConstraints');
+        //if (!$basicConstraints || !$basicConstraints['cA']) {
+        //    return false;
+        //}
+
+        $this->CAs[] = $cert;
+
+        $this->dn = $olddn;
+        $this->currentCert = $oldcert;
+        $this->signatureSubject = $oldsigsubj;
+
+        return true;
+    }
+
+    /**
+     * Validate an X.509 certificate against a URL
+     *
+     * From RFC2818 "HTTP over TLS":
+     *
+     * Matching is performed using the matching rules specified by
+     * [RFC2459].  If more than one identity of a given type is present in
+     * the certificate (e.g., more than one dNSName name, a match in any one
+     * of the set is considered acceptable.) Names may contain the wildcard
+     * character * which is considered to match any single domain name
+     * component or component fragment. E.g., *.a.com matches foo.a.com but
+     * not bar.foo.a.com. f*.com matches foo.com but not bar.com.
+     *
+     * @param string $url
+     * @access public
+     * @return bool
+     */
+    function validateURL($url)
+    {
+        if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
+            return false;
+        }
+
+        $components = parse_url($url);
+        if (!isset($components['host'])) {
+            return false;
+        }
+
+        if ($names = $this->getExtension('id-ce-subjectAltName')) {
+            foreach ($names as $name) {
+                foreach ($name as $key => $value) {
+                    $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
+                    switch ($key) {
+                        case 'dNSName':
+                            /* From RFC2818 "HTTP over TLS":
+
+                               If a subjectAltName extension of type dNSName is present, that MUST
+                               be used as the identity. Otherwise, the (most specific) Common Name
+                               field in the Subject field of the certificate MUST be used. Although
+                               the use of the Common Name is existing practice, it is deprecated and
+                               Certification Authorities are encouraged to use the dNSName instead. */
+                            if (preg_match('#^' . $value . '$#', $components['host'])) {
+                                return true;
+                            }
+                            break;
+                        case 'iPAddress':
+                            /* From RFC2818 "HTTP over TLS":
+
+                               In some cases, the URI is specified as an IP address rather than a
+                               hostname. In this case, the iPAddress subjectAltName must be present
+                               in the certificate and must exactly match the IP in the URI. */
+                            if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
+                                return true;
+                            }
+                    }
+                }
+            }
+            return false;
+        }
+
+        if ($value = $this->getDNProp('id-at-commonName')) {
+            $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value[0]);
+            return preg_match('#^' . $value . '$#', $components['host']);
+        }
+
+        return false;
+    }
+
+    /**
+     * Validate a date
+     *
+     * If $date isn't defined it is assumed to be the current date.
+     *
+     * @param \DateTime|string $date optional
+     * @access public
+     */
+    function validateDate($date = null)
+    {
+        if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
+            return false;
+        }
+
+        if (!isset($date)) {
+            $date = new DateTime(null, new DateTimeZone(@date_default_timezone_get()));
+        }
+
+        $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
+        $notBefore = isset($notBefore['generalTime']) ? $notBefore['generalTime'] : $notBefore['utcTime'];
+
+        $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
+        $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
+
+        if (is_string($date)) {
+            $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+        }
+
+        $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
+        $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
+
+        switch (true) {
+            case $date < $notBefore:
+            case $date > $notAfter:
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Fetches a URL
+     *
+     * @param string $url
+     * @access private
+     * @return bool|string
+     */
+    static function _fetchURL($url)
+    {
+        if (self::$disable_url_fetch) {
+            return false;
+        }
+
+        $parts = parse_url($url);
+        $data = '';
+        switch ($parts['scheme']) {
+            case 'http':
+                $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
+                if (!$fsock) {
+                    return false;
+                }
+                $path = $parts['path'];
+                if (isset($parts['query'])) {
+                    $path.= '?' . $parts['query'];
+                }
+                fputs($fsock, "GET $path HTTP/1.0\r\n");
+                fputs($fsock, "Host: $parts[host]\r\n\r\n");
+                $line = fgets($fsock, 1024);
+                if (strlen($line) < 3) {
+                    return false;
+                }
+                preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
+                if ($temp[1] != '200') {
+                    return false;
+                }
+
+                // skip the rest of the headers in the http response
+                while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
+                }
+
+                while (!feof($fsock)) {
+                    $temp = fread($fsock, 1024);
+                    if ($temp === false) {
+                        return false;
+                    }
+                    $data.= $temp;
+                }
+
+                break;
+            //case 'ftp':
+            //case 'ldap':
+            //default:
+        }
+
+        return $data;
+    }
+
+    /**
+     * Validates an intermediate cert as identified via authority info access extension
+     *
+     * See https://tools.ietf.org/html/rfc4325 for more info
+     *
+     * @param bool $caonly
+     * @param int $count
+     * @access private
+     * @return bool
+     */
+    function _testForIntermediate($caonly, $count)
+    {
+        $opts = $this->getExtension('id-pe-authorityInfoAccess');
+        if (!is_array($opts)) {
+            return false;
+        }
+        foreach ($opts as $opt) {
+            if ($opt['accessMethod'] == 'id-ad-caIssuers') {
+                // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
+                // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
+                // discusses
+                if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
+                    $url = $opt['accessLocation']['uniformResourceIdentifier'];
+                    break;
+                }
+            }
+        }
+
+        if (!isset($url)) {
+            return false;
+        }
+
+        $cert = static::_fetchURL($url);
+        if (!is_string($cert)) {
+            return false;
+        }
+
+        $parent = new static();
+        $parent->CAs = $this->CAs;
+        /*
+         "Conforming applications that support HTTP or FTP for accessing
+          certificates MUST be able to accept .cer files and SHOULD be able
+          to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
+
+         A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
+
+         These are currently unsupported
+        */
+        if (!is_array($parent->loadX509($cert))) {
+            return false;
+        }
+
+        if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
+            return false;
+        }
+
+        $this->CAs[] = $parent->currentCert;
+        //$this->loadCA($cert);
+
+        return true;
+    }
+
+    /**
+     * Validate a signature
+     *
+     * Works on X.509 certs, CSR's and CRL's.
+     * Returns true if the signature is verified, false if it is not correct or null on error
+     *
+     * By default returns false for self-signed certs. Call validateSignature(false) to make this support
+     * self-signed.
+     *
+     * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}.
+     *
+     * @param bool $caonly optional
+     * @access public
+     * @return mixed
+     */
+    function validateSignature($caonly = true)
+    {
+        return $this->_validateSignatureCountable($caonly, 0);
+    }
+
+    /**
+     * Validate a signature
+     *
+     * Performs said validation whilst keeping track of how many times validation method is called
+     *
+     * @param bool $caonly
+     * @param int $count
+     * @access private
+     * @return mixed
+     */
+    function _validateSignatureCountable($caonly, $count)
+    {
+        if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
+            return null;
+        }
+
+        if ($count == self::$recur_limit) {
+            return false;
+        }
+
+        /* TODO:
+           "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
+            -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
+
+           implement pathLenConstraint in the id-ce-basicConstraints extension */
+
+        switch (true) {
+            case isset($this->currentCert['tbsCertificate']):
+                // self-signed cert
+                switch (true) {
+                    case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']:
+                    case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING):
+                        $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+                        $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
+                        switch (true) {
+                            case !is_array($authorityKey):
+                            case !$subjectKeyID:
+                            case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                                $signingCert = $this->currentCert; // working cert
+                        }
+                }
+
+                if (!empty($this->CAs)) {
+                    for ($i = 0; $i < count($this->CAs); $i++) {
+                        // even if the cert is a self-signed one we still want to see if it's a CA;
+                        // if not, we'll conditionally return an error
+                        $ca = $this->CAs[$i];
+                        switch (true) {
+                            case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']:
+                            case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']):
+                                $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+                                $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+                                switch (true) {
+                                    case !is_array($authorityKey):
+                                    case !$subjectKeyID:
+                                    case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                                        if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
+                                            break 2; // serial mismatch - check other ca
+                                        }
+                                        $signingCert = $ca; // working cert
+                                        break 3;
+                                }
+                        }
+                    }
+                    if (count($this->CAs) == $i && $caonly) {
+                        return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
+                    }
+                } elseif (!isset($signingCert) || $caonly) {
+                    return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
+                }
+                return $this->_validateSignature(
+                    $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
+                    $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'],
+                    $this->currentCert['signatureAlgorithm']['algorithm'],
+                    substr(base64_decode($this->currentCert['signature']), 1),
+                    $this->signatureSubject
+                );
+            case isset($this->currentCert['certificationRequestInfo']):
+                return $this->_validateSignature(
+                    $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'],
+                    $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'],
+                    $this->currentCert['signatureAlgorithm']['algorithm'],
+                    substr(base64_decode($this->currentCert['signature']), 1),
+                    $this->signatureSubject
+                );
+            case isset($this->currentCert['publicKeyAndChallenge']):
+                return $this->_validateSignature(
+                    $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'],
+                    $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'],
+                    $this->currentCert['signatureAlgorithm']['algorithm'],
+                    substr(base64_decode($this->currentCert['signature']), 1),
+                    $this->signatureSubject
+                );
+            case isset($this->currentCert['tbsCertList']):
+                if (!empty($this->CAs)) {
+                    for ($i = 0; $i < count($this->CAs); $i++) {
+                        $ca = $this->CAs[$i];
+                        switch (true) {
+                            case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']:
+                            case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']):
+                                $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+                                $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+                                switch (true) {
+                                    case !is_array($authorityKey):
+                                    case !$subjectKeyID:
+                                    case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                                        if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
+                                            break 2; // serial mismatch - check other ca
+                                        }
+                                        $signingCert = $ca; // working cert
+                                        break 3;
+                                }
+                        }
+                    }
+                }
+                if (!isset($signingCert)) {
+                    return false;
+                }
+                return $this->_validateSignature(
+                    $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
+                    $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'],
+                    $this->currentCert['signatureAlgorithm']['algorithm'],
+                    substr(base64_decode($this->currentCert['signature']), 1),
+                    $this->signatureSubject
+                );
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Validates a signature
+     *
+     * Returns true if the signature is verified, false if it is not correct or null on error
+     *
+     * @param string $publicKeyAlgorithm
+     * @param string $publicKey
+     * @param string $signatureAlgorithm
+     * @param string $signature
+     * @param string $signatureSubject
+     * @access private
+     * @return int
+     */
+    function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
+    {
+        switch ($publicKeyAlgorithm) {
+            case 'rsaEncryption':
+                $rsa = new RSA();
+                $rsa->loadKey($publicKey);
+
+                switch ($signatureAlgorithm) {
+                    case 'md2WithRSAEncryption':
+                    case 'md5WithRSAEncryption':
+                    case 'sha1WithRSAEncryption':
+                    case 'sha224WithRSAEncryption':
+                    case 'sha256WithRSAEncryption':
+                    case 'sha384WithRSAEncryption':
+                    case 'sha512WithRSAEncryption':
+                        $rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
+                        $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
+                        if (!@$rsa->verify($signatureSubject, $signature)) {
+                            return false;
+                        }
+                        break;
+                    default:
+                        return null;
+                }
+                break;
+            default:
+                return null;
+        }
+
+        return true;
+    }
+
+    /**
+     * Sets the recursion limit
+     *
+     * When validating a signature it may be necessary to download intermediate certs from URI's.
+     * An intermediate cert that linked to itself would result in an infinite loop so to prevent
+     * that we set a recursion limit. A negative number means that there is no recursion limit.
+     *
+     * @param int $count
+     * @access public
+     */
+    static function setRecurLimit($count)
+    {
+        self::$recur_limit = $count;
+    }
+
+    /**
+     * Prevents URIs from being automatically retrieved
+     *
+     * @access public
+     */
+    static function disableURLFetch()
+    {
+        self::$disable_url_fetch = true;
+    }
+
+    /**
+     * Allows URIs to be automatically retrieved
+     *
+     * @access public
+     */
+    static function enableURLFetch()
+    {
+        self::$disable_url_fetch = false;
+    }
+
+    /**
+     * Reformat public keys
+     *
+     * Reformats a public key to a format supported by phpseclib (if applicable)
+     *
+     * @param string $algorithm
+     * @param string $key
+     * @access private
+     * @return string
+     */
+    function _reformatKey($algorithm, $key)
+    {
+        switch ($algorithm) {
+            case 'rsaEncryption':
+                return
+                    "-----BEGIN RSA PUBLIC KEY-----\r\n" .
+                    // subjectPublicKey is stored as a bit string in X.509 certs.  the first byte of a bit string represents how many bits
+                    // in the last byte should be ignored.  the following only supports non-zero stuff but as none of the X.509 certs Firefox
+                    // uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do.
+                    chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) .
+                    '-----END RSA PUBLIC KEY-----';
+            default:
+                return $key;
+        }
+    }
+
+    /**
+     * Decodes an IP address
+     *
+     * Takes in a base64 encoded "blob" and returns a human readable IP address
+     *
+     * @param string $ip
+     * @access private
+     * @return string
+     */
+    function _decodeIP($ip)
+    {
+        return inet_ntop(base64_decode($ip));
+    }
+
+    /**
+     * Decodes an IP address in a name constraints extension
+     *
+     * Takes in a base64 encoded "blob" and returns a human readable IP address / mask
+     *
+     * @param string $ip
+     * @access private
+     * @return array
+     */
+    function _decodeNameConstraintIP($ip)
+    {
+        $ip = base64_decode($ip);
+        $size = strlen($ip) >> 1;
+        $mask = substr($ip, $size);
+        $ip = substr($ip, 0, $size);
+        return array(inet_ntop($ip), inet_ntop($mask));
+    }
+
+    /**
+     * Encodes an IP address
+     *
+     * Takes a human readable IP address into a base64-encoded "blob"
+     *
+     * @param string|array $ip
+     * @access private
+     * @return string
+     */
+    function _encodeIP($ip)
+    {
+        return is_string($ip) ?
+            base64_encode(inet_pton($ip)) :
+            base64_encode(inet_pton($ip[0]) . inet_pton($ip[1]));
+    }
+
+    /**
+     * "Normalizes" a Distinguished Name property
+     *
+     * @param string $propName
+     * @access private
+     * @return mixed
+     */
+    function _translateDNProp($propName)
+    {
+        switch (strtolower($propName)) {
+            case 'id-at-countryname':
+            case 'countryname':
+            case 'c':
+                return 'id-at-countryName';
+            case 'id-at-organizationname':
+            case 'organizationname':
+            case 'o':
+                return 'id-at-organizationName';
+            case 'id-at-dnqualifier':
+            case 'dnqualifier':
+                return 'id-at-dnQualifier';
+            case 'id-at-commonname':
+            case 'commonname':
+            case 'cn':
+                return 'id-at-commonName';
+            case 'id-at-stateorprovincename':
+            case 'stateorprovincename':
+            case 'state':
+            case 'province':
+            case 'provincename':
+            case 'st':
+                return 'id-at-stateOrProvinceName';
+            case 'id-at-localityname':
+            case 'localityname':
+            case 'l':
+                return 'id-at-localityName';
+            case 'id-emailaddress':
+            case 'emailaddress':
+                return 'pkcs-9-at-emailAddress';
+            case 'id-at-serialnumber':
+            case 'serialnumber':
+                return 'id-at-serialNumber';
+            case 'id-at-postalcode':
+            case 'postalcode':
+                return 'id-at-postalCode';
+            case 'id-at-streetaddress':
+            case 'streetaddress':
+                return 'id-at-streetAddress';
+            case 'id-at-name':
+            case 'name':
+                return 'id-at-name';
+            case 'id-at-givenname':
+            case 'givenname':
+                return 'id-at-givenName';
+            case 'id-at-surname':
+            case 'surname':
+            case 'sn':
+                return 'id-at-surname';
+            case 'id-at-initials':
+            case 'initials':
+                return 'id-at-initials';
+            case 'id-at-generationqualifier':
+            case 'generationqualifier':
+                return 'id-at-generationQualifier';
+            case 'id-at-organizationalunitname':
+            case 'organizationalunitname':
+            case 'ou':
+                return 'id-at-organizationalUnitName';
+            case 'id-at-pseudonym':
+            case 'pseudonym':
+                return 'id-at-pseudonym';
+            case 'id-at-title':
+            case 'title':
+                return 'id-at-title';
+            case 'id-at-description':
+            case 'description':
+                return 'id-at-description';
+            case 'id-at-role':
+            case 'role':
+                return 'id-at-role';
+            case 'id-at-uniqueidentifier':
+            case 'uniqueidentifier':
+            case 'x500uniqueidentifier':
+                return 'id-at-uniqueIdentifier';
+            case 'postaladdress':
+            case 'id-at-postaladdress':
+                return 'id-at-postalAddress';
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Set a Distinguished Name property
+     *
+     * @param string $propName
+     * @param mixed $propValue
+     * @param string $type optional
+     * @access public
+     * @return bool
+     */
+    function setDNProp($propName, $propValue, $type = 'utf8String')
+    {
+        if (empty($this->dn)) {
+            $this->dn = array('rdnSequence' => array());
+        }
+
+        if (($propName = $this->_translateDNProp($propName)) === false) {
+            return false;
+        }
+
+        foreach ((array) $propValue as $v) {
+            if (!is_array($v) && isset($type)) {
+                $v = array($type => $v);
+            }
+            $this->dn['rdnSequence'][] = array(
+                array(
+                    'type' => $propName,
+                    'value'=> $v
+                )
+            );
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove Distinguished Name properties
+     *
+     * @param string $propName
+     * @access public
+     */
+    function removeDNProp($propName)
+    {
+        if (empty($this->dn)) {
+            return;
+        }
+
+        if (($propName = $this->_translateDNProp($propName)) === false) {
+            return;
+        }
+
+        $dn = &$this->dn['rdnSequence'];
+        $size = count($dn);
+        for ($i = 0; $i < $size; $i++) {
+            if ($dn[$i][0]['type'] == $propName) {
+                unset($dn[$i]);
+            }
+        }
+
+        $dn = array_values($dn);
+        // fix for https://bugs.php.net/75433 affecting PHP 7.2
+        if (!isset($dn[0])) {
+            $dn = array_splice($dn, 0, 0);
+        }
+    }
+
+    /**
+     * Get Distinguished Name properties
+     *
+     * @param string $propName
+     * @param array $dn optional
+     * @param bool $withType optional
+     * @return mixed
+     * @access public
+     */
+    function getDNProp($propName, $dn = null, $withType = false)
+    {
+        if (!isset($dn)) {
+            $dn = $this->dn;
+        }
+
+        if (empty($dn)) {
+            return false;
+        }
+
+        if (($propName = $this->_translateDNProp($propName)) === false) {
+            return false;
+        }
+
+        $asn1 = new ASN1();
+        $asn1->loadOIDs($this->oids);
+        $filters = array();
+        $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+        $asn1->loadFilters($filters);
+        $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+        $dn = $dn['rdnSequence'];
+        $result = array();
+        for ($i = 0; $i < count($dn); $i++) {
+            if ($dn[$i][0]['type'] == $propName) {
+                $v = $dn[$i][0]['value'];
+                if (!$withType) {
+                    if (is_array($v)) {
+                        foreach ($v as $type => $s) {
+                            $type = array_search($type, $asn1->ANYmap, true);
+                            if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+                                $s = $asn1->convert($s, $type);
+                                if ($s !== false) {
+                                    $v = $s;
+                                    break;
+                                }
+                            }
+                        }
+                        if (is_array($v)) {
+                            $v = array_pop($v); // Always strip data type.
+                        }
+                    } elseif (is_object($v) && $v instanceof Element) {
+                        $map = $this->_getMapping($propName);
+                        if (!is_bool($map)) {
+                            $decoded = $asn1->decodeBER($v);
+                            $v = $asn1->asn1map($decoded[0], $map);
+                        }
+                    }
+                }
+                $result[] = $v;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Set a Distinguished Name
+     *
+     * @param mixed $dn
+     * @param bool $merge optional
+     * @param string $type optional
+     * @access public
+     * @return bool
+     */
+    function setDN($dn, $merge = false, $type = 'utf8String')
+    {
+        if (!$merge) {
+            $this->dn = null;
+        }
+
+        if (is_array($dn)) {
+            if (isset($dn['rdnSequence'])) {
+                $this->dn = $dn; // No merge here.
+                return true;
+            }
+
+            // handles stuff generated by openssl_x509_parse()
+            foreach ($dn as $prop => $value) {
+                if (!$this->setDNProp($prop, $value, $type)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // handles everything else
+        $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
+        for ($i = 1; $i < count($results); $i+=2) {
+            $prop = trim($results[$i], ', =/');
+            $value = $results[$i + 1];
+            if (!$this->setDNProp($prop, $value, $type)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Get the Distinguished Name for a certificates subject
+     *
+     * @param mixed $format optional
+     * @param array $dn optional
+     * @access public
+     * @return bool
+     */
+    function getDN($format = self::DN_ARRAY, $dn = null)
+    {
+        if (!isset($dn)) {
+            $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn;
+        }
+
+        switch ((int) $format) {
+            case self::DN_ARRAY:
+                return $dn;
+            case self::DN_ASN1:
+                $asn1 = new ASN1();
+                $asn1->loadOIDs($this->oids);
+                $filters = array();
+                $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+                $asn1->loadFilters($filters);
+                $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+                return $asn1->encodeDER($dn, $this->Name);
+            case self::DN_CANON:
+                //  No SEQUENCE around RDNs and all string values normalized as
+                // trimmed lowercase UTF-8 with all spacing as one blank.
+                // constructed RDNs will not be canonicalized
+                $asn1 = new ASN1();
+                $asn1->loadOIDs($this->oids);
+                $filters = array();
+                $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+                $asn1->loadFilters($filters);
+                $result = '';
+                $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+                foreach ($dn['rdnSequence'] as $rdn) {
+                    foreach ($rdn as $i => $attr) {
+                        $attr = &$rdn[$i];
+                        if (is_array($attr['value'])) {
+                            foreach ($attr['value'] as $type => $v) {
+                                $type = array_search($type, $asn1->ANYmap, true);
+                                if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+                                    $v = $asn1->convert($v, $type);
+                                    if ($v !== false) {
+                                        $v = preg_replace('/\s+/', ' ', $v);
+                                        $attr['value'] = strtolower(trim($v));
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    $result .= $asn1->encodeDER($rdn, $this->RelativeDistinguishedName);
+                }
+                return $result;
+            case self::DN_HASH:
+                $dn = $this->getDN(self::DN_CANON, $dn);
+                $hash = new Hash('sha1');
+                $hash = $hash->hash($dn);
+                extract(unpack('Vhash', $hash));
+                return strtolower(bin2hex(pack('N', $hash)));
+        }
+
+        // Default is to return a string.
+        $start = true;
+        $output = '';
+
+        $result = array();
+        $asn1 = new ASN1();
+        $asn1->loadOIDs($this->oids);
+        $filters = array();
+        $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+        $asn1->loadFilters($filters);
+        $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+
+        foreach ($dn['rdnSequence'] as $field) {
+            $prop = $field[0]['type'];
+            $value = $field[0]['value'];
+
+            $delim = ', ';
+            switch ($prop) {
+                case 'id-at-countryName':
+                    $desc = 'C';
+                    break;
+                case 'id-at-stateOrProvinceName':
+                    $desc = 'ST';
+                    break;
+                case 'id-at-organizationName':
+                    $desc = 'O';
+                    break;
+                case 'id-at-organizationalUnitName':
+                    $desc = 'OU';
+                    break;
+                case 'id-at-commonName':
+                    $desc = 'CN';
+                    break;
+                case 'id-at-localityName':
+                    $desc = 'L';
+                    break;
+                case 'id-at-surname':
+                    $desc = 'SN';
+                    break;
+                case 'id-at-uniqueIdentifier':
+                    $delim = '/';
+                    $desc = 'x500UniqueIdentifier';
+                    break;
+                case 'id-at-postalAddress':
+                    $delim = '/';
+                    $desc = 'postalAddress';
+                    break;
+                default:
+                    $delim = '/';
+                    $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop);
+            }
+
+            if (!$start) {
+                $output.= $delim;
+            }
+            if (is_array($value)) {
+                foreach ($value as $type => $v) {
+                    $type = array_search($type, $asn1->ANYmap, true);
+                    if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+                        $v = $asn1->convert($v, $type);
+                        if ($v !== false) {
+                            $value = $v;
+                            break;
+                        }
+                    }
+                }
+                if (is_array($value)) {
+                    $value = array_pop($value); // Always strip data type.
+                }
+            } elseif (is_object($value) && $value instanceof Element) {
+                $callback = function ($x) {
+                    return "\x" . bin2hex($x[0]);
+                };
+                $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
+            }
+            $output.= $desc . '=' . $value;
+            $result[$desc] = isset($result[$desc]) ?
+                array_merge((array) $result[$desc], array($value)) :
+                $value;
+            $start = false;
+        }
+
+        return $format == self::DN_OPENSSL ? $result : $output;
+    }
+
+    /**
+     * Get the Distinguished Name for a certificate/crl issuer
+     *
+     * @param int $format optional
+     * @access public
+     * @return mixed
+     */
+    function getIssuerDN($format = self::DN_ARRAY)
+    {
+        switch (true) {
+            case !isset($this->currentCert) || !is_array($this->currentCert):
+                break;
+            case isset($this->currentCert['tbsCertificate']):
+                return $this->getDN($format, $this->currentCert['tbsCertificate']['issuer']);
+            case isset($this->currentCert['tbsCertList']):
+                return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']);
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the Distinguished Name for a certificate/csr subject
+     * Alias of getDN()
+     *
+     * @param int $format optional
+     * @access public
+     * @return mixed
+     */
+    function getSubjectDN($format = self::DN_ARRAY)
+    {
+        switch (true) {
+            case !empty($this->dn):
+                return $this->getDN($format);
+            case !isset($this->currentCert) || !is_array($this->currentCert):
+                break;
+            case isset($this->currentCert['tbsCertificate']):
+                return $this->getDN($format, $this->currentCert['tbsCertificate']['subject']);
+            case isset($this->currentCert['certificationRequestInfo']):
+                return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']);
+        }
+
+        return false;
+    }
+
+    /**
+     * Get an individual Distinguished Name property for a certificate/crl issuer
+     *
+     * @param string $propName
+     * @param bool $withType optional
+     * @access public
+     * @return mixed
+     */
+    function getIssuerDNProp($propName, $withType = false)
+    {
+        switch (true) {
+            case !isset($this->currentCert) || !is_array($this->currentCert):
+                break;
+            case isset($this->currentCert['tbsCertificate']):
+                return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType);
+            case isset($this->currentCert['tbsCertList']):
+                return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType);
+        }
+
+        return false;
+    }
+
+    /**
+     * Get an individual Distinguished Name property for a certificate/csr subject
+     *
+     * @param string $propName
+     * @param bool $withType optional
+     * @access public
+     * @return mixed
+     */
+    function getSubjectDNProp($propName, $withType = false)
+    {
+        switch (true) {
+            case !empty($this->dn):
+                return $this->getDNProp($propName, null, $withType);
+            case !isset($this->currentCert) || !is_array($this->currentCert):
+                break;
+            case isset($this->currentCert['tbsCertificate']):
+                return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType);
+            case isset($this->currentCert['certificationRequestInfo']):
+                return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType);
+        }
+
+        return false;
+    }
+
+    /**
+     * Get the certificate chain for the current cert
+     *
+     * @access public
+     * @return mixed
+     */
+    function getChain()
+    {
+        $chain = array($this->currentCert);
+
+        if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
+            return false;
+        }
+        if (empty($this->CAs)) {
+            return $chain;
+        }
+        while (true) {
+            $currentCert = $chain[count($chain) - 1];
+            for ($i = 0; $i < count($this->CAs); $i++) {
+                $ca = $this->CAs[$i];
+                if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
+                    $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert);
+                    $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+                    switch (true) {
+                        case !is_array($authorityKey):
+                        case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+                            if ($currentCert === $ca) {
+                                break 3;
+                            }
+                            $chain[] = $ca;
+                            break 2;
+                    }
+                }
+            }
+            if ($i == count($this->CAs)) {
+                break;
+            }
+        }
+        foreach ($chain as $key => $value) {
+            $chain[$key] = new X509();
+            $chain[$key]->loadX509($value);
+        }
+        return $chain;
+    }
+
+    /**
+     * Set public key
+     *
+     * Key needs to be a \phpseclib\Crypt\RSA object
+     *
+     * @param object $key
+     * @access public
+     * @return bool
+     */
+    function setPublicKey($key)
+    {
+        $key->setPublicKey();
+        $this->publicKey = $key;
+    }
+
+    /**
+     * Set private key
+     *
+     * Key needs to be a \phpseclib\Crypt\RSA object
+     *
+     * @param object $key
+     * @access public
+     */
+    function setPrivateKey($key)
+    {
+        $this->privateKey = $key;
+    }
+
+    /**
+     * Set challenge
+     *
+     * Used for SPKAC CSR's
+     *
+     * @param string $challenge
+     * @access public
+     */
+    function setChallenge($challenge)
+    {
+        $this->challenge = $challenge;
+    }
+
+    /**
+     * Gets the public key
+     *
+     * Returns a \phpseclib\Crypt\RSA object or a false.
+     *
+     * @access public
+     * @return mixed
+     */
+    function getPublicKey()
+    {
+        if (isset($this->publicKey)) {
+            return $this->publicKey;
+        }
+
+        if (isset($this->currentCert) && is_array($this->currentCert)) {
+            foreach (array('tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo') as $path) {
+                $keyinfo = $this->_subArray($this->currentCert, $path);
+                if (!empty($keyinfo)) {
+                    break;
+                }
+            }
+        }
+        if (empty($keyinfo)) {
+            return false;
+        }
+
+        $key = $keyinfo['subjectPublicKey'];
+
+        switch ($keyinfo['algorithm']['algorithm']) {
+            case 'rsaEncryption':
+                $publicKey = new RSA();
+                $publicKey->loadKey($key);
+                $publicKey->setPublicKey();
+                break;
+            default:
+                return false;
+        }
+
+        return $publicKey;
+    }
+
+    /**
+     * Load a Certificate Signing Request
+     *
+     * @param string|array $csr
+     * @param int $mode
+     * @access public
+     * @return mixed
+     */
+    function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT)
+    {
+        if (is_array($csr) && isset($csr['certificationRequestInfo'])) {
+            unset($this->currentCert);
+            unset($this->currentKeyIdentifier);
+            unset($this->signatureSubject);
+            $this->dn = $csr['certificationRequestInfo']['subject'];
+            if (!isset($this->dn)) {
+                return false;
+            }
+
+            $this->currentCert = $csr;
+            return $csr;
+        }
+
+        // see http://tools.ietf.org/html/rfc2986
+
+        $asn1 = new ASN1();
+
+        if ($mode != self::FORMAT_DER) {
+            $newcsr = $this->_extractBER($csr);
+            if ($mode == self::FORMAT_PEM && $csr == $newcsr) {
+                return false;
+            }
+            $csr = $newcsr;
+        }
+        $orig = $csr;
+
+        if ($csr === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $asn1->loadOIDs($this->oids);
+        $decoded = $asn1->decodeBER($csr);
+
+        if (empty($decoded)) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $csr = $asn1->asn1map($decoded[0], $this->CertificationRequest);
+        if (!isset($csr) || $csr === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
+        $this->_mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
+
+        $this->dn = $csr['certificationRequestInfo']['subject'];
+
+        $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+        $algorithm = &$csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'];
+        $key = &$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'];
+        $key = $this->_reformatKey($algorithm, $key);
+
+        switch ($algorithm) {
+            case 'rsaEncryption':
+                $this->publicKey = new RSA();
+                $this->publicKey->loadKey($key);
+                $this->publicKey->setPublicKey();
+                break;
+            default:
+                $this->publicKey = null;
+        }
+
+        $this->currentKeyIdentifier = null;
+        $this->currentCert = $csr;
+
+        return $csr;
+    }
+
+    /**
+     * Save CSR request
+     *
+     * @param array $csr
+     * @param int $format optional
+     * @access public
+     * @return string
+     */
+    function saveCSR($csr, $format = self::FORMAT_PEM)
+    {
+        if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) {
+            return false;
+        }
+
+        switch (true) {
+            case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')):
+            case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']):
+                break;
+            default:
+                switch ($algorithm) {
+                    case 'rsaEncryption':
+                        $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']
+                            = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
+                        $csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null;
+                        $csr['signatureAlgorithm']['parameters'] = null;
+                        $csr['certificationRequestInfo']['signature']['parameters'] = null;
+                }
+        }
+
+        $asn1 = new ASN1();
+
+        $asn1->loadOIDs($this->oids);
+
+        $filters = array();
+        $filters['certificationRequestInfo']['subject']['rdnSequence']['value']
+            = array('type' => ASN1::TYPE_UTF8_STRING);
+
+        $asn1->loadFilters($filters);
+
+        $this->_mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
+        $this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
+        $csr = $asn1->encodeDER($csr, $this->CertificationRequest);
+
+        switch ($format) {
+            case self::FORMAT_DER:
+                return $csr;
+            // case self::FORMAT_PEM:
+            default:
+                return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----';
+        }
+    }
+
+    /**
+     * Load a SPKAC CSR
+     *
+     * SPKAC's are produced by the HTML5 keygen element:
+     *
+     * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen
+     *
+     * @param string|array $spkac
+     * @access public
+     * @return mixed
+     */
+    function loadSPKAC($spkac)
+    {
+        if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) {
+            unset($this->currentCert);
+            unset($this->currentKeyIdentifier);
+            unset($this->signatureSubject);
+            $this->currentCert = $spkac;
+            return $spkac;
+        }
+
+        // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge
+
+        $asn1 = new ASN1();
+
+        // OpenSSL produces SPKAC's that are preceded by the string SPKAC=
+        $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac);
+        $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
+        if ($temp != false) {
+            $spkac = $temp;
+        }
+        $orig = $spkac;
+
+        if ($spkac === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $asn1->loadOIDs($this->oids);
+        $decoded = $asn1->decodeBER($spkac);
+
+        if (empty($decoded)) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $spkac = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge);
+
+        if (!isset($spkac) || $spkac === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+        $algorithm = &$spkac['publicKeyAndChallenge']['spki']['algorithm']['algorithm'];
+        $key = &$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'];
+        $key = $this->_reformatKey($algorithm, $key);
+
+        switch ($algorithm) {
+            case 'rsaEncryption':
+                $this->publicKey = new RSA();
+                $this->publicKey->loadKey($key);
+                $this->publicKey->setPublicKey();
+                break;
+            default:
+                $this->publicKey = null;
+        }
+
+        $this->currentKeyIdentifier = null;
+        $this->currentCert = $spkac;
+
+        return $spkac;
+    }
+
+    /**
+     * Save a SPKAC CSR request
+     *
+     * @param string|array $spkac
+     * @param int $format optional
+     * @access public
+     * @return string
+     */
+    function saveSPKAC($spkac, $format = self::FORMAT_PEM)
+    {
+        if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) {
+            return false;
+        }
+
+        $algorithm = $this->_subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm');
+        switch (true) {
+            case !$algorithm:
+            case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']):
+                break;
+            default:
+                switch ($algorithm) {
+                    case 'rsaEncryption':
+                        $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']
+                            = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])));
+                }
+        }
+
+        $asn1 = new ASN1();
+
+        $asn1->loadOIDs($this->oids);
+        $spkac = $asn1->encodeDER($spkac, $this->SignedPublicKeyAndChallenge);
+
+        switch ($format) {
+            case self::FORMAT_DER:
+                return $spkac;
+            // case self::FORMAT_PEM:
+            default:
+                // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much
+                // no other SPKAC decoders phpseclib will use that same format
+                return 'SPKAC=' . base64_encode($spkac);
+        }
+    }
+
+    /**
+     * Load a Certificate Revocation List
+     *
+     * @param string $crl
+     * @param int $mode
+     * @access public
+     * @return mixed
+     */
+    function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT)
+    {
+        if (is_array($crl) && isset($crl['tbsCertList'])) {
+            $this->currentCert = $crl;
+            unset($this->signatureSubject);
+            return $crl;
+        }
+
+        $asn1 = new ASN1();
+
+        if ($mode != self::FORMAT_DER) {
+            $newcrl = $this->_extractBER($crl);
+            if ($mode == self::FORMAT_PEM && $crl == $newcrl) {
+                return false;
+            }
+            $crl = $newcrl;
+        }
+        $orig = $crl;
+
+        if ($crl === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $asn1->loadOIDs($this->oids);
+        $decoded = $asn1->decodeBER($crl);
+
+        if (empty($decoded)) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $crl = $asn1->asn1map($decoded[0], $this->CertificateList);
+        if (!isset($crl) || $crl === false) {
+            $this->currentCert = false;
+            return false;
+        }
+
+        $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+        $this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
+        if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) {
+            $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
+        }
+        if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) {
+            $rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates');
+            if ($rclist_ref) {
+                $rclist = $crl['tbsCertList']['revokedCertificates'];
+                foreach ($rclist as $i => $extension) {
+                    if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) {
+                        $this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1);
+                    }
+                }
+            }
+        }
+
+        $this->currentKeyIdentifier = null;
+        $this->currentCert = $crl;
+
+        return $crl;
+    }
+
+    /**
+     * Save Certificate Revocation List.
+     *
+     * @param array $crl
+     * @param int $format optional
+     * @access public
+     * @return string
+     */
+    function saveCRL($crl, $format = self::FORMAT_PEM)
+    {
+        if (!is_array($crl) || !isset($crl['tbsCertList'])) {
+            return false;
+        }
+
+        $asn1 = new ASN1();
+
+        $asn1->loadOIDs($this->oids);
+
+        $filters = array();
+        $filters['tbsCertList']['issuer']['rdnSequence']['value']
+            = array('type' => ASN1::TYPE_UTF8_STRING);
+        $filters['tbsCertList']['signature']['parameters']
+            = array('type' => ASN1::TYPE_UTF8_STRING);
+        $filters['signatureAlgorithm']['parameters']
+            = array('type' => ASN1::TYPE_UTF8_STRING);
+
+        if (empty($crl['tbsCertList']['signature']['parameters'])) {
+            $filters['tbsCertList']['signature']['parameters']
+                = array('type' => ASN1::TYPE_NULL);
+        }
+
+        if (empty($crl['signatureAlgorithm']['parameters'])) {
+            $filters['signatureAlgorithm']['parameters']
+                = array('type' => ASN1::TYPE_NULL);
+        }
+
+        $asn1->loadFilters($filters);
+
+        $this->_mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
+        $this->_mapOutExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
+        $rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
+        if (is_array($rclist)) {
+            foreach ($rclist as $i => $extension) {
+                $this->_mapOutExtensions($rclist, "$i/crlEntryExtensions", $asn1);
+            }
+        }
+
+        $crl = $asn1->encodeDER($crl, $this->CertificateList);
+
+        switch ($format) {
+            case self::FORMAT_DER:
+                return $crl;
+            // case self::FORMAT_PEM:
+            default:
+                return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl), 64) . '-----END X509 CRL-----';
+        }
+    }
+
+    /**
+     * Helper function to build a time field according to RFC 3280 section
+     *  - 4.1.2.5 Validity
+     *  - 5.1.2.4 This Update
+     *  - 5.1.2.5 Next Update
+     *  - 5.1.2.6 Revoked Certificates
+     * by choosing utcTime iff year of date given is before 2050 and generalTime else.
+     *
+     * @param string $date in format date('D, d M Y H:i:s O')
+     * @access private
+     * @return array
+     */
+    function _timeField($date)
+    {
+        if ($date instanceof Element) {
+            return $date;
+        }
+        $dateObj = new DateTime($date, new DateTimeZone('GMT'));
+        $year = $dateObj->format('Y'); // the same way ASN1.php parses this
+        if ($year < 2050) {
+            return array('utcTime' => $date);
+        } else {
+            return array('generalTime' => $date);
+        }
+    }
+
+    /**
+     * Sign an X.509 certificate
+     *
+     * $issuer's private key needs to be loaded.
+     * $subject can be either an existing X.509 cert (if you want to resign it),
+     * a CSR or something with the DN and public key explicitly set.
+     *
+     * @param \phpseclib\File\X509 $issuer
+     * @param \phpseclib\File\X509 $subject
+     * @param string $signatureAlgorithm optional
+     * @access public
+     * @return mixed
+     */
+    function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')
+    {
+        if (!is_object($issuer->privateKey) || empty($issuer->dn)) {
+            return false;
+        }
+
+        if (isset($subject->publicKey) && !($subjectPublicKey = $subject->_formatSubjectPublicKey())) {
+            return false;
+        }
+
+        $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+        $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null;
+
+        if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) {
+            $this->currentCert = $subject->currentCert;
+            $this->currentCert['tbsCertificate']['signature']['algorithm'] = $signatureAlgorithm;
+            $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+
+            if (!empty($this->startDate)) {
+                $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->_timeField($this->startDate);
+            }
+            if (!empty($this->endDate)) {
+                $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->_timeField($this->endDate);
+            }
+            if (!empty($this->serialNumber)) {
+                $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber;
+            }
+            if (!empty($subject->dn)) {
+                $this->currentCert['tbsCertificate']['subject'] = $subject->dn;
+            }
+            if (!empty($subject->publicKey)) {
+                $this->currentCert['tbsCertificate']['subjectPublicKeyInfo'] = $subjectPublicKey;
+            }
+            $this->removeExtension('id-ce-authorityKeyIdentifier');
+            if (isset($subject->domains)) {
+                $this->removeExtension('id-ce-subjectAltName');
+            }
+        } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) {
+            return false;
+        } else {
+            if (!isset($subject->publicKey)) {
+                return false;
+            }
+
+            $startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+            $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
+
+            $endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
+            $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
+
+            /* "The serial number MUST be a positive integer"
+               "Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
+                -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
+
+               for the integer to be positive the leading bit needs to be 0 hence the
+               application of a bitmap
+            */
+            $serialNumber = !empty($this->serialNumber) ?
+                $this->serialNumber :
+                new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256);
+
+            $this->currentCert = array(
+                'tbsCertificate' =>
+                    array(
+                        'version' => 'v3',
+                        'serialNumber' => $serialNumber, // $this->setSerialNumber()
+                        'signature' => array('algorithm' => $signatureAlgorithm),
+                        'issuer' => false, // this is going to be overwritten later
+                        'validity' => array(
+                            'notBefore' => $this->_timeField($startDate), // $this->setStartDate()
+                            'notAfter' => $this->_timeField($endDate)   // $this->setEndDate()
+                        ),
+                        'subject' => $subject->dn,
+                        'subjectPublicKeyInfo' => $subjectPublicKey
+                    ),
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
+            );
+
+            // Copy extensions from CSR.
+            $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0);
+
+            if (!empty($csrexts)) {
+                $this->currentCert['tbsCertificate']['extensions'] = $csrexts;
+            }
+        }
+
+        $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn;
+
+        if (isset($issuer->currentKeyIdentifier)) {
+            $this->setExtension('id-ce-authorityKeyIdentifier', array(
+                    //'authorityCertIssuer' => array(
+                    //    array(
+                    //        'directoryName' => $issuer->dn
+                    //    )
+                    //),
+                    'keyIdentifier' => $issuer->currentKeyIdentifier
+                ));
+            //$extensions = &$this->currentCert['tbsCertificate']['extensions'];
+            //if (isset($issuer->serialNumber)) {
+            //    $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
+            //}
+            //unset($extensions);
+        }
+
+        if (isset($subject->currentKeyIdentifier)) {
+            $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier);
+        }
+
+        $altName = array();
+
+        if (isset($subject->domains) && count($subject->domains)) {
+            $altName = array_map(array('\phpseclib\File\X509', '_dnsName'), $subject->domains);
+        }
+
+        if (isset($subject->ipAddresses) && count($subject->ipAddresses)) {
+            // should an IP address appear as the CN if no domain name is specified? idk
+            //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1);
+            $ipAddresses = array();
+            foreach ($subject->ipAddresses as $ipAddress) {
+                $encoded = $subject->_ipAddress($ipAddress);
+                if ($encoded !== false) {
+                    $ipAddresses[] = $encoded;
+                }
+            }
+            if (count($ipAddresses)) {
+                $altName = array_merge($altName, $ipAddresses);
+            }
+        }
+
+        if (!empty($altName)) {
+            $this->setExtension('id-ce-subjectAltName', $altName);
+        }
+
+        if ($this->caFlag) {
+            $keyUsage = $this->getExtension('id-ce-keyUsage');
+            if (!$keyUsage) {
+                $keyUsage = array();
+            }
+
+            $this->setExtension(
+                'id-ce-keyUsage',
+                array_values(array_unique(array_merge($keyUsage, array('cRLSign', 'keyCertSign'))))
+            );
+
+            $basicConstraints = $this->getExtension('id-ce-basicConstraints');
+            if (!$basicConstraints) {
+                $basicConstraints = array();
+            }
+
+            $this->setExtension(
+                'id-ce-basicConstraints',
+                array_unique(array_merge(array('cA' => true), $basicConstraints)),
+                true
+            );
+
+            if (!isset($subject->currentKeyIdentifier)) {
+                $this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false);
+            }
+        }
+
+        // resync $this->signatureSubject
+        // save $tbsCertificate in case there are any \phpseclib\File\ASN1\Element objects in it
+        $tbsCertificate = $this->currentCert['tbsCertificate'];
+        $this->loadX509($this->saveX509($this->currentCert));
+
+        $result = $this->_sign($issuer->privateKey, $signatureAlgorithm);
+        $result['tbsCertificate'] = $tbsCertificate;
+
+        $this->currentCert = $currentCert;
+        $this->signatureSubject = $signatureSubject;
+
+        return $result;
+    }
+
+    /**
+     * Sign a CSR
+     *
+     * @access public
+     * @return mixed
+     */
+    function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption')
+    {
+        if (!is_object($this->privateKey) || empty($this->dn)) {
+            return false;
+        }
+
+        $origPublicKey = $this->publicKey;
+        $class = get_class($this->privateKey);
+        $this->publicKey = new $class();
+        $this->publicKey->loadKey($this->privateKey->getPublicKey());
+        $this->publicKey->setPublicKey();
+        if (!($publicKey = $this->_formatSubjectPublicKey())) {
+            return false;
+        }
+        $this->publicKey = $origPublicKey;
+
+        $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+        $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null;
+
+        if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) {
+            $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+            if (!empty($this->dn)) {
+                $this->currentCert['certificationRequestInfo']['subject'] = $this->dn;
+            }
+            $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey;
+        } else {
+            $this->currentCert = array(
+                'certificationRequestInfo' =>
+                    array(
+                        'version' => 'v1',
+                        'subject' => $this->dn,
+                        'subjectPKInfo' => $publicKey
+                    ),
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
+            );
+        }
+
+        // resync $this->signatureSubject
+        // save $certificationRequestInfo in case there are any \phpseclib\File\ASN1\Element objects in it
+        $certificationRequestInfo = $this->currentCert['certificationRequestInfo'];
+        $this->loadCSR($this->saveCSR($this->currentCert));
+
+        $result = $this->_sign($this->privateKey, $signatureAlgorithm);
+        $result['certificationRequestInfo'] = $certificationRequestInfo;
+
+        $this->currentCert = $currentCert;
+        $this->signatureSubject = $signatureSubject;
+
+        return $result;
+    }
+
+    /**
+     * Sign a SPKAC
+     *
+     * @access public
+     * @return mixed
+     */
+    function signSPKAC($signatureAlgorithm = 'sha1WithRSAEncryption')
+    {
+        if (!is_object($this->privateKey)) {
+            return false;
+        }
+
+        $origPublicKey = $this->publicKey;
+        $class = get_class($this->privateKey);
+        $this->publicKey = new $class();
+        $this->publicKey->loadKey($this->privateKey->getPublicKey());
+        $this->publicKey->setPublicKey();
+        $publicKey = $this->_formatSubjectPublicKey();
+        if (!$publicKey) {
+            return false;
+        }
+        $this->publicKey = $origPublicKey;
+
+        $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+        $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null;
+
+        // re-signing a SPKAC seems silly but since everything else supports re-signing why not?
+        if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) {
+            $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+            $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey;
+            if (!empty($this->challenge)) {
+                // the bitwise AND ensures that the output is a valid IA5String
+                $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge));
+            }
+        } else {
+            $this->currentCert = array(
+                'publicKeyAndChallenge' =>
+                    array(
+                        'spki' => $publicKey,
+                        // quoting <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen>,
+                        // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified."
+                        // both Firefox and OpenSSL ("openssl spkac -key private.key") behave this way
+                        // we could alternatively do this instead if we ignored the specs:
+                        // Random::string(8) & str_repeat("\x7F", 8)
+                        'challenge' => !empty($this->challenge) ? $this->challenge : ''
+                    ),
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
+            );
+        }
+
+        // resync $this->signatureSubject
+        // save $publicKeyAndChallenge in case there are any \phpseclib\File\ASN1\Element objects in it
+        $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge'];
+        $this->loadSPKAC($this->saveSPKAC($this->currentCert));
+
+        $result = $this->_sign($this->privateKey, $signatureAlgorithm);
+        $result['publicKeyAndChallenge'] = $publicKeyAndChallenge;
+
+        $this->currentCert = $currentCert;
+        $this->signatureSubject = $signatureSubject;
+
+        return $result;
+    }
+
+    /**
+     * Sign a CRL
+     *
+     * $issuer's private key needs to be loaded.
+     *
+     * @param \phpseclib\File\X509 $issuer
+     * @param \phpseclib\File\X509 $crl
+     * @param string $signatureAlgorithm optional
+     * @access public
+     * @return mixed
+     */
+    function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption')
+    {
+        if (!is_object($issuer->privateKey) || empty($issuer->dn)) {
+            return false;
+        }
+
+        $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+        $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
+
+        $thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+        $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
+
+        if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
+            $this->currentCert = $crl->currentCert;
+            $this->currentCert['tbsCertList']['signature']['algorithm'] = $signatureAlgorithm;
+            $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+        } else {
+            $this->currentCert = array(
+                'tbsCertList' =>
+                    array(
+                        'version' => 'v2',
+                        'signature' => array('algorithm' => $signatureAlgorithm),
+                        'issuer' => false, // this is going to be overwritten later
+                        'thisUpdate' => $this->_timeField($thisUpdate) // $this->setStartDate()
+                    ),
+                    'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+                    'signature'          => false // this is going to be overwritten later
+            );
+        }
+
+        $tbsCertList = &$this->currentCert['tbsCertList'];
+        $tbsCertList['issuer'] = $issuer->dn;
+        $tbsCertList['thisUpdate'] = $this->_timeField($thisUpdate);
+
+        if (!empty($this->endDate)) {
+            $tbsCertList['nextUpdate'] = $this->_timeField($this->endDate); // $this->setEndDate()
+        } else {
+            unset($tbsCertList['nextUpdate']);
+        }
+
+        if (!empty($this->serialNumber)) {
+            $crlNumber = $this->serialNumber;
+        } else {
+            $crlNumber = $this->getExtension('id-ce-cRLNumber');
+            // "The CRL number is a non-critical CRL extension that conveys a
+            //  monotonically increasing sequence number for a given CRL scope and
+            //  CRL issuer.  This extension allows users to easily determine when a
+            //  particular CRL supersedes another CRL."
+            // -- https://tools.ietf.org/html/rfc5280#section-5.2.3
+            $crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null;
+        }
+
+        $this->removeExtension('id-ce-authorityKeyIdentifier');
+        $this->removeExtension('id-ce-issuerAltName');
+
+        // Be sure version >= v2 if some extension found.
+        $version = isset($tbsCertList['version']) ? $tbsCertList['version'] : 0;
+        if (!$version) {
+            if (!empty($tbsCertList['crlExtensions'])) {
+                $version = 1; // v2.
+            } elseif (!empty($tbsCertList['revokedCertificates'])) {
+                foreach ($tbsCertList['revokedCertificates'] as $cert) {
+                    if (!empty($cert['crlEntryExtensions'])) {
+                        $version = 1; // v2.
+                    }
+                }
+            }
+
+            if ($version) {
+                $tbsCertList['version'] = $version;
+            }
+        }
+
+        // Store additional extensions.
+        if (!empty($tbsCertList['version'])) { // At least v2.
+            if (!empty($crlNumber)) {
+                $this->setExtension('id-ce-cRLNumber', $crlNumber);
+            }
+
+            if (isset($issuer->currentKeyIdentifier)) {
+                $this->setExtension('id-ce-authorityKeyIdentifier', array(
+                        //'authorityCertIssuer' => array(
+                        //    array(
+                        //        'directoryName' => $issuer->dn
+                        //    )
+                        //),
+                        'keyIdentifier' => $issuer->currentKeyIdentifier
+                    ));
+                //$extensions = &$tbsCertList['crlExtensions'];
+                //if (isset($issuer->serialNumber)) {
+                //    $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
+                //}
+                //unset($extensions);
+            }
+
+            $issuerAltName = $this->getExtension('id-ce-subjectAltName', $issuer->currentCert);
+
+            if ($issuerAltName !== false) {
+                $this->setExtension('id-ce-issuerAltName', $issuerAltName);
+            }
+        }
+
+        if (empty($tbsCertList['revokedCertificates'])) {
+            unset($tbsCertList['revokedCertificates']);
+        }
+
+        unset($tbsCertList);
+
+        // resync $this->signatureSubject
+        // save $tbsCertList in case there are any \phpseclib\File\ASN1\Element objects in it
+        $tbsCertList = $this->currentCert['tbsCertList'];
+        $this->loadCRL($this->saveCRL($this->currentCert));
+
+        $result = $this->_sign($issuer->privateKey, $signatureAlgorithm);
+        $result['tbsCertList'] = $tbsCertList;
+
+        $this->currentCert = $currentCert;
+        $this->signatureSubject = $signatureSubject;
+
+        return $result;
+    }
+
+    /**
+     * X.509 certificate signing helper function.
+     *
+     * @param \phpseclib\File\X509 $key
+     * @param string $signatureAlgorithm
+     * @access public
+     * @return mixed
+     */
+    function _sign($key, $signatureAlgorithm)
+    {
+        if ($key instanceof RSA) {
+            switch ($signatureAlgorithm) {
+                case 'md2WithRSAEncryption':
+                case 'md5WithRSAEncryption':
+                case 'sha1WithRSAEncryption':
+                case 'sha224WithRSAEncryption':
+                case 'sha256WithRSAEncryption':
+                case 'sha384WithRSAEncryption':
+                case 'sha512WithRSAEncryption':
+                    $key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
+                    $key->setSignatureMode(RSA::SIGNATURE_PKCS1);
+
+                    $this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject));
+                    return $this->currentCert;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Set certificate start date
+     *
+     * @param string $date
+     * @access public
+     */
+    function setStartDate($date)
+    {
+        if (!is_object($date) || !is_a($date, 'DateTime')) {
+            $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+        }
+
+        $this->startDate = $date->format('D, d M Y H:i:s O');
+    }
+
+    /**
+     * Set certificate end date
+     *
+     * @param string $date
+     * @access public
+     */
+    function setEndDate($date)
+    {
+        /*
+          To indicate that a certificate has no well-defined expiration date,
+          the notAfter SHOULD be assigned the GeneralizedTime value of
+          99991231235959Z.
+
+          -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5
+        */
+        if (strtolower($date) == 'lifetime') {
+            $temp = '99991231235959Z';
+            $asn1 = new ASN1();
+            $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
+            $this->endDate = new Element($temp);
+        } else {
+            if (!is_object($date) || !is_a($date, 'DateTime')) {
+                $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+            }
+
+            $this->endDate = $date->format('D, d M Y H:i:s O');
+        }
+    }
+
+    /**
+     * Set Serial Number
+     *
+     * @param string $serial
+     * @param int $base optional
+     * @access public
+     */
+    function setSerialNumber($serial, $base = -256)
+    {
+        $this->serialNumber = new BigInteger($serial, $base);
+    }
+
+    /**
+     * Turns the certificate into a certificate authority
+     *
+     * @access public
+     */
+    function makeCA()
+    {
+        $this->caFlag = true;
+    }
+
+    /**
+     * Check for validity of subarray
+     *
+     * This is intended for use in conjunction with _subArrayUnchecked(),
+     * implementing the checks included in _subArray() but without copying
+     * a potentially large array by passing its reference by-value to is_array().
+     *
+     * @param array $root
+     * @param string $path
+     * @return boolean
+     * @access private
+     */
+    function _isSubArrayValid($root, $path)
+    {
+        if (!is_array($root)) {
+            return false;
+        }
+
+        foreach (explode('/', $path) as $i) {
+            if (!is_array($root)) {
+                return false;
+            }
+
+            if (!isset($root[$i])) {
+                return true;
+            }
+
+            $root = $root[$i];
+        }
+
+        return true;
+    }
+
+    /**
+     * Get a reference to a subarray
+     *
+     * This variant of _subArray() does no is_array() checking,
+     * so $root should be checked with _isSubArrayValid() first.
+     *
+     * This is here for performance reasons:
+     * Passing a reference (i.e. $root) by-value (i.e. to is_array())
+     * creates a copy. If $root is an especially large array, this is expensive.
+     *
+     * @param array $root
+     * @param string $path  absolute path with / as component separator
+     * @param bool $create optional
+     * @access private
+     * @return array|false
+     */
+    function &_subArrayUnchecked(&$root, $path, $create = false)
+    {
+        $false = false;
+
+        foreach (explode('/', $path) as $i) {
+            if (!isset($root[$i])) {
+                if (!$create) {
+                    return $false;
+                }
+
+                $root[$i] = array();
+            }
+
+            $root = &$root[$i];
+        }
+
+        return $root;
+    }
+
+    /**
+     * Get a reference to a subarray
+     *
+     * @param array $root
+     * @param string $path  absolute path with / as component separator
+     * @param bool $create optional
+     * @access private
+     * @return array|false
+     */
+    function &_subArray(&$root, $path, $create = false)
+    {
+        $false = false;
+
+        if (!is_array($root)) {
+            return $false;
+        }
+
+        foreach (explode('/', $path) as $i) {
+            if (!is_array($root)) {
+                return $false;
+            }
+
+            if (!isset($root[$i])) {
+                if (!$create) {
+                    return $false;
+                }
+
+                $root[$i] = array();
+            }
+
+            $root = &$root[$i];
+        }
+
+        return $root;
+    }
+
+    /**
+     * Get a reference to an extension subarray
+     *
+     * @param array $root
+     * @param string $path optional absolute path with / as component separator
+     * @param bool $create optional
+     * @access private
+     * @return array|false
+     */
+    function &_extensions(&$root, $path = null, $create = false)
+    {
+        if (!isset($root)) {
+            $root = $this->currentCert;
+        }
+
+        switch (true) {
+            case !empty($path):
+            case !is_array($root):
+                break;
+            case isset($root['tbsCertificate']):
+                $path = 'tbsCertificate/extensions';
+                break;
+            case isset($root['tbsCertList']):
+                $path = 'tbsCertList/crlExtensions';
+                break;
+            case isset($root['certificationRequestInfo']):
+                $pth = 'certificationRequestInfo/attributes';
+                $attributes = &$this->_subArray($root, $pth, $create);
+
+                if (is_array($attributes)) {
+                    foreach ($attributes as $key => $value) {
+                        if ($value['type'] == 'pkcs-9-at-extensionRequest') {
+                            $path = "$pth/$key/value/0";
+                            break 2;
+                        }
+                    }
+                    if ($create) {
+                        $key = count($attributes);
+                        $attributes[] = array('type' => 'pkcs-9-at-extensionRequest', 'value' => array());
+                        $path = "$pth/$key/value/0";
+                    }
+                }
+                break;
+        }
+
+        $extensions = &$this->_subArray($root, $path, $create);
+
+        if (!is_array($extensions)) {
+            $false = false;
+            return $false;
+        }
+
+        return $extensions;
+    }
+
+    /**
+     * Remove an Extension
+     *
+     * @param string $id
+     * @param string $path optional
+     * @access private
+     * @return bool
+     */
+    function _removeExtension($id, $path = null)
+    {
+        $extensions = &$this->_extensions($this->currentCert, $path);
+
+        if (!is_array($extensions)) {
+            return false;
+        }
+
+        $result = false;
+        foreach ($extensions as $key => $value) {
+            if ($value['extnId'] == $id) {
+                unset($extensions[$key]);
+                $result = true;
+            }
+        }
+
+        $extensions = array_values($extensions);
+        // fix for https://bugs.php.net/75433 affecting PHP 7.2
+        if (!isset($extensions[0])) {
+            $extensions = array_splice($extensions, 0, 0);
+        }
+        return $result;
+    }
+
+    /**
+     * Get an Extension
+     *
+     * Returns the extension if it exists and false if not
+     *
+     * @param string $id
+     * @param array $cert optional
+     * @param string $path optional
+     * @access private
+     * @return mixed
+     */
+    function _getExtension($id, $cert = null, $path = null)
+    {
+        $extensions = $this->_extensions($cert, $path);
+
+        if (!is_array($extensions)) {
+            return false;
+        }
+
+        foreach ($extensions as $key => $value) {
+            if ($value['extnId'] == $id) {
+                return $value['extnValue'];
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a list of all extensions in use
+     *
+     * @param array $cert optional
+     * @param string $path optional
+     * @access private
+     * @return array
+     */
+    function _getExtensions($cert = null, $path = null)
+    {
+        $exts = $this->_extensions($cert, $path);
+        $extensions = array();
+
+        if (is_array($exts)) {
+            foreach ($exts as $extension) {
+                $extensions[] = $extension['extnId'];
+            }
+        }
+
+        return $extensions;
+    }
+
+    /**
+     * Set an Extension
+     *
+     * @param string $id
+     * @param mixed $value
+     * @param bool $critical optional
+     * @param bool $replace optional
+     * @param string $path optional
+     * @access private
+     * @return bool
+     */
+    function _setExtension($id, $value, $critical = false, $replace = true, $path = null)
+    {
+        $extensions = &$this->_extensions($this->currentCert, $path, true);
+
+        if (!is_array($extensions)) {
+            return false;
+        }
+
+        $newext = array('extnId'  => $id, 'critical' => $critical, 'extnValue' => $value);
+
+        foreach ($extensions as $key => $value) {
+            if ($value['extnId'] == $id) {
+                if (!$replace) {
+                    return false;
+                }
+
+                $extensions[$key] = $newext;
+                return true;
+            }
+        }
+
+        $extensions[] = $newext;
+        return true;
+    }
+
+    /**
+     * Remove a certificate, CSR or CRL Extension
+     *
+     * @param string $id
+     * @access public
+     * @return bool
+     */
+    function removeExtension($id)
+    {
+        return $this->_removeExtension($id);
+    }
+
+    /**
+     * Get a certificate, CSR or CRL Extension
+     *
+     * Returns the extension if it exists and false if not
+     *
+     * @param string $id
+     * @param array $cert optional
+     * @access public
+     * @return mixed
+     */
+    function getExtension($id, $cert = null)
+    {
+        return $this->_getExtension($id, $cert);
+    }
+
+    /**
+     * Returns a list of all extensions in use in certificate, CSR or CRL
+     *
+     * @param array $cert optional
+     * @access public
+     * @return array
+     */
+    function getExtensions($cert = null)
+    {
+        return $this->_getExtensions($cert);
+    }
+
+    /**
+     * Set a certificate, CSR or CRL Extension
+     *
+     * @param string $id
+     * @param mixed $value
+     * @param bool $critical optional
+     * @param bool $replace optional
+     * @access public
+     * @return bool
+     */
+    function setExtension($id, $value, $critical = false, $replace = true)
+    {
+        return $this->_setExtension($id, $value, $critical, $replace);
+    }
+
+    /**
+     * Remove a CSR attribute.
+     *
+     * @param string $id
+     * @param int $disposition optional
+     * @access public
+     * @return bool
+     */
+    function removeAttribute($id, $disposition = self::ATTR_ALL)
+    {
+        $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes');
+
+        if (!is_array($attributes)) {
+            return false;
+        }
+
+        $result = false;
+        foreach ($attributes as $key => $attribute) {
+            if ($attribute['type'] == $id) {
+                $n = count($attribute['value']);
+                switch (true) {
+                    case $disposition == self::ATTR_APPEND:
+                    case $disposition == self::ATTR_REPLACE:
+                        return false;
+                    case $disposition >= $n:
+                        $disposition -= $n;
+                        break;
+                    case $disposition == self::ATTR_ALL:
+                    case $n == 1:
+                        unset($attributes[$key]);
+                        $result = true;
+                        break;
+                    default:
+                        unset($attributes[$key]['value'][$disposition]);
+                        $attributes[$key]['value'] = array_values($attributes[$key]['value']);
+                        $result = true;
+                        break;
+                }
+                if ($result && $disposition != self::ATTR_ALL) {
+                    break;
+                }
+            }
+        }
+
+        $attributes = array_values($attributes);
+        return $result;
+    }
+
+    /**
+     * Get a CSR attribute
+     *
+     * Returns the attribute if it exists and false if not
+     *
+     * @param string $id
+     * @param int $disposition optional
+     * @param array $csr optional
+     * @access public
+     * @return mixed
+     */
+    function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null)
+    {
+        if (empty($csr)) {
+            $csr = $this->currentCert;
+        }
+
+        $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes');
+
+        if (!is_array($attributes)) {
+            return false;
+        }
+
+        foreach ($attributes as $key => $attribute) {
+            if ($attribute['type'] == $id) {
+                $n = count($attribute['value']);
+                switch (true) {
+                    case $disposition == self::ATTR_APPEND:
+                    case $disposition == self::ATTR_REPLACE:
+                        return false;
+                    case $disposition == self::ATTR_ALL:
+                        return $attribute['value'];
+                    case $disposition >= $n:
+                        $disposition -= $n;
+                        break;
+                    default:
+                        return $attribute['value'][$disposition];
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a list of all CSR attributes in use
+     *
+     * @param array $csr optional
+     * @access public
+     * @return array
+     */
+    function getAttributes($csr = null)
+    {
+        if (empty($csr)) {
+            $csr = $this->currentCert;
+        }
+
+        $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes');
+        $attrs = array();
+
+        if (is_array($attributes)) {
+            foreach ($attributes as $attribute) {
+                $attrs[] = $attribute['type'];
+            }
+        }
+
+        return $attrs;
+    }
+
+    /**
+     * Set a CSR attribute
+     *
+     * @param string $id
+     * @param mixed $value
+     * @param bool $disposition optional
+     * @access public
+     * @return bool
+     */
+    function setAttribute($id, $value, $disposition = self::ATTR_ALL)
+    {
+        $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes', true);
+
+        if (!is_array($attributes)) {
+            return false;
+        }
+
+        switch ($disposition) {
+            case self::ATTR_REPLACE:
+                $disposition = self::ATTR_APPEND;
+            case self::ATTR_ALL:
+                $this->removeAttribute($id);
+                break;
+        }
+
+        foreach ($attributes as $key => $attribute) {
+            if ($attribute['type'] == $id) {
+                $n = count($attribute['value']);
+                switch (true) {
+                    case $disposition == self::ATTR_APPEND:
+                        $last = $key;
+                        break;
+                    case $disposition >= $n:
+                        $disposition -= $n;
+                        break;
+                    default:
+                        $attributes[$key]['value'][$disposition] = $value;
+                        return true;
+                }
+            }
+        }
+
+        switch (true) {
+            case $disposition >= 0:
+                return false;
+            case isset($last):
+                $attributes[$last]['value'][] = $value;
+                break;
+            default:
+                $attributes[] = array('type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value: array($value));
+                break;
+        }
+
+        return true;
+    }
+
+    /**
+     * Sets the subject key identifier
+     *
+     * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions.
+     *
+     * @param string $value
+     * @access public
+     */
+    function setKeyIdentifier($value)
+    {
+        if (empty($value)) {
+            unset($this->currentKeyIdentifier);
+        } else {
+            $this->currentKeyIdentifier = base64_encode($value);
+        }
+    }
+
+    /**
+     * Compute a public key identifier.
+     *
+     * Although key identifiers may be set to any unique value, this function
+     * computes key identifiers from public key according to the two
+     * recommended methods (4.2.1.2 RFC 3280).
+     * Highly polymorphic: try to accept all possible forms of key:
+     * - Key object
+     * - \phpseclib\File\X509 object with public or private key defined
+     * - Certificate or CSR array
+     * - \phpseclib\File\ASN1\Element object
+     * - PEM or DER string
+     *
+     * @param mixed $key optional
+     * @param int $method optional
+     * @access public
+     * @return string binary key identifier
+     */
+    function computeKeyIdentifier($key = null, $method = 1)
+    {
+        if (is_null($key)) {
+            $key = $this;
+        }
+
+        switch (true) {
+            case is_string($key):
+                break;
+            case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']):
+                return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method);
+            case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']):
+                return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method);
+            case !is_object($key):
+                return false;
+            case $key instanceof Element:
+                // Assume the element is a bitstring-packed key.
+                $asn1 = new ASN1();
+                $decoded = $asn1->decodeBER($key->element);
+                if (empty($decoded)) {
+                    return false;
+                }
+                $raw = $asn1->asn1map($decoded[0], array('type' => ASN1::TYPE_BIT_STRING));
+                if (empty($raw)) {
+                    return false;
+                }
+                $raw = base64_decode($raw);
+                // If the key is private, compute identifier from its corresponding public key.
+                $key = new RSA();
+                if (!$key->loadKey($raw)) {
+                    return false;   // Not an unencrypted RSA key.
+                }
+                if ($key->getPrivateKey() !== false) {  // If private.
+                    return $this->computeKeyIdentifier($key, $method);
+                }
+                $key = $raw;    // Is a public key.
+                break;
+            case $key instanceof X509:
+                if (isset($key->publicKey)) {
+                    return $this->computeKeyIdentifier($key->publicKey, $method);
+                }
+                if (isset($key->privateKey)) {
+                    return $this->computeKeyIdentifier($key->privateKey, $method);
+                }
+                if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) {
+                    return $this->computeKeyIdentifier($key->currentCert, $method);
+                }
+                return false;
+            default: // Should be a key object (i.e.: \phpseclib\Crypt\RSA).
+                $key = $key->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1);
+                break;
+        }
+
+        // If in PEM format, convert to binary.
+        $key = $this->_extractBER($key);
+
+        // Now we have the key string: compute its sha-1 sum.
+        $hash = new Hash('sha1');
+        $hash = $hash->hash($key);
+
+        if ($method == 2) {
+            $hash = substr($hash, -8);
+            $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40);
+        }
+
+        return $hash;
+    }
+
+    /**
+     * Format a public key as appropriate
+     *
+     * @access private
+     * @return array
+     */
+    function _formatSubjectPublicKey()
+    {
+        if ($this->publicKey instanceof RSA) {
+            // the following two return statements do the same thing. i dunno.. i just prefer the later for some reason.
+            // the former is a good example of how to do fuzzing on the public key
+            //return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey())));
+            return array(
+                'algorithm' => array('algorithm' => 'rsaEncryption'),
+                'subjectPublicKey' => $this->publicKey->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1)
+            );
+        }
+
+        return false;
+    }
+
+    /**
+     * Set the domain name's which the cert is to be valid for
+     *
+     * @access public
+     * @return array
+     */
+    function setDomain()
+    {
+        $this->domains = func_get_args();
+        $this->removeDNProp('id-at-commonName');
+        $this->setDNProp('id-at-commonName', $this->domains[0]);
+    }
+
+    /**
+     * Set the IP Addresses's which the cert is to be valid for
+     *
+     * @access public
+     */
+    function setIPAddress()
+    {
+        $this->ipAddresses = func_get_args();
+        /*
+        if (!isset($this->domains)) {
+            $this->removeDNProp('id-at-commonName');
+            $this->setDNProp('id-at-commonName', $this->ipAddresses[0]);
+        }
+        */
+    }
+
+    /**
+     * Helper function to build domain array
+     *
+     * @access private
+     * @param string $domain
+     * @return array
+     */
+    function _dnsName($domain)
+    {
+        return array('dNSName' => $domain);
+    }
+
+    /**
+     * Helper function to build IP Address array
+     *
+     * (IPv6 is not currently supported)
+     *
+     * @access private
+     * @param string $address
+     * @return array
+     */
+    function _iPAddress($address)
+    {
+        return array('iPAddress' => $address);
+    }
+
+    /**
+     * Get the index of a revoked certificate.
+     *
+     * @param array $rclist
+     * @param string $serial
+     * @param bool $create optional
+     * @access private
+     * @return int|false
+     */
+    function _revokedCertificate(&$rclist, $serial, $create = false)
+    {
+        $serial = new BigInteger($serial);
+
+        foreach ($rclist as $i => $rc) {
+            if (!($serial->compare($rc['userCertificate']))) {
+                return $i;
+            }
+        }
+
+        if (!$create) {
+            return false;
+        }
+
+        $i = count($rclist);
+        $revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+        $rclist[] = array('userCertificate' => $serial,
+                          'revocationDate'  => $this->_timeField($revocationDate->format('D, d M Y H:i:s O')));
+        return $i;
+    }
+
+    /**
+     * Revoke a certificate.
+     *
+     * @param string $serial
+     * @param string $date optional
+     * @access public
+     * @return bool
+     */
+    function revoke($serial, $date = null)
+    {
+        if (isset($this->currentCert['tbsCertList'])) {
+            if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) {
+                if ($this->_revokedCertificate($rclist, $serial) === false) { // If not yet revoked
+                    if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) {
+                        if (!empty($date)) {
+                            $rclist[$i]['revocationDate'] = $this->_timeField($date);
+                        }
+
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Unrevoke a certificate.
+     *
+     * @param string $serial
+     * @access public
+     * @return bool
+     */
+    function unrevoke($serial)
+    {
+        if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) {
+            if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+                unset($rclist[$i]);
+                $rclist = array_values($rclist);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Get a revoked certificate.
+     *
+     * @param string $serial
+     * @access public
+     * @return mixed
+     */
+    function getRevoked($serial)
+    {
+        if (is_array($rclist = $this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) {
+            if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+                return $rclist[$i];
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * List revoked certificates
+     *
+     * @param array $crl optional
+     * @access public
+     * @return array
+     */
+    function listRevoked($crl = null)
+    {
+        if (!isset($crl)) {
+            $crl = $this->currentCert;
+        }
+
+        if (!isset($crl['tbsCertList'])) {
+            return false;
+        }
+
+        $result = array();
+
+        if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
+            foreach ($rclist as $rc) {
+                $result[] = $rc['userCertificate']->toString();
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Remove a Revoked Certificate Extension
+     *
+     * @param string $serial
+     * @param string $id
+     * @access public
+     * @return bool
+     */
+    function removeRevokedCertificateExtension($serial, $id)
+    {
+        if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) {
+            if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+                return $this->_removeExtension($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Get a Revoked Certificate Extension
+     *
+     * Returns the extension if it exists and false if not
+     *
+     * @param string $serial
+     * @param string $id
+     * @param array $crl optional
+     * @access public
+     * @return mixed
+     */
+    function getRevokedCertificateExtension($serial, $id, $crl = null)
+    {
+        if (!isset($crl)) {
+            $crl = $this->currentCert;
+        }
+
+        if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
+            if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+                return $this->_getExtension($id, $crl,  "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a list of all extensions in use for a given revoked certificate
+     *
+     * @param string $serial
+     * @param array $crl optional
+     * @access public
+     * @return array
+     */
+    function getRevokedCertificateExtensions($serial, $crl = null)
+    {
+        if (!isset($crl)) {
+            $crl = $this->currentCert;
+        }
+
+        if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
+            if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+                return $this->_getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Set a Revoked Certificate Extension
+     *
+     * @param string $serial
+     * @param string $id
+     * @param mixed $value
+     * @param bool $critical optional
+     * @param bool $replace optional
+     * @access public
+     * @return bool
+     */
+    function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true)
+    {
+        if (isset($this->currentCert['tbsCertList'])) {
+            if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) {
+                if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) {
+                    return $this->_setExtension($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Extract raw BER from Base64 encoding
+     *
+     * @access private
+     * @param string $str
+     * @return string
+     */
+    function _extractBER($str)
+    {
+        /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
+         * above and beyond the ceritificate.
+         * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
+         *
+         * Bag Attributes
+         *     localKeyID: 01 00 00 00
+         * subject=/O=organization/OU=org unit/CN=common name
+         * issuer=/O=organization/CN=common name
+         */
+        if (strlen($str) > ini_get('pcre.backtrack_limit')) {
+            $temp = $str;
+        } else {
+            $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
+            $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1);
+        }
+        // remove new lines
+        $temp = str_replace(array("\r", "\n", ' '), '', $temp);
+        // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
+        $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp);
+        $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
+        return $temp != false ? $temp : $str;
+    }
+
+    /**
+     * Returns the OID corresponding to a name
+     *
+     * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if
+     * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version
+     * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able
+     * to work from version to version.
+     *
+     * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that
+     * what's being passed to it already is an OID and return that instead. A few examples.
+     *
+     * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1'
+     * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1'
+     * getOID('zzz') == 'zzz'
+     *
+     * @access public
+     * @return string
+     */
+    function getOID($name)
+    {
+        static $reverseMap;
+        if (!isset($reverseMap)) {
+            $reverseMap = array_flip($this->oids);
+        }
+        return isset($reverseMap[$name]) ? $reverseMap[$name] : $name;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
new file mode 100644
index 00000000..8d1291db
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
@@ -0,0 +1,3787 @@
+<?php
+
+/**
+ * Pure-PHP arbitrary precision integer arithmetic library.
+ *
+ * Supports base-2, base-10, base-16, and base-256 numbers.  Uses the GMP or BCMath extensions, if available,
+ * and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
+ * {@link self::MODE_INTERNAL self::MODE_INTERNAL} mode)
+ *
+ * BigInteger uses base-2**26 to perform operations such as multiplication and division and
+ * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction.  Because the largest possible
+ * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating
+ * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are
+ * used.  As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,
+ * which only supports integers.  Although this fact will slow this library down, the fact that such a high
+ * base is being used should more than compensate.
+ *
+ * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format.  ie.
+ * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1)
+ *
+ * Useful resources are as follows:
+ *
+ *  - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}
+ *  - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}
+ *  - Java's BigInteger classes.  See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip
+ *
+ * Here's an example of how to use this library:
+ * <code>
+ * <?php
+ *    $a = new \phpseclib\Math\BigInteger(2);
+ *    $b = new \phpseclib\Math\BigInteger(3);
+ *
+ *    $c = $a->add($b);
+ *
+ *    echo $c->toString(); // outputs 5
+ * ?>
+ * </code>
+ *
+ * @category  Math
+ * @package   BigInteger
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2006 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ */
+
+namespace phpseclib\Math;
+
+use phpseclib\Crypt\Random;
+
+/**
+ * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
+ * numbers.
+ *
+ * @package BigInteger
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class BigInteger
+{
+    /**#@+
+     * Reduction constants
+     *
+     * @access private
+     * @see BigInteger::_reduce()
+     */
+    /**
+     * @see BigInteger::_montgomery()
+     * @see BigInteger::_prepMontgomery()
+     */
+    const MONTGOMERY = 0;
+    /**
+     * @see BigInteger::_barrett()
+     */
+    const BARRETT = 1;
+    /**
+     * @see BigInteger::_mod2()
+     */
+    const POWEROF2 = 2;
+    /**
+     * @see BigInteger::_remainder()
+     */
+    const CLASSIC = 3;
+    /**
+     * @see BigInteger::__clone()
+     */
+    const NONE = 4;
+    /**#@-*/
+
+    /**#@+
+     * Array constants
+     *
+     * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and
+     * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.
+     *
+     * @access private
+    */
+    /**
+     * $result[self::VALUE] contains the value.
+     */
+    const VALUE = 0;
+    /**
+     * $result[self::SIGN] contains the sign.
+     */
+    const SIGN = 1;
+    /**#@-*/
+
+    /**#@+
+     * @access private
+     * @see BigInteger::_montgomery()
+     * @see BigInteger::_barrett()
+    */
+    /**
+     * Cache constants
+     *
+     * $cache[self::VARIABLE] tells us whether or not the cached data is still valid.
+     */
+    const VARIABLE = 0;
+    /**
+     * $cache[self::DATA] contains the cached data.
+     */
+    const DATA = 1;
+    /**#@-*/
+
+    /**#@+
+     * Mode constants.
+     *
+     * @access private
+     * @see BigInteger::__construct()
+    */
+    /**
+     * To use the pure-PHP implementation
+     */
+    const MODE_INTERNAL = 1;
+    /**
+     * To use the BCMath library
+     *
+     * (if enabled; otherwise, the internal implementation will be used)
+     */
+    const MODE_BCMATH = 2;
+    /**
+     * To use the GMP library
+     *
+     * (if present; otherwise, either the BCMath or the internal implementation will be used)
+     */
+    const MODE_GMP = 3;
+    /**#@-*/
+
+    /**
+     * Karatsuba Cutoff
+     *
+     * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?
+     *
+     * @access private
+     */
+    const KARATSUBA_CUTOFF = 25;
+
+    /**#@+
+     * Static properties used by the pure-PHP implementation.
+     *
+     * @see __construct()
+     */
+    protected static $base;
+    protected static $baseFull;
+    protected static $maxDigit;
+    protected static $msb;
+
+    /**
+     * $max10 in greatest $max10Len satisfying
+     * $max10 = 10**$max10Len <= 2**$base.
+     */
+    protected static $max10;
+
+    /**
+     * $max10Len in greatest $max10Len satisfying
+     * $max10 = 10**$max10Len <= 2**$base.
+     */
+    protected static $max10Len;
+    protected static $maxDigit2;
+    /**#@-*/
+
+    /**
+     * Holds the BigInteger's value.
+     *
+     * @var array
+     * @access private
+     */
+    var $value;
+
+    /**
+     * Holds the BigInteger's magnitude.
+     *
+     * @var bool
+     * @access private
+     */
+    var $is_negative = false;
+
+    /**
+     * Precision
+     *
+     * @see self::setPrecision()
+     * @access private
+     */
+    var $precision = -1;
+
+    /**
+     * Precision Bitmask
+     *
+     * @see self::setPrecision()
+     * @access private
+     */
+    var $bitmask = false;
+
+    /**
+     * Mode independent value used for serialization.
+     *
+     * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
+     * a variable that'll be serializable regardless of whether or not extensions are being used.  Unlike $this->value,
+     * however, $this->hex is only calculated when $this->__sleep() is called.
+     *
+     * @see self::__sleep()
+     * @see self::__wakeup()
+     * @var string
+     * @access private
+     */
+    var $hex;
+
+    /**
+     * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
+     *
+     * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
+     * two's compliment.  The sole exception to this is -10, which is treated the same as 10 is.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('0x32', 16); // 50 in base-16
+     *
+     *    echo $a->toString(); // outputs 50
+     * ?>
+     * </code>
+     *
+     * @param int|string|resource $x base-10 number or base-$base number if $base set.
+     * @param int $base
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function __construct($x = 0, $base = 10)
+    {
+        if (!defined('MATH_BIGINTEGER_MODE')) {
+            switch (true) {
+                case extension_loaded('gmp'):
+                    define('MATH_BIGINTEGER_MODE', self::MODE_GMP);
+                    break;
+                case extension_loaded('bcmath'):
+                    define('MATH_BIGINTEGER_MODE', self::MODE_BCMATH);
+                    break;
+                default:
+                    define('MATH_BIGINTEGER_MODE', self::MODE_INTERNAL);
+            }
+        }
+
+        if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+            // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
+            $versions = array();
+
+            // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
+            if (function_exists('phpinfo')) {
+                ob_start();
+                @phpinfo();
+                $content = ob_get_contents();
+                ob_end_clean();
+
+                preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
+
+                if (!empty($matches[1])) {
+                    for ($i = 0; $i < count($matches[1]); $i++) {
+                        $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
+
+                        // Remove letter part in OpenSSL version
+                        if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
+                            $versions[$matches[1][$i]] = $fullVersion;
+                        } else {
+                            $versions[$matches[1][$i]] = $m[0];
+                        }
+                    }
+                }
+            }
+
+            // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
+            switch (true) {
+                case !isset($versions['Header']):
+                case !isset($versions['Library']):
+                case $versions['Header'] == $versions['Library']:
+                case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
+                    define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
+                    break;
+                default:
+                    define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
+            }
+        }
+
+        if (!defined('PHP_INT_SIZE')) {
+            define('PHP_INT_SIZE', 4);
+        }
+
+        if (empty(self::$base) && MATH_BIGINTEGER_MODE == self::MODE_INTERNAL) {
+            switch (PHP_INT_SIZE) {
+                case 8: // use 64-bit integers if int size is 8 bytes
+                    self::$base      = 31;
+                    self::$baseFull  = 0x80000000;
+                    self::$maxDigit  = 0x7FFFFFFF;
+                    self::$msb       = 0x40000000;
+                    self::$max10     = 1000000000;
+                    self::$max10Len  = 9;
+                    self::$maxDigit2 = pow(2, 62);
+                    break;
+                //case 4: // use 64-bit floats if int size is 4 bytes
+                default:
+                    self::$base      = 26;
+                    self::$baseFull  = 0x4000000;
+                    self::$maxDigit  = 0x3FFFFFF;
+                    self::$msb       = 0x2000000;
+                    self::$max10     = 10000000;
+                    self::$max10Len  = 7;
+                    self::$maxDigit2 = pow(2, 52); // pow() prevents truncation
+            }
+        }
+
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                switch (true) {
+                    case is_resource($x) && get_resource_type($x) == 'GMP integer':
+                    // PHP 5.6 switched GMP from using resources to objects
+                    case $x instanceof \GMP:
+                        $this->value = $x;
+                        return;
+                }
+                $this->value = gmp_init(0);
+                break;
+            case self::MODE_BCMATH:
+                $this->value = '0';
+                break;
+            default:
+                $this->value = array();
+        }
+
+        // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48
+        // '0' is the only value like this per http://php.net/empty
+        if (empty($x) && (abs($base) != 256 || $x !== '0')) {
+            return;
+        }
+
+        switch ($base) {
+            case -256:
+                if (ord($x[0]) & 0x80) {
+                    $x = ~$x;
+                    $this->is_negative = true;
+                }
+            case 256:
+                switch (MATH_BIGINTEGER_MODE) {
+                    case self::MODE_GMP:
+                        $this->value = function_exists('gmp_import') ?
+                            gmp_import($x) :
+                            gmp_init('0x' . bin2hex($x));
+                        if ($this->is_negative) {
+                            $this->value = gmp_neg($this->value);
+                        }
+                        break;
+                    case self::MODE_BCMATH:
+                        // round $len to the nearest 4 (thanks, DavidMJ!)
+                        $len = (strlen($x) + 3) & ~3;
+
+                        $x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
+
+                        for ($i = 0; $i < $len; $i+= 4) {
+                            $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32
+                            $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);
+                        }
+
+                        if ($this->is_negative) {
+                            $this->value = '-' . $this->value;
+                        }
+
+                        break;
+                    // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
+                    default:
+                        while (strlen($x)) {
+                            $this->value[] = $this->_bytes2int($this->_base256_rshift($x, self::$base));
+                        }
+                }
+
+                if ($this->is_negative) {
+                    if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+                        $this->is_negative = false;
+                    }
+                    $temp = $this->add(new static('-1'));
+                    $this->value = $temp->value;
+                }
+                break;
+            case 16:
+            case -16:
+                if ($base > 0 && $x[0] == '-') {
+                    $this->is_negative = true;
+                    $x = substr($x, 1);
+                }
+
+                $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
+
+                $is_negative = false;
+                if ($base < 0 && hexdec($x[0]) >= 8) {
+                    $this->is_negative = $is_negative = true;
+                    $x = bin2hex(~pack('H*', $x));
+                }
+
+                switch (MATH_BIGINTEGER_MODE) {
+                    case self::MODE_GMP:
+                        $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
+                        $this->value = gmp_init($temp);
+                        $this->is_negative = false;
+                        break;
+                    case self::MODE_BCMATH:
+                        $x = (strlen($x) & 1) ? '0' . $x : $x;
+                        $temp = new static(pack('H*', $x), 256);
+                        $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
+                        $this->is_negative = false;
+                        break;
+                    default:
+                        $x = (strlen($x) & 1) ? '0' . $x : $x;
+                        $temp = new static(pack('H*', $x), 256);
+                        $this->value = $temp->value;
+                }
+
+                if ($is_negative) {
+                    $temp = $this->add(new static('-1'));
+                    $this->value = $temp->value;
+                }
+                break;
+            case 10:
+            case -10:
+                // (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
+                // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
+                // [^-0-9].*: find any non-numeric characters and then any characters that follow that
+                $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
+                if (!strlen($x) || $x == '-') {
+                    $x = '0';
+                }
+
+                switch (MATH_BIGINTEGER_MODE) {
+                    case self::MODE_GMP:
+                        $this->value = gmp_init($x);
+                        break;
+                    case self::MODE_BCMATH:
+                        // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
+                        // results then doing it on '-1' does (modInverse does $x[0])
+                        $this->value = $x === '-' ? '0' : (string) $x;
+                        break;
+                    default:
+                        $temp = new static();
+
+                        $multiplier = new static();
+                        $multiplier->value = array(self::$max10);
+
+                        if ($x[0] == '-') {
+                            $this->is_negative = true;
+                            $x = substr($x, 1);
+                        }
+
+                        $x = str_pad($x, strlen($x) + ((self::$max10Len - 1) * strlen($x)) % self::$max10Len, 0, STR_PAD_LEFT);
+                        while (strlen($x)) {
+                            $temp = $temp->multiply($multiplier);
+                            $temp = $temp->add(new static($this->_int2bytes(substr($x, 0, self::$max10Len)), 256));
+                            $x = substr($x, self::$max10Len);
+                        }
+
+                        $this->value = $temp->value;
+                }
+                break;
+            case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
+            case -2:
+                if ($base > 0 && $x[0] == '-') {
+                    $this->is_negative = true;
+                    $x = substr($x, 1);
+                }
+
+                $x = preg_replace('#^([01]*).*#', '$1', $x);
+                $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
+
+                $str = '0x';
+                while (strlen($x)) {
+                    $part = substr($x, 0, 4);
+                    $str.= dechex(bindec($part));
+                    $x = substr($x, 4);
+                }
+
+                if ($this->is_negative) {
+                    $str = '-' . $str;
+                }
+
+                $temp = new static($str, 8 * $base); // ie. either -16 or +16
+                $this->value = $temp->value;
+                $this->is_negative = $temp->is_negative;
+
+                break;
+            default:
+                // base not supported, so we'll let $this == 0
+        }
+    }
+
+    /**
+     * Converts a BigInteger to a byte string (eg. base-256).
+     *
+     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
+     * saved as two's compliment.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('65');
+     *
+     *    echo $a->toBytes(); // outputs chr(65)
+     * ?>
+     * </code>
+     *
+     * @param bool $twos_compliment
+     * @return string
+     * @access public
+     * @internal Converts a base-2**26 number to base-2**8
+     */
+    function toBytes($twos_compliment = false)
+    {
+        if ($twos_compliment) {
+            $comparison = $this->compare(new static());
+            if ($comparison == 0) {
+                return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+            }
+
+            $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
+            $bytes = $temp->toBytes();
+
+            if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1
+                $bytes = chr(0);
+            }
+
+            if ($this->precision <= 0 && (ord($bytes[0]) & 0x80)) {
+                $bytes = chr(0) . $bytes;
+            }
+
+            return $comparison < 0 ? ~$bytes : $bytes;
+        }
+
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                if (gmp_cmp($this->value, gmp_init(0)) == 0) {
+                    return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+                }
+
+                if (function_exists('gmp_export')) {
+                    $temp = gmp_export($this->value);
+                } else {
+                    $temp = gmp_strval(gmp_abs($this->value), 16);
+                    $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
+                    $temp = pack('H*', $temp);
+                }
+
+                return $this->precision > 0 ?
+                    substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
+                    ltrim($temp, chr(0));
+            case self::MODE_BCMATH:
+                if ($this->value === '0') {
+                    return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+                }
+
+                $value = '';
+                $current = $this->value;
+
+                if ($current[0] == '-') {
+                    $current = substr($current, 1);
+                }
+
+                while (bccomp($current, '0', 0) > 0) {
+                    $temp = bcmod($current, '16777216');
+                    $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
+                    $current = bcdiv($current, '16777216', 0);
+                }
+
+                return $this->precision > 0 ?
+                    substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
+                    ltrim($value, chr(0));
+        }
+
+        if (!count($this->value)) {
+            return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+        }
+        $result = $this->_int2bytes($this->value[count($this->value) - 1]);
+
+        $temp = $this->copy();
+
+        for ($i = count($temp->value) - 2; $i >= 0; --$i) {
+            $temp->_base256_lshift($result, self::$base);
+            $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
+        }
+
+        return $this->precision > 0 ?
+            str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :
+            $result;
+    }
+
+    /**
+     * Converts a BigInteger to a hex string (eg. base-16)).
+     *
+     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
+     * saved as two's compliment.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('65');
+     *
+     *    echo $a->toHex(); // outputs '41'
+     * ?>
+     * </code>
+     *
+     * @param bool $twos_compliment
+     * @return string
+     * @access public
+     * @internal Converts a base-2**26 number to base-2**8
+     */
+    function toHex($twos_compliment = false)
+    {
+        return bin2hex($this->toBytes($twos_compliment));
+    }
+
+    /**
+     * Converts a BigInteger to a bit string (eg. base-2).
+     *
+     * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
+     * saved as two's compliment.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('65');
+     *
+     *    echo $a->toBits(); // outputs '1000001'
+     * ?>
+     * </code>
+     *
+     * @param bool $twos_compliment
+     * @return string
+     * @access public
+     * @internal Converts a base-2**26 number to base-2**2
+     */
+    function toBits($twos_compliment = false)
+    {
+        $hex = $this->toHex($twos_compliment);
+        $bits = '';
+        for ($i = strlen($hex) - 6, $start = strlen($hex) % 6; $i >= $start; $i-=6) {
+            $bits = str_pad(decbin(hexdec(substr($hex, $i, 6))), 24, '0', STR_PAD_LEFT) . $bits;
+        }
+        if ($start) { // hexdec('') == 0
+            $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8 * $start, '0', STR_PAD_LEFT) . $bits;
+        }
+        $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
+
+        if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) {
+            return '0' . $result;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Converts a BigInteger to a base-10 number.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('50');
+     *
+     *    echo $a->toString(); // outputs 50
+     * ?>
+     * </code>
+     *
+     * @return string
+     * @access public
+     * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
+     */
+    function toString()
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                return gmp_strval($this->value);
+            case self::MODE_BCMATH:
+                if ($this->value === '0') {
+                    return '0';
+                }
+
+                return ltrim($this->value, '0');
+        }
+
+        if (!count($this->value)) {
+            return '0';
+        }
+
+        $temp = $this->copy();
+        $temp->bitmask = false;
+        $temp->is_negative = false;
+
+        $divisor = new static();
+        $divisor->value = array(self::$max10);
+        $result = '';
+        while (count($temp->value)) {
+            list($temp, $mod) = $temp->divide($divisor);
+            $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', self::$max10Len, '0', STR_PAD_LEFT) . $result;
+        }
+        $result = ltrim($result, '0');
+        if (empty($result)) {
+            $result = '0';
+        }
+
+        if ($this->is_negative) {
+            $result = '-' . $result;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Copy an object
+     *
+     * PHP5 passes objects by reference while PHP4 passes by value.  As such, we need a function to guarantee
+     * that all objects are passed by value, when appropriate.  More information can be found here:
+     *
+     * {@link http://php.net/language.oop5.basic#51624}
+     *
+     * @access public
+     * @see self::__clone()
+     * @return \phpseclib\Math\BigInteger
+     */
+    function copy()
+    {
+        $temp = new static();
+        $temp->value = $this->value;
+        $temp->is_negative = $this->is_negative;
+        $temp->precision = $this->precision;
+        $temp->bitmask = $this->bitmask;
+        return $temp;
+    }
+
+    /**
+     *  __toString() magic method
+     *
+     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call
+     * toString().
+     *
+     * @access public
+     * @internal Implemented per a suggestion by Techie-Michael - thanks!
+     */
+    function __toString()
+    {
+        return $this->toString();
+    }
+
+    /**
+     * __clone() magic method
+     *
+     * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly
+     * in PHP5.  You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5
+     * only syntax of $y = clone $x.  As such, if you're trying to write an application that works on both PHP4 and
+     * PHP5, call BigInteger::copy(), instead.
+     *
+     * @access public
+     * @see self::copy()
+     * @return \phpseclib\Math\BigInteger
+     */
+    function __clone()
+    {
+        return $this->copy();
+    }
+
+    /**
+     *  __sleep() magic method
+     *
+     * Will be called, automatically, when serialize() is called on a BigInteger object.
+     *
+     * @see self::__wakeup()
+     * @access public
+     */
+    function __sleep()
+    {
+        $this->hex = $this->toHex(true);
+        $vars = array('hex');
+        if ($this->precision > 0) {
+            $vars[] = 'precision';
+        }
+        return $vars;
+    }
+
+    /**
+     *  __wakeup() magic method
+     *
+     * Will be called, automatically, when unserialize() is called on a BigInteger object.
+     *
+     * @see self::__sleep()
+     * @access public
+     */
+    function __wakeup()
+    {
+        $temp = new static($this->hex, -16);
+        $this->value = $temp->value;
+        $this->is_negative = $temp->is_negative;
+        if ($this->precision > 0) {
+            // recalculate $this->bitmask
+            $this->setPrecision($this->precision);
+        }
+    }
+
+    /**
+     *  __debugInfo() magic method
+     *
+     * Will be called, automatically, when print_r() or var_dump() are called
+     *
+     * @access public
+     */
+    function __debugInfo()
+    {
+        $opts = array();
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $engine = 'gmp';
+                break;
+            case self::MODE_BCMATH:
+                $engine = 'bcmath';
+                break;
+            case self::MODE_INTERNAL:
+                $engine = 'internal';
+                $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit';
+        }
+        if (MATH_BIGINTEGER_MODE != self::MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+            $opts[] = 'OpenSSL';
+        }
+        if (!empty($opts)) {
+            $engine.= ' (' . implode('.', $opts) . ')';
+        }
+        return array(
+            'value' => '0x' . $this->toHex(true),
+            'engine' => $engine
+        );
+    }
+
+    /**
+     * Adds two BigIntegers.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('10');
+     *    $b = new \phpseclib\Math\BigInteger('20');
+     *
+     *    $c = $a->add($b);
+     *
+     *    echo $c->toString(); // outputs 30
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $y
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal Performs base-2**52 addition
+     */
+    function add($y)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_add($this->value, $y->value);
+
+                return $this->_normalize($temp);
+            case self::MODE_BCMATH:
+                $temp = new static();
+                $temp->value = bcadd($this->value, $y->value, 0);
+
+                return $this->_normalize($temp);
+        }
+
+        $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);
+
+        $result = new static();
+        $result->value = $temp[self::VALUE];
+        $result->is_negative = $temp[self::SIGN];
+
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Performs addition.
+     *
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return array
+     * @access private
+     */
+    function _add($x_value, $x_negative, $y_value, $y_negative)
+    {
+        $x_size = count($x_value);
+        $y_size = count($y_value);
+
+        if ($x_size == 0) {
+            return array(
+                self::VALUE => $y_value,
+                self::SIGN => $y_negative
+            );
+        } elseif ($y_size == 0) {
+            return array(
+                self::VALUE => $x_value,
+                self::SIGN => $x_negative
+            );
+        }
+
+        // subtract, if appropriate
+        if ($x_negative != $y_negative) {
+            if ($x_value == $y_value) {
+                return array(
+                    self::VALUE => array(),
+                    self::SIGN => false
+                );
+            }
+
+            $temp = $this->_subtract($x_value, false, $y_value, false);
+            $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?
+                                          $x_negative : $y_negative;
+
+            return $temp;
+        }
+
+        if ($x_size < $y_size) {
+            $size = $x_size;
+            $value = $y_value;
+        } else {
+            $size = $y_size;
+            $value = $x_value;
+        }
+
+        $value[count($value)] = 0; // just in case the carry adds an extra digit
+
+        $carry = 0;
+        for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
+            $sum = $x_value[$j] * self::$baseFull + $x_value[$i] + $y_value[$j] * self::$baseFull + $y_value[$i] + $carry;
+            $carry = $sum >= self::$maxDigit2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
+            $sum = $carry ? $sum - self::$maxDigit2 : $sum;
+
+            $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
+
+            $value[$i] = (int) ($sum - self::$baseFull * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
+            $value[$j] = $temp;
+        }
+
+        if ($j == $size) { // ie. if $y_size is odd
+            $sum = $x_value[$i] + $y_value[$i] + $carry;
+            $carry = $sum >= self::$baseFull;
+            $value[$i] = $carry ? $sum - self::$baseFull : $sum;
+            ++$i; // ie. let $i = $j since we've just done $value[$i]
+        }
+
+        if ($carry) {
+            for (; $value[$i] == self::$maxDigit; ++$i) {
+                $value[$i] = 0;
+            }
+            ++$value[$i];
+        }
+
+        return array(
+            self::VALUE => $this->_trim($value),
+            self::SIGN => $x_negative
+        );
+    }
+
+    /**
+     * Subtracts two BigIntegers.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('10');
+     *    $b = new \phpseclib\Math\BigInteger('20');
+     *
+     *    $c = $a->subtract($b);
+     *
+     *    echo $c->toString(); // outputs -10
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $y
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal Performs base-2**52 subtraction
+     */
+    function subtract($y)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_sub($this->value, $y->value);
+
+                return $this->_normalize($temp);
+            case self::MODE_BCMATH:
+                $temp = new static();
+                $temp->value = bcsub($this->value, $y->value, 0);
+
+                return $this->_normalize($temp);
+        }
+
+        $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);
+
+        $result = new static();
+        $result->value = $temp[self::VALUE];
+        $result->is_negative = $temp[self::SIGN];
+
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Performs subtraction.
+     *
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return array
+     * @access private
+     */
+    function _subtract($x_value, $x_negative, $y_value, $y_negative)
+    {
+        $x_size = count($x_value);
+        $y_size = count($y_value);
+
+        if ($x_size == 0) {
+            return array(
+                self::VALUE => $y_value,
+                self::SIGN => !$y_negative
+            );
+        } elseif ($y_size == 0) {
+            return array(
+                self::VALUE => $x_value,
+                self::SIGN => $x_negative
+            );
+        }
+
+        // add, if appropriate (ie. -$x - +$y or +$x - -$y)
+        if ($x_negative != $y_negative) {
+            $temp = $this->_add($x_value, false, $y_value, false);
+            $temp[self::SIGN] = $x_negative;
+
+            return $temp;
+        }
+
+        $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
+
+        if (!$diff) {
+            return array(
+                self::VALUE => array(),
+                self::SIGN => false
+            );
+        }
+
+        // switch $x and $y around, if appropriate.
+        if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) {
+            $temp = $x_value;
+            $x_value = $y_value;
+            $y_value = $temp;
+
+            $x_negative = !$x_negative;
+
+            $x_size = count($x_value);
+            $y_size = count($y_value);
+        }
+
+        // at this point, $x_value should be at least as big as - if not bigger than - $y_value
+
+        $carry = 0;
+        for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
+            $sum = $x_value[$j] * self::$baseFull + $x_value[$i] - $y_value[$j] * self::$baseFull - $y_value[$i] - $carry;
+            $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
+            $sum = $carry ? $sum + self::$maxDigit2 : $sum;
+
+            $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
+
+            $x_value[$i] = (int) ($sum - self::$baseFull * $temp);
+            $x_value[$j] = $temp;
+        }
+
+        if ($j == $y_size) { // ie. if $y_size is odd
+            $sum = $x_value[$i] - $y_value[$i] - $carry;
+            $carry = $sum < 0;
+            $x_value[$i] = $carry ? $sum + self::$baseFull : $sum;
+            ++$i;
+        }
+
+        if ($carry) {
+            for (; !$x_value[$i]; ++$i) {
+                $x_value[$i] = self::$maxDigit;
+            }
+            --$x_value[$i];
+        }
+
+        return array(
+            self::VALUE => $this->_trim($x_value),
+            self::SIGN => $x_negative
+        );
+    }
+
+    /**
+     * Multiplies two BigIntegers
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('10');
+     *    $b = new \phpseclib\Math\BigInteger('20');
+     *
+     *    $c = $a->multiply($b);
+     *
+     *    echo $c->toString(); // outputs 200
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $x
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function multiply($x)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_mul($this->value, $x->value);
+
+                return $this->_normalize($temp);
+            case self::MODE_BCMATH:
+                $temp = new static();
+                $temp->value = bcmul($this->value, $x->value, 0);
+
+                return $this->_normalize($temp);
+        }
+
+        $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);
+
+        $product = new static();
+        $product->value = $temp[self::VALUE];
+        $product->is_negative = $temp[self::SIGN];
+
+        return $this->_normalize($product);
+    }
+
+    /**
+     * Performs multiplication.
+     *
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return array
+     * @access private
+     */
+    function _multiply($x_value, $x_negative, $y_value, $y_negative)
+    {
+        //if ( $x_value == $y_value ) {
+        //    return array(
+        //        self::VALUE => $this->_square($x_value),
+        //        self::SIGN => $x_sign != $y_value
+        //    );
+        //}
+
+        $x_length = count($x_value);
+        $y_length = count($y_value);
+
+        if (!$x_length || !$y_length) { // a 0 is being multiplied
+            return array(
+                self::VALUE => array(),
+                self::SIGN => false
+            );
+        }
+
+        return array(
+            self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ?
+                $this->_trim($this->_regularMultiply($x_value, $y_value)) :
+                $this->_trim($this->_karatsuba($x_value, $y_value)),
+            self::SIGN => $x_negative != $y_negative
+        );
+    }
+
+    /**
+     * Performs long multiplication on two BigIntegers
+     *
+     * Modeled after 'multiply' in MutableBigInteger.java.
+     *
+     * @param array $x_value
+     * @param array $y_value
+     * @return array
+     * @access private
+     */
+    function _regularMultiply($x_value, $y_value)
+    {
+        $x_length = count($x_value);
+        $y_length = count($y_value);
+
+        if (!$x_length || !$y_length) { // a 0 is being multiplied
+            return array();
+        }
+
+        if ($x_length < $y_length) {
+            $temp = $x_value;
+            $x_value = $y_value;
+            $y_value = $temp;
+
+            $x_length = count($x_value);
+            $y_length = count($y_value);
+        }
+
+        $product_value = $this->_array_repeat(0, $x_length + $y_length);
+
+        // the following for loop could be removed if the for loop following it
+        // (the one with nested for loops) initially set $i to 0, but
+        // doing so would also make the result in one set of unnecessary adds,
+        // since on the outermost loops first pass, $product->value[$k] is going
+        // to always be 0
+
+        $carry = 0;
+
+        for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
+            $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
+            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+            $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
+        }
+
+        $product_value[$j] = $carry;
+
+        // the above for loop is what the previous comment was talking about.  the
+        // following for loop is the "one with nested for loops"
+        for ($i = 1; $i < $y_length; ++$i) {
+            $carry = 0;
+
+            for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
+                $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
+                $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+                $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
+            }
+
+            $product_value[$k] = $carry;
+        }
+
+        return $product_value;
+    }
+
+    /**
+     * Performs Karatsuba multiplication on two BigIntegers
+     *
+     * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
+     *
+     * @param array $x_value
+     * @param array $y_value
+     * @return array
+     * @access private
+     */
+    function _karatsuba($x_value, $y_value)
+    {
+        $m = min(count($x_value) >> 1, count($y_value) >> 1);
+
+        if ($m < self::KARATSUBA_CUTOFF) {
+            return $this->_regularMultiply($x_value, $y_value);
+        }
+
+        $x1 = array_slice($x_value, $m);
+        $x0 = array_slice($x_value, 0, $m);
+        $y1 = array_slice($y_value, $m);
+        $y0 = array_slice($y_value, 0, $m);
+
+        $z2 = $this->_karatsuba($x1, $y1);
+        $z0 = $this->_karatsuba($x0, $y0);
+
+        $z1 = $this->_add($x1, false, $x0, false);
+        $temp = $this->_add($y1, false, $y0, false);
+        $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]);
+        $temp = $this->_add($z2, false, $z0, false);
+        $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
+
+        $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
+        $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
+
+        $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
+        $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false);
+
+        return $xy[self::VALUE];
+    }
+
+    /**
+     * Performs squaring
+     *
+     * @param array $x
+     * @return array
+     * @access private
+     */
+    function _square($x = false)
+    {
+        return count($x) < 2 * self::KARATSUBA_CUTOFF ?
+            $this->_trim($this->_baseSquare($x)) :
+            $this->_trim($this->_karatsubaSquare($x));
+    }
+
+    /**
+     * Performs traditional squaring on two BigIntegers
+     *
+     * Squaring can be done faster than multiplying a number by itself can be.  See
+     * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
+     *
+     * @param array $value
+     * @return array
+     * @access private
+     */
+    function _baseSquare($value)
+    {
+        if (empty($value)) {
+            return array();
+        }
+        $square_value = $this->_array_repeat(0, 2 * count($value));
+
+        for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {
+            $i2 = $i << 1;
+
+            $temp = $square_value[$i2] + $value[$i] * $value[$i];
+            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+            $square_value[$i2] = (int) ($temp - self::$baseFull * $carry);
+
+            // note how we start from $i+1 instead of 0 as we do in multiplication.
+            for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
+                $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
+                $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+                $square_value[$k] = (int) ($temp - self::$baseFull * $carry);
+            }
+
+            // the following line can yield values larger 2**15.  at this point, PHP should switch
+            // over to floats.
+            $square_value[$i + $max_index + 1] = $carry;
+        }
+
+        return $square_value;
+    }
+
+    /**
+     * Performs Karatsuba "squaring" on two BigIntegers
+     *
+     * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
+     *
+     * @param array $value
+     * @return array
+     * @access private
+     */
+    function _karatsubaSquare($value)
+    {
+        $m = count($value) >> 1;
+
+        if ($m < self::KARATSUBA_CUTOFF) {
+            return $this->_baseSquare($value);
+        }
+
+        $x1 = array_slice($value, $m);
+        $x0 = array_slice($value, 0, $m);
+
+        $z2 = $this->_karatsubaSquare($x1);
+        $z0 = $this->_karatsubaSquare($x0);
+
+        $z1 = $this->_add($x1, false, $x0, false);
+        $z1 = $this->_karatsubaSquare($z1[self::VALUE]);
+        $temp = $this->_add($z2, false, $z0, false);
+        $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
+
+        $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
+        $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
+
+        $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
+        $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false);
+
+        return $xx[self::VALUE];
+    }
+
+    /**
+     * Divides two BigIntegers.
+     *
+     * Returns an array whose first element contains the quotient and whose second element contains the
+     * "common residue".  If the remainder would be positive, the "common residue" and the remainder are the
+     * same.  If the remainder would be negative, the "common residue" is equal to the sum of the remainder
+     * and the divisor (basically, the "common residue" is the first positive modulo).
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('10');
+     *    $b = new \phpseclib\Math\BigInteger('20');
+     *
+     *    list($quotient, $remainder) = $a->divide($b);
+     *
+     *    echo $quotient->toString(); // outputs 0
+     *    echo "\r\n";
+     *    echo $remainder->toString(); // outputs 10
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $y
+     * @return array
+     * @access public
+     * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
+     */
+    function divide($y)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $quotient = new static();
+                $remainder = new static();
+
+                list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
+
+                if (gmp_sign($remainder->value) < 0) {
+                    $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
+                }
+
+                return array($this->_normalize($quotient), $this->_normalize($remainder));
+            case self::MODE_BCMATH:
+                $quotient = new static();
+                $remainder = new static();
+
+                $quotient->value = bcdiv($this->value, $y->value, 0);
+                $remainder->value = bcmod($this->value, $y->value);
+
+                if ($remainder->value[0] == '-') {
+                    $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
+                }
+
+                return array($this->_normalize($quotient), $this->_normalize($remainder));
+        }
+
+        if (count($y->value) == 1) {
+            list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
+            $quotient = new static();
+            $remainder = new static();
+            $quotient->value = $q;
+            $remainder->value = array($r);
+            $quotient->is_negative = $this->is_negative != $y->is_negative;
+            return array($this->_normalize($quotient), $this->_normalize($remainder));
+        }
+
+        static $zero;
+        if (!isset($zero)) {
+            $zero = new static();
+        }
+
+        $x = $this->copy();
+        $y = $y->copy();
+
+        $x_sign = $x->is_negative;
+        $y_sign = $y->is_negative;
+
+        $x->is_negative = $y->is_negative = false;
+
+        $diff = $x->compare($y);
+
+        if (!$diff) {
+            $temp = new static();
+            $temp->value = array(1);
+            $temp->is_negative = $x_sign != $y_sign;
+            return array($this->_normalize($temp), $this->_normalize(new static()));
+        }
+
+        if ($diff < 0) {
+            // if $x is negative, "add" $y.
+            if ($x_sign) {
+                $x = $y->subtract($x);
+            }
+            return array($this->_normalize(new static()), $this->_normalize($x));
+        }
+
+        // normalize $x and $y as described in HAC 14.23 / 14.24
+        $msb = $y->value[count($y->value) - 1];
+        for ($shift = 0; !($msb & self::$msb); ++$shift) {
+            $msb <<= 1;
+        }
+        $x->_lshift($shift);
+        $y->_lshift($shift);
+        $y_value = &$y->value;
+
+        $x_max = count($x->value) - 1;
+        $y_max = count($y->value) - 1;
+
+        $quotient = new static();
+        $quotient_value = &$quotient->value;
+        $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
+
+        static $temp, $lhs, $rhs;
+        if (!isset($temp)) {
+            $temp = new static();
+            $lhs =  new static();
+            $rhs =  new static();
+        }
+        $temp_value = &$temp->value;
+        $rhs_value =  &$rhs->value;
+
+        // $temp = $y << ($x_max - $y_max-1) in base 2**26
+        $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
+
+        while ($x->compare($temp) >= 0) {
+            // calculate the "common residue"
+            ++$quotient_value[$x_max - $y_max];
+            $x = $x->subtract($temp);
+            $x_max = count($x->value) - 1;
+        }
+
+        for ($i = $x_max; $i >= $y_max + 1; --$i) {
+            $x_value = &$x->value;
+            $x_window = array(
+                isset($x_value[$i]) ? $x_value[$i] : 0,
+                isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,
+                isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0
+            );
+            $y_window = array(
+                $y_value[$y_max],
+                ($y_max > 0) ? $y_value[$y_max - 1] : 0
+            );
+
+            $q_index = $i - $y_max - 1;
+            if ($x_window[0] == $y_window[0]) {
+                $quotient_value[$q_index] = self::$maxDigit;
+            } else {
+                $quotient_value[$q_index] = $this->_safe_divide(
+                    $x_window[0] * self::$baseFull + $x_window[1],
+                    $y_window[0]
+                );
+            }
+
+            $temp_value = array($y_window[1], $y_window[0]);
+
+            $lhs->value = array($quotient_value[$q_index]);
+            $lhs = $lhs->multiply($temp);
+
+            $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
+
+            while ($lhs->compare($rhs) > 0) {
+                --$quotient_value[$q_index];
+
+                $lhs->value = array($quotient_value[$q_index]);
+                $lhs = $lhs->multiply($temp);
+            }
+
+            $adjust = $this->_array_repeat(0, $q_index);
+            $temp_value = array($quotient_value[$q_index]);
+            $temp = $temp->multiply($y);
+            $temp_value = &$temp->value;
+            if (count($temp_value)) {
+                $temp_value = array_merge($adjust, $temp_value);
+            }
+
+            $x = $x->subtract($temp);
+
+            if ($x->compare($zero) < 0) {
+                $temp_value = array_merge($adjust, $y_value);
+                $x = $x->add($temp);
+
+                --$quotient_value[$q_index];
+            }
+
+            $x_max = count($x_value) - 1;
+        }
+
+        // unnormalize the remainder
+        $x->_rshift($shift);
+
+        $quotient->is_negative = $x_sign != $y_sign;
+
+        // calculate the "common residue", if appropriate
+        if ($x_sign) {
+            $y->_rshift($shift);
+            $x = $y->subtract($x);
+        }
+
+        return array($this->_normalize($quotient), $this->_normalize($x));
+    }
+
+    /**
+     * Divides a BigInteger by a regular integer
+     *
+     * abc / x = a00 / x + b0 / x + c / x
+     *
+     * @param array $dividend
+     * @param array $divisor
+     * @return array
+     * @access private
+     */
+    function _divide_digit($dividend, $divisor)
+    {
+        $carry = 0;
+        $result = array();
+
+        for ($i = count($dividend) - 1; $i >= 0; --$i) {
+            $temp = self::$baseFull * $carry + $dividend[$i];
+            $result[$i] = $this->_safe_divide($temp, $divisor);
+            $carry = (int) ($temp - $divisor * $result[$i]);
+        }
+
+        return array($result, $carry);
+    }
+
+    /**
+     * Performs modular exponentiation.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger('10');
+     *    $b = new \phpseclib\Math\BigInteger('20');
+     *    $c = new \phpseclib\Math\BigInteger('30');
+     *
+     *    $c = $a->modPow($b, $c);
+     *
+     *    echo $c->toString(); // outputs 10
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $e
+     * @param \phpseclib\Math\BigInteger $n
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
+     *    and although the approach involving repeated squaring does vastly better, it, too, is impractical
+     *    for our purposes.  The reason being that division - by far the most complicated and time-consuming
+     *    of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
+     *
+     *    Modular reductions resolve this issue.  Although an individual modular reduction takes more time
+     *    then an individual division, when performed in succession (with the same modulo), they're a lot faster.
+     *
+     *    The two most commonly used modular reductions are Barrett and Montgomery reduction.  Montgomery reduction,
+     *    although faster, only works when the gcd of the modulo and of the base being used is 1.  In RSA, when the
+     *    base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
+     *    the product of two odd numbers is odd), but what about when RSA isn't used?
+     *
+     *    In contrast, Barrett reduction has no such constraint.  As such, some bigint implementations perform a
+     *    Barrett reduction after every operation in the modpow function.  Others perform Barrett reductions when the
+     *    modulo is even and Montgomery reductions when the modulo is odd.  BigInteger.java's modPow method, however,
+     *    uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
+     *    the other, a power of two - and recombine them, later.  This is the method that this modPow function uses.
+     *    {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
+     */
+    function modPow($e, $n)
+    {
+        $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
+
+        if ($e->compare(new static()) < 0) {
+            $e = $e->abs();
+
+            $temp = $this->modInverse($n);
+            if ($temp === false) {
+                return false;
+            }
+
+            return $this->_normalize($temp->modPow($e, $n));
+        }
+
+        if (MATH_BIGINTEGER_MODE == self::MODE_GMP) {
+            $temp = new static();
+            $temp->value = gmp_powm($this->value, $e->value, $n->value);
+
+            return $this->_normalize($temp);
+        }
+
+        if ($this->compare(new static()) < 0 || $this->compare($n) > 0) {
+            list(, $temp) = $this->divide($n);
+            return $temp->modPow($e, $n);
+        }
+
+        if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+            $components = array(
+                'modulus' => $n->toBytes(true),
+                'publicExponent' => $e->toBytes(true)
+            );
+
+            $components = array(
+                'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']),
+                'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
+            );
+
+            $RSAPublicKey = pack(
+                'Ca*a*a*',
+                48,
+                $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
+                $components['modulus'],
+                $components['publicExponent']
+            );
+
+            $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+            $RSAPublicKey = chr(0) . $RSAPublicKey;
+            $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
+
+            $encapsulated = pack(
+                'Ca*a*',
+                48,
+                $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)),
+                $rsaOID . $RSAPublicKey
+            );
+
+            $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
+                             chunk_split(base64_encode($encapsulated)) .
+                             '-----END PUBLIC KEY-----';
+
+            $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT);
+
+            if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
+                return new static($result, 256);
+            }
+        }
+
+        if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
+            $temp = new static();
+            $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
+
+            return $this->_normalize($temp);
+        }
+
+        if (empty($e->value)) {
+            $temp = new static();
+            $temp->value = array(1);
+            return $this->_normalize($temp);
+        }
+
+        if ($e->value == array(1)) {
+            list(, $temp) = $this->divide($n);
+            return $this->_normalize($temp);
+        }
+
+        if ($e->value == array(2)) {
+            $temp = new static();
+            $temp->value = $this->_square($this->value);
+            list(, $temp) = $temp->divide($n);
+            return $this->_normalize($temp);
+        }
+
+        return $this->_normalize($this->_slidingWindow($e, $n, self::BARRETT));
+
+        // the following code, although not callable, can be run independently of the above code
+        // although the above code performed better in my benchmarks the following could might
+        // perform better under different circumstances. in lieu of deleting it it's just been
+        // made uncallable
+
+        // is the modulo odd?
+        if ($n->value[0] & 1) {
+            return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY));
+        }
+        // if it's not, it's even
+
+        // find the lowest set bit (eg. the max pow of 2 that divides $n)
+        for ($i = 0; $i < count($n->value); ++$i) {
+            if ($n->value[$i]) {
+                $temp = decbin($n->value[$i]);
+                $j = strlen($temp) - strrpos($temp, '1') - 1;
+                $j+= 26 * $i;
+                break;
+            }
+        }
+        // at this point, 2^$j * $n/(2^$j) == $n
+
+        $mod1 = $n->copy();
+        $mod1->_rshift($j);
+        $mod2 = new static();
+        $mod2->value = array(1);
+        $mod2->_lshift($j);
+
+        $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, self::MONTGOMERY) : new static();
+        $part2 = $this->_slidingWindow($e, $mod2, self::POWEROF2);
+
+        $y1 = $mod2->modInverse($mod1);
+        $y2 = $mod1->modInverse($mod2);
+
+        $result = $part1->multiply($mod2);
+        $result = $result->multiply($y1);
+
+        $temp = $part2->multiply($mod1);
+        $temp = $temp->multiply($y2);
+
+        $result = $result->add($temp);
+        list(, $result) = $result->divide($n);
+
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Performs modular exponentiation.
+     *
+     * Alias for modPow().
+     *
+     * @param \phpseclib\Math\BigInteger $e
+     * @param \phpseclib\Math\BigInteger $n
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function powMod($e, $n)
+    {
+        return $this->modPow($e, $n);
+    }
+
+    /**
+     * Sliding Window k-ary Modular Exponentiation
+     *
+     * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}.  In a departure from those algorithims,
+     * however, this function performs a modular reduction after every multiplication and squaring operation.
+     * As such, this function has the same preconditions that the reductions being used do.
+     *
+     * @param \phpseclib\Math\BigInteger $e
+     * @param \phpseclib\Math\BigInteger $n
+     * @param int $mode
+     * @return \phpseclib\Math\BigInteger
+     * @access private
+     */
+    function _slidingWindow($e, $n, $mode)
+    {
+        static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function
+        //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1
+
+        $e_value = $e->value;
+        $e_length = count($e_value) - 1;
+        $e_bits = decbin($e_value[$e_length]);
+        for ($i = $e_length - 1; $i >= 0; --$i) {
+            $e_bits.= str_pad(decbin($e_value[$i]), self::$base, '0', STR_PAD_LEFT);
+        }
+
+        $e_length = strlen($e_bits);
+
+        // calculate the appropriate window size.
+        // $window_size == 3 if $window_ranges is between 25 and 81, for example.
+        for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) {
+        }
+
+        $n_value = $n->value;
+
+        // precompute $this^0 through $this^$window_size
+        $powers = array();
+        $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);
+        $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);
+
+        // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end
+        // in a 1.  ie. it's supposed to be odd.
+        $temp = 1 << ($window_size - 1);
+        for ($i = 1; $i < $temp; ++$i) {
+            $i2 = $i << 1;
+            $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);
+        }
+
+        $result = array(1);
+        $result = $this->_prepareReduce($result, $n_value, $mode);
+
+        for ($i = 0; $i < $e_length;) {
+            if (!$e_bits[$i]) {
+                $result = $this->_squareReduce($result, $n_value, $mode);
+                ++$i;
+            } else {
+                for ($j = $window_size - 1; $j > 0; --$j) {
+                    if (!empty($e_bits[$i + $j])) {
+                        break;
+                    }
+                }
+
+                // eg. the length of substr($e_bits, $i, $j + 1)
+                for ($k = 0; $k <= $j; ++$k) {
+                    $result = $this->_squareReduce($result, $n_value, $mode);
+                }
+
+                $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
+
+                $i += $j + 1;
+            }
+        }
+
+        $temp = new static();
+        $temp->value = $this->_reduce($result, $n_value, $mode);
+
+        return $temp;
+    }
+
+    /**
+     * Modular reduction
+     *
+     * For most $modes this will return the remainder.
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $n
+     * @param int $mode
+     * @return array
+     */
+    function _reduce($x, $n, $mode)
+    {
+        switch ($mode) {
+            case self::MONTGOMERY:
+                return $this->_montgomery($x, $n);
+            case self::BARRETT:
+                return $this->_barrett($x, $n);
+            case self::POWEROF2:
+                $lhs = new static();
+                $lhs->value = $x;
+                $rhs = new static();
+                $rhs->value = $n;
+                return $x->_mod2($n);
+            case self::CLASSIC:
+                $lhs = new static();
+                $lhs->value = $x;
+                $rhs = new static();
+                $rhs->value = $n;
+                list(, $temp) = $lhs->divide($rhs);
+                return $temp->value;
+            case self::NONE:
+                return $x;
+            default:
+                // an invalid $mode was provided
+        }
+    }
+
+    /**
+     * Modular reduction preperation
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $n
+     * @param int $mode
+     * @return array
+     */
+    function _prepareReduce($x, $n, $mode)
+    {
+        if ($mode == self::MONTGOMERY) {
+            return $this->_prepMontgomery($x, $n);
+        }
+        return $this->_reduce($x, $n, $mode);
+    }
+
+    /**
+     * Modular multiply
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $y
+     * @param array $n
+     * @param int $mode
+     * @return array
+     */
+    function _multiplyReduce($x, $y, $n, $mode)
+    {
+        if ($mode == self::MONTGOMERY) {
+            return $this->_montgomeryMultiply($x, $y, $n);
+        }
+        $temp = $this->_multiply($x, false, $y, false);
+        return $this->_reduce($temp[self::VALUE], $n, $mode);
+    }
+
+    /**
+     * Modular square
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $n
+     * @param int $mode
+     * @return array
+     */
+    function _squareReduce($x, $n, $mode)
+    {
+        if ($mode == self::MONTGOMERY) {
+            return $this->_montgomeryMultiply($x, $x, $n);
+        }
+        return $this->_reduce($this->_square($x), $n, $mode);
+    }
+
+    /**
+     * Modulos for Powers of Two
+     *
+     * Calculates $x%$n, where $n = 2**$e, for some $e.  Since this is basically the same as doing $x & ($n-1),
+     * we'll just use this function as a wrapper for doing that.
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param \phpseclib\Math\BigInteger $n
+     * @return \phpseclib\Math\BigInteger
+     */
+    function _mod2($n)
+    {
+        $temp = new static();
+        $temp->value = array(1);
+        return $this->bitwise_and($n->subtract($temp));
+    }
+
+    /**
+     * Barrett Modular Reduction
+     *
+     * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information.  Modified slightly,
+     * so as not to require negative numbers (initially, this script didn't support negative numbers).
+     *
+     * Employs "folding", as described at
+     * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}.  To quote from
+     * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."
+     *
+     * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that
+     * usable on account of (1) its not using reasonable radix points as discussed in
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable
+     * radix points, it only works when there are an even number of digits in the denominator.  The reason for (2) is that
+     * (x >> 1) + (x >> 1) != x / 2 + x / 2.  If x is even, they're the same, but if x is odd, they're not.  See the in-line
+     * comments for details.
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $n
+     * @param array $m
+     * @return array
+     */
+    function _barrett($n, $m)
+    {
+        static $cache = array(
+            self::VARIABLE => array(),
+            self::DATA => array()
+        );
+
+        $m_length = count($m);
+
+        // if ($this->_compare($n, $this->_square($m)) >= 0) {
+        if (count($n) > 2 * $m_length) {
+            $lhs = new static();
+            $rhs = new static();
+            $lhs->value = $n;
+            $rhs->value = $m;
+            list(, $temp) = $lhs->divide($rhs);
+            return $temp->value;
+        }
+
+        // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced
+        if ($m_length < 5) {
+            return $this->_regularBarrett($n, $m);
+        }
+
+        // n = 2 * m.length
+
+        if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
+            $key = count($cache[self::VARIABLE]);
+            $cache[self::VARIABLE][] = $m;
+
+            $lhs = new static();
+            $lhs_value = &$lhs->value;
+            $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));
+            $lhs_value[] = 1;
+            $rhs = new static();
+            $rhs->value = $m;
+
+            list($u, $m1) = $lhs->divide($rhs);
+            $u = $u->value;
+            $m1 = $m1->value;
+
+            $cache[self::DATA][] = array(
+                'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)
+                'm1'=> $m1 // m.length
+            );
+        } else {
+            extract($cache[self::DATA][$key]);
+        }
+
+        $cutoff = $m_length + ($m_length >> 1);
+        $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)
+        $msd = array_slice($n, $cutoff);    // m.length >> 1
+        $lsd = $this->_trim($lsd);
+        $temp = $this->_multiply($msd, false, $m1, false);
+        $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1
+
+        if ($m_length & 1) {
+            return $this->_regularBarrett($n[self::VALUE], $m);
+        }
+
+        // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2
+        $temp = array_slice($n[self::VALUE], $m_length - 1);
+        // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2
+        // if odd:  ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1
+        $temp = $this->_multiply($temp, false, $u, false);
+        // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1
+        // if odd:  (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)
+        $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1);
+        // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1
+        // if odd:  (m.length - (m.length >> 1)) + m.length     = 2 * m.length - (m.length >> 1)
+        $temp = $this->_multiply($temp, false, $m, false);
+
+        // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit
+        // number from a m.length + (m.length >> 1) + 1 digit number.  ie. there'd be an extra digit and the while loop
+        // following this comment would loop a lot (hence our calling _regularBarrett() in that situation).
+
+        $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false);
+
+        while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) {
+            $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false);
+        }
+
+        return $result[self::VALUE];
+    }
+
+    /**
+     * (Regular) Barrett Modular Reduction
+     *
+     * For numbers with more than four digits BigInteger::_barrett() is faster.  The difference between that and this
+     * is that this function does not fold the denominator into a smaller form.
+     *
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $n
+     * @return array
+     */
+    function _regularBarrett($x, $n)
+    {
+        static $cache = array(
+            self::VARIABLE => array(),
+            self::DATA => array()
+        );
+
+        $n_length = count($n);
+
+        if (count($x) > 2 * $n_length) {
+            $lhs = new static();
+            $rhs = new static();
+            $lhs->value = $x;
+            $rhs->value = $n;
+            list(, $temp) = $lhs->divide($rhs);
+            return $temp->value;
+        }
+
+        if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
+            $key = count($cache[self::VARIABLE]);
+            $cache[self::VARIABLE][] = $n;
+            $lhs = new static();
+            $lhs_value = &$lhs->value;
+            $lhs_value = $this->_array_repeat(0, 2 * $n_length);
+            $lhs_value[] = 1;
+            $rhs = new static();
+            $rhs->value = $n;
+            list($temp, ) = $lhs->divide($rhs); // m.length
+            $cache[self::DATA][] = $temp->value;
+        }
+
+        // 2 * m.length - (m.length - 1) = m.length + 1
+        $temp = array_slice($x, $n_length - 1);
+        // (m.length + 1) + m.length = 2 * m.length + 1
+        $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false);
+        // (2 * m.length + 1) - (m.length - 1) = m.length + 2
+        $temp = array_slice($temp[self::VALUE], $n_length + 1);
+
+        // m.length + 1
+        $result = array_slice($x, 0, $n_length + 1);
+        // m.length + 1
+        $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);
+        // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)
+
+        if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) {
+            $corrector_value = $this->_array_repeat(0, $n_length + 1);
+            $corrector_value[count($corrector_value)] = 1;
+            $result = $this->_add($result, false, $corrector_value, false);
+            $result = $result[self::VALUE];
+        }
+
+        // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits
+        $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]);
+        while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) {
+            $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false);
+        }
+
+        return $result[self::VALUE];
+    }
+
+    /**
+     * Performs long multiplication up to $stop digits
+     *
+     * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
+     *
+     * @see self::_regularBarrett()
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @param int $stop
+     * @return array
+     * @access private
+     */
+    function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
+    {
+        $x_length = count($x_value);
+        $y_length = count($y_value);
+
+        if (!$x_length || !$y_length) { // a 0 is being multiplied
+            return array(
+                self::VALUE => array(),
+                self::SIGN => false
+            );
+        }
+
+        if ($x_length < $y_length) {
+            $temp = $x_value;
+            $x_value = $y_value;
+            $y_value = $temp;
+
+            $x_length = count($x_value);
+            $y_length = count($y_value);
+        }
+
+        $product_value = $this->_array_repeat(0, $x_length + $y_length);
+
+        // the following for loop could be removed if the for loop following it
+        // (the one with nested for loops) initially set $i to 0, but
+        // doing so would also make the result in one set of unnecessary adds,
+        // since on the outermost loops first pass, $product->value[$k] is going
+        // to always be 0
+
+        $carry = 0;
+
+        for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
+            $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
+            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+            $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
+        }
+
+        if ($j < $stop) {
+            $product_value[$j] = $carry;
+        }
+
+        // the above for loop is what the previous comment was talking about.  the
+        // following for loop is the "one with nested for loops"
+
+        for ($i = 1; $i < $y_length; ++$i) {
+            $carry = 0;
+
+            for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
+                $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
+                $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+                $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
+            }
+
+            if ($k < $stop) {
+                $product_value[$k] = $carry;
+            }
+        }
+
+        return array(
+            self::VALUE => $this->_trim($product_value),
+            self::SIGN => $x_negative != $y_negative
+        );
+    }
+
+    /**
+     * Montgomery Modular Reduction
+     *
+     * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.
+     * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be
+     * improved upon (basically, by using the comba method).  gcd($n, 2) must be equal to one for this function
+     * to work correctly.
+     *
+     * @see self::_prepMontgomery()
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $n
+     * @return array
+     */
+    function _montgomery($x, $n)
+    {
+        static $cache = array(
+            self::VARIABLE => array(),
+            self::DATA => array()
+        );
+
+        if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
+            $key = count($cache[self::VARIABLE]);
+            $cache[self::VARIABLE][] = $x;
+            $cache[self::DATA][] = $this->_modInverse67108864($n);
+        }
+
+        $k = count($n);
+
+        $result = array(self::VALUE => $x);
+
+        for ($i = 0; $i < $k; ++$i) {
+            $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key];
+            $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
+            $temp = $this->_regularMultiply(array($temp), $n);
+            $temp = array_merge($this->_array_repeat(0, $i), $temp);
+            $result = $this->_add($result[self::VALUE], false, $temp, false);
+        }
+
+        $result[self::VALUE] = array_slice($result[self::VALUE], $k);
+
+        if ($this->_compare($result, false, $n, false) >= 0) {
+            $result = $this->_subtract($result[self::VALUE], false, $n, false);
+        }
+
+        return $result[self::VALUE];
+    }
+
+    /**
+     * Montgomery Multiply
+     *
+     * Interleaves the montgomery reduction and long multiplication algorithms together as described in
+     * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}
+     *
+     * @see self::_prepMontgomery()
+     * @see self::_montgomery()
+     * @access private
+     * @param array $x
+     * @param array $y
+     * @param array $m
+     * @return array
+     */
+    function _montgomeryMultiply($x, $y, $m)
+    {
+        $temp = $this->_multiply($x, false, $y, false);
+        return $this->_montgomery($temp[self::VALUE], $m);
+
+        // the following code, although not callable, can be run independently of the above code
+        // although the above code performed better in my benchmarks the following could might
+        // perform better under different circumstances. in lieu of deleting it it's just been
+        // made uncallable
+
+        static $cache = array(
+            self::VARIABLE => array(),
+            self::DATA => array()
+        );
+
+        if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
+            $key = count($cache[self::VARIABLE]);
+            $cache[self::VARIABLE][] = $m;
+            $cache[self::DATA][] = $this->_modInverse67108864($m);
+        }
+
+        $n = max(count($x), count($y), count($m));
+        $x = array_pad($x, $n, 0);
+        $y = array_pad($y, $n, 0);
+        $m = array_pad($m, $n, 0);
+        $a = array(self::VALUE => $this->_array_repeat(0, $n + 1));
+        for ($i = 0; $i < $n; ++$i) {
+            $temp = $a[self::VALUE][0] + $x[$i] * $y[0];
+            $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
+            $temp = $temp * $cache[self::DATA][$key];
+            $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
+            $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
+            $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false);
+            $a[self::VALUE] = array_slice($a[self::VALUE], 1);
+        }
+        if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) {
+            $a = $this->_subtract($a[self::VALUE], false, $m, false);
+        }
+        return $a[self::VALUE];
+    }
+
+    /**
+     * Prepare a number for use in Montgomery Modular Reductions
+     *
+     * @see self::_montgomery()
+     * @see self::_slidingWindow()
+     * @access private
+     * @param array $x
+     * @param array $n
+     * @return array
+     */
+    function _prepMontgomery($x, $n)
+    {
+        $lhs = new static();
+        $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);
+        $rhs = new static();
+        $rhs->value = $n;
+
+        list(, $temp) = $lhs->divide($rhs);
+        return $temp->value;
+    }
+
+    /**
+     * Modular Inverse of a number mod 2**26 (eg. 67108864)
+     *
+     * Based off of the bnpInvDigit function implemented and justified in the following URL:
+     *
+     * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js}
+     *
+     * The following URL provides more info:
+     *
+     * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85}
+     *
+     * As for why we do all the bitmasking...  strange things can happen when converting from floats to ints. For
+     * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields
+     * int(-2147483648).  To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't
+     * auto-converted to floats.  The outermost bitmask is present because without it, there's no guarantee that
+     * the "residue" returned would be the so-called "common residue".  We use fmod, in the last step, because the
+     * maximum possible $x is 26 bits and the maximum $result is 16 bits.  Thus, we have to be able to handle up to
+     * 40 bits, which only 64-bit floating points will support.
+     *
+     * Thanks to Pedro Gimeno Fortea for input!
+     *
+     * @see self::_montgomery()
+     * @access private
+     * @param array $x
+     * @return int
+     */
+    function _modInverse67108864($x) // 2**26 == 67,108,864
+    {
+        $x = -$x[0];
+        $result = $x & 0x3; // x**-1 mod 2**2
+        $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4
+        $result = ($result * (2 - ($x & 0xFF) * $result))  & 0xFF; // x**-1 mod 2**8
+        $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16
+        $result = fmod($result * (2 - fmod($x * $result, self::$baseFull)), self::$baseFull); // x**-1 mod 2**26
+        return $result & self::$maxDigit;
+    }
+
+    /**
+     * Calculates modular inverses.
+     *
+     * Say you have (30 mod 17 * x mod 17) mod 17 == 1.  x can be found using modular inverses.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger(30);
+     *    $b = new \phpseclib\Math\BigInteger(17);
+     *
+     *    $c = $a->modInverse($b);
+     *    echo $c->toString(); // outputs 4
+     *
+     *    echo "\r\n";
+     *
+     *    $d = $a->multiply($c);
+     *    list(, $d) = $d->divide($b);
+     *    echo $d; // outputs 1 (as per the definition of modular inverse)
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $n
+     * @return \phpseclib\Math\BigInteger|false
+     * @access public
+     * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.
+     */
+    function modInverse($n)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_invert($this->value, $n->value);
+
+                return ($temp->value === false) ? false : $this->_normalize($temp);
+        }
+
+        static $zero, $one;
+        if (!isset($zero)) {
+            $zero = new static();
+            $one = new static(1);
+        }
+
+        // $x mod -$n == $x mod $n.
+        $n = $n->abs();
+
+        if ($this->compare($zero) < 0) {
+            $temp = $this->abs();
+            $temp = $temp->modInverse($n);
+            return $this->_normalize($n->subtract($temp));
+        }
+
+        extract($this->extendedGCD($n));
+
+        if (!$gcd->equals($one)) {
+            return false;
+        }
+
+        $x = $x->compare($zero) < 0 ? $x->add($n) : $x;
+
+        return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x);
+    }
+
+    /**
+     * Calculates the greatest common divisor and Bezout's identity.
+     *
+     * Say you have 693 and 609.  The GCD is 21.  Bezout's identity states that there exist integers x and y such that
+     * 693*x + 609*y == 21.  In point of fact, there are actually an infinite number of x and y combinations and which
+     * combination is returned is dependent upon which mode is in use.  See
+     * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger(693);
+     *    $b = new \phpseclib\Math\BigInteger(609);
+     *
+     *    extract($a->extendedGCD($b));
+     *
+     *    echo $gcd->toString() . "\r\n"; // outputs 21
+     *    echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $n
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal Calculates the GCD using the binary xGCD algorithim described in
+     *    {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}.  As the text above 14.61 notes,
+     *    the more traditional algorithim requires "relatively costly multiple-precision divisions".
+     */
+    function extendedGCD($n)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                extract(gmp_gcdext($this->value, $n->value));
+
+                return array(
+                    'gcd' => $this->_normalize(new static($g)),
+                    'x'   => $this->_normalize(new static($s)),
+                    'y'   => $this->_normalize(new static($t))
+                );
+            case self::MODE_BCMATH:
+                // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works
+                // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway.  as is,
+                // the basic extended euclidean algorithim is what we're using.
+
+                $u = $this->value;
+                $v = $n->value;
+
+                $a = '1';
+                $b = '0';
+                $c = '0';
+                $d = '1';
+
+                while (bccomp($v, '0', 0) != 0) {
+                    $q = bcdiv($u, $v, 0);
+
+                    $temp = $u;
+                    $u = $v;
+                    $v = bcsub($temp, bcmul($v, $q, 0), 0);
+
+                    $temp = $a;
+                    $a = $c;
+                    $c = bcsub($temp, bcmul($a, $q, 0), 0);
+
+                    $temp = $b;
+                    $b = $d;
+                    $d = bcsub($temp, bcmul($b, $q, 0), 0);
+                }
+
+                return array(
+                    'gcd' => $this->_normalize(new static($u)),
+                    'x'   => $this->_normalize(new static($a)),
+                    'y'   => $this->_normalize(new static($b))
+                );
+        }
+
+        $y = $n->copy();
+        $x = $this->copy();
+        $g = new static();
+        $g->value = array(1);
+
+        while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) {
+            $x->_rshift(1);
+            $y->_rshift(1);
+            $g->_lshift(1);
+        }
+
+        $u = $x->copy();
+        $v = $y->copy();
+
+        $a = new static();
+        $b = new static();
+        $c = new static();
+        $d = new static();
+
+        $a->value = $d->value = $g->value = array(1);
+        $b->value = $c->value = array();
+
+        while (!empty($u->value)) {
+            while (!($u->value[0] & 1)) {
+                $u->_rshift(1);
+                if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) {
+                    $a = $a->add($y);
+                    $b = $b->subtract($x);
+                }
+                $a->_rshift(1);
+                $b->_rshift(1);
+            }
+
+            while (!($v->value[0] & 1)) {
+                $v->_rshift(1);
+                if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) {
+                    $c = $c->add($y);
+                    $d = $d->subtract($x);
+                }
+                $c->_rshift(1);
+                $d->_rshift(1);
+            }
+
+            if ($u->compare($v) >= 0) {
+                $u = $u->subtract($v);
+                $a = $a->subtract($c);
+                $b = $b->subtract($d);
+            } else {
+                $v = $v->subtract($u);
+                $c = $c->subtract($a);
+                $d = $d->subtract($b);
+            }
+        }
+
+        return array(
+            'gcd' => $this->_normalize($g->multiply($v)),
+            'x'   => $this->_normalize($c),
+            'y'   => $this->_normalize($d)
+        );
+    }
+
+    /**
+     * Calculates the greatest common divisor
+     *
+     * Say you have 693 and 609.  The GCD is 21.
+     *
+     * Here's an example:
+     * <code>
+     * <?php
+     *    $a = new \phpseclib\Math\BigInteger(693);
+     *    $b = new \phpseclib\Math\BigInteger(609);
+     *
+     *    $gcd = a->extendedGCD($b);
+     *
+     *    echo $gcd->toString() . "\r\n"; // outputs 21
+     * ?>
+     * </code>
+     *
+     * @param \phpseclib\Math\BigInteger $n
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function gcd($n)
+    {
+        extract($this->extendedGCD($n));
+        return $gcd;
+    }
+
+    /**
+     * Absolute value.
+     *
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function abs()
+    {
+        $temp = new static();
+
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp->value = gmp_abs($this->value);
+                break;
+            case self::MODE_BCMATH:
+                $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value;
+                break;
+            default:
+                $temp->value = $this->value;
+        }
+
+        return $temp;
+    }
+
+    /**
+     * Compares two numbers.
+     *
+     * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite.  The reason for this is
+     * demonstrated thusly:
+     *
+     * $x  > $y: $x->compare($y)  > 0
+     * $x  < $y: $x->compare($y)  < 0
+     * $x == $y: $x->compare($y) == 0
+     *
+     * Note how the same comparison operator is used.  If you want to test for equality, use $x->equals($y).
+     *
+     * @param \phpseclib\Math\BigInteger $y
+     * @return int that is < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
+     * @access public
+     * @see self::equals()
+     * @internal Could return $this->subtract($x), but that's not as fast as what we do do.
+     */
+    function compare($y)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $r = gmp_cmp($this->value, $y->value);
+                if ($r < -1) {
+                    $r = -1;
+                }
+                if ($r > 1) {
+                    $r = 1;
+                }
+                return $r;
+            case self::MODE_BCMATH:
+                return bccomp($this->value, $y->value, 0);
+        }
+
+        return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative);
+    }
+
+    /**
+     * Compares two numbers.
+     *
+     * @param array $x_value
+     * @param bool $x_negative
+     * @param array $y_value
+     * @param bool $y_negative
+     * @return int
+     * @see self::compare()
+     * @access private
+     */
+    function _compare($x_value, $x_negative, $y_value, $y_negative)
+    {
+        if ($x_negative != $y_negative) {
+            return (!$x_negative && $y_negative) ? 1 : -1;
+        }
+
+        $result = $x_negative ? -1 : 1;
+
+        if (count($x_value) != count($y_value)) {
+            return (count($x_value) > count($y_value)) ? $result : -$result;
+        }
+        $size = max(count($x_value), count($y_value));
+
+        $x_value = array_pad($x_value, $size, 0);
+        $y_value = array_pad($y_value, $size, 0);
+
+        for ($i = count($x_value) - 1; $i >= 0; --$i) {
+            if ($x_value[$i] != $y_value[$i]) {
+                return ($x_value[$i] > $y_value[$i]) ? $result : -$result;
+            }
+        }
+
+        return 0;
+    }
+
+    /**
+     * Tests the equality of two numbers.
+     *
+     * If you need to see if one number is greater than or less than another number, use BigInteger::compare()
+     *
+     * @param \phpseclib\Math\BigInteger $x
+     * @return bool
+     * @access public
+     * @see self::compare()
+     */
+    function equals($x)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                return gmp_cmp($this->value, $x->value) == 0;
+            default:
+                return $this->value === $x->value && $this->is_negative == $x->is_negative;
+        }
+    }
+
+    /**
+     * Set Precision
+     *
+     * Some bitwise operations give different results depending on the precision being used.  Examples include left
+     * shift, not, and rotates.
+     *
+     * @param int $bits
+     * @access public
+     */
+    function setPrecision($bits)
+    {
+        $this->precision = $bits;
+        if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) {
+            $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
+        } else {
+            $this->bitmask = new static(bcpow('2', $bits, 0));
+        }
+
+        $temp = $this->_normalize($this);
+        $this->value = $temp->value;
+    }
+
+    /**
+     * Logical And
+     *
+     * @param \phpseclib\Math\BigInteger $x
+     * @access public
+     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+     * @return \phpseclib\Math\BigInteger
+     */
+    function bitwise_and($x)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_and($this->value, $x->value);
+
+                return $this->_normalize($temp);
+            case self::MODE_BCMATH:
+                $left = $this->toBytes();
+                $right = $x->toBytes();
+
+                $length = max(strlen($left), strlen($right));
+
+                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
+                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
+
+                return $this->_normalize(new static($left & $right, 256));
+        }
+
+        $result = $this->copy();
+
+        $length = min(count($x->value), count($this->value));
+
+        $result->value = array_slice($result->value, 0, $length);
+
+        for ($i = 0; $i < $length; ++$i) {
+            $result->value[$i]&= $x->value[$i];
+        }
+
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Logical Or
+     *
+     * @param \phpseclib\Math\BigInteger $x
+     * @access public
+     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+     * @return \phpseclib\Math\BigInteger
+     */
+    function bitwise_or($x)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_or($this->value, $x->value);
+
+                return $this->_normalize($temp);
+            case self::MODE_BCMATH:
+                $left = $this->toBytes();
+                $right = $x->toBytes();
+
+                $length = max(strlen($left), strlen($right));
+
+                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
+                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
+
+                return $this->_normalize(new static($left | $right, 256));
+        }
+
+        $length = max(count($this->value), count($x->value));
+        $result = $this->copy();
+        $result->value = array_pad($result->value, $length, 0);
+        $x->value = array_pad($x->value, $length, 0);
+
+        for ($i = 0; $i < $length; ++$i) {
+            $result->value[$i]|= $x->value[$i];
+        }
+
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Logical Exclusive-Or
+     *
+     * @param \phpseclib\Math\BigInteger $x
+     * @access public
+     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+     * @return \phpseclib\Math\BigInteger
+     */
+    function bitwise_xor($x)
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                $temp = new static();
+                $temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value));
+                return $this->_normalize($temp);
+            case self::MODE_BCMATH:
+                $left = $this->toBytes();
+                $right = $x->toBytes();
+
+                $length = max(strlen($left), strlen($right));
+
+                $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
+                $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
+
+                return $this->_normalize(new static($left ^ $right, 256));
+        }
+
+        $length = max(count($this->value), count($x->value));
+        $result = $this->copy();
+        $result->is_negative = false;
+        $result->value = array_pad($result->value, $length, 0);
+        $x->value = array_pad($x->value, $length, 0);
+
+        for ($i = 0; $i < $length; ++$i) {
+            $result->value[$i]^= $x->value[$i];
+        }
+
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Logical Not
+     *
+     * @access public
+     * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+     * @return \phpseclib\Math\BigInteger
+     */
+    function bitwise_not()
+    {
+        // calculuate "not" without regard to $this->precision
+        // (will always result in a smaller number.  ie. ~1 isn't 1111 1110 - it's 0)
+        $temp = $this->toBytes();
+        if ($temp == '') {
+            return $this->_normalize(new static());
+        }
+        $pre_msb = decbin(ord($temp[0]));
+        $temp = ~$temp;
+        $msb = decbin(ord($temp[0]));
+        if (strlen($msb) == 8) {
+            $msb = substr($msb, strpos($msb, '0'));
+        }
+        $temp[0] = chr(bindec($msb));
+
+        // see if we need to add extra leading 1's
+        $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8;
+        $new_bits = $this->precision - $current_bits;
+        if ($new_bits <= 0) {
+            return $this->_normalize(new static($temp, 256));
+        }
+
+        // generate as many leading 1's as we need to.
+        $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
+        $this->_base256_lshift($leading_ones, $current_bits);
+
+        $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT);
+
+        return $this->_normalize(new static($leading_ones | $temp, 256));
+    }
+
+    /**
+     * Logical Right Shift
+     *
+     * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
+     *
+     * @param int $shift
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal The only version that yields any speed increases is the internal version.
+     */
+    function bitwise_rightShift($shift)
+    {
+        $temp = new static();
+
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                static $two;
+
+                if (!isset($two)) {
+                    $two = gmp_init('2');
+                }
+
+                $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift));
+
+                break;
+            case self::MODE_BCMATH:
+                $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0);
+
+                break;
+            default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten
+                     // and I don't want to do that...
+                $temp->value = $this->value;
+                $temp->_rshift($shift);
+        }
+
+        return $this->_normalize($temp);
+    }
+
+    /**
+     * Logical Left Shift
+     *
+     * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
+     *
+     * @param int $shift
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal The only version that yields any speed increases is the internal version.
+     */
+    function bitwise_leftShift($shift)
+    {
+        $temp = new static();
+
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                static $two;
+
+                if (!isset($two)) {
+                    $two = gmp_init('2');
+                }
+
+                $temp->value = gmp_mul($this->value, gmp_pow($two, $shift));
+
+                break;
+            case self::MODE_BCMATH:
+                $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);
+
+                break;
+            default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten
+                     // and I don't want to do that...
+                $temp->value = $this->value;
+                $temp->_lshift($shift);
+        }
+
+        return $this->_normalize($temp);
+    }
+
+    /**
+     * Logical Left Rotate
+     *
+     * Instead of the top x bits being dropped they're appended to the shifted bit string.
+     *
+     * @param int $shift
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function bitwise_leftRotate($shift)
+    {
+        $bits = $this->toBytes();
+
+        if ($this->precision > 0) {
+            $precision = $this->precision;
+            if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
+                $mask = $this->bitmask->subtract(new static(1));
+                $mask = $mask->toBytes();
+            } else {
+                $mask = $this->bitmask->toBytes();
+            }
+        } else {
+            $temp = ord($bits[0]);
+            for ($i = 0; $temp >> $i; ++$i) {
+            }
+            $precision = 8 * strlen($bits) - 8 + $i;
+            $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
+        }
+
+        if ($shift < 0) {
+            $shift+= $precision;
+        }
+        $shift%= $precision;
+
+        if (!$shift) {
+            return $this->copy();
+        }
+
+        $left = $this->bitwise_leftShift($shift);
+        $left = $left->bitwise_and(new static($mask, 256));
+        $right = $this->bitwise_rightShift($precision - $shift);
+        $result = MATH_BIGINTEGER_MODE != self::MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right);
+        return $this->_normalize($result);
+    }
+
+    /**
+     * Logical Right Rotate
+     *
+     * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
+     *
+     * @param int $shift
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     */
+    function bitwise_rightRotate($shift)
+    {
+        return $this->bitwise_leftRotate(-$shift);
+    }
+
+    /**
+     * Generates a random BigInteger
+     *
+     * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
+     *
+     * @param int $size
+     * @return \phpseclib\Math\BigInteger
+     * @access private
+     */
+    function _random_number_helper($size)
+    {
+        if (class_exists('\phpseclib\Crypt\Random')) {
+            $random = Random::string($size);
+        } else {
+            $random = '';
+
+            if ($size & 1) {
+                $random.= chr(mt_rand(0, 255));
+            }
+
+            $blocks = $size >> 1;
+            for ($i = 0; $i < $blocks; ++$i) {
+                // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
+                $random.= pack('n', mt_rand(0, 0xFFFF));
+            }
+        }
+
+        return new static($random, 256);
+    }
+
+    /**
+     * Generate a random number
+     *
+     * Returns a random number between $min and $max where $min and $max
+     * can be defined using one of the two methods:
+     *
+     * $min->random($max)
+     * $max->random($min)
+     *
+     * @param \phpseclib\Math\BigInteger $arg1
+     * @param \phpseclib\Math\BigInteger $arg2
+     * @return \phpseclib\Math\BigInteger
+     * @access public
+     * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object.
+     *           That method is still supported for BC purposes.
+     */
+    function random($arg1, $arg2 = false)
+    {
+        if ($arg1 === false) {
+            return false;
+        }
+
+        if ($arg2 === false) {
+            $max = $arg1;
+            $min = $this;
+        } else {
+            $min = $arg1;
+            $max = $arg2;
+        }
+
+        $compare = $max->compare($min);
+
+        if (!$compare) {
+            return $this->_normalize($min);
+        } elseif ($compare < 0) {
+            // if $min is bigger then $max, swap $min and $max
+            $temp = $max;
+            $max = $min;
+            $min = $temp;
+        }
+
+        static $one;
+        if (!isset($one)) {
+            $one = new static(1);
+        }
+
+        $max = $max->subtract($min->subtract($one));
+        $size = strlen(ltrim($max->toBytes(), chr(0)));
+
+        /*
+            doing $random % $max doesn't work because some numbers will be more likely to occur than others.
+            eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145
+            would produce 5 whereas the only value of random that could produce 139 would be 139. ie.
+            not all numbers would be equally likely. some would be more likely than others.
+
+            creating a whole new random number until you find one that is within the range doesn't work
+            because, for sufficiently small ranges, the likelihood that you'd get a number within that range
+            would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability
+            would be pretty high that $random would be greater than $max.
+
+            phpseclib works around this using the technique described here:
+
+            http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
+        */
+        $random_max = new static(chr(1) . str_repeat("\0", $size), 256);
+        $random = $this->_random_number_helper($size);
+
+        list($max_multiple) = $random_max->divide($max);
+        $max_multiple = $max_multiple->multiply($max);
+
+        while ($random->compare($max_multiple) >= 0) {
+            $random = $random->subtract($max_multiple);
+            $random_max = $random_max->subtract($max_multiple);
+            $random = $random->bitwise_leftShift(8);
+            $random = $random->add($this->_random_number_helper(1));
+            $random_max = $random_max->bitwise_leftShift(8);
+            list($max_multiple) = $random_max->divide($max);
+            $max_multiple = $max_multiple->multiply($max);
+        }
+        list(, $random) = $random->divide($max);
+
+        return $this->_normalize($random->add($min));
+    }
+
+    /**
+     * Generate a random prime number.
+     *
+     * If there's not a prime within the given range, false will be returned.
+     * If more than $timeout seconds have elapsed, give up and return false.
+     *
+     * @param \phpseclib\Math\BigInteger $arg1
+     * @param \phpseclib\Math\BigInteger $arg2
+     * @param int $timeout
+     * @return Math_BigInteger|false
+     * @access public
+     * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
+     */
+    function randomPrime($arg1, $arg2 = false, $timeout = false)
+    {
+        if ($arg1 === false) {
+            return false;
+        }
+
+        if ($arg2 === false) {
+            $max = $arg1;
+            $min = $this;
+        } else {
+            $min = $arg1;
+            $max = $arg2;
+        }
+
+        $compare = $max->compare($min);
+
+        if (!$compare) {
+            return $min->isPrime() ? $min : false;
+        } elseif ($compare < 0) {
+            // if $min is bigger then $max, swap $min and $max
+            $temp = $max;
+            $max = $min;
+            $min = $temp;
+        }
+
+        static $one, $two;
+        if (!isset($one)) {
+            $one = new static(1);
+            $two = new static(2);
+        }
+
+        $start = time();
+
+        $x = $this->random($min, $max);
+
+        // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
+        if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) {
+            $p = new static();
+            $p->value = gmp_nextprime($x->value);
+
+            if ($p->compare($max) <= 0) {
+                return $p;
+            }
+
+            if (!$min->equals($x)) {
+                $x = $x->subtract($one);
+            }
+
+            return $x->randomPrime($min, $x);
+        }
+
+        if ($x->equals($two)) {
+            return $x;
+        }
+
+        $x->_make_odd();
+        if ($x->compare($max) > 0) {
+            // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range
+            if ($min->equals($max)) {
+                return false;
+            }
+            $x = $min->copy();
+            $x->_make_odd();
+        }
+
+        $initial_x = $x->copy();
+
+        while (true) {
+            if ($timeout !== false && time() - $start > $timeout) {
+                return false;
+            }
+
+            if ($x->isPrime()) {
+                return $x;
+            }
+
+            $x = $x->add($two);
+
+            if ($x->compare($max) > 0) {
+                $x = $min->copy();
+                if ($x->equals($two)) {
+                    return $x;
+                }
+                $x->_make_odd();
+            }
+
+            if ($x->equals($initial_x)) {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Make the current number odd
+     *
+     * If the current number is odd it'll be unchanged.  If it's even, one will be added to it.
+     *
+     * @see self::randomPrime()
+     * @access private
+     */
+    function _make_odd()
+    {
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                gmp_setbit($this->value, 0);
+                break;
+            case self::MODE_BCMATH:
+                if ($this->value[strlen($this->value) - 1] % 2 == 0) {
+                    $this->value = bcadd($this->value, '1');
+                }
+                break;
+            default:
+                $this->value[0] |= 1;
+        }
+    }
+
+    /**
+     * Checks a numer to see if it's prime
+     *
+     * Assuming the $t parameter is not set, this function has an error rate of 2**-80.  The main motivation for the
+     * $t parameter is distributability.  BigInteger::randomPrime() can be distributed across multiple pageloads
+     * on a website instead of just one.
+     *
+     * @param \phpseclib\Math\BigInteger $t
+     * @return bool
+     * @access public
+     * @internal Uses the
+     *     {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}.  See
+     *     {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}.
+     */
+    function isPrime($t = false)
+    {
+        $length = strlen($this->toBytes());
+
+        if (!$t) {
+            // see HAC 4.49 "Note (controlling the error probability)"
+            // @codingStandardsIgnoreStart
+                 if ($length >= 163) { $t =  2; } // floor(1300 / 8)
+            else if ($length >= 106) { $t =  3; } // floor( 850 / 8)
+            else if ($length >= 81 ) { $t =  4; } // floor( 650 / 8)
+            else if ($length >= 68 ) { $t =  5; } // floor( 550 / 8)
+            else if ($length >= 56 ) { $t =  6; } // floor( 450 / 8)
+            else if ($length >= 50 ) { $t =  7; } // floor( 400 / 8)
+            else if ($length >= 43 ) { $t =  8; } // floor( 350 / 8)
+            else if ($length >= 37 ) { $t =  9; } // floor( 300 / 8)
+            else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8)
+            else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8)
+            else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8)
+            else                     { $t = 27; }
+            // @codingStandardsIgnoreEnd
+        }
+
+        // ie. gmp_testbit($this, 0)
+        // ie. isEven() or !isOdd()
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                return gmp_prob_prime($this->value, $t) != 0;
+            case self::MODE_BCMATH:
+                if ($this->value === '2') {
+                    return true;
+                }
+                if ($this->value[strlen($this->value) - 1] % 2 == 0) {
+                    return false;
+                }
+                break;
+            default:
+                if ($this->value == array(2)) {
+                    return true;
+                }
+                if (~$this->value[0] & 1) {
+                    return false;
+                }
+        }
+
+        static $primes, $zero, $one, $two;
+
+        if (!isset($primes)) {
+            $primes = array(
+                3,    5,    7,    11,   13,   17,   19,   23,   29,   31,   37,   41,   43,   47,   53,   59,
+                61,   67,   71,   73,   79,   83,   89,   97,   101,  103,  107,  109,  113,  127,  131,  137,
+                139,  149,  151,  157,  163,  167,  173,  179,  181,  191,  193,  197,  199,  211,  223,  227,
+                229,  233,  239,  241,  251,  257,  263,  269,  271,  277,  281,  283,  293,  307,  311,  313,
+                317,  331,  337,  347,  349,  353,  359,  367,  373,  379,  383,  389,  397,  401,  409,  419,
+                421,  431,  433,  439,  443,  449,  457,  461,  463,  467,  479,  487,  491,  499,  503,  509,
+                521,  523,  541,  547,  557,  563,  569,  571,  577,  587,  593,  599,  601,  607,  613,  617,
+                619,  631,  641,  643,  647,  653,  659,  661,  673,  677,  683,  691,  701,  709,  719,  727,
+                733,  739,  743,  751,  757,  761,  769,  773,  787,  797,  809,  811,  821,  823,  827,  829,
+                839,  853,  857,  859,  863,  877,  881,  883,  887,  907,  911,  919,  929,  937,  941,  947,
+                953,  967,  971,  977,  983,  991,  997
+            );
+
+            if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+                for ($i = 0; $i < count($primes); ++$i) {
+                    $primes[$i] = new static($primes[$i]);
+                }
+            }
+
+            $zero = new static();
+            $one = new static(1);
+            $two = new static(2);
+        }
+
+        if ($this->equals($one)) {
+            return false;
+        }
+
+        // see HAC 4.4.1 "Random search for probable primes"
+        if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+            foreach ($primes as $prime) {
+                list(, $r) = $this->divide($prime);
+                if ($r->equals($zero)) {
+                    return $this->equals($prime);
+                }
+            }
+        } else {
+            $value = $this->value;
+            foreach ($primes as $prime) {
+                list(, $r) = $this->_divide_digit($value, $prime);
+                if (!$r) {
+                    return count($value) == 1 && $value[0] == $prime;
+                }
+            }
+        }
+
+        $n   = $this->copy();
+        $n_1 = $n->subtract($one);
+        $n_2 = $n->subtract($two);
+
+        $r = $n_1->copy();
+        $r_value = $r->value;
+        // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
+        if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
+            $s = 0;
+            // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
+            while ($r->value[strlen($r->value) - 1] % 2 == 0) {
+                $r->value = bcdiv($r->value, '2', 0);
+                ++$s;
+            }
+        } else {
+            for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
+                $temp = ~$r_value[$i] & 0xFFFFFF;
+                for ($j = 1; ($temp >> $j) & 1; ++$j) {
+                }
+                if ($j != 25) {
+                    break;
+                }
+            }
+            $s = 26 * $i + $j;
+            $r->_rshift($s);
+        }
+
+        for ($i = 0; $i < $t; ++$i) {
+            $a = $this->random($two, $n_2);
+            $y = $a->modPow($r, $n);
+
+            if (!$y->equals($one) && !$y->equals($n_1)) {
+                for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {
+                    $y = $y->modPow($two, $n);
+                    if ($y->equals($one)) {
+                        return false;
+                    }
+                }
+
+                if (!$y->equals($n_1)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Logical Left Shift
+     *
+     * Shifts BigInteger's by $shift bits.
+     *
+     * @param int $shift
+     * @access private
+     */
+    function _lshift($shift)
+    {
+        if ($shift == 0) {
+            return;
+        }
+
+        $num_digits = (int) ($shift / self::$base);
+        $shift %= self::$base;
+        $shift = 1 << $shift;
+
+        $carry = 0;
+
+        for ($i = 0; $i < count($this->value); ++$i) {
+            $temp = $this->value[$i] * $shift + $carry;
+            $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+            $this->value[$i] = (int) ($temp - $carry * self::$baseFull);
+        }
+
+        if ($carry) {
+            $this->value[count($this->value)] = $carry;
+        }
+
+        while ($num_digits--) {
+            array_unshift($this->value, 0);
+        }
+    }
+
+    /**
+     * Logical Right Shift
+     *
+     * Shifts BigInteger's by $shift bits.
+     *
+     * @param int $shift
+     * @access private
+     */
+    function _rshift($shift)
+    {
+        if ($shift == 0) {
+            return;
+        }
+
+        $num_digits = (int) ($shift / self::$base);
+        $shift %= self::$base;
+        $carry_shift = self::$base - $shift;
+        $carry_mask = (1 << $shift) - 1;
+
+        if ($num_digits) {
+            $this->value = array_slice($this->value, $num_digits);
+        }
+
+        $carry = 0;
+
+        for ($i = count($this->value) - 1; $i >= 0; --$i) {
+            $temp = $this->value[$i] >> $shift | $carry;
+            $carry = ($this->value[$i] & $carry_mask) << $carry_shift;
+            $this->value[$i] = $temp;
+        }
+
+        $this->value = $this->_trim($this->value);
+    }
+
+    /**
+     * Normalize
+     *
+     * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision
+     *
+     * @param \phpseclib\Math\BigInteger $result
+     * @return \phpseclib\Math\BigInteger
+     * @see self::_trim()
+     * @access private
+     */
+    function _normalize($result)
+    {
+        $result->precision = $this->precision;
+        $result->bitmask = $this->bitmask;
+
+        switch (MATH_BIGINTEGER_MODE) {
+            case self::MODE_GMP:
+                if ($this->bitmask !== false) {
+                    $flip = gmp_cmp($result->value, gmp_init(0)) < 0;
+                    if ($flip) {
+                        $result->value = gmp_neg($result->value);
+                    }
+                    $result->value = gmp_and($result->value, $result->bitmask->value);
+                    if ($flip) {
+                        $result->value = gmp_neg($result->value);
+                    }
+                }
+
+                return $result;
+            case self::MODE_BCMATH:
+                if (!empty($result->bitmask->value)) {
+                    $result->value = bcmod($result->value, $result->bitmask->value);
+                }
+
+                return $result;
+        }
+
+        $value = &$result->value;
+
+        if (!count($value)) {
+            $result->is_negative = false;
+            return $result;
+        }
+
+        $value = $this->_trim($value);
+
+        if (!empty($result->bitmask->value)) {
+            $length = min(count($value), count($this->bitmask->value));
+            $value = array_slice($value, 0, $length);
+
+            for ($i = 0; $i < $length; ++$i) {
+                $value[$i] = $value[$i] & $this->bitmask->value[$i];
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Trim
+     *
+     * Removes leading zeros
+     *
+     * @param array $value
+     * @return \phpseclib\Math\BigInteger
+     * @access private
+     */
+    function _trim($value)
+    {
+        for ($i = count($value) - 1; $i >= 0; --$i) {
+            if ($value[$i]) {
+                break;
+            }
+            unset($value[$i]);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Array Repeat
+     *
+     * @param array $input
+     * @param mixed $multiplier
+     * @return array
+     * @access private
+     */
+    function _array_repeat($input, $multiplier)
+    {
+        return ($multiplier) ? array_fill(0, $multiplier, $input) : array();
+    }
+
+    /**
+     * Logical Left Shift
+     *
+     * Shifts binary strings $shift bits, essentially multiplying by 2**$shift.
+     *
+     * @param string $x (by reference)
+     * @param int $shift
+     * @return string
+     * @access private
+     */
+    function _base256_lshift(&$x, $shift)
+    {
+        if ($shift == 0) {
+            return;
+        }
+
+        $num_bytes = $shift >> 3; // eg. floor($shift/8)
+        $shift &= 7; // eg. $shift % 8
+
+        $carry = 0;
+        for ($i = strlen($x) - 1; $i >= 0; --$i) {
+            $temp = ord($x[$i]) << $shift | $carry;
+            $x[$i] = chr($temp);
+            $carry = $temp >> 8;
+        }
+        $carry = ($carry != 0) ? chr($carry) : '';
+        $x = $carry . $x . str_repeat(chr(0), $num_bytes);
+    }
+
+    /**
+     * Logical Right Shift
+     *
+     * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder.
+     *
+     * @param string $x (by referenc)
+     * @param int $shift
+     * @return string
+     * @access private
+     */
+    function _base256_rshift(&$x, $shift)
+    {
+        if ($shift == 0) {
+            $x = ltrim($x, chr(0));
+            return '';
+        }
+
+        $num_bytes = $shift >> 3; // eg. floor($shift/8)
+        $shift &= 7; // eg. $shift % 8
+
+        $remainder = '';
+        if ($num_bytes) {
+            $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes;
+            $remainder = substr($x, $start);
+            $x = substr($x, 0, -$num_bytes);
+        }
+
+        $carry = 0;
+        $carry_shift = 8 - $shift;
+        for ($i = 0; $i < strlen($x); ++$i) {
+            $temp = (ord($x[$i]) >> $shift) | $carry;
+            $carry = (ord($x[$i]) << $carry_shift) & 0xFF;
+            $x[$i] = chr($temp);
+        }
+        $x = ltrim($x, chr(0));
+
+        $remainder = chr($carry >> $carry_shift) . $remainder;
+
+        return ltrim($remainder, chr(0));
+    }
+
+    // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long
+    // at 32-bits, while java's longs are 64-bits.
+
+    /**
+     * Converts 32-bit integers to bytes.
+     *
+     * @param int $x
+     * @return string
+     * @access private
+     */
+    function _int2bytes($x)
+    {
+        return ltrim(pack('N', $x), chr(0));
+    }
+
+    /**
+     * Converts bytes to 32-bit integers
+     *
+     * @param string $x
+     * @return int
+     * @access private
+     */
+    function _bytes2int($x)
+    {
+        $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));
+        return $temp['int'];
+    }
+
+    /**
+     * DER-encode an integer
+     *
+     * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL
+     *
+     * @see self::modPow()
+     * @access private
+     * @param int $length
+     * @return string
+     */
+    function _encodeASN1Length($length)
+    {
+        if ($length <= 0x7F) {
+            return chr($length);
+        }
+
+        $temp = ltrim(pack('N', $length), chr(0));
+        return pack('Ca*', 0x80 | strlen($temp), $temp);
+    }
+
+    /**
+     * Single digit division
+     *
+     * Even if int64 is being used the division operator will return a float64 value
+     * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't
+     * have the precision of int64 this is a problem so, when int64 is being used,
+     * we'll guarantee that the dividend is divisible by first subtracting the remainder.
+     *
+     * @access private
+     * @param int $x
+     * @param int $y
+     * @return int
+     */
+    function _safe_divide($x, $y)
+    {
+        if (self::$base === 26) {
+            return (int) ($x / $y);
+        }
+
+        // self::$base === 31
+        return ($x - ($x % $y)) / $y;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
new file mode 100644
index 00000000..ee6e1c9d
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
@@ -0,0 +1,349 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SCP.
+ *
+ * PHP version 5
+ *
+ * The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ *    if (!$ssh->login('username', 'password')) {
+ *        exit('bad login');
+ *    }
+ *    $scp = new \phpseclib\Net\SCP($ssh);
+ *
+ *    $scp->put('abcd', str_repeat('x', 1024*1024));
+ * ?>
+ * </code>
+ *
+ * @category  Net
+ * @package   SCP
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2010 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+/**
+ * Pure-PHP implementations of SCP.
+ *
+ * @package SCP
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class SCP
+{
+    /**#@+
+     * @access public
+     * @see \phpseclib\Net\SCP::put()
+     */
+    /**
+     * Reads data from a local file.
+     */
+    const SOURCE_LOCAL_FILE = 1;
+    /**
+     * Reads data from a string.
+     */
+    const SOURCE_STRING = 2;
+    /**#@-*/
+
+    /**#@+
+     * @access private
+     * @see \phpseclib\Net\SCP::_send()
+     * @see \phpseclib\Net\SCP::_receive()
+    */
+    /**
+     * SSH1 is being used.
+     */
+    const MODE_SSH1 = 1;
+    /**
+     * SSH2 is being used.
+     */
+    const MODE_SSH2 =  2;
+    /**#@-*/
+
+    /**
+     * SSH Object
+     *
+     * @var object
+     * @access private
+     */
+    var $ssh;
+
+    /**
+     * Packet Size
+     *
+     * @var int
+     * @access private
+     */
+    var $packet_size;
+
+    /**
+     * Mode
+     *
+     * @var int
+     * @access private
+     */
+    var $mode;
+
+    /**
+     * Default Constructor.
+     *
+     * Connects to an SSH server
+     *
+     * @param \phpseclib\Net\SSH1|\phpseclib\Net\SSH2 $ssh
+     * @return \phpseclib\Net\SCP
+     * @access public
+     */
+    function __construct($ssh)
+    {
+        if ($ssh instanceof SSH2) {
+            $this->mode = self::MODE_SSH2;
+        } elseif ($ssh instanceof SSH1) {
+            $this->packet_size = 50000;
+            $this->mode = self::MODE_SSH1;
+        } else {
+            return;
+        }
+
+        $this->ssh = $ssh;
+    }
+
+    /**
+     * Uploads a file to the SCP server.
+     *
+     * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem.  $data is dumped directly into $remote_file.
+     * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes
+     * long, containing 'filename.ext' as its contents.
+     *
+     * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior.  With self::SOURCE_LOCAL_FILE, $remote_file will
+     * contain as many bytes as filename.ext does on your local filesystem.  If your filename.ext is 1MB then that is how
+     * large $remote_file will be, as well.
+     *
+     * Currently, only binary mode is supported.  As such, if the line endings need to be adjusted, you will need to take
+     * care of that, yourself.
+     *
+     * @param string $remote_file
+     * @param string $data
+     * @param int $mode
+     * @param callable $callback
+     * @return bool
+     * @access public
+     */
+    function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
+    {
+        if (!isset($this->ssh)) {
+            return false;
+        }
+
+        if (empty($remote_file)) {
+            user_error('remote_file cannot be blank', E_USER_NOTICE);
+            return false;
+        }
+
+        if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
+            return false;
+        }
+
+        $temp = $this->_receive();
+        if ($temp !== chr(0)) {
+            return false;
+        }
+
+        if ($this->mode == self::MODE_SSH2) {
+            $this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4;
+        }
+
+        $remote_file = basename($remote_file);
+
+        if ($mode == self::SOURCE_STRING) {
+            $size = strlen($data);
+        } else {
+            if (!is_file($data)) {
+                user_error("$data is not a valid file", E_USER_NOTICE);
+                return false;
+            }
+
+            $fp = @fopen($data, 'rb');
+            if (!$fp) {
+                return false;
+            }
+            $size = filesize($data);
+        }
+
+        $this->_send('C0644 ' . $size . ' ' . $remote_file . "\n");
+
+        $temp = $this->_receive();
+        if ($temp !== chr(0)) {
+            return false;
+        }
+
+        $sent = 0;
+        while ($sent < $size) {
+            $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
+            $this->_send($temp);
+            $sent+= strlen($temp);
+
+            if (is_callable($callback)) {
+                call_user_func($callback, $sent);
+            }
+        }
+        $this->_close();
+
+        if ($mode != self::SOURCE_STRING) {
+            fclose($fp);
+        }
+
+        return true;
+    }
+
+    /**
+     * Downloads a file from the SCP server.
+     *
+     * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
+     * the operation was unsuccessful.  If $local_file is defined, returns true or false depending on the success of the
+     * operation
+     *
+     * @param string $remote_file
+     * @param string $local_file
+     * @return mixed
+     * @access public
+     */
+    function get($remote_file, $local_file = false)
+    {
+        if (!isset($this->ssh)) {
+            return false;
+        }
+
+        if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
+            return false;
+        }
+
+        $this->_send("\0");
+
+        if (!preg_match('#(?<perms>[^ ]+) (?<size>\d+) (?<name>.+)#', rtrim($this->_receive()), $info)) {
+            return false;
+        }
+
+        $this->_send("\0");
+
+        $size = 0;
+
+        if ($local_file !== false) {
+            $fp = @fopen($local_file, 'wb');
+            if (!$fp) {
+                return false;
+            }
+        }
+
+        $content = '';
+        while ($size < $info['size']) {
+            $data = $this->_receive();
+
+            // Terminate the loop in case the server repeatedly sends an empty response
+            if ($data === false) {
+                user_error('No data received from server', E_USER_NOTICE);
+                return false;
+            }
+
+            // SCP usually seems to split stuff out into 16k chunks
+            $size+= strlen($data);
+
+            if ($local_file === false) {
+                $content.= $data;
+            } else {
+                fputs($fp, $data);
+            }
+        }
+
+        $this->_close();
+
+        if ($local_file !== false) {
+            fclose($fp);
+            return true;
+        }
+
+        return $content;
+    }
+
+    /**
+     * Sends a packet to an SSH server
+     *
+     * @param string $data
+     * @access private
+     */
+    function _send($data)
+    {
+        switch ($this->mode) {
+            case self::MODE_SSH2:
+                $this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data);
+                break;
+            case self::MODE_SSH1:
+                $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
+                $this->ssh->_send_binary_packet($data);
+        }
+    }
+
+    /**
+     * Receives a packet from an SSH server
+     *
+     * @return string
+     * @access private
+     */
+    function _receive()
+    {
+        switch ($this->mode) {
+            case self::MODE_SSH2:
+                return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true);
+            case self::MODE_SSH1:
+                if (!$this->ssh->bitmap) {
+                    return false;
+                }
+                while (true) {
+                    $response = $this->ssh->_get_binary_packet();
+                    switch ($response[SSH1::RESPONSE_TYPE]) {
+                        case NET_SSH1_SMSG_STDOUT_DATA:
+                            if (strlen($response[SSH1::RESPONSE_DATA]) < 4) {
+                                return false;
+                            }
+                            extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
+                            return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length);
+                        case NET_SSH1_SMSG_STDERR_DATA:
+                            break;
+                        case NET_SSH1_SMSG_EXITSTATUS:
+                            $this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
+                            fclose($this->ssh->fsock);
+                            $this->ssh->bitmap = 0;
+                            return false;
+                        default:
+                            user_error('Unknown packet received', E_USER_NOTICE);
+                            return false;
+                    }
+                }
+        }
+    }
+
+    /**
+     * Closes the connection to an SSH server
+     *
+     * @access private
+     */
+    function _close()
+    {
+        switch ($this->mode) {
+            case self::MODE_SSH2:
+                $this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true);
+                break;
+            case self::MODE_SSH1:
+                $this->ssh->disconnect();
+        }
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
new file mode 100644
index 00000000..cdccd60e
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
@@ -0,0 +1,3901 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SFTP.
+ *
+ * PHP version 5
+ *
+ * Supports SFTPv2/3/4/5/6. Defaults to v3.
+ *
+ * The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $sftp = new \phpseclib\Net\SFTP('www.domain.tld');
+ *    if (!$sftp->login('username', 'password')) {
+ *        exit('Login Failed');
+ *    }
+ *
+ *    echo $sftp->pwd() . "\r\n";
+ *    $sftp->put('filename.ext', 'hello, world!');
+ *    print_r($sftp->nlist());
+ * ?>
+ * </code>
+ *
+ * @category  Net
+ * @package   SFTP
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2009 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+/**
+ * Pure-PHP implementations of SFTP.
+ *
+ * @package SFTP
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class SFTP extends SSH2
+{
+    /**
+     * SFTP channel constant
+     *
+     * \phpseclib\Net\SSH2::exec() uses 0 and \phpseclib\Net\SSH2::read() / \phpseclib\Net\SSH2::write() use 1.
+     *
+     * @see \phpseclib\Net\SSH2::_send_channel_packet()
+     * @see \phpseclib\Net\SSH2::_get_channel_packet()
+     * @access private
+     */
+    const CHANNEL = 0x100;
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Net\SFTP::put()
+    */
+    /**
+     * Reads data from a local file.
+     */
+    const SOURCE_LOCAL_FILE = 1;
+    /**
+     * Reads data from a string.
+     */
+    // this value isn't really used anymore but i'm keeping it reserved for historical reasons
+    const SOURCE_STRING = 2;
+    /**
+     * Reads data from callback:
+     * function callback($length) returns string to proceed, null for EOF
+     */
+    const SOURCE_CALLBACK = 16;
+    /**
+     * Resumes an upload
+     */
+    const RESUME = 4;
+    /**
+     * Append a local file to an already existing remote file
+     */
+    const RESUME_START = 8;
+    /**#@-*/
+
+    /**
+     * Packet Types
+     *
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $packet_types = array();
+
+    /**
+     * Status Codes
+     *
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $status_codes = array();
+
+    /**
+     * The Request ID
+     *
+     * The request ID exists in the off chance that a packet is sent out-of-order.  Of course, this library doesn't support
+     * concurrent actions, so it's somewhat academic, here.
+     *
+     * @var boolean
+     * @see self::_send_sftp_packet()
+     * @access private
+     */
+    var $use_request_id = false;
+
+    /**
+     * The Packet Type
+     *
+     * The request ID exists in the off chance that a packet is sent out-of-order.  Of course, this library doesn't support
+     * concurrent actions, so it's somewhat academic, here.
+     *
+     * @var int
+     * @see self::_get_sftp_packet()
+     * @access private
+     */
+    var $packet_type = -1;
+
+    /**
+     * Packet Buffer
+     *
+     * @var string
+     * @see self::_get_sftp_packet()
+     * @access private
+     */
+    var $packet_buffer = '';
+
+    /**
+     * Extensions supported by the server
+     *
+     * @var array
+     * @see self::_initChannel()
+     * @access private
+     */
+    var $extensions = array();
+
+    /**
+     * Server SFTP version
+     *
+     * @var int
+     * @see self::_initChannel()
+     * @access private
+     */
+    var $version;
+
+    /**
+     * Default Server SFTP version
+     *
+     * @var int
+     * @see self::_initChannel()
+     * @access private
+     */
+    var $defaultVersion;
+
+    /**
+     * Preferred SFTP version
+     *
+     * @var int
+     * @see self::_initChannel()
+     * @access private
+     */
+    var $preferredVersion = 3;
+
+    /**
+     * Current working directory
+     *
+     * @var string
+     * @see self::realpath()
+     * @see self::chdir()
+     * @access private
+     */
+    var $pwd = false;
+
+    /**
+     * Packet Type Log
+     *
+     * @see self::getLog()
+     * @var array
+     * @access private
+     */
+    var $packet_type_log = array();
+
+    /**
+     * Packet Log
+     *
+     * @see self::getLog()
+     * @var array
+     * @access private
+     */
+    var $packet_log = array();
+
+    /**
+     * Error information
+     *
+     * @see self::getSFTPErrors()
+     * @see self::getLastSFTPError()
+     * @var array
+     * @access private
+     */
+    var $sftp_errors = array();
+
+    /**
+     * Stat Cache
+     *
+     * Rather than always having to open a directory and close it immediately there after to see if a file is a directory
+     * we'll cache the results.
+     *
+     * @see self::_update_stat_cache()
+     * @see self::_remove_from_stat_cache()
+     * @see self::_query_stat_cache()
+     * @var array
+     * @access private
+     */
+    var $stat_cache = array();
+
+    /**
+     * Max SFTP Packet Size
+     *
+     * @see self::__construct()
+     * @see self::get()
+     * @var array
+     * @access private
+     */
+    var $max_sftp_packet;
+
+    /**
+     * Stat Cache Flag
+     *
+     * @see self::disableStatCache()
+     * @see self::enableStatCache()
+     * @var bool
+     * @access private
+     */
+    var $use_stat_cache = true;
+
+    /**
+     * Sort Options
+     *
+     * @see self::_comparator()
+     * @see self::setListOrder()
+     * @var array
+     * @access private
+     */
+    var $sortOptions = array();
+
+    /**
+     * Canonicalization Flag
+     *
+     * Determines whether or not paths should be canonicalized before being
+     * passed on to the remote server.
+     *
+     * @see self::enablePathCanonicalization()
+     * @see self::disablePathCanonicalization()
+     * @see self::realpath()
+     * @var bool
+     * @access private
+     */
+    var $canonicalize_paths = true;
+
+    /**
+     * Request Buffers
+     *
+     * @see self::_get_sftp_packet()
+     * @var array
+     * @access private
+     */
+    var $requestBuffer = array();
+
+    /**
+     * Preserve timestamps on file downloads / uploads
+     *
+     * @see self::get()
+     * @see self::put()
+     * @var bool
+     * @access private
+     */
+    var $preserveTime = false;
+
+    /**
+     * Arbitrary Length Packets Flag
+     *
+     * Determines whether or not packets of any length should be allowed,
+     * in cases where the server chooses the packet length (such as
+     * directory listings). By default, packets are only allowed to be
+     * 256 * 1024 bytes (SFTP_MAX_MSG_LENGTH from OpenSSH's sftp-common.h)
+     *
+     * @see self::enableArbitraryLengthPackets()
+     * @see self::_get_sftp_packet()
+     * @var bool
+     * @access private
+     */
+    var $allow_arbitrary_length_packets = false;
+
+    /**
+     * Was the last packet due to the channels being closed or not?
+     *
+     * @see self::get()
+     * @see self::get_sftp_packet()
+     * @var bool
+     * @access private
+     */
+    var $channel_close = false;
+
+    /**
+     * Has the SFTP channel been partially negotiated?
+     *
+     * @var bool
+     * @access private
+     */
+    var $partial_init = false;
+
+    /**
+     * http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
+     * the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why
+     *
+     * @var array
+     * @access private
+     */
+    var $attributes = array();
+
+    /**
+     * @var array
+     * @access private
+     */
+    var $open_flags = array();
+
+    /**
+     * SFTPv5+ changed the flags up:
+     * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3
+     *
+     * @var array
+     * @access private
+     */
+    var $open_flags5 = array();
+
+    /**
+     * http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
+     * see \phpseclib\Net\SFTP::_parseLongname() for an explanation
+     *
+     * @var array
+     */
+    var $file_types = array();
+
+    /**
+     * Default Constructor.
+     *
+     * Connects to an SFTP server
+     *
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
+     * @return \phpseclib\Net\SFTP
+     * @access public
+     */
+    function __construct($host, $port = 22, $timeout = 10)
+    {
+        parent::__construct($host, $port, $timeout);
+
+        $this->max_sftp_packet = 1 << 15;
+
+        $this->packet_types = array(
+            1  => 'NET_SFTP_INIT',
+            2  => 'NET_SFTP_VERSION',
+            3  => 'NET_SFTP_OPEN',
+            4  => 'NET_SFTP_CLOSE',
+            5  => 'NET_SFTP_READ',
+            6  => 'NET_SFTP_WRITE',
+            7  => 'NET_SFTP_LSTAT',
+            9  => 'NET_SFTP_SETSTAT',
+            10 => 'NET_SFTP_FSETSTAT',
+            11 => 'NET_SFTP_OPENDIR',
+            12 => 'NET_SFTP_READDIR',
+            13 => 'NET_SFTP_REMOVE',
+            14 => 'NET_SFTP_MKDIR',
+            15 => 'NET_SFTP_RMDIR',
+            16 => 'NET_SFTP_REALPATH',
+            17 => 'NET_SFTP_STAT',
+            18 => 'NET_SFTP_RENAME',
+            19 => 'NET_SFTP_READLINK',
+            20 => 'NET_SFTP_SYMLINK',
+            21 => 'NET_SFTP_LINK',
+
+            101=> 'NET_SFTP_STATUS',
+            102=> 'NET_SFTP_HANDLE',
+            103=> 'NET_SFTP_DATA',
+            104=> 'NET_SFTP_NAME',
+            105=> 'NET_SFTP_ATTRS',
+
+            200=> 'NET_SFTP_EXTENDED'
+        );
+        $this->status_codes = array(
+            0 => 'NET_SFTP_STATUS_OK',
+            1 => 'NET_SFTP_STATUS_EOF',
+            2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',
+            3 => 'NET_SFTP_STATUS_PERMISSION_DENIED',
+            4 => 'NET_SFTP_STATUS_FAILURE',
+            5 => 'NET_SFTP_STATUS_BAD_MESSAGE',
+            6 => 'NET_SFTP_STATUS_NO_CONNECTION',
+            7 => 'NET_SFTP_STATUS_CONNECTION_LOST',
+            8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED',
+            9 => 'NET_SFTP_STATUS_INVALID_HANDLE',
+            10 => 'NET_SFTP_STATUS_NO_SUCH_PATH',
+            11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS',
+            12 => 'NET_SFTP_STATUS_WRITE_PROTECT',
+            13 => 'NET_SFTP_STATUS_NO_MEDIA',
+            14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM',
+            15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED',
+            16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL',
+            17 => 'NET_SFTP_STATUS_LOCK_CONFLICT',
+            18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY',
+            19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY',
+            20 => 'NET_SFTP_STATUS_INVALID_FILENAME',
+            21 => 'NET_SFTP_STATUS_LINK_LOOP',
+            22 => 'NET_SFTP_STATUS_CANNOT_DELETE',
+            23 => 'NET_SFTP_STATUS_INVALID_PARAMETER',
+            24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY',
+            25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT',
+            26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED',
+            27 => 'NET_SFTP_STATUS_DELETE_PENDING',
+            28 => 'NET_SFTP_STATUS_FILE_CORRUPT',
+            29 => 'NET_SFTP_STATUS_OWNER_INVALID',
+            30 => 'NET_SFTP_STATUS_GROUP_INVALID',
+            31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK'
+        );
+        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
+        // the order, in this case, matters quite a lot - see \phpseclib\Net\SFTP::_parseAttributes() to understand why
+        $this->attributes = array(
+            0x00000001 => 'NET_SFTP_ATTR_SIZE',
+            0x00000002 => 'NET_SFTP_ATTR_UIDGID',          // defined in SFTPv3, removed in SFTPv4+
+            0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP',      // defined in SFTPv4+
+            0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS',
+            0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME',
+            0x00000010 => 'NET_SFTP_ATTR_CREATETIME',      // SFTPv4+
+            0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME',
+            0x00000040 => 'NET_SFTP_ATTR_ACL',
+            0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES',
+            0x00000200 => 'NET_SFTP_ATTR_BITS',            // SFTPv5+
+            0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+
+            0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT',
+            0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE',
+            0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT',
+            0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME',
+            0x00008000 => 'NET_SFTP_ATTR_CTIME',
+            // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers
+            // yields inconsistent behavior depending on how php is compiled.  so we left shift -1 (which, in
+            // two's compliment, consists of all 1 bits) by 31.  on 64-bit systems this'll yield 0xFFFFFFFF80000000.
+            // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
+            (PHP_INT_SIZE == 4 ? -1 : 0xFFFFFFFF) => 'NET_SFTP_ATTR_EXTENDED'
+        );
+        $this->open_flags = array(
+            0x00000001 => 'NET_SFTP_OPEN_READ',
+            0x00000002 => 'NET_SFTP_OPEN_WRITE',
+            0x00000004 => 'NET_SFTP_OPEN_APPEND',
+            0x00000008 => 'NET_SFTP_OPEN_CREATE',
+            0x00000010 => 'NET_SFTP_OPEN_TRUNCATE',
+            0x00000020 => 'NET_SFTP_OPEN_EXCL',
+            0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4
+        );
+        // SFTPv5+ changed the flags up:
+        // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3
+        $this->open_flags5 = array(
+            // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened
+            0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW',
+            0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE',
+            0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING',
+            0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE',
+            0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING',
+            // the rest of the flags are not supported
+            0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored"
+            0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC',
+            0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE',
+            0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ',
+            0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE',
+            0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE',
+            0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY',
+            0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW',
+            0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE',
+            0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO',
+            0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP',
+            0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM',
+            0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER',
+        );
+        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
+        // see \phpseclib\Net\SFTP::_parseLongname() for an explanation
+        $this->file_types = array(
+            1 => 'NET_SFTP_TYPE_REGULAR',
+            2 => 'NET_SFTP_TYPE_DIRECTORY',
+            3 => 'NET_SFTP_TYPE_SYMLINK',
+            4 => 'NET_SFTP_TYPE_SPECIAL',
+            5 => 'NET_SFTP_TYPE_UNKNOWN',
+            // the followin types were first defined for use in SFTPv5+
+            // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
+            6 => 'NET_SFTP_TYPE_SOCKET',
+            7 => 'NET_SFTP_TYPE_CHAR_DEVICE',
+            8 => 'NET_SFTP_TYPE_BLOCK_DEVICE',
+            9 => 'NET_SFTP_TYPE_FIFO'
+        );
+        $this->_define_array(
+            $this->packet_types,
+            $this->status_codes,
+            $this->attributes,
+            $this->open_flags,
+            $this->open_flags5,
+            $this->file_types
+        );
+
+        if (!defined('NET_SFTP_QUEUE_SIZE')) {
+            define('NET_SFTP_QUEUE_SIZE', 32);
+        }
+        if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) {
+            define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024);
+        }
+    }
+
+    /**
+     * Check a few things before SFTP functions are called
+     *
+     * @return bool
+     * @access public
+     */
+    function _precheck()
+    {
+        if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+            return false;
+        }
+
+        if ($this->pwd === false) {
+            return $this->_init_sftp_connection();
+        }
+
+        return true;
+    }
+
+    /**
+     * Partially initialize an SFTP connection
+     *
+     * @return bool
+     * @access public
+     */
+    function _partial_init_sftp_connection()
+    {
+        $this->window_size_server_to_client[self::CHANNEL] = $this->window_size;
+
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            self::CHANNEL,
+            $this->window_size,
+            0x4000
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+        $response = $this->_get_channel_packet(self::CHANNEL, true);
+        if ($response === false) {
+            return false;
+        } elseif ($response === true && $this->isTimeout()) {
+            return false;
+        }
+
+        $packet = pack(
+            'CNNa*CNa*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[self::CHANNEL],
+            strlen('subsystem'),
+            'subsystem',
+            1,
+            strlen('sftp'),
+            'sftp'
+        );
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+        $response = $this->_get_channel_packet(self::CHANNEL, true);
+        if ($response === false) {
+            // from PuTTY's psftp.exe
+            $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
+                       "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" .
+                       "exec sftp-server";
+            // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does
+            // is redundant
+            $packet = pack(
+                'CNNa*CNa*',
+                NET_SSH2_MSG_CHANNEL_REQUEST,
+                $this->server_channels[self::CHANNEL],
+                strlen('exec'),
+                'exec',
+                1,
+                strlen($command),
+                $command
+            );
+            if (!$this->_send_binary_packet($packet)) {
+                return false;
+            }
+
+            $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+            $response = $this->_get_channel_packet(self::CHANNEL, true);
+            if ($response === false) {
+                return false;
+            }
+        } elseif ($response === true && $this->isTimeout()) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
+
+        if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_VERSION) {
+            user_error('Expected SSH_FXP_VERSION');
+            return false;
+        }
+
+        $this->use_request_id = true;
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nversion', $this->_string_shift($response, 4)));
+        $this->defaultVersion = $version;
+        while (!empty($response)) {
+            if (strlen($response) < 4) {
+                return false;
+            }
+            extract(unpack('Nlength', $this->_string_shift($response, 4)));
+            $key = $this->_string_shift($response, $length);
+            if (strlen($response) < 4) {
+                return false;
+            }
+            extract(unpack('Nlength', $this->_string_shift($response, 4)));
+            $value = $this->_string_shift($response, $length);
+            $this->extensions[$key] = $value;
+        }
+
+        $this->partial_init = true;
+
+        return true;
+    }
+
+    /**
+     * (Re)initializes the SFTP channel
+     *
+     * @return bool
+     * @access private
+     */
+    function _init_sftp_connection()
+    {
+        if (!$this->partial_init && !$this->_partial_init_sftp_connection()) {
+            return false;
+        }
+
+        /*
+         A Note on SFTPv4/5/6 support:
+         <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.1> states the following:
+
+         "If the client wishes to interoperate with servers that support noncontiguous version
+          numbers it SHOULD send '3'"
+
+         Given that the server only sends its version number after the client has already done so, the above
+         seems to be suggesting that v3 should be the default version.  This makes sense given that v3 is the
+         most popular.
+
+         <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.5> states the following;
+
+         "If the server did not send the "versions" extension, or the version-from-list was not included, the
+          server MAY send a status response describing the failure, but MUST then close the channel without
+          processing any further requests."
+
+         So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and
+         a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4?  If it only implements
+         v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed
+         in draft-ietf-secsh-filexfer-13 would be quite impossible.  As such, what \phpseclib\Net\SFTP would do is close the
+         channel and reopen it with a new and updated SSH_FXP_INIT packet.
+        */
+        $this->version = $this->defaultVersion;
+        if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) {
+            $versions = explode(',', $this->extensions['versions']);
+            $supported = array(6, 5, 4);
+            if ($this->preferredVersion) {
+                $supported = array_diff($supported, array($this->preferredVersion));
+                array_unshift($supported, $this->preferredVersion);
+            }
+            foreach ($supported as $ver) {
+                if (in_array($ver, $versions)) {
+                    if ($ver === $this->version) {
+                        break;
+                    }
+                    $this->version = (int) $ver;
+                    $packet = pack('Na*Na*', strlen('version-select'), 'version-select', strlen($ver), $ver);
+                    if (!$this->_send_sftp_packet(NET_SFTP_EXTENDED, $packet)) {
+                        return false;
+                    }
+                    $response = $this->_get_sftp_packet();
+                    if ($this->packet_type != NET_SFTP_STATUS) {
+                        user_error('Expected SSH_FXP_STATUS');
+                        return false;
+                    }
+
+                    if (strlen($response) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+                    if ($status != NET_SFTP_STATUS_OK) {
+                        $this->_logError($response, $status);
+                        return false;
+                    }
+
+                    break;
+                }
+            }
+        }
+
+        /*
+         SFTPv4+ defines a 'newline' extension.  SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com',
+         however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's
+         not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for
+         one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that
+         'newline@vandyke.com' would.
+        */
+        /*
+        if (isset($this->extensions['newline@vandyke.com'])) {
+            $this->extensions['newline'] = $this->extensions['newline@vandyke.com'];
+            unset($this->extensions['newline@vandyke.com']);
+        }
+        */
+
+        if ($this->version < 2 || $this->version > 6) {
+            return false;
+        }
+
+        $this->pwd = true;
+        $this->pwd = $this->_realpath('.');
+        if ($this->pwd === false) {
+            if (!$this->canonicalize_paths) {
+                user_error('Unable to canonicalize current working directory');
+                return false;
+            }
+            $this->canonicalize_paths = false;
+            $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
+        }
+
+        $this->_update_stat_cache($this->pwd, array());
+
+        return true;
+    }
+
+    /**
+     * Disable the stat cache
+     *
+     * @access public
+     */
+    function disableStatCache()
+    {
+        $this->use_stat_cache = false;
+    }
+
+    /**
+     * Enable the stat cache
+     *
+     * @access public
+     */
+    function enableStatCache()
+    {
+        $this->use_stat_cache = true;
+    }
+
+    /**
+     * Clear the stat cache
+     *
+     * @access public
+     */
+    function clearStatCache()
+    {
+        $this->stat_cache = array();
+    }
+
+    /**
+     * Enable path canonicalization
+     *
+     * @access public
+     */
+    function enablePathCanonicalization()
+    {
+        $this->canonicalize_paths = true;
+    }
+
+    /**
+     * Disable path canonicalization
+     *
+     * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path
+     *
+     * @access public
+     */
+    function disablePathCanonicalization()
+    {
+        $this->canonicalize_paths = false;
+    }
+
+    /**
+     * Enable arbitrary length packets
+     *
+     * @access public
+     */
+    function enableArbitraryLengthPackets()
+    {
+        $this->allow_arbitrary_length_packets = true;
+    }
+
+    /**
+     * Disable arbitrary length packets
+     *
+     * @access public
+     */
+    function disableArbitraryLengthPackets()
+    {
+        $this->allow_arbitrary_length_packets = false;
+    }
+
+    /**
+     * Returns the current directory name
+     *
+     * @return mixed
+     * @access public
+     */
+    function pwd()
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        return $this->pwd;
+    }
+
+    /**
+     * Logs errors
+     *
+     * @param string $response
+     * @param int $status
+     * @access public
+     */
+    function _logError($response, $status = -1)
+    {
+        if ($status == -1) {
+            if (strlen($response) < 4) {
+                return;
+            }
+            extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        }
+
+        $error = $this->status_codes[$status];
+
+        if ($this->version > 2 || strlen($response) < 4) {
+            extract(unpack('Nlength', $this->_string_shift($response, 4)));
+            $this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length);
+        } else {
+            $this->sftp_errors[] = $error;
+        }
+    }
+
+    /**
+     * Returns canonicalized absolute pathname
+     *
+     * realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input
+     * path and returns the canonicalized absolute pathname.
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function realpath($path)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        return $this->_realpath($path);
+    }
+
+    /**
+     * Canonicalize the Server-Side Path Name
+     *
+     * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it.  Returns
+     * the absolute (canonicalized) path.
+     *
+     * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
+     *
+     * @see self::chdir()
+     * @see self::disablePathCanonicalization()
+     * @param string $path
+     * @return mixed
+     * @access private
+     */
+    function _realpath($path)
+    {
+        if (!$this->canonicalize_paths) {
+            if ($this->pwd === true) {
+                return '.';
+            }
+            if (!strlen($path) || $path[0] != '/') {
+                $path = $this->pwd . '/' . $path;
+            }
+
+            $parts = explode('/', $path);
+            $afterPWD = $beforePWD = [];
+            foreach ($parts as $part) {
+                switch ($part) {
+                    //case '': // some SFTP servers /require/ double /'s. see https://github.com/phpseclib/phpseclib/pull/1137
+                    case '.':
+                        break;
+                    case '..':
+                        if (!empty($afterPWD)) {
+                            array_pop($afterPWD);
+                        } else {
+                            $beforePWD[] = '..';
+                        }
+                        break;
+                    default:
+                        $afterPWD[] = $part;
+                }
+            }
+
+            $beforePWD = count($beforePWD) ? implode('/', $beforePWD) : '.';
+            return $beforePWD . '/' . implode('/', $afterPWD);
+        }
+
+        if ($this->pwd === true) {
+            // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
+            if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
+                return false;
+            }
+
+            $response = $this->_get_sftp_packet();
+            switch ($this->packet_type) {
+                case NET_SFTP_NAME:
+                    // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following
+                    // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
+                    // at is the first part and that part is defined the same in SFTP versions 3 through 6.
+                    $this->_string_shift($response, 4); // skip over the count - it should be 1, anyway
+                    if (strlen($response) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                    return $this->_string_shift($response, $length);
+                case NET_SFTP_STATUS:
+                    $this->_logError($response);
+                    return false;
+                default:
+                    return false;
+            }
+        }
+
+        if (!strlen($path) || $path[0] != '/') {
+            $path = $this->pwd . '/' . $path;
+        }
+
+        $path = explode('/', $path);
+        $new = array();
+        foreach ($path as $dir) {
+            if (!strlen($dir)) {
+                continue;
+            }
+            switch ($dir) {
+                case '..':
+                    array_pop($new);
+                case '.':
+                    break;
+                default:
+                    $new[] = $dir;
+            }
+        }
+
+        return '/' . implode('/', $new);
+    }
+
+    /**
+     * Changes the current directory
+     *
+     * @param string $dir
+     * @return bool
+     * @access public
+     */
+    function chdir($dir)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        // assume current dir if $dir is empty
+        if ($dir === '') {
+            $dir = './';
+        // suffix a slash if needed
+        } elseif ($dir[strlen($dir) - 1] != '/') {
+            $dir.= '/';
+        }
+
+        $dir = $this->_realpath($dir);
+
+        // confirm that $dir is, in fact, a valid directory
+        if ($this->use_stat_cache && is_array($this->_query_stat_cache($dir))) {
+            $this->pwd = $dir;
+            return true;
+        }
+
+        // we could do a stat on the alleged $dir to see if it's a directory but that doesn't tell us
+        // the currently logged in user has the appropriate permissions or not. maybe you could see if
+        // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy
+        // way to get those with SFTP
+
+        if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {
+            return false;
+        }
+
+        // see \phpseclib\Net\SFTP::nlist() for a more thorough explanation of the following
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                $handle = substr($response, 4);
+                break;
+            case NET_SFTP_STATUS:
+                $this->_logError($response);
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+
+        if (!$this->_close_handle($handle)) {
+            return false;
+        }
+
+        $this->_update_stat_cache($dir, array());
+
+        $this->pwd = $dir;
+        return true;
+    }
+
+    /**
+     * Returns a list of files in the given directory
+     *
+     * @param string $dir
+     * @param bool $recursive
+     * @return mixed
+     * @access public
+     */
+    function nlist($dir = '.', $recursive = false)
+    {
+        return $this->_nlist_helper($dir, $recursive, '');
+    }
+
+    /**
+     * Helper method for nlist
+     *
+     * @param string $dir
+     * @param bool $recursive
+     * @param string $relativeDir
+     * @return mixed
+     * @access private
+     */
+    function _nlist_helper($dir, $recursive, $relativeDir)
+    {
+        $files = $this->_list($dir, false);
+
+        // If we get an int back, then that is an "unexpected" status.
+        // We do not have a file list, so return false.
+        if (is_int($files)) {
+            return false;
+        }
+
+        if (!$recursive || $files === false) {
+            return $files;
+        }
+
+        $result = array();
+        foreach ($files as $value) {
+            if ($value == '.' || $value == '..') {
+                if ($relativeDir == '') {
+                    $result[] = $value;
+                }
+                continue;
+            }
+            if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) {
+                $temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
+                $temp = is_array($temp) ? $temp : array();
+                $result = array_merge($result, $temp);
+            } else {
+                $result[] = $relativeDir . $value;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns a detailed list of files in the given directory
+     *
+     * @param string $dir
+     * @param bool $recursive
+     * @return mixed
+     * @access public
+     */
+    function rawlist($dir = '.', $recursive = false)
+    {
+        $files = $this->_list($dir, true);
+
+        // If we get an int back, then that is an "unexpected" status.
+        // We do not have a file list, so return false.
+        if (is_int($files)) {
+            return false;
+        }
+
+        if (!$recursive || $files === false) {
+            return $files;
+        }
+
+        static $depth = 0;
+
+        foreach ($files as $key => $value) {
+            if ($depth != 0 && $key == '..') {
+                unset($files[$key]);
+                continue;
+            }
+            $is_directory = false;
+            if ($key != '.' && $key != '..') {
+                if ($this->use_stat_cache) {
+                    $is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
+                } else {
+                    $stat = $this->lstat($dir . '/' . $key);
+                    $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
+                }
+            }
+
+            if ($is_directory) {
+                $depth++;
+                $files[$key] = $this->rawlist($dir . '/' . $key, true);
+                $depth--;
+            } else {
+                $files[$key] = (object) $value;
+            }
+        }
+
+        return $files;
+    }
+
+    /**
+     * Reads a list, be it detailed or not, of files in the given directory
+     *
+     * @param string $dir
+     * @param bool $raw
+     * @return mixed
+     * @access private
+     */
+    function _list($dir, $raw = true)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $dir = $this->_realpath($dir . '/');
+        if ($dir === false) {
+            return false;
+        }
+
+        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2
+        if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2
+                // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that
+                // represent the length of the string and leave it at that
+                $handle = substr($response, 4);
+                break;
+            case NET_SFTP_STATUS:
+                // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+                $this->_logError($response, $status);
+                return $status;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+
+        $this->_update_stat_cache($dir, array());
+
+        $contents = array();
+        while (true) {
+            // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2
+            // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many
+            // SSH_MSG_CHANNEL_DATA messages is not known to me.
+            if (!$this->_send_sftp_packet(NET_SFTP_READDIR, pack('Na*', strlen($handle), $handle))) {
+                return false;
+            }
+
+            $response = $this->_get_sftp_packet();
+            switch ($this->packet_type) {
+                case NET_SFTP_NAME:
+                    if (strlen($response) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Ncount', $this->_string_shift($response, 4)));
+                    for ($i = 0; $i < $count; $i++) {
+                        if (strlen($response) < 4) {
+                            return false;
+                        }
+                        extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                        $shortname = $this->_string_shift($response, $length);
+                        // SFTPv4 "removed the long filename from the names structure-- it can now be
+                        //         built from information available in the attrs structure."
+                        if ($this->version < 4) {
+                            if (strlen($response) < 4) {
+                                return false;
+                            }
+                            extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                            $longname = $this->_string_shift($response, $length);
+                        }
+                        $attributes = $this->_parseAttributes($response);
+                        if (!isset($attributes['type']) && $this->version < 4) {
+                            $fileType = $this->_parseLongname($longname);
+                            if ($fileType) {
+                                $attributes['type'] = $fileType;
+                            }
+                        }
+                        $contents[$shortname] = $attributes + array('filename' => $shortname);
+
+                        if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) {
+                            $this->_update_stat_cache($dir . '/' . $shortname, array());
+                        } else {
+                            if ($shortname == '..') {
+                                $temp = $this->_realpath($dir . '/..') . '/.';
+                            } else {
+                                $temp = $dir . '/' . $shortname;
+                            }
+                            $this->_update_stat_cache($temp, (object) array('lstat' => $attributes));
+                        }
+                        // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the
+                        // final SSH_FXP_STATUS packet should tell us that, already.
+                    }
+                    break;
+                case NET_SFTP_STATUS:
+                    if (strlen($response) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+                    if ($status != NET_SFTP_STATUS_EOF) {
+                        $this->_logError($response, $status);
+                        return $status;
+                    }
+                    break 2;
+                default:
+                    user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
+                    return false;
+            }
+        }
+
+        if (!$this->_close_handle($handle)) {
+            return false;
+        }
+
+        if (count($this->sortOptions)) {
+            uasort($contents, array(&$this, '_comparator'));
+        }
+
+        return $raw ? $contents : array_map('strval', array_keys($contents));
+    }
+
+    /**
+     * Compares two rawlist entries using parameters set by setListOrder()
+     *
+     * Intended for use with uasort()
+     *
+     * @param array $a
+     * @param array $b
+     * @return int
+     * @access private
+     */
+    function _comparator($a, $b)
+    {
+        switch (true) {
+            case $a['filename'] === '.' || $b['filename'] === '.':
+                if ($a['filename'] === $b['filename']) {
+                    return 0;
+                }
+                return $a['filename'] === '.' ? -1 : 1;
+            case $a['filename'] === '..' || $b['filename'] === '..':
+                if ($a['filename'] === $b['filename']) {
+                    return 0;
+                }
+                return $a['filename'] === '..' ? -1 : 1;
+            case isset($a['type']) && $a['type'] === NET_SFTP_TYPE_DIRECTORY:
+                if (!isset($b['type'])) {
+                    return 1;
+                }
+                if ($b['type'] !== $a['type']) {
+                    return -1;
+                }
+                break;
+            case isset($b['type']) && $b['type'] === NET_SFTP_TYPE_DIRECTORY:
+                return 1;
+        }
+        foreach ($this->sortOptions as $sort => $order) {
+            if (!isset($a[$sort]) || !isset($b[$sort])) {
+                if (isset($a[$sort])) {
+                    return -1;
+                }
+                if (isset($b[$sort])) {
+                    return 1;
+                }
+                return 0;
+            }
+            switch ($sort) {
+                case 'filename':
+                    $result = strcasecmp($a['filename'], $b['filename']);
+                    if ($result) {
+                        return $order === SORT_DESC ? -$result : $result;
+                    }
+                    break;
+                case 'permissions':
+                case 'mode':
+                    $a[$sort]&= 07777;
+                    $b[$sort]&= 07777;
+                default:
+                    if ($a[$sort] === $b[$sort]) {
+                        break;
+                    }
+                    return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort];
+            }
+        }
+    }
+
+    /**
+     * Defines how nlist() and rawlist() will be sorted - if at all.
+     *
+     * If sorting is enabled directories and files will be sorted independently with
+     * directories appearing before files in the resultant array that is returned.
+     *
+     * Any parameter returned by stat is a valid sort parameter for this function.
+     * Filename comparisons are case insensitive.
+     *
+     * Examples:
+     *
+     * $sftp->setListOrder('filename', SORT_ASC);
+     * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC);
+     * $sftp->setListOrder(true);
+     *    Separates directories from files but doesn't do any sorting beyond that
+     * $sftp->setListOrder();
+     *    Don't do any sort of sorting
+     *
+     * @access public
+     */
+    function setListOrder()
+    {
+        $this->sortOptions = array();
+        $args = func_get_args();
+        if (empty($args)) {
+            return;
+        }
+        $len = count($args) & 0x7FFFFFFE;
+        for ($i = 0; $i < $len; $i+=2) {
+            $this->sortOptions[$args[$i]] = $args[$i + 1];
+        }
+        if (!count($this->sortOptions)) {
+            $this->sortOptions = array('bogus' => true);
+        }
+    }
+
+    /**
+     * Returns the file size, in bytes, or false, on failure
+     *
+     * Files larger than 4GB will show up as being exactly 4GB.
+     *
+     * @param string $filename
+     * @return mixed
+     * @access public
+     */
+    function size($filename)
+    {
+        $result = $this->stat($filename);
+        if ($result === false) {
+            return false;
+        }
+        return isset($result['size']) ? $result['size'] : -1;
+    }
+
+    /**
+     * Save files / directories to cache
+     *
+     * @param string $path
+     * @param mixed $value
+     * @access private
+     */
+    function _update_stat_cache($path, $value)
+    {
+        if ($this->use_stat_cache === false) {
+            return;
+        }
+
+        // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/'))
+        $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
+
+        $temp = &$this->stat_cache;
+        $max = count($dirs) - 1;
+        foreach ($dirs as $i => $dir) {
+            // if $temp is an object that means one of two things.
+            //  1. a file was deleted and changed to a directory behind phpseclib's back
+            //  2. it's a symlink. when lstat is done it's unclear what it's a symlink to
+            if (is_object($temp)) {
+                $temp = array();
+            }
+            if (!isset($temp[$dir])) {
+                $temp[$dir] = array();
+            }
+            if ($i === $max) {
+                if (is_object($temp[$dir]) && is_object($value)) {
+                    if (!isset($value->stat) && isset($temp[$dir]->stat)) {
+                        $value->stat = $temp[$dir]->stat;
+                    }
+                    if (!isset($value->lstat) && isset($temp[$dir]->lstat)) {
+                        $value->lstat = $temp[$dir]->lstat;
+                    }
+                }
+                $temp[$dir] = $value;
+                break;
+            }
+            $temp = &$temp[$dir];
+        }
+    }
+
+    /**
+     * Remove files / directories from cache
+     *
+     * @param string $path
+     * @return bool
+     * @access private
+     */
+    function _remove_from_stat_cache($path)
+    {
+        $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
+
+        $temp = &$this->stat_cache;
+        $max = count($dirs) - 1;
+        foreach ($dirs as $i => $dir) {
+            if (!is_array($temp)) {
+                return false;
+            }
+            if ($i === $max) {
+                unset($temp[$dir]);
+                return true;
+            }
+            if (!isset($temp[$dir])) {
+                return false;
+            }
+            $temp = &$temp[$dir];
+        }
+    }
+
+    /**
+     * Checks cache for path
+     *
+     * Mainly used by file_exists
+     *
+     * @param string $path
+     * @return mixed
+     * @access private
+     */
+    function _query_stat_cache($path)
+    {
+        $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
+
+        $temp = &$this->stat_cache;
+        foreach ($dirs as $dir) {
+            if (!is_array($temp)) {
+                return null;
+            }
+            if (!isset($temp[$dir])) {
+                return null;
+            }
+            $temp = &$temp[$dir];
+        }
+        return $temp;
+    }
+
+    /**
+     * Returns general information about a file.
+     *
+     * Returns an array on success and false otherwise.
+     *
+     * @param string $filename
+     * @return mixed
+     * @access public
+     */
+    function stat($filename)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $filename = $this->_realpath($filename);
+        if ($filename === false) {
+            return false;
+        }
+
+        if ($this->use_stat_cache) {
+            $result = $this->_query_stat_cache($filename);
+            if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) {
+                return $result['.']->stat;
+            }
+            if (is_object($result) && isset($result->stat)) {
+                return $result->stat;
+            }
+        }
+
+        $stat = $this->_stat($filename, NET_SFTP_STAT);
+        if ($stat === false) {
+            $this->_remove_from_stat_cache($filename);
+            return false;
+        }
+        if (isset($stat['type'])) {
+            if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+                $filename.= '/.';
+            }
+            $this->_update_stat_cache($filename, (object) array('stat' => $stat));
+            return $stat;
+        }
+
+        $pwd = $this->pwd;
+        $stat['type'] = $this->chdir($filename) ?
+            NET_SFTP_TYPE_DIRECTORY :
+            NET_SFTP_TYPE_REGULAR;
+        $this->pwd = $pwd;
+
+        if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+            $filename.= '/.';
+        }
+        $this->_update_stat_cache($filename, (object) array('stat' => $stat));
+
+        return $stat;
+    }
+
+    /**
+     * Returns general information about a file or symbolic link.
+     *
+     * Returns an array on success and false otherwise.
+     *
+     * @param string $filename
+     * @return mixed
+     * @access public
+     */
+    function lstat($filename)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $filename = $this->_realpath($filename);
+        if ($filename === false) {
+            return false;
+        }
+
+        if ($this->use_stat_cache) {
+            $result = $this->_query_stat_cache($filename);
+            if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) {
+                return $result['.']->lstat;
+            }
+            if (is_object($result) && isset($result->lstat)) {
+                return $result->lstat;
+            }
+        }
+
+        $lstat = $this->_stat($filename, NET_SFTP_LSTAT);
+        if ($lstat === false) {
+            $this->_remove_from_stat_cache($filename);
+            return false;
+        }
+        if (isset($lstat['type'])) {
+            if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+                $filename.= '/.';
+            }
+            $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
+            return $lstat;
+        }
+
+        $stat = $this->_stat($filename, NET_SFTP_STAT);
+
+        if ($lstat != $stat) {
+            $lstat = array_merge($lstat, array('type' => NET_SFTP_TYPE_SYMLINK));
+            $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
+            return $stat;
+        }
+
+        $pwd = $this->pwd;
+        $lstat['type'] = $this->chdir($filename) ?
+            NET_SFTP_TYPE_DIRECTORY :
+            NET_SFTP_TYPE_REGULAR;
+        $this->pwd = $pwd;
+
+        if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+            $filename.= '/.';
+        }
+        $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
+
+        return $lstat;
+    }
+
+    /**
+     * Returns general information about a file or symbolic link
+     *
+     * Determines information without calling \phpseclib\Net\SFTP::realpath().
+     * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
+     *
+     * @param string $filename
+     * @param int $type
+     * @return mixed
+     * @access private
+     */
+    function _stat($filename, $type)
+    {
+        // SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
+        $packet = pack('Na*', strlen($filename), $filename);
+        if (!$this->_send_sftp_packet($type, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_ATTRS:
+                return $this->_parseAttributes($response);
+            case NET_SFTP_STATUS:
+                $this->_logError($response);
+                return false;
+        }
+
+        user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
+        return false;
+    }
+
+    /**
+     * Truncates a file to a given length
+     *
+     * @param string $filename
+     * @param int $new_size
+     * @return bool
+     * @access public
+     */
+    function truncate($filename, $new_size)
+    {
+        $attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); // 4294967296 == 0x100000000 == 1<<32
+
+        return $this->_setstat($filename, $attr, false);
+    }
+
+    /**
+     * Sets access and modification time of file.
+     *
+     * If the file does not exist, it will be created.
+     *
+     * @param string $filename
+     * @param int $time
+     * @param int $atime
+     * @return bool
+     * @access public
+     */
+    function touch($filename, $time = null, $atime = null)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $filename = $this->_realpath($filename);
+        if ($filename === false) {
+            return false;
+        }
+
+        if (!isset($time)) {
+            $time = time();
+        }
+        if (!isset($atime)) {
+            $atime = $time;
+        }
+
+        if ($this->version < 4) {
+            $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $atime, $time);
+        } else {
+            $attr = pack(
+                'N5',
+                NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME,
+                $atime / 4294967296,
+                $atime,
+                $time / 4294967296,
+                $time
+            );
+        }
+
+        $packet = pack('Na*', strlen($filename), $filename);
+        $packet.= $this->version >= 5 ?
+            pack('N2', 0, NET_SFTP_OPEN_OPEN_EXISTING) :
+            pack('N', NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL);
+        $packet.= $attr;
+
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                return $this->_close_handle(substr($response, 4));
+            case NET_SFTP_STATUS:
+                $this->_logError($response);
+                break;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+
+        return $this->_setstat($filename, $attr, false);
+    }
+
+    /**
+     * Changes file or directory owner
+     *
+     * $uid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string
+     * would be of the form "user@dns_domain" but it does not need to be.
+     * `$sftp->getSupportedVersions()['version']` will return the specific version
+     * that's being used.
+     *
+     * Returns true on success or false on error.
+     *
+     * @param string $filename
+     * @param int|string $uid
+     * @param bool $recursive
+     * @return bool
+     * @access public
+     */
+    function chown($filename, $uid, $recursive = false)
+    {
+        /*
+         quoting <https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.5>,
+
+         "To avoid a representation that is tied to a particular underlying
+          implementation at the client or server, the use of UTF-8 strings has
+          been chosen.  The string should be of the form "user@dns_domain".
+          This will allow for a client and server that do not use the same
+          local representation the ability to translate to a common syntax that
+          can be interpreted by both.  In the case where there is no
+          translation available to the client or server, the attribute value
+          must be constructed without the "@"."
+
+         phpseclib _could_ auto append the dns_domain to $uid BUT what if it shouldn't
+         have one? phpseclib would have no way of knowing so rather than guess phpseclib
+         will just use whatever value the user provided
+       */
+
+        $attr = $this->version < 4 ?
+            // quoting <http://www.kernel.org/doc/man-pages/online/pages/man2/chown.2.html>,
+            // "if the owner or group is specified as -1, then that ID is not changed"
+            pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1) :
+            // quoting <https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.5>,
+            // "If either the owner or group field is zero length, the field should be
+            //  considered absent, and no change should be made to that specific field
+            //  during a modification operation"
+            pack('NNa*Na*', NET_SFTP_ATTR_OWNERGROUP, strlen($uid), $uid, 0, '');
+
+        return $this->_setstat($filename, $attr, $recursive);
+    }
+
+    /**
+     * Changes file or directory group
+     *
+     * $gid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string
+     * would be of the form "user@dns_domain" but it does not need to be.
+     * `$sftp->getSupportedVersions()['version']` will return the specific version
+     * that's being used.
+     *
+     * Returns true on success or false on error.
+     *
+     * @param string $filename
+     * @param int|string $gid
+     * @param bool $recursive
+     * @return bool
+     * @access public
+     */
+    function chgrp($filename, $gid, $recursive = false)
+    {
+        $attr = $this->version < 4 ?
+            pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) :
+            pack('NNa*Na*', NET_SFTP_ATTR_OWNERGROUP, 0, '', strlen($gid), $gid);
+
+        return $this->_setstat($filename, $attr, $recursive);
+    }
+
+    /**
+     * Set permissions on a file.
+     *
+     * Returns the new file permissions on success or false on error.
+     * If $recursive is true than this just returns true or false.
+     *
+     * @param int $mode
+     * @param string $filename
+     * @param bool $recursive
+     * @return mixed
+     * @access public
+     */
+    function chmod($mode, $filename, $recursive = false)
+    {
+        if (is_string($mode) && is_int($filename)) {
+            $temp = $mode;
+            $mode = $filename;
+            $filename = $temp;
+        }
+
+        $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
+        if (!$this->_setstat($filename, $attr, $recursive)) {
+            return false;
+        }
+        if ($recursive) {
+            return true;
+        }
+
+        $filename = $this->realpath($filename);
+        // rather than return what the permissions *should* be, we'll return what they actually are.  this will also
+        // tell us if the file actually exists.
+        // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
+        $packet = pack('Na*', strlen($filename), $filename);
+        if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_ATTRS:
+                $attrs = $this->_parseAttributes($response);
+                return $attrs['permissions'];
+            case NET_SFTP_STATUS:
+                $this->_logError($response);
+                return false;
+        }
+
+        user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
+        return false;
+    }
+
+    /**
+     * Sets information about a file
+     *
+     * @param string $filename
+     * @param string $attr
+     * @param bool $recursive
+     * @return bool
+     * @access private
+     */
+    function _setstat($filename, $attr, $recursive)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $filename = $this->_realpath($filename);
+        if ($filename === false) {
+            return false;
+        }
+
+        $this->_remove_from_stat_cache($filename);
+
+        if ($recursive) {
+            $i = 0;
+            $result = $this->_setstat_recursive($filename, $attr, $i);
+            $this->_read_put_responses($i);
+            return $result;
+        }
+
+        $packet = $this->version >= 4 ?
+            pack('Na*a*Ca*', strlen($filename), $filename, substr($attr, 0, 4), NET_SFTP_TYPE_UNKNOWN, substr($attr, 4)) :
+            pack('Na*a*', strlen($filename), $filename, $attr);
+        if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, $packet)) {
+            return false;
+        }
+
+        /*
+         "Because some systems must use separate system calls to set various attributes, it is possible that a failure
+          response will be returned, but yet some of the attributes may be have been successfully modified.  If possible,
+          servers SHOULD avoid this situation; however, clients MUST be aware that this is possible."
+
+          -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
+        */
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            $this->_logError($response, $status);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Recursively sets information on directories on the SFTP server
+     *
+     * Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
+     *
+     * @param string $path
+     * @param string $attr
+     * @param int $i
+     * @return bool
+     * @access private
+     */
+    function _setstat_recursive($path, $attr, &$i)
+    {
+        if (!$this->_read_put_responses($i)) {
+            return false;
+        }
+        $i = 0;
+        $entries = $this->_list($path, true);
+
+        if ($entries === false || is_int($entries)) {
+            return $this->_setstat($path, $attr, false);
+        }
+
+        // normally $entries would have at least . and .. but it might not if the directories
+        // permissions didn't allow reading
+        if (empty($entries)) {
+            return false;
+        }
+
+        unset($entries['.'], $entries['..']);
+        foreach ($entries as $filename => $props) {
+            if (!isset($props['type'])) {
+                return false;
+            }
+
+            $temp = $path . '/' . $filename;
+            if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) {
+                if (!$this->_setstat_recursive($temp, $attr, $i)) {
+                    return false;
+                }
+            } else {
+                $packet = $this->version >= 4 ?
+                    pack('Na*Ca*', strlen($temp), $temp, NET_SFTP_TYPE_UNKNOWN, $attr) :
+                    pack('Na*a*', strlen($temp), $temp, $attr);
+                if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, $packet)) {
+                    return false;
+                }
+
+                $i++;
+
+                if ($i >= NET_SFTP_QUEUE_SIZE) {
+                    if (!$this->_read_put_responses($i)) {
+                        return false;
+                    }
+                    $i = 0;
+                }
+            }
+        }
+
+        $packet = $this->version >= 4 ?
+            pack('Na*Ca*', strlen($temp), $temp, NET_SFTP_TYPE_UNKNOWN, $attr) :
+            pack('Na*a*', strlen($temp), $temp, $attr);
+        if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, $packet)) {
+            return false;
+        }
+
+        $i++;
+
+        if ($i >= NET_SFTP_QUEUE_SIZE) {
+            if (!$this->_read_put_responses($i)) {
+                return false;
+            }
+            $i = 0;
+        }
+
+        return true;
+    }
+
+    /**
+     * Return the target of a symbolic link
+     *
+     * @param string $link
+     * @return mixed
+     * @access public
+     */
+    function readlink($link)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $link = $this->_realpath($link);
+
+        if (!$this->_send_sftp_packet(NET_SFTP_READLINK, pack('Na*', strlen($link), $link))) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_NAME:
+                break;
+            case NET_SFTP_STATUS:
+                $this->_logError($response);
+                return false;
+            default:
+                user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
+                return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Ncount', $this->_string_shift($response, 4)));
+        // the file isn't a symlink
+        if (!$count) {
+            return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nlength', $this->_string_shift($response, 4)));
+        return $this->_string_shift($response, $length);
+    }
+
+    /**
+     * Create a symlink
+     *
+     * symlink() creates a symbolic link to the existing target with the specified name link.
+     *
+     * @param string $target
+     * @param string $link
+     * @return bool
+     * @access public
+     */
+    function symlink($target, $link)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        //$target = $this->_realpath($target);
+        $link = $this->_realpath($link);
+
+        /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-12.1 :
+
+           Changed the SYMLINK packet to be LINK and give it the ability to
+           create hard links.  Also change it's packet number because many
+           implementation implemented SYMLINK with the arguments reversed.
+           Hopefully the new argument names make it clear which way is which.
+        */
+        if ($this->version == 6) {
+            $type = NET_SFTP_LINK;
+            $packet = pack('Na*Na*C', strlen($link), $link, strlen($target), $target, 1);
+        } else {
+            $type = NET_SFTP_SYMLINK;
+            /* quoting http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL#347 :
+
+               3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK
+
+               When OpenSSH's sftp-server was implemented, the order of the arguments
+               to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately,
+               the reversal was not noticed until the server was widely deployed. Since
+               fixing this to follow the specification would cause incompatibility, the
+               current order was retained. For correct operation, clients should send
+               SSH_FXP_SYMLINK as follows:
+
+                   uint32      id
+                   string      targetpath
+                   string      linkpath */
+            $packet = substr($this->server_identifier, 0, 15) == 'SSH-2.0-OpenSSH' ?
+                pack('Na*Na*', strlen($target), $target, strlen($link), $link) :
+                pack('Na*Na*', strlen($link), $link, strlen($target), $target);
+        }
+        if (!$this->_send_sftp_packet($type, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            $this->_logError($response, $status);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Creates a directory.
+     *
+     * @param string $dir
+     * @param int $mode
+     * @param bool $recursive
+     * @return bool
+     * @access public
+     */
+    function mkdir($dir, $mode = -1, $recursive = false)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $dir = $this->_realpath($dir);
+
+        if ($recursive) {
+            $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir));
+            if (empty($dirs[0])) {
+                array_shift($dirs);
+                $dirs[0] = '/' . $dirs[0];
+            }
+            for ($i = 0; $i < count($dirs); $i++) {
+                $temp = array_slice($dirs, 0, $i + 1);
+                $temp = implode('/', $temp);
+                $result = $this->_mkdir_helper($temp, $mode);
+            }
+            return $result;
+        }
+
+        return $this->_mkdir_helper($dir, $mode);
+    }
+
+    /**
+     * Helper function for directory creation
+     *
+     * @param string $dir
+     * @param int $mode
+     * @return bool
+     * @access private
+     */
+    function _mkdir_helper($dir, $mode)
+    {
+        // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing)
+        if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, "\0\0\0\0"))) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            $this->_logError($response, $status);
+            return false;
+        }
+
+        if ($mode !== -1) {
+            $this->chmod($mode, $dir);
+        }
+
+        return true;
+    }
+
+    /**
+     * Removes a directory.
+     *
+     * @param string $dir
+     * @return bool
+     * @access public
+     */
+    function rmdir($dir)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $dir = $this->_realpath($dir);
+        if ($dir === false) {
+            return false;
+        }
+
+        if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
+            $this->_logError($response, $status);
+            return false;
+        }
+
+        $this->_remove_from_stat_cache($dir);
+        // the following will do a soft delete, which would be useful if you deleted a file
+        // and then tried to do a stat on the deleted file. the above, in contrast, does
+        // a hard delete
+        //$this->_update_stat_cache($dir, false);
+
+        return true;
+    }
+
+    /**
+     * Uploads a file to the SFTP server.
+     *
+     * By default, \phpseclib\Net\SFTP::put() does not read from the local filesystem.  $data is dumped directly into $remote_file.
+     * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SFTP::get(), you will get a file, twelve bytes
+     * long, containing 'filename.ext' as its contents.
+     *
+     * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior.  With self::SOURCE_LOCAL_FILE, $remote_file will
+     * contain as many bytes as filename.ext does on your local filesystem.  If your filename.ext is 1MB then that is how
+     * large $remote_file will be, as well.
+     *
+     * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number
+     * of bytes to return, and returns a string if there is some data or null if there is no more data
+     *
+     * If $data is a resource then it'll be used as a resource instead.
+     *
+     * Currently, only binary mode is supported.  As such, if the line endings need to be adjusted, you will need to take
+     * care of that, yourself.
+     *
+     * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with
+     * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following:
+     *
+     * self::SOURCE_LOCAL_FILE | self::RESUME
+     *
+     * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace
+     * self::RESUME with self::RESUME_START.
+     *
+     * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed.
+     *
+     * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME
+     * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle
+     * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the
+     * middle of one.
+     *
+     * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE.
+     *
+     * @param string $remote_file
+     * @param string|resource $data
+     * @param int $mode
+     * @param int $start
+     * @param int $local_start
+     * @param callable|null $progressCallback
+     * @return bool
+     * @access public
+     * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
+     */
+    function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $remote_file = $this->_realpath($remote_file);
+        if ($remote_file === false) {
+            return false;
+        }
+
+        $this->_remove_from_stat_cache($remote_file);
+
+        if ($this->version >= 5) {
+            $flags = NET_SFTP_OPEN_OPEN_OR_CREATE;
+        } else {
+            $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
+            // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file."
+            // in practice, it doesn't seem to do that.
+            //$flags|= ($mode & SFTP::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE;
+        }
+
+        if ($start >= 0) {
+            $offset = $start;
+        } elseif ($mode & self::RESUME) {
+            // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called
+            $size = $this->size($remote_file);
+            $offset = $size !== false ? $size : 0;
+        } else {
+            $offset = 0;
+            if ($this->version >= 5) {
+                $flags = NET_SFTP_OPEN_CREATE_TRUNCATE;
+            } else {
+                $flags|= NET_SFTP_OPEN_TRUNCATE;
+            }
+        }
+
+        $packet = pack('Na*', strlen($remote_file), $remote_file);
+        $packet.= $this->version >= 5 ?
+            pack('N3', 0, $flags, 0) :
+            pack('N2', $flags, 0);
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                $handle = substr($response, 4);
+                break;
+            case NET_SFTP_STATUS:
+                $this->_logError($response);
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+
+        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
+        $dataCallback = false;
+        switch (true) {
+            case $mode & self::SOURCE_CALLBACK:
+                if (!is_callable($data)) {
+                    user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
+                }
+                $dataCallback = $data;
+                // do nothing
+                break;
+            case is_resource($data):
+                $mode = $mode & ~self::SOURCE_LOCAL_FILE;
+                $info = stream_get_meta_data($data);
+                if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
+                    $fp = fopen('php://memory', 'w+');
+                    stream_copy_to_stream($data, $fp);
+                    rewind($fp);
+                } else {
+                    $fp = $data;
+                }
+                break;
+            case $mode & self::SOURCE_LOCAL_FILE:
+                if (!is_file($data)) {
+                    user_error("$data is not a valid file");
+                    return false;
+                }
+                $fp = @fopen($data, 'rb');
+                if (!$fp) {
+                    return false;
+                }
+        }
+
+        if (isset($fp)) {
+            $stat = fstat($fp);
+            $size = !empty($stat) ? $stat['size'] : 0;
+
+            if ($local_start >= 0) {
+                fseek($fp, $local_start);
+                $size-= $local_start;
+            }
+        } elseif ($dataCallback) {
+            $size = 0;
+        } else {
+            $size = strlen($data);
+        }
+
+        $sent = 0;
+        $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
+
+        $sftp_packet_size = $this->max_sftp_packet;
+        // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header"
+        $sftp_packet_size-= strlen($handle) + 25;
+        $i = $j = 0;
+        while ($dataCallback || ($size === 0 || $sent < $size)) {
+            if ($dataCallback) {
+                $temp = call_user_func($dataCallback, $sftp_packet_size);
+                if (is_null($temp)) {
+                    break;
+                }
+            } else {
+                $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
+                if ($temp === false || $temp === '') {
+                    break;
+                }
+            }
+
+            $subtemp = $offset + $sent;
+            $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
+            if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) {
+                if ($mode & self::SOURCE_LOCAL_FILE) {
+                    fclose($fp);
+                }
+                return false;
+            }
+            $sent+= strlen($temp);
+            if (is_callable($progressCallback)) {
+                call_user_func($progressCallback, $sent);
+            }
+
+            $i++;
+            $j++;
+
+            if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) {
+                if (!$this->_read_put_responses($i)) {
+                    $i = 0;
+                    break;
+                }
+                $i = 0;
+            }
+        }
+
+        $result = $this->_close_handle($handle);
+
+        if (!$this->_read_put_responses($i)) {
+            if ($mode & self::SOURCE_LOCAL_FILE) {
+                fclose($fp);
+            }
+            $this->_close_handle($handle);
+            return false;
+        }
+
+        if ($mode & SFTP::SOURCE_LOCAL_FILE) {
+            if (isset($fp) && is_resource($fp)) {
+                fclose($fp);
+            }
+
+            if ($this->preserveTime) {
+                $stat = stat($data);
+                if ($this->version < 4) {
+                    $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $stat['atime'], $stat['mtime']);
+                } else {
+                    $attr = pack(
+                        'N5',
+                        NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME,
+                        $stat['atime'] / 4294967296,
+                        $stat['atime'],
+                        $stat['mtime'] / 4294967296,
+                        $stat['mtime']
+                    );
+                }
+
+                if (!$this->_setstat($remote_file, $attr, false)) {
+                    user_error('Error setting file time');
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Reads multiple successive SSH_FXP_WRITE responses
+     *
+     * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i
+     * SSH_FXP_WRITEs, in succession, and then reading $i responses.
+     *
+     * @param int $i
+     * @return bool
+     * @access private
+     */
+    function _read_put_responses($i)
+    {
+        while ($i--) {
+            $response = $this->_get_sftp_packet();
+            if ($this->packet_type != NET_SFTP_STATUS) {
+                user_error('Expected SSH_FXP_STATUS');
+                return false;
+            }
+
+            if (strlen($response) < 4) {
+                return false;
+            }
+            extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+            if ($status != NET_SFTP_STATUS_OK) {
+                $this->_logError($response, $status);
+                break;
+            }
+        }
+
+        return $i < 0;
+    }
+
+    /**
+     * Close handle
+     *
+     * @param string $handle
+     * @return bool
+     * @access private
+     */
+    function _close_handle($handle)
+    {
+        if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {
+            return false;
+        }
+
+        // "The client MUST release all resources associated with the handle regardless of the status."
+        //  -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            $this->_logError($response, $status);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Downloads a file from the SFTP server.
+     *
+     * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
+     * the operation was unsuccessful.  If $local_file is defined, returns true or false depending on the success of the
+     * operation.
+     *
+     * $offset and $length can be used to download files in chunks.
+     *
+     * @param string $remote_file
+     * @param string $local_file
+     * @param int $offset
+     * @param int $length
+     * @param callable|null $progressCallback
+     * @return mixed
+     * @access public
+     */
+    function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $remote_file = $this->_realpath($remote_file);
+        if ($remote_file === false) {
+            return false;
+        }
+
+        $packet = pack('Na*', strlen($remote_file), $remote_file);
+        $packet.= $this->version >= 5 ?
+            pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) :
+            pack('N2', NET_SFTP_OPEN_READ, 0);
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                $handle = substr($response, 4);
+                break;
+            case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+                $this->_logError($response);
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+
+        if (is_resource($local_file)) {
+            $fp = $local_file;
+            $stat = fstat($fp);
+            $res_offset = $stat['size'];
+        } else {
+            $res_offset = 0;
+            if ($local_file !== false && !is_callable($local_file)) {
+                $fp = fopen($local_file, 'wb');
+                if (!$fp) {
+                    return false;
+                }
+            } else {
+                $content = '';
+            }
+        }
+
+        $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file);
+
+        $start = $offset;
+        $read = 0;
+        while (true) {
+            $i = 0;
+
+            while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
+                $tempoffset = $start + $read;
+
+                $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
+
+                $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
+                if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) {
+                    if ($fclose_check) {
+                        fclose($fp);
+                    }
+                    return false;
+                }
+                $packet = null;
+                $read+= $packet_size;
+                $i++;
+            }
+
+            if (!$i) {
+                break;
+            }
+
+            $packets_sent = $i - 1;
+
+            $clear_responses = false;
+            while ($i > 0) {
+                $i--;
+
+                if ($clear_responses) {
+                    $this->_get_sftp_packet($packets_sent - $i);
+                    continue;
+                } else {
+                    $response = $this->_get_sftp_packet($packets_sent - $i);
+                }
+
+                switch ($this->packet_type) {
+                    case NET_SFTP_DATA:
+                        $temp = substr($response, 4);
+                        $offset+= strlen($temp);
+                        if ($local_file === false) {
+                            $content.= $temp;
+                        } elseif (is_callable($local_file)) {
+                            $local_file($temp);
+                        } else {
+                            fputs($fp, $temp);
+                        }
+                        if (is_callable($progressCallback)) {
+                            call_user_func($progressCallback, $offset);
+                        }
+                        $temp = null;
+                        break;
+                    case NET_SFTP_STATUS:
+                        // could, in theory, return false if !strlen($content) but we'll hold off for the time being
+                        $this->_logError($response);
+                        $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
+                        break;
+                    default:
+                        if ($fclose_check) {
+                            fclose($fp);
+                        }
+                        // maybe the file was successfully transferred, maybe it wasn't
+                        if ($this->channel_close) {
+                            $this->partial_init = false;
+                            $this->_init_sftp_connection();
+                            return false;
+                        } else {
+                            user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
+                        }
+                }
+                $response = null;
+            }
+
+            if ($clear_responses) {
+                break;
+            }
+        }
+
+        if ($length > 0 && $length <= $offset - $start) {
+            if ($local_file === false) {
+                $content = substr($content, 0, $length);
+            } else {
+                ftruncate($fp, $length + $res_offset);
+            }
+        }
+
+        if ($fclose_check) {
+            fclose($fp);
+
+            if ($this->preserveTime) {
+                $stat = $this->stat($remote_file);
+                touch($local_file, $stat['mtime'], $stat['atime']);
+            }
+        }
+
+        if (!$this->_close_handle($handle)) {
+            return false;
+        }
+
+        // if $content isn't set that means a file was written to
+        return isset($content) ? $content : true;
+    }
+
+    /**
+     * Deletes a file on the SFTP server.
+     *
+     * @param string $path
+     * @param bool $recursive
+     * @return bool
+     * @access public
+     */
+    function delete($path, $recursive = true)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        if (is_object($path)) {
+            // It's an object. Cast it as string before we check anything else.
+            $path = (string) $path;
+        }
+
+        if (!is_string($path) || $path == '') {
+            return false;
+        }
+
+        $path = $this->_realpath($path);
+        if ($path === false) {
+            return false;
+        }
+
+        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
+        if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            $this->_logError($response, $status);
+            if (!$recursive) {
+                return false;
+            }
+            $i = 0;
+            $result = $this->_delete_recursive($path, $i);
+            $this->_read_put_responses($i);
+            return $result;
+        }
+
+        $this->_remove_from_stat_cache($path);
+
+        return true;
+    }
+
+    /**
+     * Recursively deletes directories on the SFTP server
+     *
+     * Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
+     *
+     * @param string $path
+     * @param int $i
+     * @return bool
+     * @access private
+     */
+    function _delete_recursive($path, &$i)
+    {
+        if (!$this->_read_put_responses($i)) {
+            return false;
+        }
+        $i = 0;
+        $entries = $this->_list($path, true);
+
+        // The folder does not exist at all, so we cannot delete it.
+        if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) {
+            return false;
+        }
+
+        // Normally $entries would have at least . and .. but it might not if the directories
+        // permissions didn't allow reading. If this happens then default to an empty list of files.
+        if ($entries === false || is_int($entries)) {
+            $entries = array();
+        }
+
+        unset($entries['.'], $entries['..']);
+        foreach ($entries as $filename => $props) {
+            if (!isset($props['type'])) {
+                return false;
+            }
+
+            $temp = $path . '/' . $filename;
+            if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) {
+                if (!$this->_delete_recursive($temp, $i)) {
+                    return false;
+                }
+            } else {
+                if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($temp), $temp))) {
+                    return false;
+                }
+                $this->_remove_from_stat_cache($temp);
+
+                $i++;
+
+                if ($i >= NET_SFTP_QUEUE_SIZE) {
+                    if (!$this->_read_put_responses($i)) {
+                        return false;
+                    }
+                    $i = 0;
+                }
+            }
+        }
+
+        if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($path), $path))) {
+            return false;
+        }
+        $this->_remove_from_stat_cache($path);
+
+        $i++;
+
+        if ($i >= NET_SFTP_QUEUE_SIZE) {
+            if (!$this->_read_put_responses($i)) {
+                return false;
+            }
+            $i = 0;
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks whether a file or directory exists
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function file_exists($path)
+    {
+        if ($this->use_stat_cache) {
+            if (!$this->_precheck()) {
+                return false;
+            }
+
+            $path = $this->_realpath($path);
+
+            $result = $this->_query_stat_cache($path);
+
+            if (isset($result)) {
+                // return true if $result is an array or if it's an stdClass object
+                return $result !== false;
+            }
+        }
+
+        return $this->stat($path) !== false;
+    }
+
+    /**
+     * Tells whether the filename is a directory
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_dir($path)
+    {
+        $result = $this->_get_stat_cache_prop($path, 'type');
+        if ($result === false) {
+            return false;
+        }
+        return $result === NET_SFTP_TYPE_DIRECTORY;
+    }
+
+    /**
+     * Tells whether the filename is a regular file
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_file($path)
+    {
+        $result = $this->_get_stat_cache_prop($path, 'type');
+        if ($result === false) {
+            return false;
+        }
+        return $result === NET_SFTP_TYPE_REGULAR;
+    }
+
+    /**
+     * Tells whether the filename is a symbolic link
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_link($path)
+    {
+        $result = $this->_get_lstat_cache_prop($path, 'type');
+        if ($result === false) {
+            return false;
+        }
+        return $result === NET_SFTP_TYPE_SYMLINK;
+    }
+
+    /**
+     * Tells whether a file exists and is readable
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_readable($path)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $path = $this->_realpath($path);
+
+        $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_READ, 0);
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                return true;
+            case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+    }
+
+    /**
+     * Tells whether the filename is writable
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_writable($path)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $path = $this->_realpath($path);
+
+        $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_WRITE, 0);
+        if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        switch ($this->packet_type) {
+            case NET_SFTP_HANDLE:
+                return true;
+            case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+                return false;
+            default:
+                user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+                return false;
+        }
+    }
+
+    /**
+     * Tells whether the filename is writeable
+     *
+     * Alias of is_writable
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function is_writeable($path)
+    {
+        return $this->is_writable($path);
+    }
+
+    /**
+     * Gets last access time of file
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function fileatime($path)
+    {
+        return $this->_get_stat_cache_prop($path, 'atime');
+    }
+
+    /**
+     * Gets file modification time
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function filemtime($path)
+    {
+        return $this->_get_stat_cache_prop($path, 'mtime');
+    }
+
+    /**
+     * Gets file permissions
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function fileperms($path)
+    {
+        return $this->_get_stat_cache_prop($path, 'permissions');
+    }
+
+    /**
+     * Gets file owner
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function fileowner($path)
+    {
+        return $this->_get_stat_cache_prop($path, 'uid');
+    }
+
+    /**
+     * Gets file group
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function filegroup($path)
+    {
+        return $this->_get_stat_cache_prop($path, 'gid');
+    }
+
+    /**
+     * Gets file size
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function filesize($path)
+    {
+        return $this->_get_stat_cache_prop($path, 'size');
+    }
+
+    /**
+     * Gets file type
+     *
+     * @param string $path
+     * @return mixed
+     * @access public
+     */
+    function filetype($path)
+    {
+        $type = $this->_get_stat_cache_prop($path, 'type');
+        if ($type === false) {
+            return false;
+        }
+
+        switch ($type) {
+            case NET_SFTP_TYPE_BLOCK_DEVICE:
+                return 'block';
+            case NET_SFTP_TYPE_CHAR_DEVICE:
+                return 'char';
+            case NET_SFTP_TYPE_DIRECTORY:
+                return 'dir';
+            case NET_SFTP_TYPE_FIFO:
+                return 'fifo';
+            case NET_SFTP_TYPE_REGULAR:
+                return 'file';
+            case NET_SFTP_TYPE_SYMLINK:
+                return 'link';
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Return a stat properity
+     *
+     * Uses cache if appropriate.
+     *
+     * @param string $path
+     * @param string $prop
+     * @return mixed
+     * @access private
+     */
+    function _get_stat_cache_prop($path, $prop)
+    {
+        return $this->_get_xstat_cache_prop($path, $prop, 'stat');
+    }
+
+    /**
+     * Return an lstat properity
+     *
+     * Uses cache if appropriate.
+     *
+     * @param string $path
+     * @param string $prop
+     * @return mixed
+     * @access private
+     */
+    function _get_lstat_cache_prop($path, $prop)
+    {
+        return $this->_get_xstat_cache_prop($path, $prop, 'lstat');
+    }
+
+    /**
+     * Return a stat or lstat properity
+     *
+     * Uses cache if appropriate.
+     *
+     * @param string $path
+     * @param string $prop
+     * @param mixed $type
+     * @return mixed
+     * @access private
+     */
+    function _get_xstat_cache_prop($path, $prop, $type)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        if ($this->use_stat_cache) {
+            $path = $this->_realpath($path);
+
+            $result = $this->_query_stat_cache($path);
+
+            if (is_object($result) && isset($result->$type)) {
+                return $result->{$type}[$prop];
+            }
+        }
+
+        $result = $this->$type($path);
+
+        if ($result === false || !isset($result[$prop])) {
+            return false;
+        }
+
+        return $result[$prop];
+    }
+
+    /**
+     * Renames a file or a directory on the SFTP server.
+     *
+     * If the file already exists this will return false
+     *
+     * @param string $oldname
+     * @param string $newname
+     * @return bool
+     * @access public
+     */
+    function rename($oldname, $newname)
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        $oldname = $this->_realpath($oldname);
+        $newname = $this->_realpath($newname);
+        if ($oldname === false || $newname === false) {
+            return false;
+        }
+
+        // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
+        $packet = pack('Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname);
+        if ($this->version >= 5) {
+            /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-6.5 ,
+
+               'flags' is 0 or a combination of:
+
+                   SSH_FXP_RENAME_OVERWRITE  0x00000001
+                   SSH_FXP_RENAME_ATOMIC     0x00000002
+                   SSH_FXP_RENAME_NATIVE     0x00000004
+
+               (none of these are currently supported) */
+            $packet.= "\0\0\0\0";
+        }
+        if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) {
+            return false;
+        }
+
+        $response = $this->_get_sftp_packet();
+        if ($this->packet_type != NET_SFTP_STATUS) {
+            user_error('Expected SSH_FXP_STATUS');
+            return false;
+        }
+
+        // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+        if (strlen($response) < 4) {
+            return false;
+        }
+        extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+        if ($status != NET_SFTP_STATUS_OK) {
+            $this->_logError($response, $status);
+            return false;
+        }
+
+        // don't move the stat cache entry over since this operation could very well change the
+        // atime and mtime attributes
+        //$this->_update_stat_cache($newname, $this->_query_stat_cache($oldname));
+        $this->_remove_from_stat_cache($oldname);
+        $this->_remove_from_stat_cache($newname);
+
+        return true;
+    }
+
+    /**
+     * Parse Time
+     *
+     * See '7.7.  Times' of draft-ietf-secsh-filexfer-13 for more info.
+     *
+     * @param string $key
+     * @param int $flags
+     * @param string $response
+     * @return array
+     * @access private
+     */
+    function _parseTime($key, $flags, &$response)
+    {
+        if (strlen($response) < 8) {
+            user_error('Malformed file attributes');
+            return array();
+        }
+        $attr = array();
+        $attr[$key] = hexdec(bin2hex($this->_string_shift($response, 8)));
+        if ($flags & NET_SFTP_ATTR_SUBSECOND_TIMES) {
+            $attr+= extract(unpack('N' . $key . '_nseconds', $this->_string_shift($response, 4)));
+        }
+        return $attr;
+    }
+
+    /**
+     * Parse Attributes
+     *
+     * See '7.  File Attributes' of draft-ietf-secsh-filexfer-13 for more info.
+     *
+     * @param string $response
+     * @return array
+     * @access private
+     */
+    function _parseAttributes(&$response)
+    {
+        if ($this->version >= 4) {
+            $length = 5;
+            $format = 'Nflags/Ctype';
+        } else {
+            $length = 4;
+            $format = 'Nflags';
+        }
+
+        $attr = array();
+        if (strlen($response) < $length) {
+            user_error('Malformed file attributes');
+            return array();
+        }
+        extract(unpack($format, $this->_string_shift($response, $length)));
+        if (isset($type)) {
+            $attr['type'] = $type;
+        }
+        foreach ($this->attributes as $key => $value) {
+            switch ($flags & $key) {
+                case NET_SFTP_ATTR_UIDGID:
+                    if ($this->version > 3) {
+                        continue 2;
+                    }
+                    break;
+                case NET_SFTP_ATTR_CREATETIME:
+                case NET_SFTP_ATTR_MODIFYTIME:
+                case NET_SFTP_ATTR_ACL:
+                case NET_SFTP_ATTR_OWNERGROUP:
+                case NET_SFTP_ATTR_SUBSECOND_TIMES:
+                    if ($this->version < 4) {
+                        continue 2;
+                    }
+                    break;
+                case NET_SFTP_ATTR_BITS:
+                    if ($this->version < 5) {
+                        continue 2;
+                    }
+                    break;
+                case NET_SFTP_ATTR_ALLOCATION_SIZE:
+                case NET_SFTP_ATTR_TEXT_HINT:
+                case NET_SFTP_ATTR_MIME_TYPE:
+                case NET_SFTP_ATTR_LINK_COUNT:
+                case NET_SFTP_ATTR_UNTRANSLATED_NAME:
+                case NET_SFTP_ATTR_CTIME:
+                    if ($this->version < 6) {
+                        continue 2;
+                    }
+            }
+            switch ($flags & $key) {
+                case NET_SFTP_ATTR_SIZE:             // 0x00000001
+                    // The size attribute is defined as an unsigned 64-bit integer.
+                    // The following will use floats on 32-bit platforms, if necessary.
+                    // As can be seen in the BigInteger class, floats are generally
+                    // IEEE 754 binary64 "double precision" on such platforms and
+                    // as such can represent integers of at least 2^50 without loss
+                    // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB.
+                    $attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
+                    break;
+                case NET_SFTP_ATTR_UIDGID:           // 0x00000002 (SFTPv3 or earlier)
+                    if (strlen($response) < 8) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
+                    break;
+                case NET_SFTP_ATTR_PERMISSIONS:      // 0x00000004
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr+= unpack('Npermissions', $this->_string_shift($response, 4));
+                    // mode == permissions; permissions was the original array key and is retained for bc purposes.
+                    // mode was added because that's the more industry standard terminology
+                    $attr+= array('mode' => $attr['permissions']);
+                    $fileType = $this->_parseMode($attr['permissions']);
+                    if ($fileType !== false) {
+                        $attr+= array('type' => $fileType);
+                    }
+                    break;
+                case NET_SFTP_ATTR_ACCESSTIME:       // 0x00000008
+                    if ($this->version >= 4) {
+                        $attr+= $this->_parseTime('atime', $flags, $response);
+                        break;
+                    }
+                    if (strlen($response) < 8) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8));
+                    break;
+                case NET_SFTP_ATTR_CREATETIME:       // 0x00000010 (SFTPv4+)
+                    $attr+= $this->_parseTime('createtime', $flags, $response);
+                    break;
+                case NET_SFTP_ATTR_MODIFYTIME:       // 0x00000020
+                    $attr+= $this->_parseTime('mtime', $flags, $response);
+                    break;
+                case NET_SFTP_ATTR_ACL:              // 0x00000040
+                    // access control list
+                    // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7
+                    // currently unsupported
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Ncount', $this->_string_shift($response, 4)));
+                    for ($i = 0; $i < $count; $i++) {
+                        if (strlen($response) < 16) {
+                            user_error('Malformed file attributes');
+                            return $attr;
+                        }
+                        extract(unpack('Ntype/Nflag/Nmask/Nlength', $this->_string_shift($response, 16)));
+                        if (strlen($response) < $length) {
+                            user_error('Malformed file attributes');
+                            return $attr;
+                        }
+                        $this->_string_shift($response, $length); // who
+                    }
+                    break;
+                case NET_SFTP_ATTR_OWNERGROUP:       // 0x00000080
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                    if (strlen($response) < $length) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr['owner'] = $this->_string_shift($response, $length);
+
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                    if (strlen($response) < $length) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr['group'] = $this->_string_shift($response, $length);
+                    break;
+                case NET_SFTP_ATTR_SUBSECOND_TIMES:  // 0x00000100
+                    break;
+                case NET_SFTP_ATTR_BITS:             // 0x00000200 (SFTPv5+)
+                    // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-5.8
+                    // currently unsupported
+                    // tells if you file is:
+                    // readonly, system, hidden, case inensitive, archive, encrypted, compressed, sparse
+                    // append only, immutable, sync
+                    if (strlen($response) < 8) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Nattrib-bits/Nattrib-bits-valid', $this->_string_shift($response, 8)));
+                    break;
+                case NET_SFTP_ATTR_ALLOCATION_SIZE:  // 0x00000400 (SFTPv6+)
+                    // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4
+                    // represents the number of bytes htat the file consumes on the disk. will
+                    // usually be larger than the 'size' field
+                    $attr['allocation-size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
+                    break;
+                case NET_SFTP_ATTR_TEXT_HINT:        // 0x00000800
+                    // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10
+                    // currently unsupported
+                    // tells if file is "known text", "guessed text", "known binary", "guessed binary"
+                    extract(unpack('Ctext-hint', $this->_string_shift($response)));
+                    break;
+                case NET_SFTP_ATTR_MIME_TYPE:        // 0x00001000
+                    // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.11
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                    if (strlen($response) < $length) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr['mime-type'] = $this->_string_shift($response, $length);
+                    break;
+                case NET_SFTP_ATTR_LINK_COUNT:       // 0x00002000
+                    // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr+= unpack('Nlink-count', $this->_string_shift($response, 4));
+                    break;
+                case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000
+                    // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                    if (strlen($response) < $length) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    $attr['untranslated-name'] = $this->_string_shift($response, $length);
+                    break;
+                case NET_SFTP_ATTR_CTIME:            // 0x00008000
+                    // 'ctime' contains the last time the file attributes were changed.  The
+                    // exact meaning of this field depends on the server.
+                    $attr+= $this->_parseTime('ctime', $flags, $response);
+                    break;
+                case NET_SFTP_ATTR_EXTENDED:         // 0x80000000
+                    if (strlen($response) < 4) {
+                        user_error('Malformed file attributes');
+                        return $attr;
+                    }
+                    extract(unpack('Ncount', $this->_string_shift($response, 4)));
+                    for ($i = 0; $i < $count; $i++) {
+                        if (strlen($response) < 4) {
+                            user_error('Malformed file attributes');
+                            return $attr;
+                        }
+                        extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                        $key = $this->_string_shift($response, $length);
+                        if (strlen($response) < 4) {
+                            user_error('Malformed file attributes');
+                            return $attr;
+                        }
+                        extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                        $attr[$key] = $this->_string_shift($response, $length);
+                    }
+            }
+        }
+        return $attr;
+    }
+
+    /**
+     * Attempt to identify the file type
+     *
+     * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway
+     *
+     * @param int $mode
+     * @return int
+     * @access private
+     */
+    function _parseMode($mode)
+    {
+        // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12
+        // see, also, http://linux.die.net/man/2/stat
+        switch ($mode & 0170000) {// ie. 1111 0000 0000 0000
+            case 0000000: // no file type specified - figure out the file type using alternative means
+                return false;
+            case 0040000:
+                return NET_SFTP_TYPE_DIRECTORY;
+            case 0100000:
+                return NET_SFTP_TYPE_REGULAR;
+            case 0120000:
+                return NET_SFTP_TYPE_SYMLINK;
+            // new types introduced in SFTPv5+
+            // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
+            case 0010000: // named pipe (fifo)
+                return NET_SFTP_TYPE_FIFO;
+            case 0020000: // character special
+                return NET_SFTP_TYPE_CHAR_DEVICE;
+            case 0060000: // block special
+                return NET_SFTP_TYPE_BLOCK_DEVICE;
+            case 0140000: // socket
+                return NET_SFTP_TYPE_SOCKET;
+            case 0160000: // whiteout
+                // "SPECIAL should be used for files that are of
+                //  a known type which cannot be expressed in the protocol"
+                return NET_SFTP_TYPE_SPECIAL;
+            default:
+                return NET_SFTP_TYPE_UNKNOWN;
+        }
+    }
+
+    /**
+     * Parse Longname
+     *
+     * SFTPv3 doesn't provide any easy way of identifying a file type.  You could try to open
+     * a file as a directory and see if an error is returned or you could try to parse the
+     * SFTPv3-specific longname field of the SSH_FXP_NAME packet.  That's what this function does.
+     * The result is returned using the
+     * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}.
+     *
+     * If the longname is in an unrecognized format bool(false) is returned.
+     *
+     * @param string $longname
+     * @return mixed
+     * @access private
+     */
+    function _parseLongname($longname)
+    {
+        // http://en.wikipedia.org/wiki/Unix_file_types
+        // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions
+        if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) {
+            switch ($longname[0]) {
+                case '-':
+                    return NET_SFTP_TYPE_REGULAR;
+                case 'd':
+                    return NET_SFTP_TYPE_DIRECTORY;
+                case 'l':
+                    return NET_SFTP_TYPE_SYMLINK;
+                default:
+                    return NET_SFTP_TYPE_SPECIAL;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Sends SFTP Packets
+     *
+     * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
+     *
+     * @param int $type
+     * @param string $data
+     * @param int $request_id
+     * @see self::_get_sftp_packet()
+     * @see self::_send_channel_packet()
+     * @return bool
+     * @access private
+     */
+    function _send_sftp_packet($type, $data, $request_id = 1)
+    {
+        // in SSH2.php the timeout is cumulative per function call. eg. exec() will
+        // timeout after 10s. but for SFTP.php it's cumulative per packet
+        $this->curTimeout = $this->timeout;
+
+        $packet = $this->use_request_id ?
+            pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) :
+            pack('NCa*',  strlen($data) + 1, $type, $data);
+
+        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+        $result = $this->_send_channel_packet(self::CHANNEL, $packet);
+        $stop = strtok(microtime(), ' ') + strtok('');
+
+        if (defined('NET_SFTP_LOGGING')) {
+            $packet_type = '-> ' . $this->packet_types[$type] .
+                           ' (' . round($stop - $start, 4) . 's)';
+            if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
+                switch (PHP_SAPI) {
+                    case 'cli':
+                        $start = $stop = "\r\n";
+                        break;
+                    default:
+                        $start = '<pre>';
+                        $stop = '</pre>';
+                }
+                echo $start . $this->_format_log(array($data), array($packet_type)) . $stop;
+                @flush();
+                @ob_flush();
+            } else {
+                $this->packet_type_log[] = $packet_type;
+                if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
+                    $this->packet_log[] = $data;
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Resets a connection for re-use
+     *
+     * @param int $reason
+     * @access private
+     */
+    function _reset_connection($reason)
+    {
+        parent::_reset_connection($reason);
+        $this->use_request_id = false;
+        $this->pwd = false;
+        $this->requestBuffer = array();
+    }
+
+    /**
+     * Receives SFTP Packets
+     *
+     * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
+     *
+     * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present.
+     * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA
+     * messages containing one SFTP packet.
+     *
+     * @see self::_send_sftp_packet()
+     * @return string
+     * @access private
+     */
+    function _get_sftp_packet($request_id = null)
+    {
+        $this->channel_close = false;
+
+        if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
+            $this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
+            $temp = $this->requestBuffer[$request_id]['packet'];
+            unset($this->requestBuffer[$request_id]);
+            return $temp;
+        }
+
+        // in SSH2.php the timeout is cumulative per function call. eg. exec() will
+        // timeout after 10s. but for SFTP.php it's cumulative per packet
+        $this->curTimeout = $this->timeout;
+
+        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+
+        // SFTP packet length
+        while (strlen($this->packet_buffer) < 4) {
+            $temp = $this->_get_channel_packet(self::CHANNEL, true);
+            if ($temp === true) {
+                if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) {
+                    $this->channel_close = true;
+                }
+                $this->packet_type = false;
+                $this->packet_buffer = '';
+                return false;
+            }
+            if ($temp === false) {
+                return false;
+            }
+            $this->packet_buffer.= $temp;
+        }
+        if (strlen($this->packet_buffer) < 4) {
+            return false;
+        }
+        extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4)));
+        $tempLength = $length;
+        $tempLength-= strlen($this->packet_buffer);
+
+        // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
+        if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) {
+            user_error('Invalid SFTP packet size');
+            return false;
+        }
+
+        // SFTP packet type and data payload
+        while ($tempLength > 0) {
+            $temp = $this->_get_channel_packet(self::CHANNEL, true);
+            if (is_bool($temp)) {
+                if ($temp && $this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) {
+                    $this->channel_close = true;
+                }
+                $this->packet_type = false;
+                $this->packet_buffer = '';
+                return false;
+            }
+            $this->packet_buffer.= $temp;
+            $tempLength-= strlen($temp);
+        }
+
+        $stop = strtok(microtime(), ' ') + strtok('');
+
+        $this->packet_type = ord($this->_string_shift($this->packet_buffer));
+
+        if ($this->use_request_id) {
+            extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id
+            $length-= 5; // account for the request id and the packet type
+        } else {
+            $length-= 1; // account for the packet type
+        }
+
+        $packet = $this->_string_shift($this->packet_buffer, $length);
+
+        if (defined('NET_SFTP_LOGGING')) {
+            $packet_type = '<- ' . $this->packet_types[$this->packet_type] .
+                           ' (' . round($stop - $start, 4) . 's)';
+            if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
+                switch (PHP_SAPI) {
+                    case 'cli':
+                        $start = $stop = "\r\n";
+                        break;
+                    default:
+                        $start = '<pre>';
+                        $stop = '</pre>';
+                }
+                echo $start . $this->_format_log(array($packet), array($packet_type)) . $stop;
+                @flush();
+                @ob_flush();
+            } else {
+                $this->packet_type_log[] = $packet_type;
+                if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
+                    $this->packet_log[] = $packet;
+                }
+            }
+        }
+
+        if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
+            $this->requestBuffer[$packet_id] = array(
+                'packet_type' => $this->packet_type,
+                'packet' => $packet
+            );
+            return $this->_get_sftp_packet($request_id);
+        }
+
+        return $packet;
+    }
+
+    /**
+     * Returns a log of the packets that have been sent and received.
+     *
+     * Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
+     *
+     * @access public
+     * @return string or Array
+     */
+    function getSFTPLog()
+    {
+        if (!defined('NET_SFTP_LOGGING')) {
+            return false;
+        }
+
+        switch (NET_SFTP_LOGGING) {
+            case self::LOG_COMPLEX:
+                return $this->_format_log($this->packet_log, $this->packet_type_log);
+                break;
+            //case self::LOG_SIMPLE:
+            default:
+                return $this->packet_type_log;
+        }
+    }
+
+    /**
+     * Returns all errors
+     *
+     * @return array
+     * @access public
+     */
+    function getSFTPErrors()
+    {
+        return $this->sftp_errors;
+    }
+
+    /**
+     * Returns the last error
+     *
+     * @return string
+     * @access public
+     */
+    function getLastSFTPError()
+    {
+        return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : '';
+    }
+
+    /**
+     * Get supported SFTP versions
+     *
+     * @return array
+     * @access public
+     */
+    function getSupportedVersions()
+    {
+        if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+            return false;
+        }
+
+        if (!$this->partial_init) {
+            $this->_partial_init_sftp_connection();
+        }
+
+        $temp = array('version' => $this->defaultVersion);
+        if (isset($this->extensions['versions'])) {
+            $temp['extensions'] = $this->extensions['versions'];
+        }
+        return $temp;
+    }
+
+    /**
+     * Get supported SFTP versions
+     *
+     * @return array
+     * @access public
+     */
+    function getNegotiatedVersion()
+    {
+        if (!$this->_precheck()) {
+            return false;
+        }
+
+        return $this->version;
+    }
+
+    /**
+     * Set preferred version
+     *
+     * If you're preferred version isn't supported then the highest supported
+     * version of SFTP will be utilized. Set to null or false or int(0) to
+     * unset the preferred version
+     *
+     * @param int $version
+     * @access public
+     */
+    function setPreferredVersion($version)
+    {
+        $this->preferredVersion = $version;
+    }
+
+    /**
+     * Disconnect
+     *
+     * @param int $reason
+     * @return bool
+     * @access private
+     */
+    function _disconnect($reason)
+    {
+        $this->pwd = false;
+        parent::_disconnect($reason);
+    }
+
+    /**
+     * Enable Date Preservation
+     *
+     * @access public
+     */
+    function enableDatePreservation()
+    {
+        $this->preserveTime = true;
+    }
+
+    /**
+     * Disable Date Preservation
+     *
+     * @access public
+     */
+    function disableDatePreservation()
+    {
+        $this->preserveTime = false;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
new file mode 100644
index 00000000..ec9e5841
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
@@ -0,0 +1,796 @@
+<?php
+
+/**
+ * SFTP Stream Wrapper
+ *
+ * Creates an sftp:// protocol handler that can be used with, for example, fopen(), dir(), etc.
+ *
+ * PHP version 5
+ *
+ * @category  Net
+ * @package   SFTP
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2013 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net\SFTP;
+
+use phpseclib\Crypt\RSA;
+use phpseclib\Net\SFTP;
+
+/**
+ * SFTP Stream Wrapper
+ *
+ * @package SFTP
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class Stream
+{
+    /**
+     * SFTP instances
+     *
+     * Rather than re-create the connection we re-use instances if possible
+     *
+     * @var array
+     */
+    static $instances;
+
+    /**
+     * SFTP instance
+     *
+     * @var object
+     * @access private
+     */
+    var $sftp;
+
+    /**
+     * Path
+     *
+     * @var string
+     * @access private
+     */
+    var $path;
+
+    /**
+     * Mode
+     *
+     * @var string
+     * @access private
+     */
+    var $mode;
+
+    /**
+     * Position
+     *
+     * @var int
+     * @access private
+     */
+    var $pos;
+
+    /**
+     * Size
+     *
+     * @var int
+     * @access private
+     */
+    var $size;
+
+    /**
+     * Directory entries
+     *
+     * @var array
+     * @access private
+     */
+    var $entries;
+
+    /**
+     * EOF flag
+     *
+     * @var bool
+     * @access private
+     */
+    var $eof;
+
+    /**
+     * Context resource
+     *
+     * Technically this needs to be publically accessible so PHP can set it directly
+     *
+     * @var resource
+     * @access public
+     */
+    var $context;
+
+    /**
+     * Notification callback function
+     *
+     * @var callable
+     * @access public
+     */
+    var $notification;
+
+    /**
+     * Registers this class as a URL wrapper.
+     *
+     * @param string $protocol The wrapper name to be registered.
+     * @return bool True on success, false otherwise.
+     * @access public
+     */
+    static function register($protocol = 'sftp')
+    {
+        if (in_array($protocol, stream_get_wrappers(), true)) {
+            return false;
+        }
+        return stream_wrapper_register($protocol, get_called_class());
+    }
+
+    /**
+     * The Constructor
+     *
+     * @access public
+     */
+    function __construct()
+    {
+        if (defined('NET_SFTP_STREAM_LOGGING')) {
+            echo "__construct()\r\n";
+        }
+    }
+
+    /**
+     * Path Parser
+     *
+     * Extract a path from a URI and actually connect to an SSH server if appropriate
+     *
+     * If "notification" is set as a context parameter the message code for successful login is
+     * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
+     *
+     * @param string $path
+     * @return string
+     * @access private
+     */
+    function _parse_path($path)
+    {
+        $orig = $path;
+        extract(parse_url($path) + array('port' => 22));
+        if (isset($query)) {
+            $path.= '?' . $query;
+        } elseif (preg_match('/(\?|\?#)$/', $orig)) {
+            $path.= '?';
+        }
+        if (isset($fragment)) {
+            $path.= '#' . $fragment;
+        } elseif ($orig[strlen($orig) - 1] == '#') {
+            $path.= '#';
+        }
+
+        if (!isset($host)) {
+            return false;
+        }
+
+        if (isset($this->context)) {
+            $context = stream_context_get_params($this->context);
+            if (isset($context['notification'])) {
+                $this->notification = $context['notification'];
+            }
+        }
+
+        if ($host[0] == '$') {
+            $host = substr($host, 1);
+            global ${$host};
+            if (($$host instanceof SFTP) === false) {
+                return false;
+            }
+            $this->sftp = $$host;
+        } else {
+            if (isset($this->context)) {
+                $context = stream_context_get_options($this->context);
+            }
+            if (isset($context[$scheme]['session'])) {
+                $sftp = $context[$scheme]['session'];
+            }
+            if (isset($context[$scheme]['sftp'])) {
+                $sftp = $context[$scheme]['sftp'];
+            }
+            if (isset($sftp) && $sftp instanceof SFTP) {
+                $this->sftp = $sftp;
+                return $path;
+            }
+            if (isset($context[$scheme]['username'])) {
+                $user = $context[$scheme]['username'];
+            }
+            if (isset($context[$scheme]['password'])) {
+                $pass = $context[$scheme]['password'];
+            }
+            if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof RSA) {
+                $pass = $context[$scheme]['privkey'];
+            }
+
+            if (!isset($user) || !isset($pass)) {
+                return false;
+            }
+
+            // casting $pass to a string is necessary in the event that it's a \phpseclib\Crypt\RSA object
+            if (isset(self::$instances[$host][$port][$user][(string) $pass])) {
+                $this->sftp = self::$instances[$host][$port][$user][(string) $pass];
+            } else {
+                $this->sftp = new SFTP($host, $port);
+                $this->sftp->disableStatCache();
+                if (isset($this->notification) && is_callable($this->notification)) {
+                    /* if !is_callable($this->notification) we could do this:
+
+                       user_error('fopen(): failed to call user notifier', E_USER_WARNING);
+
+                       the ftp wrapper gives errors like that when the notifier isn't callable.
+                       i've opted not to do that, however, since the ftp wrapper gives the line
+                       on which the fopen occurred as the line number - not the line that the
+                       user_error is on.
+                    */
+                    call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
+                    call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
+                    if (!$this->sftp->login($user, $pass)) {
+                        call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0);
+                        return false;
+                    }
+                    call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0);
+                } else {
+                    if (!$this->sftp->login($user, $pass)) {
+                        return false;
+                    }
+                }
+                self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
+            }
+        }
+
+        return $path;
+    }
+
+    /**
+     * Opens file or URL
+     *
+     * @param string $path
+     * @param string $mode
+     * @param int $options
+     * @param string $opened_path
+     * @return bool
+     * @access public
+     */
+    function _stream_open($path, $mode, $options, &$opened_path)
+    {
+        $path = $this->_parse_path($path);
+
+        if ($path === false) {
+            return false;
+        }
+        $this->path = $path;
+
+        $this->size = $this->sftp->size($path);
+        $this->mode = preg_replace('#[bt]$#', '', $mode);
+        $this->eof = false;
+
+        if ($this->size === false) {
+            if ($this->mode[0] == 'r') {
+                return false;
+            } else {
+                $this->sftp->touch($path);
+                $this->size = 0;
+            }
+        } else {
+            switch ($this->mode[0]) {
+                case 'x':
+                    return false;
+                case 'w':
+                    $this->sftp->truncate($path, 0);
+                    $this->size = 0;
+            }
+        }
+
+        $this->pos = $this->mode[0] != 'a' ? 0 : $this->size;
+
+        return true;
+    }
+
+    /**
+     * Read from stream
+     *
+     * @param int $count
+     * @return mixed
+     * @access public
+     */
+    function _stream_read($count)
+    {
+        switch ($this->mode) {
+            case 'w':
+            case 'a':
+            case 'x':
+            case 'c':
+                return false;
+        }
+
+        // commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite
+        //if ($this->pos >= $this->size) {
+        //    $this->eof = true;
+        //    return false;
+        //}
+
+        $result = $this->sftp->get($this->path, false, $this->pos, $count);
+        if (isset($this->notification) && is_callable($this->notification)) {
+            if ($result === false) {
+                call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
+                return 0;
+            }
+            // seems that PHP calls stream_read in 8k chunks
+            call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size);
+        }
+
+        if (empty($result)) { // ie. false or empty string
+            $this->eof = true;
+            return false;
+        }
+        $this->pos+= strlen($result);
+
+        return $result;
+    }
+
+    /**
+     * Write to stream
+     *
+     * @param string $data
+     * @return mixed
+     * @access public
+     */
+    function _stream_write($data)
+    {
+        switch ($this->mode) {
+            case 'r':
+                return false;
+        }
+
+        $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos);
+        if (isset($this->notification) && is_callable($this->notification)) {
+            if (!$result) {
+                call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
+                return 0;
+            }
+            // seems that PHP splits up strings into 8k blocks before calling stream_write
+            call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data));
+        }
+
+        if ($result === false) {
+            return false;
+        }
+        $this->pos+= strlen($data);
+        if ($this->pos > $this->size) {
+            $this->size = $this->pos;
+        }
+        $this->eof = false;
+        return strlen($data);
+    }
+
+    /**
+     * Retrieve the current position of a stream
+     *
+     * @return int
+     * @access public
+     */
+    function _stream_tell()
+    {
+        return $this->pos;
+    }
+
+    /**
+     * Tests for end-of-file on a file pointer
+     *
+     * In my testing there are four classes functions that normally effect the pointer:
+     * fseek, fputs  / fwrite, fgets / fread and ftruncate.
+     *
+     * Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof()
+     * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof()
+     * will return false. do fread($fp, 1) and feof() will then return true.
+     *
+     * @return bool
+     * @access public
+     */
+    function _stream_eof()
+    {
+        return $this->eof;
+    }
+
+    /**
+     * Seeks to specific location in a stream
+     *
+     * @param int $offset
+     * @param int $whence
+     * @return bool
+     * @access public
+     */
+    function _stream_seek($offset, $whence)
+    {
+        switch ($whence) {
+            case SEEK_SET:
+                if ($offset < 0) {
+                    return false;
+                }
+                break;
+            case SEEK_CUR:
+                $offset+= $this->pos;
+                break;
+            case SEEK_END:
+                $offset+= $this->size;
+        }
+
+        $this->pos = $offset;
+        $this->eof = false;
+        return true;
+    }
+
+    /**
+     * Change stream options
+     *
+     * @param string $path
+     * @param int $option
+     * @param mixed $var
+     * @return bool
+     * @access public
+     */
+    function _stream_metadata($path, $option, $var)
+    {
+        $path = $this->_parse_path($path);
+        if ($path === false) {
+            return false;
+        }
+
+        // stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined
+        // see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246
+        //     and https://github.com/php/php-src/blob/master/main/php_streams.h#L592
+        switch ($option) {
+            case 1: // PHP_STREAM_META_TOUCH
+                $time = isset($var[0]) ? $var[0] : null;
+                $atime = isset($var[1]) ? $var[1] : null;
+                return $this->sftp->touch($path, $time, $atime);
+            case 2: // PHP_STREAM_OWNER_NAME
+            case 3: // PHP_STREAM_GROUP_NAME
+                return false;
+            case 4: // PHP_STREAM_META_OWNER
+                return $this->sftp->chown($path, $var);
+            case 5: // PHP_STREAM_META_GROUP
+                return $this->sftp->chgrp($path, $var);
+            case 6: // PHP_STREAM_META_ACCESS
+                return $this->sftp->chmod($path, $var) !== false;
+        }
+    }
+
+    /**
+     * Retrieve the underlaying resource
+     *
+     * @param int $cast_as
+     * @return resource
+     * @access public
+     */
+    function _stream_cast($cast_as)
+    {
+        return $this->sftp->fsock;
+    }
+
+    /**
+     * Advisory file locking
+     *
+     * @param int $operation
+     * @return bool
+     * @access public
+     */
+    function _stream_lock($operation)
+    {
+        return false;
+    }
+
+    /**
+     * Renames a file or directory
+     *
+     * Attempts to rename oldname to newname, moving it between directories if necessary.
+     * If newname exists, it will be overwritten.  This is a departure from what \phpseclib\Net\SFTP
+     * does.
+     *
+     * @param string $path_from
+     * @param string $path_to
+     * @return bool
+     * @access public
+     */
+    function _rename($path_from, $path_to)
+    {
+        $path1 = parse_url($path_from);
+        $path2 = parse_url($path_to);
+        unset($path1['path'], $path2['path']);
+        if ($path1 != $path2) {
+            return false;
+        }
+
+        $path_from = $this->_parse_path($path_from);
+        $path_to = parse_url($path_to);
+        if ($path_from === false) {
+            return false;
+        }
+
+        $path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2
+        // "It is an error if there already exists a file with the name specified by newpath."
+        //  -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5
+        if (!$this->sftp->rename($path_from, $path_to)) {
+            if ($this->sftp->stat($path_to)) {
+                return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to);
+            }
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Open directory handle
+     *
+     * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and
+     * removed in 5.4 I'm just going to ignore it.
+     *
+     * Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client
+     * sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting
+     * the SFTP specs:
+     *
+     *    The SSH_FXP_NAME response has the following format:
+     *
+     *        uint32     id
+     *        uint32     count
+     *        repeats count times:
+     *                string     filename
+     *                string     longname
+     *                ATTRS      attrs
+     *
+     * @param string $path
+     * @param int $options
+     * @return bool
+     * @access public
+     */
+    function _dir_opendir($path, $options)
+    {
+        $path = $this->_parse_path($path);
+        if ($path === false) {
+            return false;
+        }
+        $this->pos = 0;
+        $this->entries = $this->sftp->nlist($path);
+        return $this->entries !== false;
+    }
+
+    /**
+     * Read entry from directory handle
+     *
+     * @return mixed
+     * @access public
+     */
+    function _dir_readdir()
+    {
+        if (isset($this->entries[$this->pos])) {
+            return $this->entries[$this->pos++];
+        }
+        return false;
+    }
+
+    /**
+     * Rewind directory handle
+     *
+     * @return bool
+     * @access public
+     */
+    function _dir_rewinddir()
+    {
+        $this->pos = 0;
+        return true;
+    }
+
+    /**
+     * Close directory handle
+     *
+     * @return bool
+     * @access public
+     */
+    function _dir_closedir()
+    {
+        return true;
+    }
+
+    /**
+     * Create a directory
+     *
+     * Only valid $options is STREAM_MKDIR_RECURSIVE
+     *
+     * @param string $path
+     * @param int $mode
+     * @param int $options
+     * @return bool
+     * @access public
+     */
+    function _mkdir($path, $mode, $options)
+    {
+        $path = $this->_parse_path($path);
+        if ($path === false) {
+            return false;
+        }
+
+        return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE);
+    }
+
+    /**
+     * Removes a directory
+     *
+     * Only valid $options is STREAM_MKDIR_RECURSIVE per <http://php.net/streamwrapper.rmdir>, however,
+     * <http://php.net/rmdir>  does not have a $recursive parameter as mkdir() does so I don't know how
+     * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as
+     * $options. What does 8 correspond to?
+     *
+     * @param string $path
+     * @param int $options
+     * @return bool
+     * @access public
+     */
+    function _rmdir($path, $options)
+    {
+        $path = $this->_parse_path($path);
+        if ($path === false) {
+            return false;
+        }
+
+        return $this->sftp->rmdir($path);
+    }
+
+    /**
+     * Flushes the output
+     *
+     * See <http://php.net/fflush>. Always returns true because \phpseclib\Net\SFTP doesn't cache stuff before writing
+     *
+     * @return bool
+     * @access public
+     */
+    function _stream_flush()
+    {
+        return true;
+    }
+
+    /**
+     * Retrieve information about a file resource
+     *
+     * @return mixed
+     * @access public
+     */
+    function _stream_stat()
+    {
+        $results = $this->sftp->stat($this->path);
+        if ($results === false) {
+            return false;
+        }
+        return $results;
+    }
+
+    /**
+     * Delete a file
+     *
+     * @param string $path
+     * @return bool
+     * @access public
+     */
+    function _unlink($path)
+    {
+        $path = $this->_parse_path($path);
+        if ($path === false) {
+            return false;
+        }
+
+        return $this->sftp->delete($path, false);
+    }
+
+    /**
+     * Retrieve information about a file
+     *
+     * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib\Net\SFTP\Stream is quiet by default
+     * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
+     * cross that bridge when and if it's reached
+     *
+     * @param string $path
+     * @param int $flags
+     * @return mixed
+     * @access public
+     */
+    function _url_stat($path, $flags)
+    {
+        $path = $this->_parse_path($path);
+        if ($path === false) {
+            return false;
+        }
+
+        $results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path);
+        if ($results === false) {
+            return false;
+        }
+
+        return $results;
+    }
+
+    /**
+     * Truncate stream
+     *
+     * @param int $new_size
+     * @return bool
+     * @access public
+     */
+    function _stream_truncate($new_size)
+    {
+        if (!$this->sftp->truncate($this->path, $new_size)) {
+            return false;
+        }
+
+        $this->eof = false;
+        $this->size = $new_size;
+
+        return true;
+    }
+
+    /**
+     * Change stream options
+     *
+     * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
+     * The other two aren't supported because of limitations in \phpseclib\Net\SFTP.
+     *
+     * @param int $option
+     * @param int $arg1
+     * @param int $arg2
+     * @return bool
+     * @access public
+     */
+    function _stream_set_option($option, $arg1, $arg2)
+    {
+        return false;
+    }
+
+    /**
+     * Close an resource
+     *
+     * @access public
+     */
+    function _stream_close()
+    {
+    }
+
+    /**
+     * __call Magic Method
+     *
+     * When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you.
+     * Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function
+     * lets you figure that out.
+     *
+     * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
+     * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
+     *
+     * @param string $name
+     * @param array $arguments
+     * @return mixed
+     * @access public
+     */
+    function __call($name, $arguments)
+    {
+        if (defined('NET_SFTP_STREAM_LOGGING')) {
+            echo $name . '(';
+            $last = count($arguments) - 1;
+            foreach ($arguments as $i => $argument) {
+                var_export($argument);
+                if ($i != $last) {
+                    echo ',';
+                }
+            }
+            echo ")\r\n";
+        }
+        $name = '_' . $name;
+        if (!method_exists($this, $name)) {
+            return false;
+        }
+        return call_user_func_array(array($this, $name), $arguments);
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
new file mode 100644
index 00000000..fc8d2acd
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
@@ -0,0 +1,1662 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SSHv1.
+ *
+ * PHP version 5
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $ssh = new \phpseclib\Net\SSH1('www.domain.tld');
+ *    if (!$ssh->login('username', 'password')) {
+ *        exit('Login Failed');
+ *    }
+ *
+ *    echo $ssh->exec('ls -la');
+ * ?>
+ * </code>
+ *
+ * Here's another short example:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $ssh = new \phpseclib\Net\SSH1('www.domain.tld');
+ *    if (!$ssh->login('username', 'password')) {
+ *        exit('Login Failed');
+ *    }
+ *
+ *    echo $ssh->read('username@username:~$');
+ *    $ssh->write("ls -la\n");
+ *    echo $ssh->read('username@username:~$');
+ * ?>
+ * </code>
+ *
+ * More information on the SSHv1 specification can be found by reading
+ * {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}.
+ *
+ * @category  Net
+ * @package   SSH1
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+use phpseclib\Crypt\DES;
+use phpseclib\Crypt\Random;
+use phpseclib\Crypt\TripleDES;
+use phpseclib\Math\BigInteger;
+
+/**
+ * Pure-PHP implementation of SSHv1.
+ *
+ * @package SSH1
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class SSH1
+{
+    /**#@+
+     * Encryption Methods
+     *
+     * @see \phpseclib\Net\SSH1::getSupportedCiphers()
+     * @access public
+     */
+    /**
+     * No encryption
+     *
+     * Not supported.
+     */
+    const CIPHER_NONE = 0;
+    /**
+     * IDEA in CFB mode
+     *
+     * Not supported.
+     */
+    const CIPHER_IDEA = 1;
+    /**
+     * DES in CBC mode
+     */
+    const CIPHER_DES = 2;
+    /**
+     * Triple-DES in CBC mode
+     *
+     * All implementations are required to support this
+     */
+    const CIPHER_3DES = 3;
+    /**
+     * TRI's Simple Stream encryption CBC
+     *
+     * Not supported nor is it defined in the official SSH1 specs.  OpenSSH, however, does define it (see cipher.h),
+     * although it doesn't use it (see cipher.c)
+     */
+    const CIPHER_BROKEN_TSS = 4;
+    /**
+     * RC4
+     *
+     * Not supported.
+     *
+     * @internal According to the SSH1 specs:
+     *
+     *        "The first 16 bytes of the session key are used as the key for
+     *         the server to client direction.  The remaining 16 bytes are used
+     *         as the key for the client to server direction.  This gives
+     *         independent 128-bit keys for each direction."
+     *
+     *     This library currently only supports encryption when the same key is being used for both directions.  This is
+     *     because there's only one $crypto object.  Two could be added ($encrypt and $decrypt, perhaps).
+     */
+    const CIPHER_RC4 = 5;
+    /**
+     * Blowfish
+     *
+     * Not supported nor is it defined in the official SSH1 specs.  OpenSSH, however, defines it (see cipher.h) and
+     * uses it (see cipher.c)
+     */
+    const CIPHER_BLOWFISH = 6;
+    /**#@-*/
+
+    /**#@+
+     * Authentication Methods
+     *
+     * @see \phpseclib\Net\SSH1::getSupportedAuthentications()
+     * @access public
+    */
+    /**
+     * .rhosts or /etc/hosts.equiv
+     */
+    const AUTH_RHOSTS = 1;
+    /**
+     * pure RSA authentication
+     */
+    const AUTH_RSA = 2;
+    /**
+     * password authentication
+     *
+     * This is the only method that is supported by this library.
+     */
+    const AUTH_PASSWORD = 3;
+    /**
+     * .rhosts with RSA host authentication
+     */
+    const AUTH_RHOSTS_RSA = 4;
+    /**#@-*/
+
+    /**#@+
+     * Terminal Modes
+     *
+     * @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html
+     * @access private
+    */
+    const TTY_OP_END = 0;
+    /**#@-*/
+
+    /**
+     * The Response Type
+     *
+     * @see \phpseclib\Net\SSH1::_get_binary_packet()
+     * @access private
+     */
+    const RESPONSE_TYPE = 1;
+
+    /**
+     * The Response Data
+     *
+     * @see \phpseclib\Net\SSH1::_get_binary_packet()
+     * @access private
+     */
+    const RESPONSE_DATA = 2;
+
+    /**#@+
+     * Execution Bitmap Masks
+     *
+     * @see \phpseclib\Net\SSH1::bitmap
+     * @access private
+    */
+    const MASK_CONSTRUCTOR = 0x00000001;
+    const MASK_CONNECTED   = 0x00000002;
+    const MASK_LOGIN       = 0x00000004;
+    const MASK_SHELL       = 0x00000008;
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Net\SSH1::getLog()
+    */
+    /**
+     * Returns the message numbers
+     */
+    const LOG_SIMPLE = 1;
+    /**
+     * Returns the message content
+     */
+    const LOG_COMPLEX = 2;
+    /**
+     * Outputs the content real-time
+     */
+    const LOG_REALTIME = 3;
+    /**
+     * Dumps the content real-time to a file
+     */
+    const LOG_REALTIME_FILE = 4;
+    /**
+     * Make sure that the log never gets larger than this
+     */
+    const LOG_MAX_SIZE = 1048576; // 1024 * 1024
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Net\SSH1::read()
+    */
+    /**
+     * Returns when a string matching $expect exactly is found
+     */
+    const READ_SIMPLE = 1;
+    /**
+     * Returns when a string matching the regular expression $expect is found
+     */
+    const READ_REGEX = 2;
+    /**#@-*/
+
+    /**
+     * The SSH identifier
+     *
+     * @var string
+     * @access private
+     */
+    var $identifier = 'SSH-1.5-phpseclib';
+
+    /**
+     * The Socket Object
+     *
+     * @var object
+     * @access private
+     */
+    var $fsock;
+
+    /**
+     * The cryptography object
+     *
+     * @var object
+     * @access private
+     */
+    var $crypto = false;
+
+    /**
+     * Execution Bitmap
+     *
+     * The bits that are set represent functions that have been called already.  This is used to determine
+     * if a requisite function has been successfully executed.  If not, an error should be thrown.
+     *
+     * @var int
+     * @access private
+     */
+    var $bitmap = 0;
+
+    /**
+     * The Server Key Public Exponent
+     *
+     * Logged for debug purposes
+     *
+     * @see self::getServerKeyPublicExponent()
+     * @var string
+     * @access private
+     */
+    var $server_key_public_exponent;
+
+    /**
+     * The Server Key Public Modulus
+     *
+     * Logged for debug purposes
+     *
+     * @see self::getServerKeyPublicModulus()
+     * @var string
+     * @access private
+     */
+    var $server_key_public_modulus;
+
+    /**
+     * The Host Key Public Exponent
+     *
+     * Logged for debug purposes
+     *
+     * @see self::getHostKeyPublicExponent()
+     * @var string
+     * @access private
+     */
+    var $host_key_public_exponent;
+
+    /**
+     * The Host Key Public Modulus
+     *
+     * Logged for debug purposes
+     *
+     * @see self::getHostKeyPublicModulus()
+     * @var string
+     * @access private
+     */
+    var $host_key_public_modulus;
+
+    /**
+     * Supported Ciphers
+     *
+     * Logged for debug purposes
+     *
+     * @see self::getSupportedCiphers()
+     * @var array
+     * @access private
+     */
+    var $supported_ciphers = array(
+        self::CIPHER_NONE       => 'No encryption',
+        self::CIPHER_IDEA       => 'IDEA in CFB mode',
+        self::CIPHER_DES        => 'DES in CBC mode',
+        self::CIPHER_3DES       => 'Triple-DES in CBC mode',
+        self::CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC',
+        self::CIPHER_RC4        => 'RC4',
+        self::CIPHER_BLOWFISH   => 'Blowfish'
+    );
+
+    /**
+     * Supported Authentications
+     *
+     * Logged for debug purposes
+     *
+     * @see self::getSupportedAuthentications()
+     * @var array
+     * @access private
+     */
+    var $supported_authentications = array(
+        self::AUTH_RHOSTS     => '.rhosts or /etc/hosts.equiv',
+        self::AUTH_RSA        => 'pure RSA authentication',
+        self::AUTH_PASSWORD   => 'password authentication',
+        self::AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication'
+    );
+
+    /**
+     * Server Identification
+     *
+     * @see self::getServerIdentification()
+     * @var string
+     * @access private
+     */
+    var $server_identification = '';
+
+    /**
+     * Protocol Flags
+     *
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $protocol_flags = array();
+
+    /**
+     * Protocol Flag Log
+     *
+     * @see self::getLog()
+     * @var array
+     * @access private
+     */
+    var $protocol_flags_log = array();
+
+    /**
+     * Message Log
+     *
+     * @see self::getLog()
+     * @var array
+     * @access private
+     */
+    var $message_log = array();
+
+    /**
+     * Real-time log file pointer
+     *
+     * @see self::_append_log()
+     * @var resource
+     * @access private
+     */
+    var $realtime_log_file;
+
+    /**
+     * Real-time log file size
+     *
+     * @see self::_append_log()
+     * @var int
+     * @access private
+     */
+    var $realtime_log_size;
+
+    /**
+     * Real-time log file wrap boolean
+     *
+     * @see self::_append_log()
+     * @var bool
+     * @access private
+     */
+    var $realtime_log_wrap;
+
+    /**
+     * Interactive Buffer
+     *
+     * @see self::read()
+     * @var array
+     * @access private
+     */
+    var $interactiveBuffer = '';
+
+    /**
+     * Current log size
+     *
+     * Should never exceed self::LOG_MAX_SIZE
+     *
+     * @see self::_send_binary_packet()
+     * @see self::_get_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $log_size;
+
+    /**
+     * Timeout
+     *
+     * @see self::setTimeout()
+     * @access private
+     */
+    var $timeout;
+
+    /**
+     * Current Timeout
+     *
+     * @see self::_get_channel_packet()
+     * @access private
+     */
+    var $curTimeout;
+
+    /**
+     * Log Boundary
+     *
+     * @see self::_format_log()
+     * @access private
+     */
+    var $log_boundary = ':';
+
+    /**
+     * Log Long Width
+     *
+     * @see self::_format_log()
+     * @access private
+     */
+    var $log_long_width = 65;
+
+    /**
+     * Log Short Width
+     *
+     * @see self::_format_log()
+     * @access private
+     */
+    var $log_short_width = 16;
+
+    /**
+     * Hostname
+     *
+     * @see self::__construct()
+     * @see self::_connect()
+     * @var string
+     * @access private
+     */
+    var $host;
+
+    /**
+     * Port Number
+     *
+     * @see self::__construct()
+     * @see self::_connect()
+     * @var int
+     * @access private
+     */
+    var $port;
+
+    /**
+     * Timeout for initial connection
+     *
+     * Set by the constructor call. Calling setTimeout() is optional. If it's not called functions like
+     * exec() won't timeout unless some PHP setting forces it too. The timeout specified in the constructor,
+     * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
+     * 10 seconds. It is used by fsockopen() in that function.
+     *
+     * @see self::__construct()
+     * @see self::_connect()
+     * @var int
+     * @access private
+     */
+    var $connectionTimeout;
+
+    /**
+     * Default cipher
+     *
+     * @see self::__construct()
+     * @see self::_connect()
+     * @var int
+     * @access private
+     */
+    var $cipher;
+
+    /**
+     * Default Constructor.
+     *
+     * Connects to an SSHv1 server
+     *
+     * @param string $host
+     * @param int $port
+     * @param int $timeout
+     * @param int $cipher
+     * @return \phpseclib\Net\SSH1
+     * @access public
+     */
+    function __construct($host, $port = 22, $timeout = 10, $cipher = self::CIPHER_3DES)
+    {
+        $this->protocol_flags = array(
+            1  => 'NET_SSH1_MSG_DISCONNECT',
+            2  => 'NET_SSH1_SMSG_PUBLIC_KEY',
+            3  => 'NET_SSH1_CMSG_SESSION_KEY',
+            4  => 'NET_SSH1_CMSG_USER',
+            9  => 'NET_SSH1_CMSG_AUTH_PASSWORD',
+            10 => 'NET_SSH1_CMSG_REQUEST_PTY',
+            12 => 'NET_SSH1_CMSG_EXEC_SHELL',
+            13 => 'NET_SSH1_CMSG_EXEC_CMD',
+            14 => 'NET_SSH1_SMSG_SUCCESS',
+            15 => 'NET_SSH1_SMSG_FAILURE',
+            16 => 'NET_SSH1_CMSG_STDIN_DATA',
+            17 => 'NET_SSH1_SMSG_STDOUT_DATA',
+            18 => 'NET_SSH1_SMSG_STDERR_DATA',
+            19 => 'NET_SSH1_CMSG_EOF',
+            20 => 'NET_SSH1_SMSG_EXITSTATUS',
+            33 => 'NET_SSH1_CMSG_EXIT_CONFIRMATION'
+        );
+
+        $this->_define_array($this->protocol_flags);
+
+        $this->host = $host;
+        $this->port = $port;
+        $this->connectionTimeout = $timeout;
+        $this->cipher = $cipher;
+    }
+
+    /**
+     * Connect to an SSHv1 server
+     *
+     * @return bool
+     * @access private
+     */
+    function _connect()
+    {
+        $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout);
+        if (!$this->fsock) {
+            user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr"));
+            return false;
+        }
+
+        $this->server_identification = $init_line = fgets($this->fsock, 255);
+
+        if (defined('NET_SSH1_LOGGING')) {
+            $this->_append_log('<-', $this->server_identification);
+            $this->_append_log('->', $this->identifier . "\r\n");
+        }
+
+        if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
+            user_error('Can only connect to SSH servers');
+            return false;
+        }
+        if ($parts[1][0] != 1) {
+            user_error("Cannot connect to SSH $parts[1] servers");
+            return false;
+        }
+
+        fputs($this->fsock, $this->identifier."\r\n");
+
+        $response = $this->_get_binary_packet();
+        if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
+            user_error('Expected SSH_SMSG_PUBLIC_KEY');
+            return false;
+        }
+
+        $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
+
+        $this->_string_shift($response[self::RESPONSE_DATA], 4);
+
+        if (strlen($response[self::RESPONSE_DATA]) < 2) {
+            return false;
+        }
+        $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+        $server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+        $this->server_key_public_exponent = $server_key_public_exponent;
+
+        if (strlen($response[self::RESPONSE_DATA]) < 2) {
+            return false;
+        }
+        $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+        $server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+
+        $this->server_key_public_modulus = $server_key_public_modulus;
+
+        $this->_string_shift($response[self::RESPONSE_DATA], 4);
+
+        if (strlen($response[self::RESPONSE_DATA]) < 2) {
+            return false;
+        }
+        $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+        $host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+        $this->host_key_public_exponent = $host_key_public_exponent;
+
+        if (strlen($response[self::RESPONSE_DATA]) < 2) {
+            return false;
+        }
+        $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+        $host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+
+        $this->host_key_public_modulus = $host_key_public_modulus;
+
+        $this->_string_shift($response[self::RESPONSE_DATA], 4);
+
+        // get a list of the supported ciphers
+        if (strlen($response[self::RESPONSE_DATA]) < 4) {
+            return false;
+        }
+        extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
+
+        foreach ($this->supported_ciphers as $mask => $name) {
+            if (($supported_ciphers_mask & (1 << $mask)) == 0) {
+                unset($this->supported_ciphers[$mask]);
+            }
+        }
+
+        // get a list of the supported authentications
+        if (strlen($response[self::RESPONSE_DATA]) < 4) {
+            return false;
+        }
+        extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
+        foreach ($this->supported_authentications as $mask => $name) {
+            if (($supported_authentications_mask & (1 << $mask)) == 0) {
+                unset($this->supported_authentications[$mask]);
+            }
+        }
+
+        $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
+
+        $session_key = Random::string(32);
+        $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
+
+        if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {
+            $double_encrypted_session_key = $this->_rsa_crypt(
+                $double_encrypted_session_key,
+                array(
+                    $server_key_public_exponent,
+                    $server_key_public_modulus
+                )
+            );
+            $double_encrypted_session_key = $this->_rsa_crypt(
+                $double_encrypted_session_key,
+                array(
+                    $host_key_public_exponent,
+                    $host_key_public_modulus
+                )
+            );
+        } else {
+            $double_encrypted_session_key = $this->_rsa_crypt(
+                $double_encrypted_session_key,
+                array(
+                    $host_key_public_exponent,
+                    $host_key_public_modulus
+                )
+            );
+            $double_encrypted_session_key = $this->_rsa_crypt(
+                $double_encrypted_session_key,
+                array(
+                    $server_key_public_exponent,
+                    $server_key_public_modulus
+                )
+            );
+        }
+
+        $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES;
+        $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_SESSION_KEY');
+            return false;
+        }
+
+        switch ($cipher) {
+            //case self::CIPHER_NONE:
+            //    $this->crypto = new \phpseclib\Crypt\Null();
+            //    break;
+            case self::CIPHER_DES:
+                $this->crypto = new DES();
+                $this->crypto->disablePadding();
+                $this->crypto->enableContinuousBuffer();
+                $this->crypto->setKey(substr($session_key, 0,  8));
+                break;
+            case self::CIPHER_3DES:
+                $this->crypto = new TripleDES(TripleDES::MODE_3CBC);
+                $this->crypto->disablePadding();
+                $this->crypto->enableContinuousBuffer();
+                $this->crypto->setKey(substr($session_key, 0, 24));
+                break;
+            //case self::CIPHER_RC4:
+            //    $this->crypto = new RC4();
+            //    $this->crypto->enableContinuousBuffer();
+            //    $this->crypto->setKey(substr($session_key, 0,  16));
+            //    break;
+        }
+
+        $response = $this->_get_binary_packet();
+
+        if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
+            user_error('Expected SSH_SMSG_SUCCESS');
+            return false;
+        }
+
+        $this->bitmap = self::MASK_CONNECTED;
+
+        return true;
+    }
+
+    /**
+     * Login
+     *
+     * @param string $username
+     * @param string $password
+     * @return bool
+     * @access public
+     */
+    function login($username, $password = '')
+    {
+        if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
+            $this->bitmap |= self::MASK_CONSTRUCTOR;
+            if (!$this->_connect()) {
+                return false;
+            }
+        }
+
+        if (!($this->bitmap & self::MASK_CONNECTED)) {
+            return false;
+        }
+
+        $data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_USER');
+            return false;
+        }
+
+        $response = $this->_get_binary_packet();
+
+        if ($response === true) {
+            return false;
+        }
+        if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
+            $this->bitmap |= self::MASK_LOGIN;
+            return true;
+        } elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
+            user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
+            return false;
+        }
+
+        $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_AUTH_PASSWORD');
+            return false;
+        }
+
+        // remove the username and password from the last logged packet
+        if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == self::LOG_COMPLEX) {
+            $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password');
+            $this->message_log[count($this->message_log) - 1] = $data;
+        }
+
+        $response = $this->_get_binary_packet();
+
+        if ($response === true) {
+            return false;
+        }
+        if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
+            $this->bitmap |= self::MASK_LOGIN;
+            return true;
+        } elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
+            return false;
+        } else {
+            user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
+            return false;
+        }
+    }
+
+    /**
+     * Set Timeout
+     *
+     * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely.  setTimeout() makes it so it'll timeout.
+     * Setting $timeout to false or 0 will mean there is no timeout.
+     *
+     * @param mixed $timeout
+     */
+    function setTimeout($timeout)
+    {
+        $this->timeout = $this->curTimeout = $timeout;
+    }
+
+    /**
+     * Executes a command on a non-interactive shell, returns the output, and quits.
+     *
+     * An SSH1 server will close the connection after a command has been executed on a non-interactive shell.  SSH2
+     * servers don't, however, this isn't an SSH2 client.  The way this works, on the server, is by initiating a
+     * shell with the -s option, as discussed in the following links:
+     *
+     * {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html}
+     * {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html}
+     *
+     * To execute further commands, a new \phpseclib\Net\SSH1 object will need to be created.
+     *
+     * Returns false on failure and the output, otherwise.
+     *
+     * @see self::interactiveRead()
+     * @see self::interactiveWrite()
+     * @param string $cmd
+     * @param bool $block
+     * @return mixed
+     * @access public
+     */
+    function exec($cmd, $block = true)
+    {
+        if (!($this->bitmap & self::MASK_LOGIN)) {
+            user_error('Operation disallowed prior to login()');
+            return false;
+        }
+
+        $data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_EXEC_CMD');
+            return false;
+        }
+
+        if (!$block) {
+            return true;
+        }
+
+        $output = '';
+        $response = $this->_get_binary_packet();
+
+        if ($response !== false) {
+            do {
+                $output.= substr($response[self::RESPONSE_DATA], 4);
+                $response = $this->_get_binary_packet();
+            } while (is_array($response) && $response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS);
+        }
+
+        $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
+
+        // i don't think it's really all that important if this packet gets sent or not.
+        $this->_send_binary_packet($data);
+
+        fclose($this->fsock);
+
+        // reset the execution bitmap - a new \phpseclib\Net\SSH1 object needs to be created.
+        $this->bitmap = 0;
+
+        return $output;
+    }
+
+    /**
+     * Creates an interactive shell
+     *
+     * @see self::interactiveRead()
+     * @see self::interactiveWrite()
+     * @return bool
+     * @access private
+     */
+    function _initShell()
+    {
+        // connect using the sample parameters in protocol-1.5.txt.
+        // according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text
+        // terminal is a command line interpreter or shell".  thus, opening a terminal session to run the shell.
+        $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_REQUEST_PTY');
+            return false;
+        }
+
+        $response = $this->_get_binary_packet();
+
+        if ($response === true) {
+            return false;
+        }
+        if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
+            user_error('Expected SSH_SMSG_SUCCESS');
+            return false;
+        }
+
+        $data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_EXEC_SHELL');
+            return false;
+        }
+
+        $this->bitmap |= self::MASK_SHELL;
+
+        //stream_set_blocking($this->fsock, 0);
+
+        return true;
+    }
+
+    /**
+     * Inputs a command into an interactive shell.
+     *
+     * @see self::interactiveWrite()
+     * @param string $cmd
+     * @return bool
+     * @access public
+     */
+    function write($cmd)
+    {
+        return $this->interactiveWrite($cmd);
+    }
+
+    /**
+     * Returns the output of an interactive shell when there's a match for $expect
+     *
+     * $expect can take the form of a string literal or, if $mode == self::READ_REGEX,
+     * a regular expression.
+     *
+     * @see self::write()
+     * @param string $expect
+     * @param int $mode
+     * @return bool
+     * @access public
+     */
+    function read($expect, $mode = self::READ_SIMPLE)
+    {
+        if (!($this->bitmap & self::MASK_LOGIN)) {
+            user_error('Operation disallowed prior to login()');
+            return false;
+        }
+
+        if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+            user_error('Unable to initiate an interactive shell session');
+            return false;
+        }
+
+        $match = $expect;
+        while (true) {
+            if ($mode == self::READ_REGEX) {
+                preg_match($expect, $this->interactiveBuffer, $matches);
+                $match = isset($matches[0]) ? $matches[0] : '';
+            }
+            $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false;
+            if ($pos !== false) {
+                return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match));
+            }
+            $response = $this->_get_binary_packet();
+
+            if ($response === true) {
+                return $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer));
+            }
+            $this->interactiveBuffer.= substr($response[self::RESPONSE_DATA], 4);
+        }
+    }
+
+    /**
+     * Inputs a command into an interactive shell.
+     *
+     * @see self::interactiveRead()
+     * @param string $cmd
+     * @return bool
+     * @access public
+     */
+    function interactiveWrite($cmd)
+    {
+        if (!($this->bitmap & self::MASK_LOGIN)) {
+            user_error('Operation disallowed prior to login()');
+            return false;
+        }
+
+        if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+            user_error('Unable to initiate an interactive shell session');
+            return false;
+        }
+
+        $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
+
+        if (!$this->_send_binary_packet($data)) {
+            user_error('Error sending SSH_CMSG_STDIN');
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the output of an interactive shell when no more output is available.
+     *
+     * Requires PHP 4.3.0 or later due to the use of the stream_select() function.  If you see stuff like
+     * "^[[00m", you're seeing ANSI escape codes.  According to
+     * {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT
+     * does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,
+     * there's not going to be much recourse.
+     *
+     * @see self::interactiveRead()
+     * @return string
+     * @access public
+     */
+    function interactiveRead()
+    {
+        if (!($this->bitmap & self::MASK_LOGIN)) {
+            user_error('Operation disallowed prior to login()');
+            return false;
+        }
+
+        if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+            user_error('Unable to initiate an interactive shell session');
+            return false;
+        }
+
+        $read = array($this->fsock);
+        $write = $except = null;
+        if (stream_select($read, $write, $except, 0)) {
+            $response = $this->_get_binary_packet();
+            return substr($response[self::RESPONSE_DATA], 4);
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * Disconnect
+     *
+     * @access public
+     */
+    function disconnect()
+    {
+        $this->_disconnect();
+    }
+
+    /**
+     * Destructor.
+     *
+     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call
+     * disconnect().
+     *
+     * @access public
+     */
+    function __destruct()
+    {
+        $this->_disconnect();
+    }
+
+    /**
+     * Disconnect
+     *
+     * @param string $msg
+     * @access private
+     */
+    function _disconnect($msg = 'Client Quit')
+    {
+        if ($this->bitmap) {
+            $data = pack('C', NET_SSH1_CMSG_EOF);
+            $this->_send_binary_packet($data);
+            /*
+            $response = $this->_get_binary_packet();
+            if ($response === true) {
+                $response = array(self::RESPONSE_TYPE => -1);
+            }
+            switch ($response[self::RESPONSE_TYPE]) {
+                case NET_SSH1_SMSG_EXITSTATUS:
+                    $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
+                    break;
+                default:
+                    $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg);
+            }
+            */
+            $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg);
+
+            $this->_send_binary_packet($data);
+            fclose($this->fsock);
+            $this->bitmap = 0;
+        }
+    }
+
+    /**
+     * Gets Binary Packets
+     *
+     * See 'The Binary Packet Protocol' of protocol-1.5.txt for more info.
+     *
+     * Also, this function could be improved upon by adding detection for the following exploit:
+     * http://www.securiteam.com/securitynews/5LP042K3FY.html
+     *
+     * @see self::_send_binary_packet()
+     * @return array
+     * @access private
+     */
+    function _get_binary_packet()
+    {
+        if (feof($this->fsock)) {
+            //user_error('connection closed prematurely');
+            return false;
+        }
+
+        if ($this->curTimeout) {
+            $read = array($this->fsock);
+            $write = $except = null;
+
+            $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+            $sec = floor($this->curTimeout);
+            $usec = 1000000 * ($this->curTimeout - $sec);
+            // on windows this returns a "Warning: Invalid CRT parameters detected" error
+            if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+                //$this->_disconnect('Timeout');
+                return true;
+            }
+            $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
+            $this->curTimeout-= $elapsed;
+        }
+
+        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+        $data = fread($this->fsock, 4);
+        if (strlen($data) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $data);
+
+        $padding_length = 8 - ($temp['length'] & 7);
+        $length = $temp['length'] + $padding_length;
+        $raw = '';
+
+        while ($length > 0) {
+            $temp = fread($this->fsock, $length);
+            if (strlen($temp) != $length) {
+                return false;
+            }
+            $raw.= $temp;
+            $length-= strlen($temp);
+        }
+        $stop = strtok(microtime(), ' ') + strtok('');
+
+        if (strlen($raw) && $this->crypto !== false) {
+            $raw = $this->crypto->decrypt($raw);
+        }
+
+        $padding = substr($raw, 0, $padding_length);
+        $type = $raw[$padding_length];
+        $data = substr($raw, $padding_length + 1, -4);
+
+        if (strlen($raw) < 4) {
+            return false;
+        }
+        $temp = unpack('Ncrc', substr($raw, -4));
+
+        //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
+        //    user_error('Bad CRC in packet from server');
+        //    return false;
+        //}
+
+        $type = ord($type);
+
+        if (defined('NET_SSH1_LOGGING')) {
+            $temp = isset($this->protocol_flags[$type]) ? $this->protocol_flags[$type] : 'UNKNOWN';
+            $temp = '<- ' . $temp .
+                    ' (' . round($stop - $start, 4) . 's)';
+            $this->_append_log($temp, $data);
+        }
+
+        return array(
+            self::RESPONSE_TYPE => $type,
+            self::RESPONSE_DATA => $data
+        );
+    }
+
+    /**
+     * Sends Binary Packets
+     *
+     * Returns true on success, false on failure.
+     *
+     * @see self::_get_binary_packet()
+     * @param string $data
+     * @return bool
+     * @access private
+     */
+    function _send_binary_packet($data)
+    {
+        if (feof($this->fsock)) {
+            //user_error('connection closed prematurely');
+            return false;
+        }
+
+        $length = strlen($data) + 4;
+
+        $padding = Random::string(8 - ($length & 7));
+
+        $orig = $data;
+        $data = $padding . $data;
+        $data.= pack('N', $this->_crc($data));
+
+        if ($this->crypto !== false) {
+            $data = $this->crypto->encrypt($data);
+        }
+
+        $packet = pack('Na*', $length, $data);
+
+        $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+        $result = strlen($packet) == fputs($this->fsock, $packet);
+        $stop = strtok(microtime(), ' ') + strtok('');
+
+        if (defined('NET_SSH1_LOGGING')) {
+            $temp = isset($this->protocol_flags[ord($orig[0])]) ? $this->protocol_flags[ord($orig[0])] : 'UNKNOWN';
+            $temp = '-> ' . $temp .
+                    ' (' . round($stop - $start, 4) . 's)';
+            $this->_append_log($temp, $orig);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Cyclic Redundancy Check (CRC)
+     *
+     * PHP's crc32 function is implemented slightly differently than the one that SSH v1 uses, so
+     * we've reimplemented it. A more detailed discussion of the differences can be found after
+     * $crc_lookup_table's initialization.
+     *
+     * @see self::_get_binary_packet()
+     * @see self::_send_binary_packet()
+     * @param string $data
+     * @return int
+     * @access private
+     */
+    function _crc($data)
+    {
+        static $crc_lookup_table = array(
+            0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+            0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+            0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+            0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+            0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+            0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+            0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+            0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+            0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+            0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+            0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+            0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+            0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+            0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+            0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+            0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+            0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+            0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+            0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+            0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+            0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+            0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+            0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+            0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+            0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+            0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+            0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+            0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+            0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+            0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+            0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+            0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+            0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+            0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+            0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+            0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+            0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+            0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+            0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+            0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+            0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+            0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+            0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+            0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+            0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+            0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+            0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+            0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+            0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+            0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+            0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+            0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+            0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+            0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+            0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+            0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+            0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+            0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+            0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+            0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+            0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+            0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+            0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+            0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+        );
+
+        // For this function to yield the same output as PHP's crc32 function, $crc would have to be
+        // set to 0xFFFFFFFF, initially - not 0x00000000 as it currently is.
+        $crc = 0x00000000;
+        $length = strlen($data);
+
+        for ($i=0; $i<$length; $i++) {
+            // We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all
+            // be zero.  PHP, unfortunately, doesn't always do this.  0x80000000 >> 8, as an example,
+            // yields 0xFF800000 - not 0x00800000.  The following link elaborates:
+            // http://www.php.net/manual/en/language.operators.bitwise.php#57281
+            $crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc_lookup_table[($crc & 0xFF) ^ ord($data[$i])];
+        }
+
+        // In addition to having to set $crc to 0xFFFFFFFF, initially, the return value must be XOR'd with
+        // 0xFFFFFFFF for this function to return the same thing that PHP's crc32 function would.
+        return $crc;
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @return string
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+
+    /**
+     * RSA Encrypt
+     *
+     * Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e
+     * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1.  Could just make anything that
+     * calls this call modexp, instead, but I think this makes things clearer, maybe...
+     *
+     * @see self::__construct()
+     * @param BigInteger $m
+     * @param array $key
+     * @return BigInteger
+     * @access private
+     */
+    function _rsa_crypt($m, $key)
+    {
+        /*
+        $rsa = new RSA();
+        $rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW);
+        $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
+        return $rsa->encrypt($m);
+        */
+
+        // To quote from protocol-1.5.txt:
+        // The most significant byte (which is only partial as the value must be
+        // less than the public modulus, which is never a power of two) is zero.
+        //
+        // The next byte contains the value 2 (which stands for public-key
+        // encrypted data in the PKCS standard [PKCS#1]).  Then, there are non-
+        // zero random bytes to fill any unused space, a zero byte, and the data
+        // to be encrypted in the least significant bytes, the last byte of the
+        // data in the least significant byte.
+
+        // Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation",
+        // under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL:
+        // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
+        $modulus = $key[1]->toBytes();
+        $length = strlen($modulus) - strlen($m) - 3;
+        $random = '';
+        while (strlen($random) != $length) {
+            $block = Random::string($length - strlen($random));
+            $block = str_replace("\x00", '', $block);
+            $random.= $block;
+        }
+        $temp = chr(0) . chr(2) . $random . chr(0) . $m;
+
+        $m = new BigInteger($temp, 256);
+        $m = $m->modPow($key[0], $key[1]);
+
+        return $m->toBytes();
+    }
+
+    /**
+     * Define Array
+     *
+     * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of
+     * named constants from it, using the value as the name of the constant and the index as the value of the constant.
+     * If any of the constants that would be defined already exists, none of the constants will be defined.
+     *
+     * @access private
+     */
+    function _define_array()
+    {
+        $args = func_get_args();
+        foreach ($args as $arg) {
+            foreach ($arg as $key => $value) {
+                if (!defined($value)) {
+                    define($value, $key);
+                } else {
+                    break 2;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a log of the packets that have been sent and received.
+     *
+     * Returns a string if NET_SSH1_LOGGING == self::LOG_COMPLEX, an array if NET_SSH1_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING')
+     *
+     * @access public
+     * @return array|false|string
+     */
+    function getLog()
+    {
+        if (!defined('NET_SSH1_LOGGING')) {
+            return false;
+        }
+
+        switch (NET_SSH1_LOGGING) {
+            case self::LOG_SIMPLE:
+                return $this->protocol_flags_log;
+                break;
+            case self::LOG_COMPLEX:
+                return $this->_format_log($this->message_log, $this->protocol_flags_log);
+                break;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Formats a log for printing
+     *
+     * @param array $message_log
+     * @param array $message_number_log
+     * @access private
+     * @return string
+     */
+    function _format_log($message_log, $message_number_log)
+    {
+        $output = '';
+        for ($i = 0; $i < count($message_log); $i++) {
+            $output.= $message_number_log[$i] . "\r\n";
+            $current_log = $message_log[$i];
+            $j = 0;
+            do {
+                if (strlen($current_log)) {
+                    $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0  ';
+                }
+                $fragment = $this->_string_shift($current_log, $this->log_short_width);
+                $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary));
+                // replace non ASCII printable characters with dots
+                // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
+                // also replace < with a . since < messes up the output on web browsers
+                $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
+                $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n";
+                $j++;
+            } while (strlen($current_log));
+            $output.= "\r\n";
+        }
+
+        return $output;
+    }
+
+    /**
+     * Helper function for _format_log
+     *
+     * For use with preg_replace_callback()
+     *
+     * @param array $matches
+     * @access private
+     * @return string
+     */
+    function _format_log_helper($matches)
+    {
+        return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
+    }
+
+    /**
+     * Return the server key public exponent
+     *
+     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
+     * the raw bytes.  This behavior is similar to PHP's md5() function.
+     *
+     * @param bool $raw_output
+     * @return string
+     * @access public
+     */
+    function getServerKeyPublicExponent($raw_output = false)
+    {
+        return $raw_output ? $this->server_key_public_exponent->toBytes() : $this->server_key_public_exponent->toString();
+    }
+
+    /**
+     * Return the server key public modulus
+     *
+     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
+     * the raw bytes.  This behavior is similar to PHP's md5() function.
+     *
+     * @param bool $raw_output
+     * @return string
+     * @access public
+     */
+    function getServerKeyPublicModulus($raw_output = false)
+    {
+        return $raw_output ? $this->server_key_public_modulus->toBytes() : $this->server_key_public_modulus->toString();
+    }
+
+    /**
+     * Return the host key public exponent
+     *
+     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
+     * the raw bytes.  This behavior is similar to PHP's md5() function.
+     *
+     * @param bool $raw_output
+     * @return string
+     * @access public
+     */
+    function getHostKeyPublicExponent($raw_output = false)
+    {
+        return $raw_output ? $this->host_key_public_exponent->toBytes() : $this->host_key_public_exponent->toString();
+    }
+
+    /**
+     * Return the host key public modulus
+     *
+     * Returns, by default, the base-10 representation.  If $raw_output is set to true, returns, instead,
+     * the raw bytes.  This behavior is similar to PHP's md5() function.
+     *
+     * @param bool $raw_output
+     * @return string
+     * @access public
+     */
+    function getHostKeyPublicModulus($raw_output = false)
+    {
+        return $raw_output ? $this->host_key_public_modulus->toBytes() : $this->host_key_public_modulus->toString();
+    }
+
+    /**
+     * Return a list of ciphers supported by SSH1 server.
+     *
+     * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
+     * is set to true, returns, instead, an array of constants.  ie. instead of array('Triple-DES in CBC mode'), you'll
+     * get array(self::CIPHER_3DES).
+     *
+     * @param bool $raw_output
+     * @return array
+     * @access public
+     */
+    function getSupportedCiphers($raw_output = false)
+    {
+        return $raw_output ? array_keys($this->supported_ciphers) : array_values($this->supported_ciphers);
+    }
+
+    /**
+     * Return a list of authentications supported by SSH1 server.
+     *
+     * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
+     * is set to true, returns, instead, an array of constants.  ie. instead of array('password authentication'), you'll
+     * get array(self::AUTH_PASSWORD).
+     *
+     * @param bool $raw_output
+     * @return array
+     * @access public
+     */
+    function getSupportedAuthentications($raw_output = false)
+    {
+        return $raw_output ? array_keys($this->supported_authentications) : array_values($this->supported_authentications);
+    }
+
+    /**
+     * Return the server identification.
+     *
+     * @return string
+     * @access public
+     */
+    function getServerIdentification()
+    {
+        return rtrim($this->server_identification);
+    }
+
+    /**
+     * Logs data packets
+     *
+     * Makes sure that only the last 1MB worth of packets will be logged
+     *
+     * @param int $protocol_flags
+     * @param string $message
+     * @access private
+     */
+    function _append_log($protocol_flags, $message)
+    {
+        switch (NET_SSH1_LOGGING) {
+            // useful for benchmarks
+            case self::LOG_SIMPLE:
+                $this->protocol_flags_log[] = $protocol_flags;
+                break;
+            // the most useful log for SSH1
+            case self::LOG_COMPLEX:
+                $this->protocol_flags_log[] = $protocol_flags;
+                $this->_string_shift($message);
+                $this->log_size+= strlen($message);
+                $this->message_log[] = $message;
+                while ($this->log_size > self::LOG_MAX_SIZE) {
+                    $this->log_size-= strlen(array_shift($this->message_log));
+                    array_shift($this->protocol_flags_log);
+                }
+                break;
+            // dump the output out realtime; packets may be interspersed with non packets,
+            // passwords won't be filtered out and select other packets may not be correctly
+            // identified
+            case self::LOG_REALTIME:
+                echo "<pre>\r\n" . $this->_format_log(array($message), array($protocol_flags)) . "\r\n</pre>\r\n";
+                @flush();
+                @ob_flush();
+                break;
+            // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
+            // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
+            // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
+            // at the beginning of the file
+            case self::LOG_REALTIME_FILE:
+                if (!isset($this->realtime_log_file)) {
+                    // PHP doesn't seem to like using constants in fopen()
+                    $filename = self::LOG_REALTIME_FILE;
+                    $fp = fopen($filename, 'w');
+                    $this->realtime_log_file = $fp;
+                }
+                if (!is_resource($this->realtime_log_file)) {
+                    break;
+                }
+                $entry = $this->_format_log(array($message), array($protocol_flags));
+                if ($this->realtime_log_wrap) {
+                    $temp = "<<< START >>>\r\n";
+                    $entry.= $temp;
+                    fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp));
+                }
+                $this->realtime_log_size+= strlen($entry);
+                if ($this->realtime_log_size > self::LOG_MAX_SIZE) {
+                    fseek($this->realtime_log_file, 0);
+                    $this->realtime_log_size = strlen($entry);
+                    $this->realtime_log_wrap = true;
+                }
+                fputs($this->realtime_log_file, $entry);
+        }
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
new file mode 100644
index 00000000..03b50f62
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
@@ -0,0 +1,5423 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SSHv2.
+ *
+ * PHP version 5
+ *
+ * Here are some examples of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ *    if (!$ssh->login('username', 'password')) {
+ *        exit('Login Failed');
+ *    }
+ *
+ *    echo $ssh->exec('pwd');
+ *    echo $ssh->exec('ls -la');
+ * ?>
+ * </code>
+ *
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $key = new \phpseclib\Crypt\RSA();
+ *    //$key->setPassword('whatever');
+ *    $key->loadKey(file_get_contents('privatekey'));
+ *
+ *    $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ *    if (!$ssh->login('username', $key)) {
+ *        exit('Login Failed');
+ *    }
+ *
+ *    echo $ssh->read('username@username:~$');
+ *    $ssh->write("ls -la\n");
+ *    echo $ssh->read('username@username:~$');
+ * ?>
+ * </code>
+ *
+ * @category  Net
+ * @package   SSH2
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+use phpseclib\Crypt\Base;
+use phpseclib\Crypt\Blowfish;
+use phpseclib\Crypt\Hash;
+use phpseclib\Crypt\Random;
+use phpseclib\Crypt\RC4;
+use phpseclib\Crypt\Rijndael;
+use phpseclib\Crypt\RSA;
+use phpseclib\Crypt\TripleDES;
+use phpseclib\Crypt\Twofish;
+use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
+use phpseclib\System\SSH\Agent;
+
+/**
+ * Pure-PHP implementation of SSHv2.
+ *
+ * @package SSH2
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class SSH2
+{
+    /**#@+
+     * Compression Types
+     *
+     * @access private
+     */
+    /**
+     * No compression
+     */
+    const NET_SSH2_COMPRESSION_NONE = 1;
+    /**
+     * zlib compression
+     */
+    const NET_SSH2_COMPRESSION_ZLIB = 2;
+    /**
+     * zlib@openssh.com
+     */
+    const NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH = 3;
+    /**#@-*/
+
+    /**#@+
+     * Execution Bitmap Masks
+     *
+     * @see \phpseclib\Net\SSH2::bitmap
+     * @access private
+     */
+    const MASK_CONSTRUCTOR   = 0x00000001;
+    const MASK_CONNECTED     = 0x00000002;
+    const MASK_LOGIN_REQ     = 0x00000004;
+    const MASK_LOGIN         = 0x00000008;
+    const MASK_SHELL         = 0x00000010;
+    const MASK_WINDOW_ADJUST = 0x00000020;
+    /**#@-*/
+
+    /**#@+
+     * Channel constants
+     *
+     * RFC4254 refers not to client and server channels but rather to sender and recipient channels.  we don't refer
+     * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with
+     * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a
+     * recepient channel.  at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel
+     * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snipet:
+     *     The 'recipient channel' is the channel number given in the original
+     *     open request, and 'sender channel' is the channel number allocated by
+     *     the other side.
+     *
+     * @see \phpseclib\Net\SSH2::_send_channel_packet()
+     * @see \phpseclib\Net\SSH2::_get_channel_packet()
+     * @access private
+    */
+    const CHANNEL_EXEC          = 1; // PuTTy uses 0x100
+    const CHANNEL_SHELL         = 2;
+    const CHANNEL_SUBSYSTEM     = 3;
+    const CHANNEL_AGENT_FORWARD = 4;
+    const CHANNEL_KEEP_ALIVE    = 5;
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Net\SSH2::getLog()
+    */
+    /**
+     * Returns the message numbers
+     */
+    const LOG_SIMPLE = 1;
+    /**
+     * Returns the message content
+     */
+    const LOG_COMPLEX = 2;
+    /**
+     * Outputs the content real-time
+     */
+    const LOG_REALTIME = 3;
+    /**
+     * Dumps the content real-time to a file
+     */
+    const LOG_REALTIME_FILE = 4;
+    /**
+     * Make sure that the log never gets larger than this
+     */
+    const LOG_MAX_SIZE = 1048576; // 1024 * 1024
+    /**#@-*/
+
+    /**#@+
+     * @access public
+     * @see \phpseclib\Net\SSH2::read()
+    */
+    /**
+     * Returns when a string matching $expect exactly is found
+     */
+    const READ_SIMPLE = 1;
+    /**
+     * Returns when a string matching the regular expression $expect is found
+     */
+    const READ_REGEX = 2;
+    /**
+     * Returns whenever a data packet is received.
+     *
+     * Some data packets may only contain a single character so it may be necessary
+     * to call read() multiple times when using this option
+     */
+    const READ_NEXT = 3;
+    /**#@-*/
+
+    /**
+     * The SSH identifier
+     *
+     * @var string
+     * @access private
+     */
+    var $identifier;
+
+    /**
+     * The Socket Object
+     *
+     * @var object
+     * @access private
+     */
+    var $fsock;
+
+    /**
+     * Execution Bitmap
+     *
+     * The bits that are set represent functions that have been called already.  This is used to determine
+     * if a requisite function has been successfully executed.  If not, an error should be thrown.
+     *
+     * @var int
+     * @access private
+     */
+    var $bitmap = 0;
+
+    /**
+     * Error information
+     *
+     * @see self::getErrors()
+     * @see self::getLastError()
+     * @var string
+     * @access private
+     */
+    var $errors = array();
+
+    /**
+     * Server Identifier
+     *
+     * @see self::getServerIdentification()
+     * @var array|false
+     * @access private
+     */
+    var $server_identifier = false;
+
+    /**
+     * Key Exchange Algorithms
+     *
+     * @see self::getKexAlgorithims()
+     * @var array|false
+     * @access private
+     */
+    var $kex_algorithms = false;
+
+    /**
+     * Key Exchange Algorithm
+     *
+     * @see self::getMethodsNegotiated()
+     * @var string|false
+     * @access private
+     */
+    var $kex_algorithm = false;
+
+    /**
+     * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+     *
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $kex_dh_group_size_min = 1536;
+
+    /**
+     * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+     *
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $kex_dh_group_size_preferred = 2048;
+
+    /**
+     * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+     *
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $kex_dh_group_size_max = 4096;
+
+    /**
+     * Server Host Key Algorithms
+     *
+     * @see self::getServerHostKeyAlgorithms()
+     * @var array|false
+     * @access private
+     */
+    var $server_host_key_algorithms = false;
+
+    /**
+     * Supported Private Key Algorithms
+     *
+     * In theory this should be the same as the Server Host Key Algorithms but, in practice,
+     * some servers (eg. Azure) will support rsa-sha2-512 as a server host key algorithm but
+     * not a private key algorithm
+     *
+     * @see self::privatekey_login()
+     * @var array|false
+     */
+    var $supported_private_key_algorithms = false;
+
+    /**
+     * Encryption Algorithms: Client to Server
+     *
+     * @see self::getEncryptionAlgorithmsClient2Server()
+     * @var array|false
+     * @access private
+     */
+    var $encryption_algorithms_client_to_server = false;
+
+    /**
+     * Encryption Algorithms: Server to Client
+     *
+     * @see self::getEncryptionAlgorithmsServer2Client()
+     * @var array|false
+     * @access private
+     */
+    var $encryption_algorithms_server_to_client = false;
+
+    /**
+     * MAC Algorithms: Client to Server
+     *
+     * @see self::getMACAlgorithmsClient2Server()
+     * @var array|false
+     * @access private
+     */
+    var $mac_algorithms_client_to_server = false;
+
+    /**
+     * MAC Algorithms: Server to Client
+     *
+     * @see self::getMACAlgorithmsServer2Client()
+     * @var array|false
+     * @access private
+     */
+    var $mac_algorithms_server_to_client = false;
+
+    /**
+     * Compression Algorithms: Client to Server
+     *
+     * @see self::getCompressionAlgorithmsClient2Server()
+     * @var array|false
+     * @access private
+     */
+    var $compression_algorithms_client_to_server = false;
+
+    /**
+     * Compression Algorithms: Server to Client
+     *
+     * @see self::getCompressionAlgorithmsServer2Client()
+     * @var array|false
+     * @access private
+     */
+    var $compression_algorithms_server_to_client = false;
+
+    /**
+     * Languages: Server to Client
+     *
+     * @see self::getLanguagesServer2Client()
+     * @var array|false
+     * @access private
+     */
+    var $languages_server_to_client = false;
+
+    /**
+     * Languages: Client to Server
+     *
+     * @see self::getLanguagesClient2Server()
+     * @var array|false
+     * @access private
+     */
+    var $languages_client_to_server = false;
+
+    /**
+     * Preferred Algorithms
+     *
+     * @see self::setPreferredAlgorithms()
+     * @var array
+     * @access private
+     */
+    var $preferred = array();
+
+    /**
+     * Block Size for Server to Client Encryption
+     *
+     * "Note that the length of the concatenation of 'packet_length',
+     *  'padding_length', 'payload', and 'random padding' MUST be a multiple
+     *  of the cipher block size or 8, whichever is larger.  This constraint
+     *  MUST be enforced, even when using stream ciphers."
+     *
+     *  -- http://tools.ietf.org/html/rfc4253#section-6
+     *
+     * @see self::__construct()
+     * @see self::_send_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $encrypt_block_size = 8;
+
+    /**
+     * Block Size for Client to Server Encryption
+     *
+     * @see self::__construct()
+     * @see self::_get_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $decrypt_block_size = 8;
+
+    /**
+     * Server to Client Encryption Object
+     *
+     * @see self::_get_binary_packet()
+     * @var object
+     * @access private
+     */
+    var $decrypt = false;
+
+    /**
+     * Client to Server Encryption Object
+     *
+     * @see self::_send_binary_packet()
+     * @var object
+     * @access private
+     */
+    var $encrypt = false;
+
+    /**
+     * Client to Server HMAC Object
+     *
+     * @see self::_send_binary_packet()
+     * @var object
+     * @access private
+     */
+    var $hmac_create = false;
+
+    /**
+     * Server to Client HMAC Object
+     *
+     * @see self::_get_binary_packet()
+     * @var object
+     * @access private
+     */
+    var $hmac_check = false;
+
+    /**
+     * Size of server to client HMAC
+     *
+     * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read.
+     * For the client to server side, the HMAC object will make the HMAC as long as it needs to be.  All we need to do is
+     * append it.
+     *
+     * @see self::_get_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $hmac_size = false;
+
+    /**
+     * Server Public Host Key
+     *
+     * @see self::getServerPublicHostKey()
+     * @var string
+     * @access private
+     */
+    var $server_public_host_key;
+
+    /**
+     * Session identifier
+     *
+     * "The exchange hash H from the first key exchange is additionally
+     *  used as the session identifier, which is a unique identifier for
+     *  this connection."
+     *
+     *  -- http://tools.ietf.org/html/rfc4253#section-7.2
+     *
+     * @see self::_key_exchange()
+     * @var string
+     * @access private
+     */
+    var $session_id = false;
+
+    /**
+     * Exchange hash
+     *
+     * The current exchange hash
+     *
+     * @see self::_key_exchange()
+     * @var string
+     * @access private
+     */
+    var $exchange_hash = false;
+
+    /**
+     * Message Numbers
+     *
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $message_numbers = array();
+
+    /**
+     * Disconnection Message 'reason codes' defined in RFC4253
+     *
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $disconnect_reasons = array();
+
+    /**
+     * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254
+     *
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $channel_open_failure_reasons = array();
+
+    /**
+     * Terminal Modes
+     *
+     * @link http://tools.ietf.org/html/rfc4254#section-8
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $terminal_modes = array();
+
+    /**
+     * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes
+     *
+     * @link http://tools.ietf.org/html/rfc4254#section-5.2
+     * @see self::__construct()
+     * @var array
+     * @access private
+     */
+    var $channel_extended_data_type_codes = array();
+
+    /**
+     * Send Sequence Number
+     *
+     * See 'Section 6.4.  Data Integrity' of rfc4253 for more info.
+     *
+     * @see self::_send_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $send_seq_no = 0;
+
+    /**
+     * Get Sequence Number
+     *
+     * See 'Section 6.4.  Data Integrity' of rfc4253 for more info.
+     *
+     * @see self::_get_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $get_seq_no = 0;
+
+    /**
+     * Server Channels
+     *
+     * Maps client channels to server channels
+     *
+     * @see self::_get_channel_packet()
+     * @see self::exec()
+     * @var array
+     * @access private
+     */
+    var $server_channels = array();
+
+    /**
+     * Channel Buffers
+     *
+     * If a client requests a packet from one channel but receives two packets from another those packets should
+     * be placed in a buffer
+     *
+     * @see self::_get_channel_packet()
+     * @see self::exec()
+     * @var array
+     * @access private
+     */
+    var $channel_buffers = array();
+
+    /**
+     * Channel Status
+     *
+     * Contains the type of the last sent message
+     *
+     * @see self::_get_channel_packet()
+     * @var array
+     * @access private
+     */
+    var $channel_status = array();
+
+    /**
+     * Packet Size
+     *
+     * Maximum packet size indexed by channel
+     *
+     * @see self::_send_channel_packet()
+     * @var array
+     * @access private
+     */
+    var $packet_size_client_to_server = array();
+
+    /**
+     * Message Number Log
+     *
+     * @see self::getLog()
+     * @var array
+     * @access private
+     */
+    var $message_number_log = array();
+
+    /**
+     * Message Log
+     *
+     * @see self::getLog()
+     * @var array
+     * @access private
+     */
+    var $message_log = array();
+
+    /**
+     * The Window Size
+     *
+     * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB)
+     *
+     * @var int
+     * @see self::_send_channel_packet()
+     * @see self::exec()
+     * @access private
+     */
+    var $window_size = 0x7FFFFFFF;
+
+    /**
+     * What we resize the window to
+     *
+     * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes.
+     * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so
+     * we'll just do what PuTTY does
+     *
+     * @var int
+     * @see self::_send_channel_packet()
+     * @see self::exec()
+     * @access private
+     */
+    var $window_resize = 0x40000000;
+
+    /**
+     * Window size, server to client
+     *
+     * Window size indexed by channel
+     *
+     * @see self::_send_channel_packet()
+     * @var array
+     * @access private
+     */
+    var $window_size_server_to_client = array();
+
+    /**
+     * Window size, client to server
+     *
+     * Window size indexed by channel
+     *
+     * @see self::_get_channel_packet()
+     * @var array
+     * @access private
+     */
+    var $window_size_client_to_server = array();
+
+    /**
+     * Server signature
+     *
+     * Verified against $this->session_id
+     *
+     * @see self::getServerPublicHostKey()
+     * @var string
+     * @access private
+     */
+    var $signature = '';
+
+    /**
+     * Server signature format
+     *
+     * ssh-rsa or ssh-dss.
+     *
+     * @see self::getServerPublicHostKey()
+     * @var string
+     * @access private
+     */
+    var $signature_format = '';
+
+    /**
+     * Interactive Buffer
+     *
+     * @see self::read()
+     * @var array
+     * @access private
+     */
+    var $interactiveBuffer = '';
+
+    /**
+     * Current log size
+     *
+     * Should never exceed self::LOG_MAX_SIZE
+     *
+     * @see self::_send_binary_packet()
+     * @see self::_get_binary_packet()
+     * @var int
+     * @access private
+     */
+    var $log_size;
+
+    /**
+     * Timeout
+     *
+     * @see self::setTimeout()
+     * @access private
+     */
+    var $timeout;
+
+    /**
+     * Current Timeout
+     *
+     * @see self::_get_channel_packet()
+     * @access private
+     */
+    var $curTimeout;
+
+    /**
+     * Keep Alive Interval
+     *
+     * @see self::setKeepAlive()
+     * @access private
+     */
+    var $keepAlive;
+
+    /**
+     * Real-time log file pointer
+     *
+     * @see self::_append_log()
+     * @var resource
+     * @access private
+     */
+    var $realtime_log_file;
+
+    /**
+     * Real-time log file size
+     *
+     * @see self::_append_log()
+     * @var int
+     * @access private
+     */
+    var $realtime_log_size;
+
+    /**
+     * Has the signature been validated?
+     *
+     * @see self::getServerPublicHostKey()
+     * @var bool
+     * @access private
+     */
+    var $signature_validated = false;
+
+    /**
+     * Real-time log file wrap boolean
+     *
+     * @see self::_append_log()
+     * @access private
+     */
+    var $realtime_log_wrap;
+
+    /**
+     * Flag to suppress stderr from output
+     *
+     * @see self::enableQuietMode()
+     * @access private
+     */
+    var $quiet_mode = false;
+
+    /**
+     * Time of first network activity
+     *
+     * @var int
+     * @access private
+     */
+    var $last_packet;
+
+    /**
+     * Exit status returned from ssh if any
+     *
+     * @var int
+     * @access private
+     */
+    var $exit_status;
+
+    /**
+     * Flag to request a PTY when using exec()
+     *
+     * @var bool
+     * @see self::enablePTY()
+     * @access private
+     */
+    var $request_pty = false;
+
+    /**
+     * Flag set while exec() is running when using enablePTY()
+     *
+     * @var bool
+     * @access private
+     */
+    var $in_request_pty_exec = false;
+
+    /**
+     * Flag set after startSubsystem() is called
+     *
+     * @var bool
+     * @access private
+     */
+    var $in_subsystem;
+
+    /**
+     * Contents of stdError
+     *
+     * @var string
+     * @access private
+     */
+    var $stdErrorLog;
+
+    /**
+     * The Last Interactive Response
+     *
+     * @see self::_keyboard_interactive_process()
+     * @var string
+     * @access private
+     */
+    var $last_interactive_response = '';
+
+    /**
+     * Keyboard Interactive Request / Responses
+     *
+     * @see self::_keyboard_interactive_process()
+     * @var array
+     * @access private
+     */
+    var $keyboard_requests_responses = array();
+
+    /**
+     * Banner Message
+     *
+     * Quoting from the RFC, "in some jurisdictions, sending a warning message before
+     * authentication may be relevant for getting legal protection."
+     *
+     * @see self::_filter()
+     * @see self::getBannerMessage()
+     * @var string
+     * @access private
+     */
+    var $banner_message = '';
+
+    /**
+     * Did read() timeout or return normally?
+     *
+     * @see self::isTimeout()
+     * @var bool
+     * @access private
+     */
+    var $is_timeout = false;
+
+    /**
+     * Log Boundary
+     *
+     * @see self::_format_log()
+     * @var string
+     * @access private
+     */
+    var $log_boundary = ':';
+
+    /**
+     * Log Long Width
+     *
+     * @see self::_format_log()
+     * @var int
+     * @access private
+     */
+    var $log_long_width = 65;
+
+    /**
+     * Log Short Width
+     *
+     * @see self::_format_log()
+     * @var int
+     * @access private
+     */
+    var $log_short_width = 16;
+
+    /**
+     * Hostname
+     *
+     * @see self::__construct()
+     * @see self::_connect()
+     * @var string
+     * @access private
+     */
+    var $host;
+
+    /**
+     * Port Number
+     *
+     * @see self::__construct()
+     * @see self::_connect()
+     * @var int
+     * @access private
+     */
+    var $port;
+
+    /**
+     * Number of columns for terminal window size
+     *
+     * @see self::getWindowColumns()
+     * @see self::setWindowColumns()
+     * @see self::setWindowSize()
+     * @var int
+     * @access private
+     */
+    var $windowColumns = 80;
+
+    /**
+     * Number of columns for terminal window size
+     *
+     * @see self::getWindowRows()
+     * @see self::setWindowRows()
+     * @see self::setWindowSize()
+     * @var int
+     * @access private
+     */
+    var $windowRows = 24;
+
+    /**
+     * Crypto Engine
+     *
+     * @see self::setCryptoEngine()
+     * @see self::_key_exchange()
+     * @var int
+     * @access private
+     */
+    var $crypto_engine = false;
+
+    /**
+     * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
+     *
+     * @var System_SSH_Agent
+     * @access private
+     */
+    var $agent;
+
+    /**
+     * Send the identification string first?
+     *
+     * @var bool
+     * @access private
+     */
+    var $send_id_string_first = true;
+
+    /**
+     * Send the key exchange initiation packet first?
+     *
+     * @var bool
+     * @access private
+     */
+    var $send_kex_first = true;
+
+    /**
+     * Some versions of OpenSSH incorrectly calculate the key size
+     *
+     * @var bool
+     * @access private
+     */
+    var $bad_key_size_fix = false;
+
+    /**
+     * Should we try to re-connect to re-establish keys?
+     *
+     * @var bool
+     * @access private
+     */
+    var $retry_connect = false;
+
+    /**
+     * Binary Packet Buffer
+     *
+     * @var string|false
+     * @access private
+     */
+    var $binary_packet_buffer = false;
+
+    /**
+     * Preferred Signature Format
+     *
+     * @var string|false
+     * @access private
+     */
+    var $preferred_signature_format = false;
+
+    /**
+     * Authentication Credentials
+     *
+     * @var array
+     * @access private
+     */
+    var $auth = array();
+
+    /**
+     * The authentication methods that may productively continue authentication.
+     *
+     * @see https://tools.ietf.org/html/rfc4252#section-5.1
+     * @var array|null
+     * @access private
+     */
+    var $auth_methods_to_continue = null;
+
+    /**
+     * Compression method
+     *
+     * @var int
+     * @access private
+     */
+    var $compress = self::NET_SSH2_COMPRESSION_NONE;
+
+    /**
+     * Decompression method
+     *
+     * @var resource|object
+     * @access private
+     */
+    var $decompress = self::NET_SSH2_COMPRESSION_NONE;
+
+    /**
+     * Compression context
+     *
+     * @var int
+     * @access private
+     */
+    var $compress_context;
+
+    /**
+     * Decompression context
+     *
+     * @var resource|object
+     * @access private
+     */
+    var $decompress_context;
+
+    /**
+     * Regenerate Compression Context
+     *
+     * @var bool
+     * @access private
+     */
+    var $regenerate_compression_context = false;
+
+    /**
+     * Regenerate Decompression Context
+     *
+     * @var bool
+     * @access private
+     */
+    var $regenerate_decompression_context = false;
+
+    /**
+     * Smart multi-factor authentication flag
+     *
+     * @var bool
+     * @access private
+     */
+    var $smartMFA = true;
+
+    /**
+     * Default Constructor.
+     *
+     * $host can either be a string, representing the host, or a stream resource.
+     *
+     * @param mixed $host
+     * @param int $port
+     * @param int $timeout
+     * @see self::login()
+     * @return \phpseclib\Net\SSH2
+     * @access public
+     */
+    function __construct($host, $port = 22, $timeout = 10)
+    {
+        $this->message_numbers = array(
+            1 => 'NET_SSH2_MSG_DISCONNECT',
+            2 => 'NET_SSH2_MSG_IGNORE',
+            3 => 'NET_SSH2_MSG_UNIMPLEMENTED',
+            4 => 'NET_SSH2_MSG_DEBUG',
+            5 => 'NET_SSH2_MSG_SERVICE_REQUEST',
+            6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',
+            20 => 'NET_SSH2_MSG_KEXINIT',
+            21 => 'NET_SSH2_MSG_NEWKEYS',
+            30 => 'NET_SSH2_MSG_KEXDH_INIT',
+            31 => 'NET_SSH2_MSG_KEXDH_REPLY',
+            50 => 'NET_SSH2_MSG_USERAUTH_REQUEST',
+            51 => 'NET_SSH2_MSG_USERAUTH_FAILURE',
+            52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS',
+            53 => 'NET_SSH2_MSG_USERAUTH_BANNER',
+
+            80 => 'NET_SSH2_MSG_GLOBAL_REQUEST',
+            81 => 'NET_SSH2_MSG_REQUEST_SUCCESS',
+            82 => 'NET_SSH2_MSG_REQUEST_FAILURE',
+            90 => 'NET_SSH2_MSG_CHANNEL_OPEN',
+            91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION',
+            92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE',
+            93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST',
+            94 => 'NET_SSH2_MSG_CHANNEL_DATA',
+            95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA',
+            96 => 'NET_SSH2_MSG_CHANNEL_EOF',
+            97 => 'NET_SSH2_MSG_CHANNEL_CLOSE',
+            98 => 'NET_SSH2_MSG_CHANNEL_REQUEST',
+            99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS',
+            100 => 'NET_SSH2_MSG_CHANNEL_FAILURE'
+        );
+        $this->disconnect_reasons = array(
+            1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT',
+            2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR',
+            3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED',
+            4 => 'NET_SSH2_DISCONNECT_RESERVED',
+            5 => 'NET_SSH2_DISCONNECT_MAC_ERROR',
+            6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR',
+            7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE',
+            8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED',
+            9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE',
+            10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST',
+            11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION',
+            12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS',
+            13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER',
+            14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE',
+            15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME'
+        );
+        $this->channel_open_failure_reasons = array(
+            1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED'
+        );
+        $this->terminal_modes = array(
+            0 => 'NET_SSH2_TTY_OP_END'
+        );
+        $this->channel_extended_data_type_codes = array(
+            1 => 'NET_SSH2_EXTENDED_DATA_STDERR'
+        );
+
+        $this->_define_array(
+            $this->message_numbers,
+            $this->disconnect_reasons,
+            $this->channel_open_failure_reasons,
+            $this->terminal_modes,
+            $this->channel_extended_data_type_codes,
+            array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),
+            array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'),
+            array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
+                  61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'),
+            // RFC 4419 - diffie-hellman-group-exchange-sha{1,256}
+            array(30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD',
+                  31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP',
+                  32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT',
+                  33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY',
+                  34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'),
+            // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org)
+            array(30 => 'NET_SSH2_MSG_KEX_ECDH_INIT',
+                  31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY')
+        );
+
+        if (is_resource($host)) {
+            $this->fsock = $host;
+            return;
+        }
+
+        if (is_string($host)) {
+            $this->host = $host;
+            $this->port = $port;
+            $this->timeout = $timeout;
+        }
+    }
+
+    /**
+     * Set Crypto Engine Mode
+     *
+     * Possible $engine values:
+     * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
+     *
+     * @param int $engine
+     * @access public
+     */
+    function setCryptoEngine($engine)
+    {
+        $this->crypto_engine = $engine;
+    }
+
+    /**
+     * Send Identification String First
+     *
+     * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
+     * both sides MUST send an identification string". It does not say which side sends it first. In
+     * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+     *
+     * @access public
+     */
+    function sendIdentificationStringFirst()
+    {
+        $this->send_id_string_first = true;
+    }
+
+    /**
+     * Send Identification String Last
+     *
+     * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
+     * both sides MUST send an identification string". It does not say which side sends it first. In
+     * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+     *
+     * @access public
+     */
+    function sendIdentificationStringLast()
+    {
+        $this->send_id_string_first = false;
+    }
+
+    /**
+     * Send SSH_MSG_KEXINIT First
+     *
+     * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
+     * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
+     * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+     *
+     * @access public
+     */
+    function sendKEXINITFirst()
+    {
+        $this->send_kex_first = true;
+    }
+
+    /**
+     * Send SSH_MSG_KEXINIT Last
+     *
+     * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
+     * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
+     * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+     *
+     * @access public
+     */
+    function sendKEXINITLast()
+    {
+        $this->send_kex_first = false;
+    }
+
+    /**
+     * Connect to an SSHv2 server
+     *
+     * @return bool
+     * @access private
+     */
+    function _connect()
+    {
+        if ($this->bitmap & self::MASK_CONSTRUCTOR) {
+            return false;
+        }
+
+        $this->bitmap |= self::MASK_CONSTRUCTOR;
+
+        $this->curTimeout = $this->timeout;
+
+        $this->last_packet = microtime(true);
+
+        if (!is_resource($this->fsock)) {
+            $start = microtime(true);
+            // with stream_select a timeout of 0 means that no timeout takes place;
+            // with fsockopen a timeout of 0 means that you instantly timeout
+            // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0
+            $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout);
+            if (!$this->fsock) {
+                $host = $this->host . ':' . $this->port;
+                user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
+                return false;
+            }
+            $elapsed = microtime(true) - $start;
+
+            if ($this->curTimeout) {
+                $this->curTimeout-= $elapsed;
+                if ($this->curTimeout < 0) {
+                    $this->is_timeout = true;
+                    return false;
+                }
+            }
+        }
+
+        $this->identifier = $this->_generate_identifier();
+
+        if ($this->send_id_string_first) {
+            fputs($this->fsock, $this->identifier . "\r\n");
+        }
+
+        /* According to the SSH2 specs,
+
+          "The server MAY send other lines of data before sending the version
+           string.  Each line SHOULD be terminated by a Carriage Return and Line
+           Feed.  Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
+           in ISO-10646 UTF-8 [RFC3629] (language is not specified).  Clients
+           MUST be able to process such lines." */
+        $data = '';
+        while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) {
+            $line = '';
+            while (true) {
+                if ($this->curTimeout) {
+                    if ($this->curTimeout < 0) {
+                        $this->is_timeout = true;
+                        return false;
+                    }
+                    $read = array($this->fsock);
+                    $write = $except = null;
+                    $start = microtime(true);
+                    $sec = (int) floor($this->curTimeout);
+                    $usec = (int) (1000000 * ($this->curTimeout - $sec));
+                    // on windows this returns a "Warning: Invalid CRT parameters detected" error
+                    // the !count() is done as a workaround for <https://bugs.php.net/42682>
+                    if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+                        $this->is_timeout = true;
+                        return false;
+                    }
+                    $elapsed = microtime(true) - $start;
+                    $this->curTimeout-= $elapsed;
+                }
+
+                $temp = stream_get_line($this->fsock, 255, "\n");
+                if (strlen($temp) == 255) {
+                    continue;
+                }
+
+                if ($temp === false) {
+                    return false;
+                }
+
+                $line.= "$temp\n";
+
+                // quoting RFC4253, "Implementers who wish to maintain
+                // compatibility with older, undocumented versions of this protocol may
+                // want to process the identification string without expecting the
+                // presence of the carriage return character for reasons described in
+                // Section 5 of this document."
+
+                //if (substr($line, -2) == "\r\n") {
+                //    break;
+                //}
+
+                break;
+            }
+
+            $data.= $line;
+        }
+
+        if (feof($this->fsock)) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+
+        $extra = $matches[1];
+
+        if (defined('NET_SSH2_LOGGING')) {
+            $this->_append_log('<-', $matches[0]);
+            $this->_append_log('->', $this->identifier . "\r\n");
+        }
+
+        $this->server_identifier = trim($temp, "\r\n");
+        if (strlen($extra)) {
+            $this->errors[] = $data;
+        }
+
+        if (version_compare($matches[3], '1.99', '<')) {
+            user_error("Cannot connect to SSH $matches[3] servers");
+            return false;
+        }
+
+        if (!$this->send_id_string_first) {
+            fputs($this->fsock, $this->identifier . "\r\n");
+        }
+
+        if (!$this->send_kex_first) {
+            $response = $this->_get_binary_packet();
+            if ($response === false) {
+                $this->bitmap = 0;
+                user_error('Connection closed by server');
+                return false;
+            }
+
+            if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
+                user_error('Expected SSH_MSG_KEXINIT');
+                return false;
+            }
+
+            if (!$this->_key_exchange($response)) {
+                return false;
+            }
+        }
+
+        if ($this->send_kex_first && !$this->_key_exchange()) {
+            return false;
+        }
+
+        $this->bitmap|= self::MASK_CONNECTED;
+
+        return true;
+    }
+
+    /**
+     * Generates the SSH identifier
+     *
+     * You should overwrite this method in your own class if you want to use another identifier
+     *
+     * @access protected
+     * @return string
+     */
+    function _generate_identifier()
+    {
+        $identifier = 'SSH-2.0-phpseclib_2.0';
+
+        $ext = array();
+        if (function_exists('sodium_crypto_box_publickey_from_secretkey')) {
+            $ext[] = 'libsodium';
+        }
+
+        if (extension_loaded('openssl')) {
+            $ext[] = 'openssl';
+        } elseif (extension_loaded('mcrypt')) {
+            $ext[] = 'mcrypt';
+        }
+
+        if (extension_loaded('gmp')) {
+            $ext[] = 'gmp';
+        } elseif (extension_loaded('bcmath')) {
+            $ext[] = 'bcmath';
+        }
+
+        if (!empty($ext)) {
+            $identifier .= ' (' . implode(', ', $ext) . ')';
+        }
+
+        return $identifier;
+    }
+
+    /**
+     * Key Exchange
+     *
+     * @param string $kexinit_payload_server optional
+     * @access private
+     */
+    function _key_exchange($kexinit_payload_server = false)
+    {
+        $preferred = $this->preferred;
+        $send_kex = true;
+
+        $kex_algorithms = isset($preferred['kex']) ?
+            $preferred['kex'] :
+            $this->getSupportedKEXAlgorithms();
+        $server_host_key_algorithms = isset($preferred['hostkey']) ?
+            $preferred['hostkey'] :
+            $this->getSupportedHostKeyAlgorithms();
+        $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ?
+            $preferred['server_to_client']['crypt'] :
+            $this->getSupportedEncryptionAlgorithms();
+        $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ?
+            $preferred['client_to_server']['crypt'] :
+            $this->getSupportedEncryptionAlgorithms();
+        $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ?
+            $preferred['server_to_client']['mac'] :
+            $this->getSupportedMACAlgorithms();
+        $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ?
+            $preferred['client_to_server']['mac'] :
+            $this->getSupportedMACAlgorithms();
+        $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ?
+            $preferred['server_to_client']['comp'] :
+            $this->getSupportedCompressionAlgorithms();
+        $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ?
+            $preferred['client_to_server']['comp'] :
+            $this->getSupportedCompressionAlgorithms();
+
+        // some SSH servers have buggy implementations of some of the above algorithms
+        switch (true) {
+            case $this->server_identifier == 'SSH-2.0-SSHD':
+            case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK':
+                if (!isset($preferred['server_to_client']['mac'])) {
+                    $s2c_mac_algorithms = array_values(array_diff(
+                        $s2c_mac_algorithms,
+                        array('hmac-sha1-96', 'hmac-md5-96')
+                    ));
+                }
+                if (!isset($preferred['client_to_server']['mac'])) {
+                    $c2s_mac_algorithms = array_values(array_diff(
+                        $c2s_mac_algorithms,
+                        array('hmac-sha1-96', 'hmac-md5-96')
+                    ));
+                }
+        }
+
+        $str_kex_algorithms = implode(',', $kex_algorithms);
+        $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
+        $encryption_algorithms_server_to_client = implode(',', $s2c_encryption_algorithms);
+        $encryption_algorithms_client_to_server = implode(',', $c2s_encryption_algorithms);
+        $mac_algorithms_server_to_client = implode(',', $s2c_mac_algorithms);
+        $mac_algorithms_client_to_server = implode(',', $c2s_mac_algorithms);
+        $compression_algorithms_server_to_client = implode(',', $s2c_compression_algorithms);
+        $compression_algorithms_client_to_server = implode(',', $c2s_compression_algorithms);
+
+        $client_cookie = Random::string(16);
+
+        $kexinit_payload_client = pack(
+            'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
+            NET_SSH2_MSG_KEXINIT,
+            $client_cookie,
+            strlen($str_kex_algorithms),
+            $str_kex_algorithms,
+            strlen($str_server_host_key_algorithms),
+            $str_server_host_key_algorithms,
+            strlen($encryption_algorithms_client_to_server),
+            $encryption_algorithms_client_to_server,
+            strlen($encryption_algorithms_server_to_client),
+            $encryption_algorithms_server_to_client,
+            strlen($mac_algorithms_client_to_server),
+            $mac_algorithms_client_to_server,
+            strlen($mac_algorithms_server_to_client),
+            $mac_algorithms_server_to_client,
+            strlen($compression_algorithms_client_to_server),
+            $compression_algorithms_client_to_server,
+            strlen($compression_algorithms_server_to_client),
+            $compression_algorithms_server_to_client,
+            0,
+            '',
+            0,
+            '',
+            0,
+            0
+        );
+
+        if ($kexinit_payload_server === false) {
+            if (!$this->_send_binary_packet($kexinit_payload_client)) {
+                return false;
+            }
+
+            $kexinit_payload_server = $this->_get_binary_packet();
+            if ($kexinit_payload_server === false) {
+                $this->bitmap = 0;
+                user_error('Connection closed by server');
+                return false;
+            }
+
+            if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
+                user_error('Expected SSH_MSG_KEXINIT');
+                return false;
+            }
+
+            $send_kex = false;
+        }
+
+        $response = $kexinit_payload_server;
+        $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
+        $server_cookie = $this->_string_shift($response, 16);
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+
+        $this->supported_private_key_algorithms = $this->server_host_key_algorithms;
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
+        $first_kex_packet_follows = $first_kex_packet_follows != 0;
+
+        if ($send_kex && !$this->_send_binary_packet($kexinit_payload_client)) {
+            return false;
+        }
+
+        // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
+        // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
+        // diffie-hellman key exchange as fast as possible
+        $decrypt = $this->_array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client);
+        $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
+        if ($decryptKeyLength === null) {
+            user_error('No compatible server to client encryption algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+
+        $encrypt = $this->_array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server);
+        $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
+        if ($encryptKeyLength === null) {
+            user_error('No compatible client to server encryption algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+
+        // through diffie-hellman key exchange a symmetric key is obtained
+        $this->kex_algorithm = $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
+        if ($kex_algorithm === false) {
+            user_error('No compatible key exchange algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+
+        $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
+        if ($server_host_key_algorithm === false) {
+            user_error('No compatible server host key algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+
+        $mac_algorithm_in = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client);
+        if ($mac_algorithm_in === false) {
+            user_error('No compatible server to client message authentication algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+
+        $compression_map = array(
+            'none' => self::NET_SSH2_COMPRESSION_NONE,
+            'zlib' => self::NET_SSH2_COMPRESSION_ZLIB,
+            'zlib@openssh.com' => self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH
+        );
+
+        $compression_algorithm_out = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server);
+        if ($compression_algorithm_out === false) {
+            user_error('No compatible client to server compression algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+        $this->compress = $compression_map[$compression_algorithm_out];
+
+        $compression_algorithm_in = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client);
+        if ($compression_algorithm_in === false) {
+            user_error('No compatible server to client compression algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+        $this->decompress = $compression_map[$compression_algorithm_in];
+
+        // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
+        $exchange_hash_rfc4419 = '';
+
+        if ($kex_algorithm === 'curve25519-sha256@libssh.org') {
+            $x = Random::string(32);
+            $eBytes = sodium_crypto_box_publickey_from_secretkey($x);
+            $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT';
+            $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY';
+            $kexHash = new Hash('sha256');
+        } else {
+            if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) {
+                $dh_group_sizes_packed = pack(
+                    'NNN',
+                    $this->kex_dh_group_size_min,
+                    $this->kex_dh_group_size_preferred,
+                    $this->kex_dh_group_size_max
+                );
+                $packet = pack(
+                    'Ca*',
+                    NET_SSH2_MSG_KEXDH_GEX_REQUEST,
+                    $dh_group_sizes_packed
+                );
+                if (!$this->_send_binary_packet($packet)) {
+                    return false;
+                }
+                $this->_updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST');
+
+                $response = $this->_get_binary_packet();
+                if ($response === false) {
+                    $this->bitmap = 0;
+                    user_error('Connection closed by server');
+                    return false;
+                }
+                extract(unpack('Ctype', $this->_string_shift($response, 1)));
+                if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) {
+                    user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
+                    return false;
+                }
+                $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP');
+
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('NprimeLength', $this->_string_shift($response, 4)));
+                $primeBytes = $this->_string_shift($response, $primeLength);
+                $prime = new BigInteger($primeBytes, -256);
+
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('NgLength', $this->_string_shift($response, 4)));
+                $gBytes = $this->_string_shift($response, $gLength);
+                $g = new BigInteger($gBytes, -256);
+
+                $exchange_hash_rfc4419 = pack(
+                    'a*Na*Na*',
+                    $dh_group_sizes_packed,
+                    $primeLength,
+                    $primeBytes,
+                    $gLength,
+                    $gBytes
+                );
+
+                $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT';
+                $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY';
+            } else {
+                switch ($kex_algorithm) {
+                    // see http://tools.ietf.org/html/rfc2409#section-6.2 and
+                    // http://tools.ietf.org/html/rfc2412, appendex E
+                    case 'diffie-hellman-group1-sha1':
+                        $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+                                '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+                                '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+                                'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
+                        break;
+                    // see http://tools.ietf.org/html/rfc3526#section-3
+                    case 'diffie-hellman-group14-sha1':
+                        $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+                                '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+                                '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+                                'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
+                                '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
+                                '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
+                                'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
+                                '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
+                        break;
+                }
+                // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
+                // the generator field element is 2 (decimal) and the hash function is sha1.
+                $g = new BigInteger(2);
+                $prime = new BigInteger($prime, 16);
+                $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT';
+                $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY';
+            }
+
+            switch ($kex_algorithm) {
+                case 'diffie-hellman-group-exchange-sha256':
+                    $kexHash = new Hash('sha256');
+                    break;
+                default:
+                    $kexHash = new Hash('sha1');
+            }
+
+            /* To increase the speed of the key exchange, both client and server may
+            reduce the size of their private exponents.  It should be at least
+            twice as long as the key material that is generated from the shared
+            secret.  For more details, see the paper by van Oorschot and Wiener
+            [VAN-OORSCHOT].
+
+            -- http://tools.ietf.org/html/rfc4419#section-6.2 */
+            $one = new BigInteger(1);
+            $keyLength = min($kexHash->getLength(), max($encryptKeyLength, $decryptKeyLength));
+            $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
+            $max = $max->subtract($one);
+
+            $x = $one->random($one, $max);
+            $e = $g->modPow($x, $prime);
+
+            $eBytes = $e->toBytes(true);
+        }
+        $data = pack('CNa*', constant($clientKexInitMessage), strlen($eBytes), $eBytes);
+
+        if (!$this->_send_binary_packet($data)) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+        switch ($clientKexInitMessage) {
+            case 'NET_SSH2_MSG_KEX_ECDH_INIT':
+                $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT');
+                break;
+            case 'NET_SSH2_MSG_KEXDH_GEX_INIT':
+                $this->_updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT');
+        }
+
+        $response = $this->_get_binary_packet();
+        if ($response === false) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+        if ($type != constant($serverKexReplyMessage)) {
+            user_error("Expected $serverKexReplyMessage");
+            return false;
+        }
+        switch ($serverKexReplyMessage) {
+            case 'NET_SSH2_MSG_KEX_ECDH_REPLY':
+                $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY');
+                break;
+            case 'NET_SSH2_MSG_KEXDH_GEX_REPLY':
+                $this->_updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY');
+        }
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']);
+
+        if (strlen($server_public_host_key) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+        $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']);
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $fBytes = $this->_string_shift($response, $temp['length']);
+
+        if (strlen($response) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($response, 4));
+        $this->signature = $this->_string_shift($response, $temp['length']);
+
+        if (strlen($this->signature) < 4) {
+            return false;
+        }
+        $temp = unpack('Nlength', $this->_string_shift($this->signature, 4));
+        $this->signature_format = $this->_string_shift($this->signature, $temp['length']);
+
+        if ($kex_algorithm === 'curve25519-sha256@libssh.org') {
+            if (strlen($fBytes) !== 32) {
+                user_error('Received curve25519 public key of invalid length.');
+                return false;
+            }
+            $key = new BigInteger(sodium_crypto_scalarmult($x, $fBytes), 256);
+            // sodium_compat doesn't emulate sodium_memzero
+            // also, with v1 of libsodium API the extension identifies itself as
+            // libsodium whereas v2 of the libsodium API (what PHP 7.2+ includes)
+            // identifies itself as sodium. sodium_compat uses the v1 API to
+            // emulate the v2 API if it's the v1 API that's available
+            if (extension_loaded('sodium') || extension_loaded('libsodium')) {
+                sodium_memzero($x);
+            }
+        } else {
+            $f = new BigInteger($fBytes, -256);
+            $key = $f->modPow($x, $prime);
+        }
+        $keyBytes = $key->toBytes(true);
+
+        $this->exchange_hash = pack(
+            'Na*Na*Na*Na*Na*a*Na*Na*Na*',
+            strlen($this->identifier),
+            $this->identifier,
+            strlen($this->server_identifier),
+            $this->server_identifier,
+            strlen($kexinit_payload_client),
+            $kexinit_payload_client,
+            strlen($kexinit_payload_server),
+            $kexinit_payload_server,
+            strlen($this->server_public_host_key),
+            $this->server_public_host_key,
+            $exchange_hash_rfc4419,
+            strlen($eBytes),
+            $eBytes,
+            strlen($fBytes),
+            $fBytes,
+            strlen($keyBytes),
+            $keyBytes
+        );
+
+        $this->exchange_hash = $kexHash->hash($this->exchange_hash);
+
+        if ($this->session_id === false) {
+            $this->session_id = $this->exchange_hash;
+        }
+
+        switch ($server_host_key_algorithm) {
+            case 'ssh-dss':
+                $expected_key_format = 'ssh-dss';
+                break;
+            //case 'rsa-sha2-256':
+            //case 'rsa-sha2-512':
+            //case 'ssh-rsa':
+            default:
+                $expected_key_format = 'ssh-rsa';
+        }
+
+        if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) {
+            switch (true) {
+                case $this->signature_format == $server_host_key_algorithm:
+                case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512':
+                case $this->signature_format != 'ssh-rsa':
+                    user_error('Server Host Key Algorithm Mismatch');
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+            }
+        }
+
+        $packet = pack(
+            'C',
+            NET_SSH2_MSG_NEWKEYS
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $response = $this->_get_binary_packet();
+
+        if ($response === false) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+        if ($type != NET_SSH2_MSG_NEWKEYS) {
+            user_error('Expected SSH_MSG_NEWKEYS');
+            return false;
+        }
+
+        $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
+
+        $this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt);
+        if ($this->encrypt) {
+            if ($this->crypto_engine) {
+                $this->encrypt->setPreferredEngine($this->crypto_engine);
+            }
+            if ($this->encrypt->block_size) {
+                $this->encrypt_block_size = $this->encrypt->block_size;
+            }
+            $this->encrypt->enableContinuousBuffer();
+            $this->encrypt->disablePadding();
+
+            if ($this->encrypt->getBlockLength()) {
+                $this->encrypt_block_size = $this->encrypt->getBlockLength() >> 3;
+            }
+
+            $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
+            while ($this->encrypt_block_size > strlen($iv)) {
+                $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
+            }
+            $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
+
+            $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id);
+            while ($encryptKeyLength > strlen($key)) {
+                $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+            }
+            $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
+
+            $this->encrypt->name = $decrypt;
+        }
+
+        $this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt);
+        if ($this->decrypt) {
+            if ($this->crypto_engine) {
+                $this->decrypt->setPreferredEngine($this->crypto_engine);
+            }
+            if ($this->decrypt->block_size) {
+                $this->decrypt_block_size = $this->decrypt->block_size;
+            }
+            $this->decrypt->enableContinuousBuffer();
+            $this->decrypt->disablePadding();
+
+            if ($this->decrypt->getBlockLength()) {
+                $this->decrypt_block_size = $this->decrypt->getBlockLength() >> 3;
+            }
+
+            $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
+            while ($this->decrypt_block_size > strlen($iv)) {
+                $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
+            }
+            $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
+
+            $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id);
+            while ($decryptKeyLength > strlen($key)) {
+                $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+            }
+            $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
+
+            $this->decrypt->name = $decrypt;
+        }
+
+        /* The "arcfour128" algorithm is the RC4 cipher, as described in
+           [SCHNEIER], using a 128-bit key.  The first 1536 bytes of keystream
+           generated by the cipher MUST be discarded, and the first byte of the
+           first encrypted packet MUST be encrypted using the 1537th byte of
+           keystream.
+
+           -- http://tools.ietf.org/html/rfc4345#section-4 */
+        if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {
+            $this->encrypt->encrypt(str_repeat("\0", 1536));
+        }
+        if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {
+            $this->decrypt->decrypt(str_repeat("\0", 1536));
+        }
+
+        $mac_algorithm_out = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server);
+        if ($mac_algorithm_out === false) {
+            user_error('No compatible client to server message authentication algorithms found');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+        }
+
+        $createKeyLength = 0; // ie. $mac_algorithm == 'none'
+        switch ($mac_algorithm_out) {
+            case 'hmac-sha2-256':
+                $this->hmac_create = new Hash('sha256');
+                $createKeyLength = 32;
+                break;
+            case 'hmac-sha1':
+                $this->hmac_create = new Hash('sha1');
+                $createKeyLength = 20;
+                break;
+            case 'hmac-sha1-96':
+                $this->hmac_create = new Hash('sha1-96');
+                $createKeyLength = 20;
+                break;
+            case 'hmac-md5':
+                $this->hmac_create = new Hash('md5');
+                $createKeyLength = 16;
+                break;
+            case 'hmac-md5-96':
+                $this->hmac_create = new Hash('md5-96');
+                $createKeyLength = 16;
+        }
+        $this->hmac_create->name = $mac_algorithm_out;
+
+        $checkKeyLength = 0;
+        $this->hmac_size = 0;
+        switch ($mac_algorithm_in) {
+            case 'hmac-sha2-256':
+                $this->hmac_check = new Hash('sha256');
+                $checkKeyLength = 32;
+                $this->hmac_size = 32;
+                break;
+            case 'hmac-sha1':
+                $this->hmac_check = new Hash('sha1');
+                $checkKeyLength = 20;
+                $this->hmac_size = 20;
+                break;
+            case 'hmac-sha1-96':
+                $this->hmac_check = new Hash('sha1-96');
+                $checkKeyLength = 20;
+                $this->hmac_size = 12;
+                break;
+            case 'hmac-md5':
+                $this->hmac_check = new Hash('md5');
+                $checkKeyLength = 16;
+                $this->hmac_size = 16;
+                break;
+            case 'hmac-md5-96':
+                $this->hmac_check = new Hash('md5-96');
+                $checkKeyLength = 16;
+                $this->hmac_size = 12;
+        }
+        $this->hmac_check->name = $mac_algorithm_in;
+
+        $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id);
+        while ($createKeyLength > strlen($key)) {
+            $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+        }
+        $this->hmac_create->setKey(substr($key, 0, $createKeyLength));
+
+        $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id);
+        while ($checkKeyLength > strlen($key)) {
+            $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+        }
+        $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
+
+        $this->regenerate_compression_context = $this->regenerate_decompression_context = true;
+
+        return true;
+    }
+
+    /**
+     * Maps an encryption algorithm name to the number of key bytes.
+     *
+     * @param string $algorithm Name of the encryption algorithm
+     * @return int|null Number of bytes as an integer or null for unknown
+     * @access private
+     */
+    function _encryption_algorithm_to_key_size($algorithm)
+    {
+        if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) {
+            return 16;
+        }
+
+        switch ($algorithm) {
+            case 'none':
+                return 0;
+            case 'aes128-cbc':
+            case 'aes128-ctr':
+            case 'arcfour':
+            case 'arcfour128':
+            case 'blowfish-cbc':
+            case 'blowfish-ctr':
+            case 'twofish128-cbc':
+            case 'twofish128-ctr':
+                return 16;
+            case '3des-cbc':
+            case '3des-ctr':
+            case 'aes192-cbc':
+            case 'aes192-ctr':
+            case 'twofish192-cbc':
+            case 'twofish192-ctr':
+                return 24;
+            case 'aes256-cbc':
+            case 'aes256-ctr':
+            case 'arcfour256':
+            case 'twofish-cbc':
+            case 'twofish256-cbc':
+            case 'twofish256-ctr':
+                return 32;
+        }
+        return null;
+    }
+
+    /**
+     * Maps an encryption algorithm name to an instance of a subclass of
+     * \phpseclib\Crypt\Base.
+     *
+     * @param string $algorithm Name of the encryption algorithm
+     * @return mixed Instance of \phpseclib\Crypt\Base or null for unknown
+     * @access private
+     */
+    function _encryption_algorithm_to_crypt_instance($algorithm)
+    {
+        switch ($algorithm) {
+            case '3des-cbc':
+                return new TripleDES();
+            case '3des-ctr':
+                return new TripleDES(Base::MODE_CTR);
+            case 'aes256-cbc':
+            case 'aes192-cbc':
+            case 'aes128-cbc':
+                return new Rijndael();
+            case 'aes256-ctr':
+            case 'aes192-ctr':
+            case 'aes128-ctr':
+                return new Rijndael(Base::MODE_CTR);
+            case 'blowfish-cbc':
+                return new Blowfish();
+            case 'blowfish-ctr':
+                return new Blowfish(Base::MODE_CTR);
+            case 'twofish128-cbc':
+            case 'twofish192-cbc':
+            case 'twofish256-cbc':
+            case 'twofish-cbc':
+                return new Twofish();
+            case 'twofish128-ctr':
+            case 'twofish192-ctr':
+            case 'twofish256-ctr':
+                return new Twofish(Base::MODE_CTR);
+            case 'arcfour':
+            case 'arcfour128':
+            case 'arcfour256':
+                return new RC4();
+        }
+        return null;
+    }
+
+    /**
+     * Tests whether or not proposed algorithm has a potential for issues
+     *
+     * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html
+     * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291
+     * @param string $algorithm Name of the encryption algorithm
+     * @return bool
+     * @access private
+     */
+    function _bad_algorithm_candidate($algorithm)
+    {
+        switch ($algorithm) {
+            case 'arcfour256':
+            case 'aes192-ctr':
+            case 'aes256-ctr':
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Login
+     *
+     * The $password parameter can be a plaintext password, a \phpseclib\Crypt\RSA object or an array
+     *
+     * @param string $username
+     * @return bool
+     * @see self::_login()
+     * @access public
+     */
+    function login($username)
+    {
+        $args = func_get_args();
+        $this->auth[] = $args;
+
+        // try logging with 'none' as an authentication method first since that's what
+        // PuTTY does
+        if (substr($this->server_identifier, 0, 15) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) {
+            if ($this->_login($username)) {
+                return true;
+            }
+            if (count($args) == 1) {
+                return false;
+            }
+        }
+        return call_user_func_array(array(&$this, '_login'), $args);
+    }
+
+    /**
+     * Login Helper
+     *
+     * @param string $username
+     * @return bool
+     * @see self::_login_helper()
+     * @access private
+     */
+    function _login($username)
+    {
+        if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
+            if (!$this->_connect()) {
+                return false;
+            }
+        }
+
+        $args = array_slice(func_get_args(), 1);
+        if (empty($args)) {
+            return $this->_login_helper($username);
+        }
+
+        while (count($args)) {
+            if (!$this->auth_methods_to_continue || !$this->smartMFA) {
+                $newargs = $args;
+                $args = array();
+            } else {
+                $newargs = array();
+                foreach ($this->auth_methods_to_continue as $method) {
+                    switch ($method) {
+                        case 'publickey':
+                            foreach ($args as $key => $arg) {
+                                if (is_object($arg)) {
+                                    $newargs[] = $arg;
+                                    unset($args[$key]);
+                                    break;
+                                }
+                            }
+                            break;
+                        case 'keyboard-interactive':
+                            $hasArray = $hasString = false;
+                            foreach ($args as $arg) {
+                                if ($hasArray || is_array($arg)) {
+                                    $hasArray = true;
+                                    break;
+                                }
+                                if ($hasString || is_string($arg)) {
+                                    $hasString = true;
+                                    break;
+                                }
+                            }
+                            if ($hasArray && $hasString) {
+                                foreach ($args as $key => $arg) {
+                                    if (is_array($arg)) {
+                                        $newargs[] = $arg;
+                                        break 2;
+                                    }
+                                }
+                            }
+                        case 'password':
+                            foreach ($args as $key => $arg) {
+                                $newargs[] = $arg;
+                                unset($args[$key]);
+                                break;
+                            }
+                    }
+                }
+            }
+
+            if (!count($newargs)) {
+                return false;
+            }
+
+            foreach ($newargs as $arg) {
+                if ($this->_login_helper($username, $arg)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Login Helper
+     *
+     * @param string $username
+     * @param string $password
+     * @return bool
+     * @access private
+     * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
+     *           by sending dummy SSH_MSG_IGNORE messages.
+     */
+    function _login_helper($username, $password = null)
+    {
+        if (!($this->bitmap & self::MASK_CONNECTED)) {
+            return false;
+        }
+
+        if (!($this->bitmap & self::MASK_LOGIN_REQ)) {
+            $packet = pack(
+                'CNa*',
+                NET_SSH2_MSG_SERVICE_REQUEST,
+                strlen('ssh-userauth'),
+                'ssh-userauth'
+            );
+
+            if (!$this->_send_binary_packet($packet)) {
+                return false;
+            }
+
+            $response = $this->_get_binary_packet();
+            if ($response === false) {
+                if ($this->retry_connect) {
+                    $this->retry_connect = false;
+                    if (!$this->_connect()) {
+                        return false;
+                    }
+                    return $this->_login_helper($username, $password);
+                }
+                $this->bitmap = 0;
+                user_error('Connection closed by server');
+                return false;
+            }
+
+            if (strlen($response) < 4) {
+                return false;
+            }
+            extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+            if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
+                user_error('Expected SSH_MSG_SERVICE_ACCEPT');
+                return false;
+            }
+            $this->bitmap |= self::MASK_LOGIN_REQ;
+        }
+
+        if (strlen($this->last_interactive_response)) {
+            return !is_string($password) && !is_array($password) ? false : $this->_keyboard_interactive_process($password);
+        }
+
+        if ($password instanceof RSA) {
+            return $this->_privatekey_login($username, $password);
+        } elseif ($password instanceof Agent) {
+            return $this->_ssh_agent_login($username, $password);
+        }
+
+        if (is_array($password)) {
+            if ($this->_keyboard_interactive_login($username, $password)) {
+                $this->bitmap |= self::MASK_LOGIN;
+                return true;
+            }
+            return false;
+        }
+
+        if (!isset($password)) {
+            $packet = pack(
+                'CNa*Na*Na*',
+                NET_SSH2_MSG_USERAUTH_REQUEST,
+                strlen($username),
+                $username,
+                strlen('ssh-connection'),
+                'ssh-connection',
+                strlen('none'),
+                'none'
+            );
+
+            if (!$this->_send_binary_packet($packet)) {
+                return false;
+            }
+
+            $response = $this->_get_binary_packet();
+            if ($response === false) {
+                $this->bitmap = 0;
+                user_error('Connection closed by server');
+                return false;
+            }
+
+            if (!strlen($response)) {
+                return false;
+            }
+            extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+            switch ($type) {
+                case NET_SSH2_MSG_USERAUTH_SUCCESS:
+                    $this->bitmap |= self::MASK_LOGIN;
+                    return true;
+                case NET_SSH2_MSG_USERAUTH_FAILURE:
+                    extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+                    $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
+                default:
+                    return false;
+            }
+        }
+
+        $packet = pack(
+            'CNa*Na*Na*CNa*',
+            NET_SSH2_MSG_USERAUTH_REQUEST,
+            strlen($username),
+            $username,
+            strlen('ssh-connection'),
+            'ssh-connection',
+            strlen('password'),
+            'password',
+            0,
+            strlen($password),
+            $password
+        );
+
+        // remove the username and password from the logged packet
+        if (!defined('NET_SSH2_LOGGING')) {
+            $logged = null;
+        } else {
+            $logged = pack(
+                'CNa*Na*Na*CNa*',
+                NET_SSH2_MSG_USERAUTH_REQUEST,
+                strlen('username'),
+                'username',
+                strlen('ssh-connection'),
+                'ssh-connection',
+                strlen('password'),
+                'password',
+                0,
+                strlen('password'),
+                'password'
+            );
+        }
+
+        if (!$this->_send_binary_packet($packet, $logged)) {
+            return false;
+        }
+
+        $response = $this->_get_binary_packet();
+        if ($response === false) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+        switch ($type) {
+            case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed
+                $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ');
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length);
+                return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
+            case NET_SSH2_MSG_USERAUTH_FAILURE:
+                // can we use keyboard-interactive authentication?  if not then either the login is bad or the server employees
+                // multi-factor authentication
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                $auth_methods = explode(',', $this->_string_shift($response, $length));
+                $this->auth_methods_to_continue = $auth_methods;
+                if (!strlen($response)) {
+                    return false;
+                }
+                extract(unpack('Cpartial_success', $this->_string_shift($response, 1)));
+                $partial_success = $partial_success != 0;
+
+                if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) {
+                    if ($this->_keyboard_interactive_login($username, $password)) {
+                        $this->bitmap |= self::MASK_LOGIN;
+                        return true;
+                    }
+                    return false;
+                }
+                return false;
+            case NET_SSH2_MSG_USERAUTH_SUCCESS:
+                $this->bitmap |= self::MASK_LOGIN;
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Login via keyboard-interactive authentication
+     *
+     * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details.  This is not a full-featured keyboard-interactive authenticator.
+     *
+     * @param string $username
+     * @param string $password
+     * @return bool
+     * @access private
+     */
+    function _keyboard_interactive_login($username, $password)
+    {
+        $packet = pack(
+            'CNa*Na*Na*Na*Na*',
+            NET_SSH2_MSG_USERAUTH_REQUEST,
+            strlen($username),
+            $username,
+            strlen('ssh-connection'),
+            'ssh-connection',
+            strlen('keyboard-interactive'),
+            'keyboard-interactive',
+            0,
+            '',
+            0,
+            ''
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        return $this->_keyboard_interactive_process($password);
+    }
+
+    /**
+     * Handle the keyboard-interactive requests / responses.
+     *
+     * @return bool
+     * @access private
+     */
+    function _keyboard_interactive_process()
+    {
+        $responses = func_get_args();
+
+        if (strlen($this->last_interactive_response)) {
+            $response = $this->last_interactive_response;
+        } else {
+            $orig = $response = $this->_get_binary_packet();
+            if ($response === false) {
+                $this->bitmap = 0;
+                user_error('Connection closed by server');
+                return false;
+            }
+        }
+
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+        switch ($type) {
+            case NET_SSH2_MSG_USERAUTH_INFO_REQUEST:
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                $this->_string_shift($response, $length); // name; may be empty
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                $this->_string_shift($response, $length); // instruction; may be empty
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                $this->_string_shift($response, $length); // language tag; may be empty
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nnum_prompts', $this->_string_shift($response, 4)));
+
+                for ($i = 0; $i < count($responses); $i++) {
+                    if (is_array($responses[$i])) {
+                        foreach ($responses[$i] as $key => $value) {
+                            $this->keyboard_requests_responses[$key] = $value;
+                        }
+                        unset($responses[$i]);
+                    }
+                }
+                $responses = array_values($responses);
+
+                if (isset($this->keyboard_requests_responses)) {
+                    for ($i = 0; $i < $num_prompts; $i++) {
+                        if (strlen($response) < 4) {
+                            return false;
+                        }
+                        extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                        // prompt - ie. "Password: "; must not be empty
+                        $prompt = $this->_string_shift($response, $length);
+                        //$echo = $this->_string_shift($response) != chr(0);
+                        foreach ($this->keyboard_requests_responses as $key => $value) {
+                            if (substr($prompt, 0, strlen($key)) == $key) {
+                                $responses[] = $value;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                // see http://tools.ietf.org/html/rfc4256#section-3.2
+                if (strlen($this->last_interactive_response)) {
+                    $this->last_interactive_response = '';
+                } else {
+                    $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST');
+                }
+
+                if (!count($responses) && $num_prompts) {
+                    $this->last_interactive_response = $orig;
+                    return false;
+                }
+
+                /*
+                   After obtaining the requested information from the user, the client
+                   MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message.
+                */
+                // see http://tools.ietf.org/html/rfc4256#section-3.4
+                $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses));
+                for ($i = 0; $i < count($responses); $i++) {
+                    $packet.= pack('Na*', strlen($responses[$i]), $responses[$i]);
+                    $logged.= pack('Na*', strlen('dummy-answer'), 'dummy-answer');
+                }
+
+                if (!$this->_send_binary_packet($packet, $logged)) {
+                    return false;
+                }
+
+                $this->_updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE');
+
+                /*
+                   After receiving the response, the server MUST send either an
+                   SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another
+                   SSH_MSG_USERAUTH_INFO_REQUEST message.
+                */
+                // maybe phpseclib should force close the connection after x request / responses?  unless something like that is done
+                // there could be an infinite loop of request / responses.
+                return $this->_keyboard_interactive_process();
+            case NET_SSH2_MSG_USERAUTH_SUCCESS:
+                return true;
+            case NET_SSH2_MSG_USERAUTH_FAILURE:
+                extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+                $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
+                return false;
+        }
+
+        return false;
+    }
+
+    /**
+     * Login with an ssh-agent provided key
+     *
+     * @param string $username
+     * @param \phpseclib\System\SSH\Agent $agent
+     * @return bool
+     * @access private
+     */
+    function _ssh_agent_login($username, $agent)
+    {
+        $this->agent = $agent;
+        $keys = $agent->requestIdentities();
+        foreach ($keys as $key) {
+            if ($this->_privatekey_login($username, $key)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Login with an RSA private key
+     *
+     * @param string $username
+     * @param \phpseclib\Crypt\RSA $privatekey
+     * @return bool
+     * @access private
+     * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
+     *           by sending dummy SSH_MSG_IGNORE messages.
+     */
+    function _privatekey_login($username, $privatekey)
+    {
+        // see http://tools.ietf.org/html/rfc4253#page-15
+        $publickey = $privatekey->getPublicKey(RSA::PUBLIC_FORMAT_RAW);
+        if ($publickey === false) {
+            return false;
+        }
+
+        $publickey = array(
+            'e' => $publickey['e']->toBytes(true),
+            'n' => $publickey['n']->toBytes(true)
+        );
+        $publickey = pack(
+            'Na*Na*Na*',
+            strlen('ssh-rsa'),
+            'ssh-rsa',
+            strlen($publickey['e']),
+            $publickey['e'],
+            strlen($publickey['n']),
+            $publickey['n']
+        );
+
+        $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa'];
+        if (isset($this->preferred['hostkey'])) {
+            $algos = array_intersect($this->preferred['hostkey'], $algos);
+        }
+        $algo = $this->_array_intersect_first($algos, $this->supported_private_key_algorithms);
+
+        switch ($algo) {
+            case 'rsa-sha2-512':
+                $hash = 'sha512';
+                $signatureType = 'rsa-sha2-512';
+                break;
+            case 'rsa-sha2-256':
+                $hash = 'sha256';
+                $signatureType = 'rsa-sha2-256';
+                break;
+            //case 'ssh-rsa':
+            default:
+                $hash = 'sha1';
+                $signatureType = 'ssh-rsa';
+        }
+
+        $part1 = pack(
+            'CNa*Na*Na*',
+            NET_SSH2_MSG_USERAUTH_REQUEST,
+            strlen($username),
+            $username,
+            strlen('ssh-connection'),
+            'ssh-connection',
+            strlen('publickey'),
+            'publickey'
+        );
+        $part2 = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($publickey), $publickey);
+
+        $packet = $part1 . chr(0) . $part2;
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $response = $this->_get_binary_packet();
+        if ($response === false) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+        switch ($type) {
+            case NET_SSH2_MSG_USERAUTH_FAILURE:
+                if (strlen($response) < 4) {
+                    return false;
+                }
+                extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+                $auth_methods = explode(',', $this->_string_shift($response, $methodlistlen));
+                if (in_array('publickey', $auth_methods) && substr($signatureType, 0, 9) == 'rsa-sha2-') {
+                    $this->supported_private_key_algorithms = array_diff($this->supported_private_key_algorithms, array('rsa-sha2-256', 'rsa-sha2-512'));
+                    return $this->_privatekey_login($username, $privatekey);
+                }
+                $this->auth_methods_to_continue = $auth_methods;
+                $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE';
+                return false;
+            case NET_SSH2_MSG_USERAUTH_PK_OK:
+                // we'll just take it on faith that the public key blob and the public key algorithm name are as
+                // they should be
+                $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK');
+                break;
+            case NET_SSH2_MSG_USERAUTH_SUCCESS:
+                $this->bitmap |= self::MASK_LOGIN;
+                return true;
+            default:
+                user_error('Unexpected response to publickey authentication pt 1');
+                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+        }
+
+        $packet = $part1 . chr(1) . $part2;
+        $privatekey->setSignatureMode(RSA::SIGNATURE_PKCS1);
+        $privatekey->setHash($hash);
+        $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
+        $signature = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($signature), $signature);
+        $packet.= pack('Na*', strlen($signature), $signature);
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $response = $this->_get_binary_packet();
+        if ($response === false) {
+            $this->bitmap = 0;
+            user_error('Connection closed by server');
+            return false;
+        }
+
+        if (!strlen($response)) {
+            return false;
+        }
+        extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+        switch ($type) {
+            case NET_SSH2_MSG_USERAUTH_FAILURE:
+                // either the login is bad or the server employs multi-factor authentication
+                extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
+                $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
+                return false;
+            case NET_SSH2_MSG_USERAUTH_SUCCESS:
+                $this->bitmap |= self::MASK_LOGIN;
+                return true;
+        }
+
+        user_error('Unexpected response to publickey authentication pt 2');
+        return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+    }
+
+    /**
+     * Set Timeout
+     *
+     * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely.  setTimeout() makes it so it'll timeout.
+     * Setting $timeout to false or 0 will mean there is no timeout.
+     *
+     * @param mixed $timeout
+     * @access public
+     */
+    function setTimeout($timeout)
+    {
+        $this->timeout = $this->curTimeout = $timeout;
+    }
+
+    /**
+     * Set Keep Alive
+     *
+     * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number.
+     *
+     * @param int $interval
+     * @access public
+     */
+    function setKeepAlive($interval)
+    {
+        $this->keepAlive = $interval;
+    }
+
+    /**
+     * Get the output from stdError
+     *
+     * @access public
+     */
+    function getStdError()
+    {
+        return $this->stdErrorLog;
+    }
+
+    /**
+     * Execute Command
+     *
+     * If $callback is set to false then \phpseclib\Net\SSH2::_get_channel_packet(self::CHANNEL_EXEC) will need to be called manually.
+     * In all likelihood, this is not a feature you want to be taking advantage of.
+     *
+     * @param string $command
+     * @param Callback $callback
+     * @return string
+     * @access public
+     */
+    function exec($command, $callback = null)
+    {
+        $this->curTimeout = $this->timeout;
+        $this->is_timeout = false;
+        $this->stdErrorLog = '';
+
+        if (!$this->isAuthenticated()) {
+            return false;
+        }
+
+        if ($this->in_request_pty_exec) {
+            user_error('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.');
+            return false;
+        }
+
+        // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to
+        // be adjusted".  0x7FFFFFFF is, at 2GB, the max size.  technically, it should probably be decremented, but,
+        // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway.
+        // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info
+        $this->window_size_server_to_client[self::CHANNEL_EXEC] = $this->window_size;
+        // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy
+        // uses 0x4000, that's what will be used here, as well.
+        $packet_size = 0x4000;
+
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            self::CHANNEL_EXEC,
+            $this->window_size_server_to_client[self::CHANNEL_EXEC],
+            $packet_size
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+        $response = $this->_get_channel_packet(self::CHANNEL_EXEC);
+        if ($response === false) {
+            return false;
+        }
+
+        if ($this->request_pty === true) {
+            $terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
+            $packet = pack(
+                'CNNa*CNa*N5a*',
+                NET_SSH2_MSG_CHANNEL_REQUEST,
+                $this->server_channels[self::CHANNEL_EXEC],
+                strlen('pty-req'),
+                'pty-req',
+                1,
+                strlen('vt100'),
+                'vt100',
+                $this->windowColumns,
+                $this->windowRows,
+                0,
+                0,
+                strlen($terminal_modes),
+                $terminal_modes
+            );
+
+            if (!$this->_send_binary_packet($packet)) {
+                return false;
+            }
+
+            $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST;
+            if (!$this->_get_channel_packet(self::CHANNEL_EXEC)) {
+                user_error('Unable to request pseudo-terminal');
+                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+            }
+
+            $this->in_request_pty_exec = true;
+        }
+
+        // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things
+        // down.  the one place where it might be desirable is if you're doing something like \phpseclib\Net\SSH2::exec('ping localhost &').
+        // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then
+        // then immediately terminate.  without such a request exec() will loop indefinitely.  the ping process won't end but
+        // neither will your script.
+
+        // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by
+        // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the
+        // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA.  RFC4254#section-5.2 corroborates.
+        $packet = pack(
+            'CNNa*CNa*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[self::CHANNEL_EXEC],
+            strlen('exec'),
+            'exec',
+            1,
+            strlen($command),
+            $command
+        );
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+        $response = $this->_get_channel_packet(self::CHANNEL_EXEC);
+        if ($response === false) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA;
+
+        if ($callback === false || $this->in_request_pty_exec) {
+            return true;
+        }
+
+        $output = '';
+        while (true) {
+            $temp = $this->_get_channel_packet(self::CHANNEL_EXEC);
+            switch (true) {
+                case $temp === true:
+                    return is_callable($callback) ? true : $output;
+                case $temp === false:
+                    return false;
+                default:
+                    if (is_callable($callback)) {
+                        if (call_user_func($callback, $temp) === true) {
+                            $this->_close_channel(self::CHANNEL_EXEC);
+                            return true;
+                        }
+                    } else {
+                        $output.= $temp;
+                    }
+            }
+        }
+    }
+
+    /**
+     * Creates an interactive shell
+     *
+     * @see self::read()
+     * @see self::write()
+     * @return bool
+     * @access private
+     */
+    function _initShell()
+    {
+        if ($this->in_request_pty_exec === true) {
+            return true;
+        }
+
+        $this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size;
+        $packet_size = 0x4000;
+
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            self::CHANNEL_SHELL,
+            $this->window_size_server_to_client[self::CHANNEL_SHELL],
+            $packet_size
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+        $response = $this->_get_channel_packet(self::CHANNEL_SHELL);
+        if ($response === false) {
+            return false;
+        }
+
+        $terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
+        $packet = pack(
+            'CNNa*CNa*N5a*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[self::CHANNEL_SHELL],
+            strlen('pty-req'),
+            'pty-req',
+            1,
+            strlen('vt100'),
+            'vt100',
+            $this->windowColumns,
+            $this->windowRows,
+            0,
+            0,
+            strlen($terminal_modes),
+            $terminal_modes
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+        if (!$this->_get_channel_packet(self::CHANNEL_SHELL)) {
+            user_error('Unable to request pseudo-terminal');
+            return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+        }
+
+        $packet = pack(
+            'CNNa*C',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[self::CHANNEL_SHELL],
+            strlen('shell'),
+            'shell',
+            1
+        );
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $response = $this->_get_channel_packet(self::CHANNEL_SHELL);
+        if ($response === false) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA;
+
+        $this->bitmap |= self::MASK_SHELL;
+
+        return true;
+    }
+
+    /**
+     * Return the channel to be used with read() / write()
+     *
+     * @see self::read()
+     * @see self::write()
+     * @return int
+     * @access public
+     */
+    function _get_interactive_channel()
+    {
+        switch (true) {
+            case $this->in_subsystem:
+                return self::CHANNEL_SUBSYSTEM;
+            case $this->in_request_pty_exec:
+                return self::CHANNEL_EXEC;
+            default:
+                return self::CHANNEL_SHELL;
+        }
+    }
+
+    /**
+     * Return an available open channel
+     *
+     * @return int
+     * @access public
+     */
+    function _get_open_channel()
+    {
+        $channel = self::CHANNEL_EXEC;
+        do {
+            if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) {
+                return $channel;
+            }
+        } while ($channel++ < self::CHANNEL_SUBSYSTEM);
+
+        return false;
+    }
+
+    /**
+     * Returns the output of an interactive shell
+     *
+     * Returns when there's a match for $expect, which can take the form of a string literal or,
+     * if $mode == self::READ_REGEX, a regular expression.
+     *
+     * @see self::write()
+     * @param string $expect
+     * @param int $mode
+     * @return string|bool
+     * @access public
+     */
+    function read($expect = '', $mode = self::READ_SIMPLE)
+    {
+        $this->curTimeout = $this->timeout;
+        $this->is_timeout = false;
+
+        if (!$this->isAuthenticated()) {
+            user_error('Operation disallowed prior to login()');
+            return false;
+        }
+
+        if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+            user_error('Unable to initiate an interactive shell session');
+            return false;
+        }
+
+        $channel = $this->_get_interactive_channel();
+
+        if ($mode == self::READ_NEXT) {
+            return $this->_get_channel_packet($channel);
+        }
+
+        $match = $expect;
+        while (true) {
+            if ($mode == self::READ_REGEX) {
+                preg_match($expect, substr($this->interactiveBuffer, -1024), $matches);
+                $match = isset($matches[0]) ? $matches[0] : '';
+            }
+            $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false;
+            if ($pos !== false) {
+                return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match));
+            }
+            $response = $this->_get_channel_packet($channel);
+            if (is_bool($response)) {
+                $this->in_request_pty_exec = false;
+                return $response ? $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)) : false;
+            }
+
+            $this->interactiveBuffer.= $response;
+        }
+    }
+
+    /**
+     * Inputs a command into an interactive shell.
+     *
+     * @see self::read()
+     * @param string $cmd
+     * @return bool
+     * @access public
+     */
+    function write($cmd)
+    {
+        if (!$this->isAuthenticated()) {
+            user_error('Operation disallowed prior to login()');
+            return false;
+        }
+
+        if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+            user_error('Unable to initiate an interactive shell session');
+            return false;
+        }
+
+        return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd);
+    }
+
+    /**
+     * Start a subsystem.
+     *
+     * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept
+     * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened.
+     * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and
+     * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented
+     * if there's sufficient demand for such a feature.
+     *
+     * @see self::stopSubsystem()
+     * @param string $subsystem
+     * @return bool
+     * @access public
+     */
+    function startSubsystem($subsystem)
+    {
+        $this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size;
+
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            self::CHANNEL_SUBSYSTEM,
+            $this->window_size,
+            0x4000
+        );
+
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+        $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM);
+        if ($response === false) {
+            return false;
+        }
+
+        $packet = pack(
+            'CNNa*CNa*',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $this->server_channels[self::CHANNEL_SUBSYSTEM],
+            strlen('subsystem'),
+            'subsystem',
+            1,
+            strlen($subsystem),
+            $subsystem
+        );
+        if (!$this->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+        $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM);
+
+        if ($response === false) {
+            return false;
+        }
+
+        $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA;
+
+        $this->bitmap |= self::MASK_SHELL;
+        $this->in_subsystem = true;
+
+        return true;
+    }
+
+    /**
+     * Stops a subsystem.
+     *
+     * @see self::startSubsystem()
+     * @return bool
+     * @access public
+     */
+    function stopSubsystem()
+    {
+        $this->in_subsystem = false;
+        $this->_close_channel(self::CHANNEL_SUBSYSTEM);
+        return true;
+    }
+
+    /**
+     * Closes a channel
+     *
+     * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call
+     *
+     * @access public
+     */
+    function reset()
+    {
+        $this->_close_channel($this->_get_interactive_channel());
+    }
+
+    /**
+     * Is timeout?
+     *
+     * Did exec() or read() return because they timed out or because they encountered the end?
+     *
+     * @access public
+     */
+    function isTimeout()
+    {
+        return $this->is_timeout;
+    }
+
+    /**
+     * Disconnect
+     *
+     * @access public
+     */
+    function disconnect()
+    {
+        $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+        if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) {
+            fclose($this->realtime_log_file);
+        }
+    }
+
+    /**
+     * Destructor.
+     *
+     * Will be called, automatically, if you're supporting just PHP5.  If you're supporting PHP4, you'll need to call
+     * disconnect().
+     *
+     * @access public
+     */
+    function __destruct()
+    {
+        $this->disconnect();
+    }
+
+    /**
+     * Is the connection still active?
+     *
+     * @return bool
+     * @access public
+     */
+    function isConnected()
+    {
+        return (bool) ($this->bitmap & self::MASK_CONNECTED);
+    }
+
+    /**
+     * Have you successfully been logged in?
+     *
+     * @return bool
+     * @access public
+     */
+    function isAuthenticated()
+    {
+        return (bool) ($this->bitmap & self::MASK_LOGIN);
+    }
+
+    /**
+     * Pings a server connection, or tries to reconnect if the connection has gone down
+     *
+     * Inspired by http://php.net/manual/en/mysqli.ping.php
+     *
+     * @return bool
+     * @access public
+     */
+    function ping()
+    {
+        if (!$this->isAuthenticated()) {
+            if (!empty($this->auth)) {
+                return $this->_reconnect();
+            }
+            return false;
+        }
+
+        $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE] = $this->window_size;
+        $packet_size = 0x4000;
+        $packet = pack(
+            'CNa*N3',
+            NET_SSH2_MSG_CHANNEL_OPEN,
+            strlen('session'),
+            'session',
+            self::CHANNEL_KEEP_ALIVE,
+            $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE],
+            $packet_size
+        );
+
+        if (!@$this->_send_binary_packet($packet)) {
+            return $this->_reconnect();
+        }
+
+        $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+        $response = @$this->_get_channel_packet(self::CHANNEL_KEEP_ALIVE);
+        if ($response !== false) {
+            $this->_close_channel(self::CHANNEL_KEEP_ALIVE);
+            return true;
+        }
+
+        return $this->_reconnect();
+    }
+
+    /**
+     * In situ reconnect method
+     *
+     * @return boolean
+     * @access private
+     */
+    function _reconnect()
+    {
+        $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
+        $this->retry_connect = true;
+        if (!$this->_connect()) {
+            return false;
+        }
+        foreach ($this->auth as $auth) {
+            $result = call_user_func_array(array(&$this, 'login'), $auth);
+        }
+        return $result;
+    }
+
+    /**
+     * Resets a connection for re-use
+     *
+     * @param int $reason
+     * @access private
+     */
+    function _reset_connection($reason)
+    {
+        $this->_disconnect($reason);
+        $this->decrypt = $this->encrypt = false;
+        $this->decrypt_block_size = $this->encrypt_block_size = 8;
+        $this->hmac_check = $this->hmac_create = false;
+        $this->hmac_size = false;
+        $this->session_id = false;
+        $this->retry_connect = true;
+        $this->get_seq_no = $this->send_seq_no = 0;
+    }
+
+    /**
+     * Gets Binary Packets
+     *
+     * See '6. Binary Packet Protocol' of rfc4253 for more info.
+     *
+     * @see self::_send_binary_packet()
+     * @return string
+     * @access private
+     */
+    function _get_binary_packet($skip_channel_filter = false)
+    {
+        if ($skip_channel_filter) {
+            $read = array($this->fsock);
+            $write = $except = null;
+
+            if (!$this->curTimeout) {
+                if ($this->keepAlive <= 0) {
+                    @stream_select($read, $write, $except, null);
+                } else {
+                    if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) {
+                        $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0));
+                        return $this->_get_binary_packet(true);
+                    }
+                }
+            } else {
+                if ($this->curTimeout < 0) {
+                    $this->is_timeout = true;
+                    return true;
+                }
+
+                $read = array($this->fsock);
+                $write = $except = null;
+
+                $start = microtime(true);
+
+                if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) {
+                    if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) {
+                        $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0));
+                        $elapsed = microtime(true) - $start;
+                        $this->curTimeout-= $elapsed;
+                        return $this->_get_binary_packet(true);
+                    }
+                    $elapsed = microtime(true) - $start;
+                    $this->curTimeout-= $elapsed;
+                }
+
+                $sec = (int)floor($this->curTimeout);
+                $usec = (int)(1000000 * ($this->curTimeout - $sec));
+
+                // on windows this returns a "Warning: Invalid CRT parameters detected" error
+                if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+                    $this->is_timeout = true;
+                    return true;
+                }
+                $elapsed = microtime(true) - $start;
+                $this->curTimeout-= $elapsed;
+            }
+        }
+
+        if (!is_resource($this->fsock) || feof($this->fsock)) {
+            $this->bitmap = 0;
+            $str = 'Connection closed (by server) prematurely';
+            if (isset($elapsed)) {
+                $str.= ' ' . $elapsed . 's';
+            }
+            user_error($str);
+            return false;
+        }
+
+        $start = microtime(true);
+        $raw = stream_get_contents($this->fsock, $this->decrypt_block_size);
+
+        if (!strlen($raw)) {
+            user_error('No data received from server');
+            return false;
+        }
+
+        if ($this->decrypt !== false) {
+            $raw = $this->decrypt->decrypt($raw);
+        }
+        if ($raw === false) {
+            user_error('Unable to decrypt content');
+            return false;
+        }
+
+        if (strlen($raw) < 5) {
+            return false;
+        }
+        extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
+
+        $remaining_length = $packet_length + 4 - $this->decrypt_block_size;
+
+        // quoting <http://tools.ietf.org/html/rfc4253#section-6.1>,
+        // "implementations SHOULD check that the packet length is reasonable"
+        // PuTTY uses 0x9000 as the actual max packet size and so to shall we
+        if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
+            if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt->name) && !($this->bitmap & SSH2::MASK_LOGIN)) {
+                $this->bad_key_size_fix = true;
+                $this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+                return false;
+            }
+            user_error('Invalid size');
+            return false;
+        }
+
+        $buffer = '';
+        while ($remaining_length > 0) {
+            $temp = stream_get_contents($this->fsock, $remaining_length);
+            if ($temp === false || feof($this->fsock)) {
+                $this->bitmap = 0;
+                user_error('Error reading from socket');
+                return false;
+            }
+            $buffer.= $temp;
+            $remaining_length-= strlen($temp);
+        }
+
+        $stop = microtime(true);
+        if (strlen($buffer)) {
+            $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
+        }
+
+        $payload = $this->_string_shift($raw, $packet_length - $padding_length - 1);
+        $padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty
+
+        if ($this->hmac_check !== false) {
+            $hmac = stream_get_contents($this->fsock, $this->hmac_size);
+            if ($hmac === false || strlen($hmac) != $this->hmac_size) {
+                $this->bitmap = 0;
+                user_error('Error reading socket');
+                return false;
+            } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
+                user_error('Invalid HMAC');
+                return false;
+            }
+        }
+
+        switch ($this->decompress) {
+            case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH:
+                if (!$this->isAuthenticated()) {
+                    break;
+                }
+            case self::NET_SSH2_COMPRESSION_ZLIB:
+                if ($this->regenerate_decompression_context) {
+                    $this->regenerate_decompression_context = false;
+
+                    $cmf = ord($payload[0]);
+                    $cm = $cmf & 0x0F;
+                    if ($cm != 8) { // deflate
+                        user_error("Only CM = 8 ('deflate') is supported ($cm)");
+                    }
+                    $cinfo = ($cmf & 0xF0) >> 4;
+                    if ($cinfo > 7) {
+                        user_error("CINFO above 7 is not allowed ($cinfo)");
+                    }
+                    $windowSize = 1 << ($cinfo + 8);
+
+                    $flg = ord($payload[1]);
+                    //$fcheck = $flg && 0x0F;
+                    if ((($cmf << 8) | $flg) % 31) {
+                        user_error('fcheck failed');
+                    }
+                    $fdict = boolval($flg & 0x20);
+                    $flevel = ($flg & 0xC0) >> 6;
+
+                    $this->decompress_context = inflate_init(ZLIB_ENCODING_RAW, array('window' => $cinfo + 8));
+                    $payload = substr($payload, 2);
+                }
+                if ($this->decompress_context) {
+                    $payload = inflate_add($this->decompress_context, $payload, ZLIB_PARTIAL_FLUSH);
+                }
+        }
+
+        $this->get_seq_no++;
+
+        if (defined('NET_SSH2_LOGGING')) {
+            $current = microtime(true);
+            $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')';
+            $message_number = '<- ' . $message_number .
+                              ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
+            $this->_append_log($message_number, $payload);
+            $this->last_packet = $current;
+        }
+
+        return $this->_filter($payload, $skip_channel_filter);
+    }
+
+    /**
+     * Filter Binary Packets
+     *
+     * Because some binary packets need to be ignored...
+     *
+     * @see self::_get_binary_packet()
+     * @return string
+     * @access private
+     */
+    function _filter($payload, $skip_channel_filter)
+    {
+        switch (ord($payload[0])) {
+            case NET_SSH2_MSG_DISCONNECT:
+                $this->_string_shift($payload, 1);
+                if (strlen($payload) < 8) {
+                    return false;
+                }
+                extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
+                $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length);
+                $this->bitmap = 0;
+                return false;
+            case NET_SSH2_MSG_IGNORE:
+                $payload = $this->_get_binary_packet($skip_channel_filter);
+                break;
+            case NET_SSH2_MSG_DEBUG:
+                $this->_string_shift($payload, 2);
+                if (strlen($payload) < 4) {
+                    return false;
+                }
+                extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+                $this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length);
+                $payload = $this->_get_binary_packet($skip_channel_filter);
+                break;
+            case NET_SSH2_MSG_UNIMPLEMENTED:
+                return false;
+            case NET_SSH2_MSG_KEXINIT:
+                if ($this->session_id !== false) {
+                    $this->send_kex_first = false;
+                    if (!$this->_key_exchange($payload)) {
+                        $this->bitmap = 0;
+                        return false;
+                    }
+                    $payload = $this->_get_binary_packet($skip_channel_filter);
+                }
+        }
+
+        // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
+        if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
+            $this->_string_shift($payload, 1);
+            if (strlen($payload) < 4) {
+                return false;
+            }
+            extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+            $this->banner_message = $this->_string_shift($payload, $length);
+            $payload = $this->_get_binary_packet();
+        }
+
+        // only called when we've already logged in
+        if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
+            if (is_bool($payload)) {
+                return $payload;
+            }
+
+            switch (ord($payload[0])) {
+                case NET_SSH2_MSG_CHANNEL_REQUEST:
+                    if (strlen($payload) == 31) {
+                        extract(unpack('cpacket_type/Nchannel/Nlength', $payload));
+                        if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) {
+                            if (ord(substr($payload, 9 + $length))) { // want reply
+                                $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel]));
+                            }
+                            $payload = $this->_get_binary_packet($skip_channel_filter);
+                        }
+                    }
+                    break;
+                case NET_SSH2_MSG_CHANNEL_DATA:
+                case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
+                case NET_SSH2_MSG_CHANNEL_CLOSE:
+                case NET_SSH2_MSG_CHANNEL_EOF:
+                    if (!$skip_channel_filter && !empty($this->server_channels)) {
+                        $this->binary_packet_buffer = $payload;
+                        $this->_get_channel_packet(true);
+                        $payload = $this->_get_binary_packet();
+                    }
+                    break;
+                case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
+                    if (strlen($payload) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+                    $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . $this->_string_shift($payload, $length);
+
+                    if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {
+                        return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                    }
+
+                    $payload = $this->_get_binary_packet($skip_channel_filter);
+                    break;
+                case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
+                    $this->_string_shift($payload, 1);
+                    if (strlen($payload) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+                    $data = $this->_string_shift($payload, $length);
+                    if (strlen($payload) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
+                    switch ($data) {
+                        case 'auth-agent':
+                        case 'auth-agent@openssh.com':
+                            if (isset($this->agent)) {
+                                $new_channel = self::CHANNEL_AGENT_FORWARD;
+
+                                if (strlen($payload) < 8) {
+                                    return false;
+                                }
+                                extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4)));
+                                extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4)));
+
+                                $this->packet_size_client_to_server[$new_channel] = $remote_window_size;
+                                $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size;
+                                $this->window_size_client_to_server[$new_channel] = $this->window_size;
+
+                                $packet_size = 0x4000;
+
+                                $packet = pack(
+                                    'CN4',
+                                    NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
+                                    $server_channel,
+                                    $new_channel,
+                                    $packet_size,
+                                    $packet_size
+                                );
+
+                                $this->server_channels[$new_channel] = $server_channel;
+                                $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION;
+                                if (!$this->_send_binary_packet($packet)) {
+                                    return false;
+                                }
+                            }
+                            break;
+                        default:
+                            $packet = pack(
+                                'CN3a*Na*',
+                                NET_SSH2_MSG_REQUEST_FAILURE,
+                                $server_channel,
+                                NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
+                                0,
+                                '',
+                                0,
+                                ''
+                            );
+
+                            if (!$this->_send_binary_packet($packet)) {
+                                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                            }
+                    }
+                    $payload = $this->_get_binary_packet($skip_channel_filter);
+                    break;
+                case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
+                    $this->_string_shift($payload, 1);
+                    if (strlen($payload) < 8) {
+                        return false;
+                    }
+                    extract(unpack('Nchannel', $this->_string_shift($payload, 4)));
+                    extract(unpack('Nwindow_size', $this->_string_shift($payload, 4)));
+                    $this->window_size_client_to_server[$channel]+= $window_size;
+
+                    $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet($skip_channel_filter);
+            }
+        }
+
+        return $payload;
+    }
+
+    /**
+     * Enable Quiet Mode
+     *
+     * Suppress stderr from output
+     *
+     * @access public
+     */
+    function enableQuietMode()
+    {
+        $this->quiet_mode = true;
+    }
+
+    /**
+     * Disable Quiet Mode
+     *
+     * Show stderr in output
+     *
+     * @access public
+     */
+    function disableQuietMode()
+    {
+        $this->quiet_mode = false;
+    }
+
+    /**
+     * Returns whether Quiet Mode is enabled or not
+     *
+     * @see self::enableQuietMode()
+     * @see self::disableQuietMode()
+     * @access public
+     * @return bool
+     */
+    function isQuietModeEnabled()
+    {
+        return $this->quiet_mode;
+    }
+
+    /**
+     * Enable request-pty when using exec()
+     *
+     * @access public
+     */
+    function enablePTY()
+    {
+        $this->request_pty = true;
+    }
+
+    /**
+     * Disable request-pty when using exec()
+     *
+     * @access public
+     */
+    function disablePTY()
+    {
+        if ($this->in_request_pty_exec) {
+            $this->_close_channel(self::CHANNEL_EXEC);
+            $this->in_request_pty_exec = false;
+        }
+        $this->request_pty = false;
+    }
+
+    /**
+     * Returns whether request-pty is enabled or not
+     *
+     * @see self::enablePTY()
+     * @see self::disablePTY()
+     * @access public
+     * @return bool
+     */
+    function isPTYEnabled()
+    {
+        return $this->request_pty;
+    }
+
+    /**
+     * Gets channel data
+     *
+     * Returns the data as a string if it's available and false if not.
+     *
+     * @param int $client_channel
+     * @param bool $skip_extended
+     * @return mixed|bool
+     * @access private
+     */
+    function _get_channel_packet($client_channel, $skip_extended = false)
+    {
+        if (!empty($this->channel_buffers[$client_channel])) {
+            switch ($this->channel_status[$client_channel]) {
+                case NET_SSH2_MSG_CHANNEL_REQUEST:
+                    foreach ($this->channel_buffers[$client_channel] as $i => $packet) {
+                        switch (ord($packet[0])) {
+                            case NET_SSH2_MSG_CHANNEL_SUCCESS:
+                            case NET_SSH2_MSG_CHANNEL_FAILURE:
+                                unset($this->channel_buffers[$client_channel][$i]);
+                                return substr($packet, 1);
+                        }
+                    }
+                    break;
+                default:
+                    return substr(array_shift($this->channel_buffers[$client_channel]), 1);
+            }
+        }
+
+        while (true) {
+            if ($this->binary_packet_buffer !== false) {
+                $response = $this->binary_packet_buffer;
+                $this->binary_packet_buffer = false;
+            } else {
+                $response = $this->_get_binary_packet(true);
+                if ($response === true && $this->is_timeout) {
+                    if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) {
+                        $this->_close_channel($client_channel);
+                    }
+                    return true;
+                }
+                if ($response === false) {
+                    $this->bitmap = 0;
+                    user_error('Connection closed by server');
+                    return false;
+                }
+            }
+
+            if ($client_channel == -1 && $response === true) {
+                return true;
+            }
+            if (!strlen($response)) {
+                return false;
+            }
+            extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+            if (strlen($response) < 4) {
+                return false;
+            }
+            if ($type == NET_SSH2_MSG_CHANNEL_OPEN) {
+                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+            } else {
+                extract(unpack('Nchannel', $this->_string_shift($response, 4)));
+            }
+
+            // will not be setup yet on incoming channel open request
+            if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) {
+                $this->window_size_server_to_client[$channel]-= strlen($response);
+
+                // resize the window, if appropriate
+                if ($this->window_size_server_to_client[$channel] < 0) {
+                // PuTTY does something more analogous to the following:
+                //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) {
+                    $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize);
+                    if (!$this->_send_binary_packet($packet)) {
+                        return false;
+                    }
+                    $this->window_size_server_to_client[$channel]+= $this->window_resize;
+                }
+
+                switch ($type) {
+                    case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
+                        /*
+                        if ($client_channel == self::CHANNEL_EXEC) {
+                            $this->_send_channel_packet($client_channel, chr(0));
+                        }
+                        */
+                        // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
+                        if (strlen($response) < 8) {
+                            return false;
+                        }
+                        extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
+                        $data = $this->_string_shift($response, $length);
+                        $this->stdErrorLog.= $data;
+                        if ($skip_extended || $this->quiet_mode) {
+                            continue 2;
+                        }
+                        if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) {
+                            return $data;
+                        }
+                        $this->channel_buffers[$channel][] = chr($type) . $data;
+
+                        continue 2;
+                    case NET_SSH2_MSG_CHANNEL_REQUEST:
+                        if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) {
+                            continue 2;
+                        }
+                        if (strlen($response) < 4) {
+                            return false;
+                        }
+                        extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                        $value = $this->_string_shift($response, $length);
+                        switch ($value) {
+                            case 'exit-signal':
+                                $this->_string_shift($response, 1);
+                                if (strlen($response) < 4) {
+                                    return false;
+                                }
+                                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                                $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
+                                $this->_string_shift($response, 1);
+                                if (strlen($response) < 4) {
+                                    return false;
+                                }
+                                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                                if ($length) {
+                                    $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
+                                }
+
+                                $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
+                                $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
+
+                                $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF;
+
+                                continue 3;
+                            case 'exit-status':
+                                if (strlen($response) < 5) {
+                                    return false;
+                                }
+                                extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5)));
+                                $this->exit_status = $exit_status;
+
+                                // "The client MAY ignore these messages."
+                                // -- http://tools.ietf.org/html/rfc4254#section-6.10
+
+                                continue 3;
+                            default:
+                                // "Some systems may not implement signals, in which case they SHOULD ignore this message."
+                                //  -- http://tools.ietf.org/html/rfc4254#section-6.9
+                                continue 3;
+                        }
+                }
+
+                switch ($this->channel_status[$channel]) {
+                    case NET_SSH2_MSG_CHANNEL_OPEN:
+                        switch ($type) {
+                            case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
+                                if (strlen($response) < 4) {
+                                    return false;
+                                }
+                                extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
+                                $this->server_channels[$channel] = $server_channel;
+                                if (strlen($response) < 4) {
+                                    return false;
+                                }
+                                extract(unpack('Nwindow_size', $this->_string_shift($response, 4)));
+                                if ($window_size < 0) {
+                                    $window_size&= 0x7FFFFFFF;
+                                    $window_size+= 0x80000000;
+                                }
+                                $this->window_size_client_to_server[$channel] = $window_size;
+                                if (strlen($response) < 4) {
+                                     return false;
+                                }
+                                $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
+                                $this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
+                                $result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+                                $this->_on_channel_open();
+                                return $result;
+                            case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
+                                user_error('Unable to open channel');
+                                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                            default:
+                                if ($client_channel == $channel) {
+                                    user_error('Unexpected response to open request');
+                                    return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                                }
+                                return $this->_get_channel_packet($client_channel, $skip_extended);
+                        }
+                        break;
+                    case NET_SSH2_MSG_CHANNEL_REQUEST:
+                        switch ($type) {
+                            case NET_SSH2_MSG_CHANNEL_SUCCESS:
+                                return true;
+                            case NET_SSH2_MSG_CHANNEL_FAILURE:
+                                return false;
+                            case NET_SSH2_MSG_CHANNEL_DATA:
+                                if (strlen($response) < 4) {
+                                    return false;
+                                }
+                                extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                                $data = $this->_string_shift($response, $length);
+                                $this->channel_buffers[$channel][] = chr($type) . $data;
+                                return $this->_get_channel_packet($client_channel, $skip_extended);
+                            default:
+                                user_error('Unable to fulfill channel request');
+                                return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+                        }
+                    case NET_SSH2_MSG_CHANNEL_CLOSE:
+                        return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+                }
+            }
+
+            // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA
+
+            switch ($type) {
+                case NET_SSH2_MSG_CHANNEL_DATA:
+                    /*
+                    if ($channel == self::CHANNEL_EXEC) {
+                        // SCP requires null packets, such as this, be sent.  further, in the case of the ssh.com SSH server
+                        // this actually seems to make things twice as fast.  more to the point, the message right after
+                        // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise.
+                        // in OpenSSH it slows things down but only by a couple thousandths of a second.
+                        $this->_send_channel_packet($channel, chr(0));
+                    }
+                    */
+                    if (strlen($response) < 4) {
+                        return false;
+                    }
+                    extract(unpack('Nlength', $this->_string_shift($response, 4)));
+                    $data = $this->_string_shift($response, $length);
+
+                    if ($channel == self::CHANNEL_AGENT_FORWARD) {
+                        $agent_response = $this->agent->_forward_data($data);
+                        if (!is_bool($agent_response)) {
+                            $this->_send_channel_packet($channel, $agent_response);
+                        }
+                        break;
+                    }
+
+                    if ($client_channel == $channel) {
+                        return $data;
+                    }
+                    $this->channel_buffers[$channel][] = chr($type) . $data;
+                    break;
+                case NET_SSH2_MSG_CHANNEL_CLOSE:
+                    $this->curTimeout = 5;
+
+                    if ($this->bitmap & self::MASK_SHELL) {
+                        $this->bitmap&= ~self::MASK_SHELL;
+                    }
+                    if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) {
+                        $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
+                    }
+
+                    $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
+                    if ($client_channel == $channel) {
+                        return true;
+                    }
+                case NET_SSH2_MSG_CHANNEL_EOF:
+                    break;
+                default:
+                    user_error("Error reading channel data ($type)");
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+            }
+        }
+    }
+
+    /**
+     * Sends Binary Packets
+     *
+     * See '6. Binary Packet Protocol' of rfc4253 for more info.
+     *
+     * @param string $data
+     * @param string $logged
+     * @see self::_get_binary_packet()
+     * @return bool
+     * @access private
+     */
+    function _send_binary_packet($data, $logged = null)
+    {
+        if (!is_resource($this->fsock) || feof($this->fsock)) {
+            $this->bitmap = 0;
+            user_error('Connection closed prematurely');
+            return false;
+        }
+
+        if (!isset($logged)) {
+            $logged = $data;
+        }
+
+        switch ($this->compress) {
+            case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH:
+                if (!$this->isAuthenticated()) {
+                    break;
+                }
+            case self::NET_SSH2_COMPRESSION_ZLIB:
+                if (!$this->regenerate_compression_context) {
+                    $header = '';
+                } else {
+                    $this->regenerate_compression_context = false;
+                    $this->compress_context = deflate_init(ZLIB_ENCODING_RAW, array('window' => 15));
+                    $header = "\x78\x9C";
+                }
+                if ($this->compress_context) {
+                    $data = $header . deflate_add($this->compress_context, $data, ZLIB_PARTIAL_FLUSH);
+                }
+        }
+
+        // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9
+        $packet_length = strlen($data) + 9;
+        // round up to the nearest $this->encrypt_block_size
+        $packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size;
+        // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length
+        $padding_length = $packet_length - strlen($data) - 5;
+        $padding = Random::string($padding_length);
+
+        // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself
+        $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);
+
+        $hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : '';
+        $this->send_seq_no++;
+
+        if ($this->encrypt !== false) {
+            $packet = $this->encrypt->encrypt($packet);
+        }
+
+        $packet.= $hmac;
+
+        $start = microtime(true);
+        $result = strlen($packet) == @fputs($this->fsock, $packet);
+        $stop = microtime(true);
+
+        if (defined('NET_SSH2_LOGGING')) {
+            $current = microtime(true);
+            $message_number = isset($this->message_numbers[ord($logged[0])]) ? $this->message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')';
+            $message_number = '-> ' . $message_number .
+                              ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
+            $this->_append_log($message_number, $logged);
+            $this->last_packet = $current;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Logs data packets
+     *
+     * Makes sure that only the last 1MB worth of packets will be logged
+     *
+     * @param string $message_number
+     * @param string $message
+     * @access private
+     */
+    function _append_log($message_number, $message)
+    {
+        // remove the byte identifying the message type from all but the first two messages (ie. the identification strings)
+        if (strlen($message_number) > 2) {
+            $this->_string_shift($message);
+        }
+
+        switch (NET_SSH2_LOGGING) {
+            // useful for benchmarks
+            case self::LOG_SIMPLE:
+                $this->message_number_log[] = $message_number;
+                break;
+            // the most useful log for SSH2
+            case self::LOG_COMPLEX:
+                $this->message_number_log[] = $message_number;
+                $this->log_size+= strlen($message);
+                $this->message_log[] = $message;
+                while ($this->log_size > self::LOG_MAX_SIZE) {
+                    $this->log_size-= strlen(array_shift($this->message_log));
+                    array_shift($this->message_number_log);
+                }
+                break;
+            // dump the output out realtime; packets may be interspersed with non packets,
+            // passwords won't be filtered out and select other packets may not be correctly
+            // identified
+            case self::LOG_REALTIME:
+                switch (PHP_SAPI) {
+                    case 'cli':
+                        $start = $stop = "\r\n";
+                        break;
+                    default:
+                        $start = '<pre>';
+                        $stop = '</pre>';
+                }
+                echo $start . $this->_format_log(array($message), array($message_number)) . $stop;
+                @flush();
+                @ob_flush();
+                break;
+            // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
+            // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
+            // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
+            // at the beginning of the file
+            case self::LOG_REALTIME_FILE:
+                if (!isset($this->realtime_log_file)) {
+                    // PHP doesn't seem to like using constants in fopen()
+                    $filename = self::LOG_REALTIME_FILENAME;
+                    $fp = fopen($filename, 'w');
+                    $this->realtime_log_file = $fp;
+                }
+                if (!is_resource($this->realtime_log_file)) {
+                    break;
+                }
+                $entry = $this->_format_log(array($message), array($message_number));
+                if ($this->realtime_log_wrap) {
+                    $temp = "<<< START >>>\r\n";
+                    $entry.= $temp;
+                    fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp));
+                }
+                $this->realtime_log_size+= strlen($entry);
+                if ($this->realtime_log_size > self::LOG_MAX_SIZE) {
+                    fseek($this->realtime_log_file, 0);
+                    $this->realtime_log_size = strlen($entry);
+                    $this->realtime_log_wrap = true;
+                }
+                fputs($this->realtime_log_file, $entry);
+        }
+    }
+
+    /**
+     * Sends channel data
+     *
+     * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate
+     *
+     * @param int $client_channel
+     * @param string $data
+     * @return bool
+     * @access private
+     */
+    function _send_channel_packet($client_channel, $data)
+    {
+        while (strlen($data)) {
+            if (!$this->window_size_client_to_server[$client_channel]) {
+                $this->bitmap^= self::MASK_WINDOW_ADJUST;
+                // using an invalid channel will let the buffers be built up for the valid channels
+                $this->_get_channel_packet(-1);
+                $this->bitmap^= self::MASK_WINDOW_ADJUST;
+            }
+
+            /* The maximum amount of data allowed is determined by the maximum
+               packet size for the channel, and the current window size, whichever
+               is smaller.
+                 -- http://tools.ietf.org/html/rfc4254#section-5.2 */
+            $max_size = min(
+                $this->packet_size_client_to_server[$client_channel],
+                $this->window_size_client_to_server[$client_channel]
+            );
+
+            $temp = $this->_string_shift($data, $max_size);
+            $packet = pack(
+                'CN2a*',
+                NET_SSH2_MSG_CHANNEL_DATA,
+                $this->server_channels[$client_channel],
+                strlen($temp),
+                $temp
+            );
+            $this->window_size_client_to_server[$client_channel]-= strlen($temp);
+            if (!$this->_send_binary_packet($packet)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Closes and flushes a channel
+     *
+     * \phpseclib\Net\SSH2 doesn't properly close most channels.  For exec() channels are normally closed by the server
+     * and for SFTP channels are presumably closed when the client disconnects.  This functions is intended
+     * for SCP more than anything.
+     *
+     * @param int $client_channel
+     * @param bool $want_reply
+     * @return bool
+     * @access private
+     */
+    function _close_channel($client_channel, $want_reply = false)
+    {
+        // see http://tools.ietf.org/html/rfc4254#section-5.3
+
+        $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
+
+        if (!$want_reply) {
+            $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
+        }
+
+        $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
+
+        $this->curTimeout = 5;
+
+        while (!is_bool($this->_get_channel_packet($client_channel))) {
+        }
+
+        if ($this->is_timeout) {
+            $this->disconnect();
+        }
+
+        if ($want_reply) {
+            $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
+        }
+
+        if ($this->bitmap & self::MASK_SHELL) {
+            $this->bitmap&= ~self::MASK_SHELL;
+        }
+    }
+
+    /**
+     * Disconnect
+     *
+     * @param int $reason
+     * @return bool
+     * @access private
+     */
+    function _disconnect($reason)
+    {
+        if ($this->bitmap & self::MASK_CONNECTED) {
+            $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
+            $this->_send_binary_packet($data);
+        }
+
+        $this->bitmap = 0;
+        if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') {
+            fclose($this->fsock);
+        }
+
+        return false;
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @return string
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+
+    /**
+     * Define Array
+     *
+     * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of
+     * named constants from it, using the value as the name of the constant and the index as the value of the constant.
+     * If any of the constants that would be defined already exists, none of the constants will be defined.
+     *
+     * @access private
+     */
+    function _define_array()
+    {
+        $args = func_get_args();
+        foreach ($args as $arg) {
+            foreach ($arg as $key => $value) {
+                if (!defined($value)) {
+                    define($value, $key);
+                } else {
+                    break 2;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns a log of the packets that have been sent and received.
+     *
+     * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING')
+     *
+     * @access public
+     * @return array|false|string
+     */
+    function getLog()
+    {
+        if (!defined('NET_SSH2_LOGGING')) {
+            return false;
+        }
+
+        switch (NET_SSH2_LOGGING) {
+            case self::LOG_SIMPLE:
+                return $this->message_number_log;
+            case self::LOG_COMPLEX:
+                $log = $this->_format_log($this->message_log, $this->message_number_log);
+                return PHP_SAPI == 'cli' ? $log : '<pre>' . $log . '</pre>';
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Formats a log for printing
+     *
+     * @param array $message_log
+     * @param array $message_number_log
+     * @access private
+     * @return string
+     */
+    function _format_log($message_log, $message_number_log)
+    {
+        $output = '';
+        for ($i = 0; $i < count($message_log); $i++) {
+            $output.= $message_number_log[$i] . "\r\n";
+            $current_log = $message_log[$i];
+            $j = 0;
+            do {
+                if (strlen($current_log)) {
+                    $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0  ';
+                }
+                $fragment = $this->_string_shift($current_log, $this->log_short_width);
+                $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary));
+                // replace non ASCII printable characters with dots
+                // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
+                // also replace < with a . since < messes up the output on web browsers
+                $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
+                $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n";
+                $j++;
+            } while (strlen($current_log));
+            $output.= "\r\n";
+        }
+
+        return $output;
+    }
+
+    /**
+     * Helper function for _format_log
+     *
+     * For use with preg_replace_callback()
+     *
+     * @param array $matches
+     * @access private
+     * @return string
+     */
+    function _format_log_helper($matches)
+    {
+        return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
+    }
+
+    /**
+     * Helper function for agent->_on_channel_open()
+     *
+     * Used when channels are created to inform agent
+     * of said channel opening. Must be called after
+     * channel open confirmation received
+     *
+     * @access private
+     */
+    function _on_channel_open()
+    {
+        if (isset($this->agent)) {
+            $this->agent->_on_channel_open($this);
+        }
+    }
+
+    /**
+     * Returns the first value of the intersection of two arrays or false if
+     * the intersection is empty. The order is defined by the first parameter.
+     *
+     * @param array $array1
+     * @param array $array2
+     * @return mixed False if intersection is empty, else intersected value.
+     * @access private
+     */
+    function _array_intersect_first($array1, $array2)
+    {
+        foreach ($array1 as $value) {
+            if (in_array($value, $array2)) {
+                return $value;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns all errors
+     *
+     * @return string[]
+     * @access public
+     */
+    function getErrors()
+    {
+        return $this->errors;
+    }
+
+    /**
+     * Returns the last error
+     *
+     * @return string
+     * @access public
+     */
+    function getLastError()
+    {
+        $count = count($this->errors);
+
+        if ($count > 0) {
+            return $this->errors[$count - 1];
+        }
+    }
+
+    /**
+     * Return the server identification.
+     *
+     * @return string
+     * @access public
+     */
+    function getServerIdentification()
+    {
+        $this->_connect();
+
+        return $this->server_identifier;
+    }
+
+    /**
+     * Return a list of the key exchange algorithms the server supports.
+     *
+     * @return array
+     * @access public
+     */
+    function getKexAlgorithms()
+    {
+        $this->_connect();
+
+        return $this->kex_algorithms;
+    }
+
+    /**
+     * Return a list of the host key (public key) algorithms the server supports.
+     *
+     * @return array
+     * @access public
+     */
+    function getServerHostKeyAlgorithms()
+    {
+        $this->_connect();
+
+        return $this->server_host_key_algorithms;
+    }
+
+    /**
+     * Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getEncryptionAlgorithmsClient2Server()
+    {
+        $this->_connect();
+
+        return $this->encryption_algorithms_client_to_server;
+    }
+
+    /**
+     * Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getEncryptionAlgorithmsServer2Client()
+    {
+        $this->_connect();
+
+        return $this->encryption_algorithms_server_to_client;
+    }
+
+    /**
+     * Return a list of the MAC algorithms the server supports, when receiving stuff from the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getMACAlgorithmsClient2Server()
+    {
+        $this->_connect();
+
+        return $this->mac_algorithms_client_to_server;
+    }
+
+    /**
+     * Return a list of the MAC algorithms the server supports, when sending stuff to the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getMACAlgorithmsServer2Client()
+    {
+        $this->_connect();
+
+        return $this->mac_algorithms_server_to_client;
+    }
+
+    /**
+     * Return a list of the compression algorithms the server supports, when receiving stuff from the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getCompressionAlgorithmsClient2Server()
+    {
+        $this->_connect();
+
+        return $this->compression_algorithms_client_to_server;
+    }
+
+    /**
+     * Return a list of the compression algorithms the server supports, when sending stuff to the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getCompressionAlgorithmsServer2Client()
+    {
+        $this->_connect();
+
+        return $this->compression_algorithms_server_to_client;
+    }
+
+    /**
+     * Return a list of the languages the server supports, when sending stuff to the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getLanguagesServer2Client()
+    {
+        $this->_connect();
+
+        return $this->languages_server_to_client;
+    }
+
+    /**
+     * Return a list of the languages the server supports, when receiving stuff from the client.
+     *
+     * @return array
+     * @access public
+     */
+    function getLanguagesClient2Server()
+    {
+        $this->_connect();
+
+        return $this->languages_client_to_server;
+    }
+
+    /**
+     * Returns a list of algorithms the server supports
+     *
+     * @return array
+     * @access public
+     */
+    function getServerAlgorithms()
+    {
+        $this->_connect();
+
+        return array(
+            'kex' => $this->kex_algorithms,
+            'hostkey' => $this->server_host_key_algorithms,
+            'client_to_server' => array(
+                'crypt' => $this->encryption_algorithms_client_to_server,
+                'mac' => $this->mac_algorithms_client_to_server,
+                'comp' => $this->compression_algorithms_client_to_server,
+                'lang' => $this->languages_client_to_server
+            ),
+            'server_to_client' => array(
+                'crypt' => $this->encryption_algorithms_server_to_client,
+                'mac' => $this->mac_algorithms_server_to_client,
+                'comp' => $this->compression_algorithms_server_to_client,
+                'lang' => $this->languages_server_to_client
+            )
+        );
+    }
+
+    /**
+     * Returns a list of KEX algorithms that phpseclib supports
+     *
+     * @return array
+     * @access public
+     */
+    function getSupportedKEXAlgorithms()
+    {
+        $kex_algorithms = array(
+            // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using
+            // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the
+            // libssh repository for more information.
+            'curve25519-sha256@libssh.org',
+
+            'diffie-hellman-group-exchange-sha256',// RFC 4419
+            'diffie-hellman-group-exchange-sha1',  // RFC 4419
+
+            // Diffie-Hellman Key Agreement (DH) using integer modulo prime
+            // groups.
+            'diffie-hellman-group14-sha1', // REQUIRED
+            'diffie-hellman-group1-sha1', // REQUIRED
+        );
+
+        if (!function_exists('sodium_crypto_box_publickey_from_secretkey')) {
+            $kex_algorithms = array_diff(
+                $kex_algorithms,
+                array('curve25519-sha256@libssh.org')
+            );
+        }
+
+        return $kex_algorithms;
+    }
+
+    /**
+     * Returns a list of host key algorithms that phpseclib supports
+     *
+     * @return array
+     * @access public
+     */
+    function getSupportedHostKeyAlgorithms()
+    {
+        return array(
+            'rsa-sha2-256', // RFC 8332
+            'rsa-sha2-512', // RFC 8332
+            'ssh-rsa', // RECOMMENDED  sign   Raw RSA Key
+            'ssh-dss'  // REQUIRED     sign   Raw DSS Key
+        );
+    }
+
+    /**
+     * Returns a list of symmetric key algorithms that phpseclib supports
+     *
+     * @return array
+     * @access public
+     */
+    function getSupportedEncryptionAlgorithms()
+    {
+        $algos = array(
+            // from <http://tools.ietf.org/html/rfc4345#section-4>:
+            'arcfour256',
+            'arcfour128',
+
+            //'arcfour',      // OPTIONAL          the ARCFOUR stream cipher with a 128-bit key
+
+            // CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
+            'aes128-ctr',     // RECOMMENDED       AES (Rijndael) in SDCTR mode, with 128-bit key
+            'aes192-ctr',     // RECOMMENDED       AES with 192-bit key
+            'aes256-ctr',     // RECOMMENDED       AES with 256-bit key
+
+            'twofish128-ctr', // OPTIONAL          Twofish in SDCTR mode, with 128-bit key
+            'twofish192-ctr', // OPTIONAL          Twofish with 192-bit key
+            'twofish256-ctr', // OPTIONAL          Twofish with 256-bit key
+
+            'aes128-cbc',     // RECOMMENDED       AES with a 128-bit key
+            'aes192-cbc',     // OPTIONAL          AES with a 192-bit key
+            'aes256-cbc',     // OPTIONAL          AES in CBC mode, with a 256-bit key
+
+            'twofish128-cbc', // OPTIONAL          Twofish with a 128-bit key
+            'twofish192-cbc', // OPTIONAL          Twofish with a 192-bit key
+            'twofish256-cbc',
+            'twofish-cbc',    // OPTIONAL          alias for "twofish256-cbc"
+                              //                   (this is being retained for historical reasons)
+
+            'blowfish-ctr',   // OPTIONAL          Blowfish in SDCTR mode
+
+            'blowfish-cbc',   // OPTIONAL          Blowfish in CBC mode
+
+            '3des-ctr',       // RECOMMENDED       Three-key 3DES in SDCTR mode
+
+            '3des-cbc',       // REQUIRED          three-key 3DES in CBC mode
+
+             //'none'           // OPTIONAL          no encryption; NOT RECOMMENDED
+        );
+
+        if ($this->crypto_engine) {
+            $engines = array($this->crypto_engine);
+        } else {
+            $engines = array(
+                Base::ENGINE_OPENSSL,
+                Base::ENGINE_MCRYPT,
+                Base::ENGINE_INTERNAL
+            );
+        }
+
+        $ciphers = array();
+        foreach ($engines as $engine) {
+            foreach ($algos as $algo) {
+                $obj = $this->_encryption_algorithm_to_crypt_instance($algo);
+                if ($obj instanceof Rijndael) {
+                    $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo));
+                }
+                switch ($algo) {
+                    case 'arcfour128':
+                    case 'arcfour256':
+                        if ($engine != Base::ENGINE_INTERNAL) {
+                            continue 2;
+                        }
+                }
+                if ($obj->isValidEngine($engine)) {
+                    $algos = array_diff($algos, array($algo));
+                    $ciphers[] = $algo;
+                }
+            }
+        }
+
+        return $ciphers;
+    }
+
+    /**
+     * Returns a list of MAC algorithms that phpseclib supports
+     *
+     * @return array
+     * @access public
+     */
+    function getSupportedMACAlgorithms()
+    {
+        return array(
+            // from <http://www.ietf.org/rfc/rfc6668.txt>:
+            'hmac-sha2-256',// RECOMMENDED     HMAC-SHA256 (digest length = key length = 32)
+
+            'hmac-sha1-96', // RECOMMENDED     first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
+            'hmac-sha1',    // REQUIRED        HMAC-SHA1 (digest length = key length = 20)
+            'hmac-md5-96',  // OPTIONAL        first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
+            'hmac-md5',     // OPTIONAL        HMAC-MD5 (digest length = key length = 16)
+            //'none'          // OPTIONAL        no MAC; NOT RECOMMENDED
+        );
+    }
+
+    /**
+     * Returns a list of compression algorithms that phpseclib supports
+     *
+     * @return array
+     * @access public
+     */
+    function getSupportedCompressionAlgorithms()
+    {
+        $algos = array('none'); // REQUIRED        no compression
+        if (function_exists('deflate_init')) {
+            $algos[] = 'zlib@openssh.com'; // https://datatracker.ietf.org/doc/html/draft-miller-secsh-compression-delayed
+            $algos[] = 'zlib';
+        }
+        return $algos;
+    }
+
+    /**
+     * Return list of negotiated algorithms
+     *
+     * Uses the same format as https://www.php.net/ssh2-methods-negotiated
+     *
+     * @return array
+     * @access public
+     */
+    function getAlgorithmsNegotiated()
+    {
+        $this->_connect();
+
+        $compression_map = array(
+            self::NET_SSH2_COMPRESSION_NONE => 'none',
+            self::NET_SSH2_COMPRESSION_ZLIB => 'zlib',
+            self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com'
+        );
+
+        return array(
+            'kex' => $this->kex_algorithm,
+            'hostkey' => $this->signature_format,
+            'client_to_server' => array(
+                'crypt' => $this->encrypt->name,
+                'mac' => $this->hmac_create->name,
+                'comp' => $compression_map[$this->compress],
+            ),
+            'server_to_client' => array(
+                'crypt' => $this->decrypt->name,
+                'mac' => $this->hmac_check->name,
+                'comp' => $compression_map[$this->decompress],
+            )
+        );
+    }
+
+    /**
+     * Accepts an associative array with up to four parameters as described at
+     * <https://www.php.net/manual/en/function.ssh2-connect.php>
+     *
+     * @param array $methods
+     * @access public
+     */
+    function setPreferredAlgorithms($methods)
+    {
+        $preferred = $methods;
+
+        if (isset($preferred['kex'])) {
+            $preferred['kex'] = array_intersect(
+                $preferred['kex'],
+                $this->getSupportedKEXAlgorithms()
+            );
+        }
+
+        if (isset($preferred['hostkey'])) {
+            $preferred['hostkey'] = array_intersect(
+                $preferred['hostkey'],
+                $this->getSupportedHostKeyAlgorithms()
+            );
+        }
+
+        $keys = array('client_to_server', 'server_to_client');
+        foreach ($keys as $key) {
+            if (isset($preferred[$key])) {
+                $a = &$preferred[$key];
+                if (isset($a['crypt'])) {
+                    $a['crypt'] = array_intersect(
+                        $a['crypt'],
+                        $this->getSupportedEncryptionAlgorithms()
+                    );
+                }
+                if (isset($a['comp'])) {
+                    $a['comp'] = array_intersect(
+                        $a['comp'],
+                        $this->getSupportedCompressionAlgorithms()
+                    );
+                }
+                if (isset($a['mac'])) {
+                    $a['mac'] = array_intersect(
+                        $a['mac'],
+                        $this->getSupportedMACAlgorithms()
+                    );
+                }
+            }
+        }
+
+        $keys = array(
+            'kex',
+            'hostkey',
+            'client_to_server/crypt',
+            'client_to_server/comp',
+            'client_to_server/mac',
+            'server_to_client/crypt',
+            'server_to_client/comp',
+            'server_to_client/mac',
+        );
+        foreach ($keys as $key) {
+            $p = $preferred;
+            $m = $methods;
+
+            $subkeys = explode('/', $key);
+            foreach ($subkeys as $subkey) {
+                if (!isset($p[$subkey])) {
+                    continue 2;
+                }
+                $p = $p[$subkey];
+                $m = $m[$subkey];
+            }
+
+            if (count($p) != count($m)) {
+                $diff = array_diff($m, $p);
+                $msg = count($diff) == 1 ?
+                    ' is not a supported algorithm' :
+                    ' are not supported algorithms';
+                user_error(implode(', ', $diff) . $msg);
+                return false;
+            }
+        }
+
+        $this->preferred = $preferred;
+    }
+
+    /**
+     * Returns the banner message.
+     *
+     * Quoting from the RFC, "in some jurisdictions, sending a warning message before
+     * authentication may be relevant for getting legal protection."
+     *
+     * @return string
+     * @access public
+     */
+    function getBannerMessage()
+    {
+        return $this->banner_message;
+    }
+
+    /**
+     * Returns the server public host key.
+     *
+     * Caching this the first time you connect to a server and checking the result on subsequent connections
+     * is recommended.  Returns false if the server signature is not signed correctly with the public host key.
+     *
+     * @return mixed
+     * @access public
+     */
+    function getServerPublicHostKey()
+    {
+        if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
+            if (!$this->_connect()) {
+                return false;
+            }
+        }
+
+        $signature = $this->signature;
+        $server_public_host_key = $this->server_public_host_key;
+
+        if (strlen($server_public_host_key) < 4) {
+            return false;
+        }
+        extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4)));
+        $this->_string_shift($server_public_host_key, $length);
+
+        if ($this->signature_validated) {
+            return $this->bitmap ?
+                $this->signature_format . ' ' . base64_encode($this->server_public_host_key) :
+                false;
+        }
+
+        $this->signature_validated = true;
+
+        switch ($this->signature_format) {
+            case 'ssh-dss':
+                $zero = new BigInteger();
+
+                if (strlen($server_public_host_key) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+                $p = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+                if (strlen($server_public_host_key) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+                $q = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+                if (strlen($server_public_host_key) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+                $g = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+                if (strlen($server_public_host_key) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+                $y = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+                /* The value for 'dss_signature_blob' is encoded as a string containing
+                   r, followed by s (which are 160-bit integers, without lengths or
+                   padding, unsigned, and in network byte order). */
+                $temp = unpack('Nlength', $this->_string_shift($signature, 4));
+                if ($temp['length'] != 40) {
+                    user_error('Invalid signature');
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+                }
+
+                $r = new BigInteger($this->_string_shift($signature, 20), 256);
+                $s = new BigInteger($this->_string_shift($signature, 20), 256);
+
+                switch (true) {
+                    case $r->equals($zero):
+                    case $r->compare($q) >= 0:
+                    case $s->equals($zero):
+                    case $s->compare($q) >= 0:
+                        user_error('Invalid signature');
+                        return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+                }
+
+                $w = $s->modInverse($q);
+
+                $u1 = $w->multiply(new BigInteger(sha1($this->exchange_hash), 16));
+                list(, $u1) = $u1->divide($q);
+
+                $u2 = $w->multiply($r);
+                list(, $u2) = $u2->divide($q);
+
+                $g = $g->modPow($u1, $p);
+                $y = $y->modPow($u2, $p);
+
+                $v = $g->multiply($y);
+                list(, $v) = $v->divide($p);
+                list(, $v) = $v->divide($q);
+
+                if (!$v->equals($r)) {
+                    user_error('Bad server signature');
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+                }
+
+                break;
+            case 'ssh-rsa':
+            case 'rsa-sha2-256':
+            case 'rsa-sha2-512':
+                if (strlen($server_public_host_key) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+                $e = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+                if (strlen($server_public_host_key) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+                $rawN = $this->_string_shift($server_public_host_key, $temp['length']);
+                $n = new BigInteger($rawN, -256);
+                $nLength = strlen(ltrim($rawN, "\0"));
+
+                /*
+                if (strlen($signature) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($signature, 4));
+                $signature = $this->_string_shift($signature, $temp['length']);
+
+                $rsa = new RSA();
+                switch ($this->signature_format) {
+                    case 'rsa-sha2-512':
+                        $hash = 'sha512';
+                        break;
+                    case 'rsa-sha2-256':
+                        $hash = 'sha256';
+                        break;
+                    //case 'ssh-rsa':
+                    default:
+                        $hash = 'sha1';
+                }
+                $rsa->setHash($hash);
+                $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
+                $rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW);
+
+                if (!$rsa->verify($this->exchange_hash, $signature)) {
+                    user_error('Bad server signature');
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+                }
+                */
+
+                if (strlen($signature) < 4) {
+                    return false;
+                }
+                $temp = unpack('Nlength', $this->_string_shift($signature, 4));
+                $s = new BigInteger($this->_string_shift($signature, $temp['length']), 256);
+
+                // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the
+                // following URL:
+                // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
+
+                // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
+
+                if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
+                    user_error('Invalid signature');
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+                }
+
+                $s = $s->modPow($e, $n);
+                $s = $s->toBytes();
+
+                switch ($this->signature_format) {
+                    case 'rsa-sha2-512':
+                        $hash = 'sha512';
+                        break;
+                    case 'rsa-sha2-256':
+                        $hash = 'sha256';
+                        break;
+                    //case 'ssh-rsa':
+                    default:
+                        $hash = 'sha1';
+                }
+                $hashObj = new Hash($hash);
+                switch ($this->signature_format) {
+                    case 'rsa-sha2-512':
+                        $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash));
+                        break;
+                    case 'rsa-sha2-256':
+                        $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash));
+                        break;
+                    //case 'ssh-rsa':
+                    default:
+                        $hash = 'sha1';
+                        $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash));
+                }
+                $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
+
+                if ($s != $h) {
+                    user_error('Bad server signature');
+                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+                }
+                break;
+            default:
+                user_error('Unsupported signature format');
+                return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+        }
+
+        return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
+    }
+
+    /**
+     * Returns the exit status of an SSH command or false.
+     *
+     * @return false|int
+     * @access public
+     */
+    function getExitStatus()
+    {
+        if (is_null($this->exit_status)) {
+            return false;
+        }
+        return $this->exit_status;
+    }
+
+    /**
+     * Returns the number of columns for the terminal window size.
+     *
+     * @return int
+     * @access public
+     */
+    function getWindowColumns()
+    {
+        return $this->windowColumns;
+    }
+
+    /**
+     * Returns the number of rows for the terminal window size.
+     *
+     * @return int
+     * @access public
+     */
+    function getWindowRows()
+    {
+        return $this->windowRows;
+    }
+
+    /**
+     * Sets the number of columns for the terminal window size.
+     *
+     * @param int $value
+     * @access public
+     */
+    function setWindowColumns($value)
+    {
+        $this->windowColumns = $value;
+    }
+
+    /**
+     * Sets the number of rows for the terminal window size.
+     *
+     * @param int $value
+     * @access public
+     */
+    function setWindowRows($value)
+    {
+        $this->windowRows = $value;
+    }
+
+    /**
+     * Sets the number of columns and rows for the terminal window size.
+     *
+     * @param int $columns
+     * @param int $rows
+     * @access public
+     */
+    function setWindowSize($columns = 80, $rows = 24)
+    {
+        $this->windowColumns = $columns;
+        $this->windowRows = $rows;
+    }
+
+    /**
+     * Update packet types in log history
+     *
+     * @param string $old
+     * @param string $new
+     * @access private
+     */
+    function _updateLogHistory($old, $new)
+    {
+        if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) {
+            $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
+                $old,
+                $new,
+                $this->message_number_log[count($this->message_number_log) - 1]
+            );
+        }
+    }
+
+    /**
+     * Return the list of authentication methods that may productively continue authentication.
+     *
+     * @see https://tools.ietf.org/html/rfc4252#section-5.1
+     * @return array|null
+     */
+    function getAuthMethodsToContinue()
+    {
+        return $this->auth_methods_to_continue;
+    }
+
+    /**
+     * Enables "smart" multi-factor authentication (MFA)
+     */
+    function enableSmartMFA()
+    {
+        $this->smartMFA = true;
+    }
+
+    /**
+     * Disables "smart" multi-factor authentication (MFA)
+     */
+    function disableSmartMFA()
+    {
+        $this->smartMFA = false;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/msd/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
new file mode 100644
index 00000000..ec1d9773
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
@@ -0,0 +1,361 @@
+<?php
+
+/**
+ * Pure-PHP ssh-agent client.
+ *
+ * PHP version 5
+ *
+ * Here are some examples of how to use this library:
+ * <code>
+ * <?php
+ *    include 'vendor/autoload.php';
+ *
+ *    $agent = new \phpseclib\System\SSH\Agent();
+ *
+ *    $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ *    if (!$ssh->login('username', $agent)) {
+ *        exit('Login Failed');
+ *    }
+ *
+ *    echo $ssh->exec('pwd');
+ *    echo $ssh->exec('ls -la');
+ * ?>
+ * </code>
+ *
+ * @category  System
+ * @package   SSH\Agent
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2014 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ * @internal  See http://api.libssh.org/rfc/PROTOCOL.agent
+ */
+
+namespace phpseclib\System\SSH;
+
+use phpseclib\Crypt\RSA;
+use phpseclib\System\SSH\Agent\Identity;
+
+/**
+ * Pure-PHP ssh-agent client identity factory
+ *
+ * requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects
+ *
+ * @package SSH\Agent
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  public
+ */
+class Agent
+{
+    /**#@+
+     * Message numbers
+     *
+     * @access private
+     */
+    // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
+    const SSH_AGENTC_REQUEST_IDENTITIES = 11;
+    // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
+    const SSH_AGENT_IDENTITIES_ANSWER = 12;
+    // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
+    const SSH_AGENTC_SIGN_REQUEST = 13;
+    // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
+    const SSH_AGENT_SIGN_RESPONSE = 14;
+    /**#@-*/
+
+    /**@+
+     * Agent forwarding status
+     *
+     * @access private
+     */
+    // no forwarding requested and not active
+    const FORWARD_NONE = 0;
+    // request agent forwarding when opportune
+    const FORWARD_REQUEST = 1;
+    // forwarding has been request and is active
+    const FORWARD_ACTIVE = 2;
+    /**#@-*/
+
+    /**
+     * Unused
+     */
+    const SSH_AGENT_FAILURE = 5;
+
+    /**
+     * Socket Resource
+     *
+     * @var resource
+     * @access private
+     */
+    var $fsock;
+
+    /**
+     * Agent forwarding status
+     *
+     * @access private
+     */
+    var $forward_status = self::FORWARD_NONE;
+
+    /**
+     * Buffer for accumulating forwarded authentication
+     * agent data arriving on SSH data channel destined
+     * for agent unix socket
+     *
+     * @access private
+     */
+    var $socket_buffer = '';
+
+    /**
+     * Tracking the number of bytes we are expecting
+     * to arrive for the agent socket on the SSH data
+     * channel
+     */
+    var $expected_bytes = 0;
+
+    /**
+     * Default Constructor
+     *
+     * @return \phpseclib\System\SSH\Agent
+     * @access public
+     */
+    function __construct($address = null)
+    {
+        if (!$address) {
+            switch (true) {
+                case isset($_SERVER['SSH_AUTH_SOCK']):
+                    $address = $_SERVER['SSH_AUTH_SOCK'];
+                    break;
+                case isset($_ENV['SSH_AUTH_SOCK']):
+                    $address = $_ENV['SSH_AUTH_SOCK'];
+                    break;
+                default:
+                    user_error('SSH_AUTH_SOCK not found');
+                    return false;
+            }
+        }
+
+        if (in_array('unix', stream_get_transports())) {
+            $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
+            if (!$this->fsock) {
+                user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
+            }
+        } else {
+            if (substr($address, 0, 9) != '\\\\.\\pipe\\' || strpos(substr($address, 9), '\\') !== false) {
+                user_error('Address is not formatted as a named pipe should be');
+            } else {
+                $this->fsock = fopen($address, 'r+b');
+                if (!$this->fsock) {
+                    user_error('Unable to open address');
+                }
+            }
+        }
+    }
+
+    /**
+     * Request Identities
+     *
+     * See "2.5.2 Requesting a list of protocol 2 keys"
+     * Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
+     *
+     * @return array
+     * @access public
+     */
+    function requestIdentities()
+    {
+        if (!$this->fsock) {
+            return array();
+        }
+
+        $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
+        if (strlen($packet) != fputs($this->fsock, $packet)) {
+            user_error('Connection closed while requesting identities');
+            return array();
+        }
+
+        $temp = fread($this->fsock, 4);
+        if (strlen($temp) != 4) {
+            user_error('Connection closed while requesting identities');
+            return array();
+        }
+        $length = current(unpack('N', $temp));
+        $type = ord(fread($this->fsock, 1));
+        if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
+            user_error('Unable to request identities');
+            return array();
+        }
+
+        $identities = array();
+        $temp = fread($this->fsock, 4);
+        if (strlen($temp) != 4) {
+            user_error('Connection closed while requesting identities');
+            return array();
+        }
+        $keyCount = current(unpack('N', $temp));
+        for ($i = 0; $i < $keyCount; $i++) {
+            $temp = fread($this->fsock, 4);
+            if (strlen($temp) != 4) {
+                user_error('Connection closed while requesting identities');
+                return array();
+            }
+            $length = current(unpack('N', $temp));
+            $key_blob = fread($this->fsock, $length);
+            if (strlen($key_blob) != $length) {
+                user_error('Connection closed while requesting identities');
+                return array();
+            }
+            $key_str = 'ssh-rsa ' . base64_encode($key_blob);
+            $temp = fread($this->fsock, 4);
+            if (strlen($temp) != 4) {
+                user_error('Connection closed while requesting identities');
+                return array();
+            }
+            $length = current(unpack('N', $temp));
+            if ($length) {
+                $temp = fread($this->fsock, $length);
+                if (strlen($temp) != $length) {
+                    user_error('Connection closed while requesting identities');
+                    return array();
+                }
+                $key_str.= ' ' . $temp;
+            }
+            $length = current(unpack('N', substr($key_blob, 0, 4)));
+            $key_type = substr($key_blob, 4, $length);
+            switch ($key_type) {
+                case 'ssh-rsa':
+                    $key = new RSA();
+                    $key->loadKey($key_str);
+                    break;
+                case 'ssh-dss':
+                    // not currently supported
+                    break;
+            }
+            // resources are passed by reference by default
+            if (isset($key)) {
+                $identity = new Identity($this->fsock);
+                $identity->setPublicKey($key);
+                $identity->setPublicKeyBlob($key_blob);
+                $identities[] = $identity;
+                unset($key);
+            }
+        }
+
+        return $identities;
+    }
+
+    /**
+     * Signal that agent forwarding should
+     * be requested when a channel is opened
+     *
+     * @return bool
+     * @access public
+     */
+    function startSSHForwarding()
+    {
+        if ($this->forward_status == self::FORWARD_NONE) {
+            $this->forward_status = self::FORWARD_REQUEST;
+        }
+    }
+
+    /**
+     * Request agent forwarding of remote server
+     *
+     * @param Net_SSH2 $ssh
+     * @return bool
+     * @access private
+     */
+    function _request_forwarding($ssh)
+    {
+        $request_channel = $ssh->_get_open_channel();
+        if ($request_channel === false) {
+            return false;
+        }
+
+        $packet = pack(
+            'CNNa*C',
+            NET_SSH2_MSG_CHANNEL_REQUEST,
+            $ssh->server_channels[$request_channel],
+            strlen('auth-agent-req@openssh.com'),
+            'auth-agent-req@openssh.com',
+            1
+        );
+
+        $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+        if (!$ssh->_send_binary_packet($packet)) {
+            return false;
+        }
+
+        $response = $ssh->_get_channel_packet($request_channel);
+        if ($response === false) {
+            return false;
+        }
+
+        $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
+        $this->forward_status = self::FORWARD_ACTIVE;
+
+        return true;
+    }
+
+    /**
+     * On successful channel open
+     *
+     * This method is called upon successful channel
+     * open to give the SSH Agent an opportunity
+     * to take further action. i.e. request agent forwarding
+     *
+     * @param Net_SSH2 $ssh
+     * @access private
+     */
+    function _on_channel_open($ssh)
+    {
+        if ($this->forward_status == self::FORWARD_REQUEST) {
+            $this->_request_forwarding($ssh);
+        }
+    }
+
+    /**
+     * Forward data to SSH Agent and return data reply
+     *
+     * @param string $data
+     * @return data from SSH Agent
+     * @access private
+     */
+    function _forward_data($data)
+    {
+        if ($this->expected_bytes > 0) {
+            $this->socket_buffer.= $data;
+            $this->expected_bytes -= strlen($data);
+        } else {
+            $agent_data_bytes = current(unpack('N', $data));
+            $current_data_bytes = strlen($data);
+            $this->socket_buffer = $data;
+            if ($current_data_bytes != $agent_data_bytes + 4) {
+                $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes;
+                return false;
+            }
+        }
+
+        if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
+            user_error('Connection closed attempting to forward data to SSH agent');
+            return false;
+        }
+
+        $this->socket_buffer = '';
+        $this->expected_bytes = 0;
+
+        $temp = fread($this->fsock, 4);
+        if (strlen($temp) != 4) {
+            user_error('Connection closed while reading data response');
+            return false;
+        }
+        $agent_reply_bytes = current(unpack('N', $temp));
+
+        $agent_reply_data = fread($this->fsock, $agent_reply_bytes);
+        if (strlen($agent_reply_data) != $agent_reply_bytes) {
+            user_error('Connection closed while reading data response');
+            return false;
+        }
+        $agent_reply_data = current(unpack('a*', $agent_reply_data));
+
+        return pack('Na*', $agent_reply_bytes, $agent_reply_data);
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/msd/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
new file mode 100644
index 00000000..68b6bfdf
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * Pure-PHP ssh-agent client.
+ *
+ * PHP version 5
+ *
+ * @category  System
+ * @package   SSH\Agent
+ * @author    Jim Wigginton <terrafrost@php.net>
+ * @copyright 2009 Jim Wigginton
+ * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
+ * @link      http://phpseclib.sourceforge.net
+ * @internal  See http://api.libssh.org/rfc/PROTOCOL.agent
+ */
+
+namespace phpseclib\System\SSH\Agent;
+
+use phpseclib\System\SSH\Agent;
+
+/**
+ * Pure-PHP ssh-agent client identity object
+ *
+ * Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
+ * This could be thought of as implementing an interface that phpseclib\Crypt\RSA
+ * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
+ * The methods in this interface would be getPublicKey and sign since those are the
+ * methods phpseclib looks for to perform public key authentication.
+ *
+ * @package SSH\Agent
+ * @author  Jim Wigginton <terrafrost@php.net>
+ * @access  internal
+ */
+class Identity
+{
+    /**@+
+     * Signature Flags
+     *
+     * See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
+     *
+     * @access private
+     */
+    const SSH_AGENT_RSA2_256 = 2;
+    const SSH_AGENT_RSA2_512 = 4;
+    /**#@-*/
+
+    /**
+     * Key Object
+     *
+     * @var \phpseclib\Crypt\RSA
+     * @access private
+     * @see self::getPublicKey()
+     */
+    var $key;
+
+    /**
+     * Key Blob
+     *
+     * @var string
+     * @access private
+     * @see self::sign()
+     */
+    var $key_blob;
+
+    /**
+     * Socket Resource
+     *
+     * @var resource
+     * @access private
+     * @see self::sign()
+     */
+    var $fsock;
+
+    /**
+     * Signature flags
+     *
+     * @var int
+     * @access private
+     * @see self::sign()
+     * @see self::setHash()
+     */
+    var $flags = 0;
+
+    /**
+     * Default Constructor.
+     *
+     * @param resource $fsock
+     * @return \phpseclib\System\SSH\Agent\Identity
+     * @access private
+     */
+    function __construct($fsock)
+    {
+        $this->fsock = $fsock;
+    }
+
+    /**
+     * Set Public Key
+     *
+     * Called by \phpseclib\System\SSH\Agent::requestIdentities()
+     *
+     * @param \phpseclib\Crypt\RSA $key
+     * @access private
+     */
+    function setPublicKey($key)
+    {
+        $this->key = $key;
+        $this->key->setPublicKey();
+    }
+
+    /**
+     * Set Public Key
+     *
+     * Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
+     * but this saves a small amount of computation.
+     *
+     * @param string $key_blob
+     * @access private
+     */
+    function setPublicKeyBlob($key_blob)
+    {
+        $this->key_blob = $key_blob;
+    }
+
+    /**
+     * Get Public Key
+     *
+     * Wrapper for $this->key->getPublicKey()
+     *
+     * @param int $format optional
+     * @return mixed
+     * @access public
+     */
+    function getPublicKey($format = null)
+    {
+        return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
+    }
+
+    /**
+     * Set Signature Mode
+     *
+     * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
+     * ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1
+     *
+     * @param int $mode
+     * @access public
+     */
+    function setSignatureMode($mode)
+    {
+    }
+
+    /**
+     * Set Hash
+     *
+     * ssh-agent doesn't support using hashes for RSA other than SHA1
+     *
+     * @param string $hash
+     * @access public
+     */
+    function setHash($hash)
+    {
+        $this->flags = 0;
+        switch ($hash) {
+            case 'sha1':
+                break;
+            case 'sha256':
+                $this->flags = self::SSH_AGENT_RSA2_256;
+                break;
+            case 'sha512':
+                $this->flags = self::SSH_AGENT_RSA2_512;
+                break;
+            default:
+                user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
+        }
+    }
+
+    /**
+     * Create a signature
+     *
+     * See "2.6.2 Protocol 2 private key signature request"
+     *
+     * @param string $message
+     * @return string
+     * @access public
+     */
+    function sign($message)
+    {
+        // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
+        $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
+        $packet = pack('Na*', strlen($packet), $packet);
+        if (strlen($packet) != fputs($this->fsock, $packet)) {
+            user_error('Connection closed during signing');
+            return false;
+        }
+
+        $temp = fread($this->fsock, 4);
+        if (strlen($temp) != 4) {
+            user_error('Connection closed during signing');
+            return false;
+        }
+        $length = current(unpack('N', $temp));
+        $type = ord(fread($this->fsock, 1));
+        if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
+            user_error('Unable to retrieve signature');
+            return false;
+        }
+
+        $signature_blob = fread($this->fsock, $length - 1);
+        if (strlen($signature_blob) != $length - 1) {
+            user_error('Connection closed during signing');
+            return false;
+        }
+        $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
+        if ($length != strlen($signature_blob)) {
+            user_error('Malformed signature blob');
+        }
+        $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
+        if ($length > strlen($signature_blob) + 4) {
+            user_error('Malformed signature blob');
+        }
+        $type = $this->_string_shift($signature_blob, $length);
+        $this->_string_shift($signature_blob, 4);
+
+        return $signature_blob;
+    }
+
+    /**
+     * String Shift
+     *
+     * Inspired by array_shift
+     *
+     * @param string $string
+     * @param int $index
+     * @return string
+     * @access private
+     */
+    function _string_shift(&$string, $index = 1)
+    {
+        $substr = substr($string, 0, $index);
+        $string = substr($string, $index);
+        return $substr;
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/msd/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
new file mode 100644
index 00000000..547688f9
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Bootstrapping File for phpseclib
+ *
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ */
+
+if (extension_loaded('mbstring')) {
+    // 2 - MB_OVERLOAD_STRING
+    // mbstring.func_overload is deprecated in php 7.2 and removed in php 8.0.
+    if (version_compare(PHP_VERSION, '8.0.0') < 0 && ini_get('mbstring.func_overload') & 2) {
+        throw new \UnexpectedValueException(
+            'Overloading of string functions using mbstring.func_overload ' .
+            'is not supported by phpseclib.'
+        );
+    }
+}
diff --git a/msd/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf b/msd/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
new file mode 100644
index 00000000..2b8b52f9
--- /dev/null
+++ b/msd/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
@@ -0,0 +1,6 @@
+# minimalist openssl.cnf file for use with phpseclib
+
+HOME			= .
+RANDFILE		= $ENV::HOME/.rnd
+
+[ v3_ca ]
diff --git a/msd/vendor/psr/log/LICENSE b/msd/vendor/psr/log/LICENSE
new file mode 100644
index 00000000..474c952b
--- /dev/null
+++ b/msd/vendor/psr/log/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/msd/vendor/psr/log/Psr/Log/AbstractLogger.php b/msd/vendor/psr/log/Psr/Log/AbstractLogger.php
new file mode 100644
index 00000000..e02f9daf
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/AbstractLogger.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger implementation that other Loggers can inherit from.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+abstract class AbstractLogger implements LoggerInterface
+{
+    /**
+     * System is unusable.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function emergency($message, array $context = array())
+    {
+        $this->log(LogLevel::EMERGENCY, $message, $context);
+    }
+
+    /**
+     * Action must be taken immediately.
+     *
+     * Example: Entire website down, database unavailable, etc. This should
+     * trigger the SMS alerts and wake you up.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function alert($message, array $context = array())
+    {
+        $this->log(LogLevel::ALERT, $message, $context);
+    }
+
+    /**
+     * Critical conditions.
+     *
+     * Example: Application component unavailable, unexpected exception.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function critical($message, array $context = array())
+    {
+        $this->log(LogLevel::CRITICAL, $message, $context);
+    }
+
+    /**
+     * Runtime errors that do not require immediate action but should typically
+     * be logged and monitored.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function error($message, array $context = array())
+    {
+        $this->log(LogLevel::ERROR, $message, $context);
+    }
+
+    /**
+     * Exceptional occurrences that are not errors.
+     *
+     * Example: Use of deprecated APIs, poor use of an API, undesirable things
+     * that are not necessarily wrong.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function warning($message, array $context = array())
+    {
+        $this->log(LogLevel::WARNING, $message, $context);
+    }
+
+    /**
+     * Normal but significant events.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function notice($message, array $context = array())
+    {
+        $this->log(LogLevel::NOTICE, $message, $context);
+    }
+
+    /**
+     * Interesting events.
+     *
+     * Example: User logs in, SQL logs.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function info($message, array $context = array())
+    {
+        $this->log(LogLevel::INFO, $message, $context);
+    }
+
+    /**
+     * Detailed debug information.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function debug($message, array $context = array())
+    {
+        $this->log(LogLevel::DEBUG, $message, $context);
+    }
+}
diff --git a/msd/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/msd/vendor/psr/log/Psr/Log/InvalidArgumentException.php
new file mode 100644
index 00000000..67f852d1
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/InvalidArgumentException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Psr\Log;
+
+class InvalidArgumentException extends \InvalidArgumentException
+{
+}
diff --git a/msd/vendor/psr/log/Psr/Log/LogLevel.php b/msd/vendor/psr/log/Psr/Log/LogLevel.php
new file mode 100644
index 00000000..9cebcace
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/LogLevel.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes log levels.
+ */
+class LogLevel
+{
+    const EMERGENCY = 'emergency';
+    const ALERT     = 'alert';
+    const CRITICAL  = 'critical';
+    const ERROR     = 'error';
+    const WARNING   = 'warning';
+    const NOTICE    = 'notice';
+    const INFO      = 'info';
+    const DEBUG     = 'debug';
+}
diff --git a/msd/vendor/psr/log/Psr/Log/LoggerAwareInterface.php b/msd/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
new file mode 100644
index 00000000..4d64f478
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger-aware instance.
+ */
+interface LoggerAwareInterface
+{
+    /**
+     * Sets a logger instance on the object.
+     *
+     * @param LoggerInterface $logger
+     *
+     * @return void
+     */
+    public function setLogger(LoggerInterface $logger);
+}
diff --git a/msd/vendor/psr/log/Psr/Log/LoggerAwareTrait.php b/msd/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
new file mode 100644
index 00000000..82bf45c8
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Basic Implementation of LoggerAwareInterface.
+ */
+trait LoggerAwareTrait
+{
+    /**
+     * The logger instance.
+     *
+     * @var LoggerInterface|null
+     */
+    protected $logger;
+
+    /**
+     * Sets a logger.
+     *
+     * @param LoggerInterface $logger
+     */
+    public function setLogger(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+}
diff --git a/msd/vendor/psr/log/Psr/Log/LoggerInterface.php b/msd/vendor/psr/log/Psr/Log/LoggerInterface.php
new file mode 100644
index 00000000..2206cfde
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/LoggerInterface.php
@@ -0,0 +1,125 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger instance.
+ *
+ * The message MUST be a string or object implementing __toString().
+ *
+ * The message MAY contain placeholders in the form: {foo} where foo
+ * will be replaced by the context data in key "foo".
+ *
+ * The context array can contain arbitrary data. The only assumption that
+ * can be made by implementors is that if an Exception instance is given
+ * to produce a stack trace, it MUST be in a key named "exception".
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
+ * for the full interface specification.
+ */
+interface LoggerInterface
+{
+    /**
+     * System is unusable.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function emergency($message, array $context = array());
+
+    /**
+     * Action must be taken immediately.
+     *
+     * Example: Entire website down, database unavailable, etc. This should
+     * trigger the SMS alerts and wake you up.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function alert($message, array $context = array());
+
+    /**
+     * Critical conditions.
+     *
+     * Example: Application component unavailable, unexpected exception.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function critical($message, array $context = array());
+
+    /**
+     * Runtime errors that do not require immediate action but should typically
+     * be logged and monitored.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function error($message, array $context = array());
+
+    /**
+     * Exceptional occurrences that are not errors.
+     *
+     * Example: Use of deprecated APIs, poor use of an API, undesirable things
+     * that are not necessarily wrong.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function warning($message, array $context = array());
+
+    /**
+     * Normal but significant events.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function notice($message, array $context = array());
+
+    /**
+     * Interesting events.
+     *
+     * Example: User logs in, SQL logs.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function info($message, array $context = array());
+
+    /**
+     * Detailed debug information.
+     *
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     */
+    public function debug($message, array $context = array());
+
+    /**
+     * Logs with an arbitrary level.
+     *
+     * @param mixed   $level
+     * @param string  $message
+     * @param mixed[] $context
+     *
+     * @return void
+     *
+     * @throws \Psr\Log\InvalidArgumentException
+     */
+    public function log($level, $message, array $context = array());
+}
diff --git a/msd/vendor/psr/log/Psr/Log/LoggerTrait.php b/msd/vendor/psr/log/Psr/Log/LoggerTrait.php
new file mode 100644
index 00000000..e392fef0
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/LoggerTrait.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger trait that classes unable to extend AbstractLogger
+ * (because they extend another class, etc) can include.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+trait LoggerTrait
+{
+    /**
+     * System is unusable.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function emergency($message, array $context = array())
+    {
+        $this->log(LogLevel::EMERGENCY, $message, $context);
+    }
+
+    /**
+     * Action must be taken immediately.
+     *
+     * Example: Entire website down, database unavailable, etc. This should
+     * trigger the SMS alerts and wake you up.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function alert($message, array $context = array())
+    {
+        $this->log(LogLevel::ALERT, $message, $context);
+    }
+
+    /**
+     * Critical conditions.
+     *
+     * Example: Application component unavailable, unexpected exception.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function critical($message, array $context = array())
+    {
+        $this->log(LogLevel::CRITICAL, $message, $context);
+    }
+
+    /**
+     * Runtime errors that do not require immediate action but should typically
+     * be logged and monitored.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function error($message, array $context = array())
+    {
+        $this->log(LogLevel::ERROR, $message, $context);
+    }
+
+    /**
+     * Exceptional occurrences that are not errors.
+     *
+     * Example: Use of deprecated APIs, poor use of an API, undesirable things
+     * that are not necessarily wrong.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function warning($message, array $context = array())
+    {
+        $this->log(LogLevel::WARNING, $message, $context);
+    }
+
+    /**
+     * Normal but significant events.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function notice($message, array $context = array())
+    {
+        $this->log(LogLevel::NOTICE, $message, $context);
+    }
+
+    /**
+     * Interesting events.
+     *
+     * Example: User logs in, SQL logs.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function info($message, array $context = array())
+    {
+        $this->log(LogLevel::INFO, $message, $context);
+    }
+
+    /**
+     * Detailed debug information.
+     *
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     */
+    public function debug($message, array $context = array())
+    {
+        $this->log(LogLevel::DEBUG, $message, $context);
+    }
+
+    /**
+     * Logs with an arbitrary level.
+     *
+     * @param mixed  $level
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     *
+     * @throws \Psr\Log\InvalidArgumentException
+     */
+    abstract public function log($level, $message, array $context = array());
+}
diff --git a/msd/vendor/psr/log/Psr/Log/NullLogger.php b/msd/vendor/psr/log/Psr/Log/NullLogger.php
new file mode 100644
index 00000000..c8f7293b
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/NullLogger.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This Logger can be used to avoid conditional log calls.
+ *
+ * Logging should always be optional, and if no logger is provided to your
+ * library creating a NullLogger instance to have something to throw logs at
+ * is a good way to avoid littering your code with `if ($this->logger) { }`
+ * blocks.
+ */
+class NullLogger extends AbstractLogger
+{
+    /**
+     * Logs with an arbitrary level.
+     *
+     * @param mixed  $level
+     * @param string $message
+     * @param array  $context
+     *
+     * @return void
+     *
+     * @throws \Psr\Log\InvalidArgumentException
+     */
+    public function log($level, $message, array $context = array())
+    {
+        // noop
+    }
+}
diff --git a/msd/vendor/psr/log/Psr/Log/Test/DummyTest.php b/msd/vendor/psr/log/Psr/Log/Test/DummyTest.php
new file mode 100644
index 00000000..9638c110
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/Test/DummyTest.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Psr\Log\Test;
+
+/**
+ * This class is internal and does not follow the BC promise.
+ *
+ * Do NOT use this class in any way.
+ *
+ * @internal
+ */
+class DummyTest
+{
+    public function __toString()
+    {
+        return 'DummyTest';
+    }
+}
diff --git a/msd/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/msd/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
new file mode 100644
index 00000000..e1e5354d
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace Psr\Log\Test;
+
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Provides a base test class for ensuring compliance with the LoggerInterface.
+ *
+ * Implementors can extend the class and implement abstract methods to run this
+ * as part of their test suite.
+ */
+abstract class LoggerInterfaceTest extends TestCase
+{
+    /**
+     * @return LoggerInterface
+     */
+    abstract public function getLogger();
+
+    /**
+     * This must return the log messages in order.
+     *
+     * The simple formatting of the messages is: "<LOG LEVEL> <MESSAGE>".
+     *
+     * Example ->error('Foo') would yield "error Foo".
+     *
+     * @return string[]
+     */
+    abstract public function getLogs();
+
+    public function testImplements()
+    {
+        $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
+    }
+
+    /**
+     * @dataProvider provideLevelsAndMessages
+     */
+    public function testLogsAtAllLevels($level, $message)
+    {
+        $logger = $this->getLogger();
+        $logger->{$level}($message, array('user' => 'Bob'));
+        $logger->log($level, $message, array('user' => 'Bob'));
+
+        $expected = array(
+            $level.' message of level '.$level.' with context: Bob',
+            $level.' message of level '.$level.' with context: Bob',
+        );
+        $this->assertEquals($expected, $this->getLogs());
+    }
+
+    public function provideLevelsAndMessages()
+    {
+        return array(
+            LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
+            LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
+            LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
+            LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
+            LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
+            LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
+            LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
+            LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
+        );
+    }
+
+    /**
+     * @expectedException \Psr\Log\InvalidArgumentException
+     */
+    public function testThrowsOnInvalidLevel()
+    {
+        $logger = $this->getLogger();
+        $logger->log('invalid level', 'Foo');
+    }
+
+    public function testContextReplacement()
+    {
+        $logger = $this->getLogger();
+        $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+
+        $expected = array('info {Message {nothing} Bob Bar a}');
+        $this->assertEquals($expected, $this->getLogs());
+    }
+
+    public function testObjectCastToString()
+    {
+        if (method_exists($this, 'createPartialMock')) {
+            $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString'));
+        } else {
+            $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
+        }
+        $dummy->expects($this->once())
+            ->method('__toString')
+            ->will($this->returnValue('DUMMY'));
+
+        $this->getLogger()->warning($dummy);
+
+        $expected = array('warning DUMMY');
+        $this->assertEquals($expected, $this->getLogs());
+    }
+
+    public function testContextCanContainAnything()
+    {
+        $closed = fopen('php://memory', 'r');
+        fclose($closed);
+
+        $context = array(
+            'bool' => true,
+            'null' => null,
+            'string' => 'Foo',
+            'int' => 0,
+            'float' => 0.5,
+            'nested' => array('with object' => new DummyTest),
+            'object' => new \DateTime,
+            'resource' => fopen('php://memory', 'r'),
+            'closed' => $closed,
+        );
+
+        $this->getLogger()->warning('Crazy context data', $context);
+
+        $expected = array('warning Crazy context data');
+        $this->assertEquals($expected, $this->getLogs());
+    }
+
+    public function testContextExceptionKeyCanBeExceptionOrOtherValues()
+    {
+        $logger = $this->getLogger();
+        $logger->warning('Random message', array('exception' => 'oops'));
+        $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
+
+        $expected = array(
+            'warning Random message',
+            'critical Uncaught Exception!'
+        );
+        $this->assertEquals($expected, $this->getLogs());
+    }
+}
diff --git a/msd/vendor/psr/log/Psr/Log/Test/TestLogger.php b/msd/vendor/psr/log/Psr/Log/Test/TestLogger.php
new file mode 100644
index 00000000..1be32304
--- /dev/null
+++ b/msd/vendor/psr/log/Psr/Log/Test/TestLogger.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace Psr\Log\Test;
+
+use Psr\Log\AbstractLogger;
+
+/**
+ * Used for testing purposes.
+ *
+ * It records all records and gives you access to them for verification.
+ *
+ * @method bool hasEmergency($record)
+ * @method bool hasAlert($record)
+ * @method bool hasCritical($record)
+ * @method bool hasError($record)
+ * @method bool hasWarning($record)
+ * @method bool hasNotice($record)
+ * @method bool hasInfo($record)
+ * @method bool hasDebug($record)
+ *
+ * @method bool hasEmergencyRecords()
+ * @method bool hasAlertRecords()
+ * @method bool hasCriticalRecords()
+ * @method bool hasErrorRecords()
+ * @method bool hasWarningRecords()
+ * @method bool hasNoticeRecords()
+ * @method bool hasInfoRecords()
+ * @method bool hasDebugRecords()
+ *
+ * @method bool hasEmergencyThatContains($message)
+ * @method bool hasAlertThatContains($message)
+ * @method bool hasCriticalThatContains($message)
+ * @method bool hasErrorThatContains($message)
+ * @method bool hasWarningThatContains($message)
+ * @method bool hasNoticeThatContains($message)
+ * @method bool hasInfoThatContains($message)
+ * @method bool hasDebugThatContains($message)
+ *
+ * @method bool hasEmergencyThatMatches($message)
+ * @method bool hasAlertThatMatches($message)
+ * @method bool hasCriticalThatMatches($message)
+ * @method bool hasErrorThatMatches($message)
+ * @method bool hasWarningThatMatches($message)
+ * @method bool hasNoticeThatMatches($message)
+ * @method bool hasInfoThatMatches($message)
+ * @method bool hasDebugThatMatches($message)
+ *
+ * @method bool hasEmergencyThatPasses($message)
+ * @method bool hasAlertThatPasses($message)
+ * @method bool hasCriticalThatPasses($message)
+ * @method bool hasErrorThatPasses($message)
+ * @method bool hasWarningThatPasses($message)
+ * @method bool hasNoticeThatPasses($message)
+ * @method bool hasInfoThatPasses($message)
+ * @method bool hasDebugThatPasses($message)
+ */
+class TestLogger extends AbstractLogger
+{
+    /**
+     * @var array
+     */
+    public $records = [];
+
+    public $recordsByLevel = [];
+
+    /**
+     * @inheritdoc
+     */
+    public function log($level, $message, array $context = [])
+    {
+        $record = [
+            'level' => $level,
+            'message' => $message,
+            'context' => $context,
+        ];
+
+        $this->recordsByLevel[$record['level']][] = $record;
+        $this->records[] = $record;
+    }
+
+    public function hasRecords($level)
+    {
+        return isset($this->recordsByLevel[$level]);
+    }
+
+    public function hasRecord($record, $level)
+    {
+        if (is_string($record)) {
+            $record = ['message' => $record];
+        }
+        return $this->hasRecordThatPasses(function ($rec) use ($record) {
+            if ($rec['message'] !== $record['message']) {
+                return false;
+            }
+            if (isset($record['context']) && $rec['context'] !== $record['context']) {
+                return false;
+            }
+            return true;
+        }, $level);
+    }
+
+    public function hasRecordThatContains($message, $level)
+    {
+        return $this->hasRecordThatPasses(function ($rec) use ($message) {
+            return strpos($rec['message'], $message) !== false;
+        }, $level);
+    }
+
+    public function hasRecordThatMatches($regex, $level)
+    {
+        return $this->hasRecordThatPasses(function ($rec) use ($regex) {
+            return preg_match($regex, $rec['message']) > 0;
+        }, $level);
+    }
+
+    public function hasRecordThatPasses(callable $predicate, $level)
+    {
+        if (!isset($this->recordsByLevel[$level])) {
+            return false;
+        }
+        foreach ($this->recordsByLevel[$level] as $i => $rec) {
+            if (call_user_func($predicate, $rec, $i)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public function __call($method, $args)
+    {
+        if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
+            $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3];
+            $level = strtolower($matches[2]);
+            if (method_exists($this, $genericMethod)) {
+                $args[] = $level;
+                return call_user_func_array([$this, $genericMethod], $args);
+            }
+        }
+        throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()');
+    }
+
+    public function reset()
+    {
+        $this->records = [];
+        $this->recordsByLevel = [];
+    }
+}
diff --git a/msd/vendor/psr/log/README.md b/msd/vendor/psr/log/README.md
new file mode 100644
index 00000000..a9f20c43
--- /dev/null
+++ b/msd/vendor/psr/log/README.md
@@ -0,0 +1,58 @@
+PSR Log
+=======
+
+This repository holds all interfaces/classes/traits related to
+[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
+
+Note that this is not a logger of its own. It is merely an interface that
+describes a logger. See the specification for more details.
+
+Installation
+------------
+
+```bash
+composer require psr/log
+```
+
+Usage
+-----
+
+If you need a logger, you can use the interface like this:
+
+```php
+<?php
+
+use Psr\Log\LoggerInterface;
+
+class Foo
+{
+    private $logger;
+
+    public function __construct(LoggerInterface $logger = null)
+    {
+        $this->logger = $logger;
+    }
+
+    public function doSomething()
+    {
+        if ($this->logger) {
+            $this->logger->info('Doing work');
+        }
+           
+        try {
+            $this->doSomethingElse();
+        } catch (Exception $exception) {
+            $this->logger->error('Oh no!', array('exception' => $exception));
+        }
+
+        // do something useful
+    }
+}
+```
+
+You can then pick one of the implementations of the interface to get a logger.
+
+If you want to implement the interface, you can require this package and
+implement `Psr\Log\LoggerInterface` in your code. Please read the
+[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+for details.
diff --git a/msd/vendor/psr/log/composer.json b/msd/vendor/psr/log/composer.json
new file mode 100644
index 00000000..ca056953
--- /dev/null
+++ b/msd/vendor/psr/log/composer.json
@@ -0,0 +1,26 @@
+{
+    "name": "psr/log",
+    "description": "Common interface for logging libraries",
+    "keywords": ["psr", "psr-3", "log"],
+    "homepage": "https://github.com/php-fig/log",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "https://www.php-fig.org/"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Psr\\Log\\": "Psr/Log/"
+        }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.1.x-dev"
+        }
+    }
+}
diff --git a/msd/vendor/psr/simple-cache/src/CacheException.php b/msd/vendor/psr/simple-cache/src/CacheException.php
new file mode 100644
index 00000000..eba53815
--- /dev/null
+++ b/msd/vendor/psr/simple-cache/src/CacheException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace Psr\SimpleCache;
+
+/**
+ * Interface used for all types of exceptions thrown by the implementing library.
+ */
+interface CacheException
+{
+}
diff --git a/msd/vendor/psr/simple-cache/src/CacheInterface.php b/msd/vendor/psr/simple-cache/src/CacheInterface.php
new file mode 100644
index 00000000..99e8d957
--- /dev/null
+++ b/msd/vendor/psr/simple-cache/src/CacheInterface.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace Psr\SimpleCache;
+
+interface CacheInterface
+{
+    /**
+     * Fetches a value from the cache.
+     *
+     * @param string $key     The unique key of this item in the cache.
+     * @param mixed  $default Default value to return if the key does not exist.
+     *
+     * @return mixed The value of the item from the cache, or $default in case of cache miss.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function get($key, $default = null);
+
+    /**
+     * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
+     *
+     * @param string                 $key   The key of the item to store.
+     * @param mixed                  $value The value of the item to store, must be serializable.
+     * @param null|int|\DateInterval $ttl   Optional. The TTL value of this item. If no value is sent and
+     *                                      the driver supports TTL then the library may set a default value
+     *                                      for it or let the driver take care of that.
+     *
+     * @return bool True on success and false on failure.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function set($key, $value, $ttl = null);
+
+    /**
+     * Delete an item from the cache by its unique key.
+     *
+     * @param string $key The unique cache key of the item to delete.
+     *
+     * @return bool True if the item was successfully removed. False if there was an error.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function delete($key);
+
+    /**
+     * Wipes clean the entire cache's keys.
+     *
+     * @return bool True on success and false on failure.
+     */
+    public function clear();
+
+    /**
+     * Obtains multiple cache items by their unique keys.
+     *
+     * @param iterable $keys    A list of keys that can obtained in a single operation.
+     * @param mixed    $default Default value to return for keys that do not exist.
+     *
+     * @return iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if $keys is neither an array nor a Traversable,
+     *   or if any of the $keys are not a legal value.
+     */
+    public function getMultiple($keys, $default = null);
+
+    /**
+     * Persists a set of key => value pairs in the cache, with an optional TTL.
+     *
+     * @param iterable               $values A list of key => value pairs for a multiple-set operation.
+     * @param null|int|\DateInterval $ttl    Optional. The TTL value of this item. If no value is sent and
+     *                                       the driver supports TTL then the library may set a default value
+     *                                       for it or let the driver take care of that.
+     *
+     * @return bool True on success and false on failure.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if $values is neither an array nor a Traversable,
+     *   or if any of the $values are not a legal value.
+     */
+    public function setMultiple($values, $ttl = null);
+
+    /**
+     * Deletes multiple cache items in a single operation.
+     *
+     * @param iterable $keys A list of string-based keys to be deleted.
+     *
+     * @return bool True if the items were successfully removed. False if there was an error.
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if $keys is neither an array nor a Traversable,
+     *   or if any of the $keys are not a legal value.
+     */
+    public function deleteMultiple($keys);
+
+    /**
+     * Determines whether an item is present in the cache.
+     *
+     * NOTE: It is recommended that has() is only to be used for cache warming type purposes
+     * and not to be used within your live applications operations for get/set, as this method
+     * is subject to a race condition where your has() will return true and immediately after,
+     * another script can remove it making the state of your app out of date.
+     *
+     * @param string $key The cache item key.
+     *
+     * @return bool
+     *
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     *   MUST be thrown if the $key string is not a legal value.
+     */
+    public function has($key);
+}
diff --git a/msd/vendor/psr/simple-cache/src/InvalidArgumentException.php b/msd/vendor/psr/simple-cache/src/InvalidArgumentException.php
new file mode 100644
index 00000000..6a9524a2
--- /dev/null
+++ b/msd/vendor/psr/simple-cache/src/InvalidArgumentException.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Psr\SimpleCache;
+
+/**
+ * Exception interface for invalid cache arguments.
+ *
+ * When an invalid argument is passed it must throw an exception which implements
+ * this interface
+ */
+interface InvalidArgumentException extends CacheException
+{
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/.editorconfig b/msd/vendor/visualappeal/php-auto-update/.editorconfig
new file mode 100644
index 00000000..465b6876
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+max_line_length = 120
+tab_width = 4
+trim_trailing_whitespace = true
diff --git a/msd/vendor/visualappeal/php-auto-update/.github/workflows/phpunit.yml b/msd/vendor/visualappeal/php-auto-update/.github/workflows/phpunit.yml
new file mode 100644
index 00000000..78041a66
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/.github/workflows/phpunit.yml
@@ -0,0 +1,39 @@
+name: PHPUnit
+
+on:
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+
+jobs:
+  build:
+
+    runs-on: ubuntu-20.04
+    strategy:
+      matrix:
+        php-versions: ['7.3', '7.4', '8.0', '8.1']
+
+    name: PHPUnit ${{ matrix.php-versions }}
+
+    steps:
+    - uses: actions/checkout@v2
+
+    - name: Validate composer.json and composer.lock
+      run: composer validate
+
+    - name: Cache Composer packages
+      id: composer-cache
+      uses: actions/cache@v2
+      with:
+        path: vendor
+        key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
+        restore-keys: |
+          ${{ runner.os }}-php-
+
+    - name: Install dependencies
+      if: steps.composer-cache.outputs.cache-hit != 'true'
+      run: composer install --prefer-dist --no-progress --no-suggest
+
+    - name: Run test suite
+      run: composer run-script test
diff --git a/msd/vendor/visualappeal/php-auto-update/.gitignore b/msd/vendor/visualappeal/php-auto-update/.gitignore
new file mode 100644
index 00000000..6d5428fb
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/.gitignore
@@ -0,0 +1,5 @@
+/example/update/temp/*
+/vendor/
+
+*.cache
+composer.lock
diff --git a/msd/vendor/visualappeal/php-auto-update/Dockerfile b/msd/vendor/visualappeal/php-auto-update/Dockerfile
new file mode 100644
index 00000000..4b6ed7b5
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/Dockerfile
@@ -0,0 +1,12 @@
+FROM php:8.0-apache
+
+MAINTAINER VisualAppeal <tim@visualappeal.de>
+
+RUN apt-get update && apt-get install -y libzip-dev libcurl4-openssl-dev
+RUN docker-php-ext-install -j$(nproc) zip curl
+
+ADD ./vendor /var/www/html/vendor
+ADD ./example /var/www/html/example
+ADD ./src /var/www/html/src
+
+RUN chown -R www-data:www-data /var/www/html/example
diff --git a/msd/vendor/visualappeal/php-auto-update/LICENSE.md b/msd/vendor/visualappeal/php-auto-update/LICENSE.md
new file mode 100644
index 00000000..d32dac96
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/LICENSE.md
@@ -0,0 +1,7 @@
+Copyright 2017 VisualAppeal GbR
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/msd/vendor/visualappeal/php-auto-update/README.md b/msd/vendor/visualappeal/php-auto-update/README.md
new file mode 100644
index 00000000..2d17b28c
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/README.md
@@ -0,0 +1,29 @@
+[![PHPUnit](https://github.com/VisualAppeal/PHP-Auto-Update/actions/workflows/phpunit.yml/badge.svg)](https://github.com/VisualAppeal/PHP-Auto-Update/actions/workflows/phpunit.yml)
+
+With this library your users can automatically update their instance of your application to the newest version. I created it as a proof of concept and don't know if it is used somewhere. So please use this library with caution because it can potentially make your users software nonfunctional if something goes wrong.
+
+## Installation
+
+* Install the library via composer [visualappeal/php-auto-update](https://packagist.org/packages/visualappeal/php-auto-update)
+* Create an update file/method in your application with your update routine (see `example/client/update/index.php`)
+* Create a `update.json` or `update.ini` on your server (where the client should get the updates, see `example/server/update.json` or `example/server/update.ini`)
+
+**Important: Please notice that PHP needs write permissions to update the files on the webserver**
+
+## Example
+
+You can start an example docker container via `docker-compose up` and see the example by visiting `http://127.0.0.1:8080/example/client/`
+
+## Client
+
+### Caching
+
+The library supports the `desarrolla2/cache` component, and you should use it! Otherwise, the client will download the update ini/json file on every request.
+
+## Server
+
+Your server needs at least one file which will be downloaded from the client to check for updates. This can be a json or an ini file. See `example/server/` for examples. The ini section key respectively the json key is the version. This library uses semantic versioning to compare the versions. See [semver.org](http://semver.org/) for details. The ini/json value is the absolute url to the update zip file. Since the library supports incremental updates, the zip file only need to contain the changes since the last version. The zip files do not need to be placed on the same server, they can be uploaded to S3 or another cloud storage, too.
+
+## Documentation
+
+For the documentation see the comments in `src/AutoUpdate.php` or the example in the `example` directory.
diff --git a/msd/vendor/visualappeal/php-auto-update/SECURITY.md b/msd/vendor/visualappeal/php-auto-update/SECURITY.md
new file mode 100644
index 00000000..fce4ae9a
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/SECURITY.md
@@ -0,0 +1,16 @@
+# Security Policy
+
+## Supported Versions
+
+The following php versions are currently supported:
+
+| Version | Supported          |
+| ------- | ------------------ |
+| 7.2 | :white_check_mark: |
+| 7.3 | :white_check_mark: |
+| 7.4 | :white_check_mark: |
+| 8.0 | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+If you find a security vulnerability, please write an email to tim@visualappeal.de.
diff --git a/msd/vendor/visualappeal/php-auto-update/composer.json b/msd/vendor/visualappeal/php-auto-update/composer.json
new file mode 100644
index 00000000..91365869
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/composer.json
@@ -0,0 +1,37 @@
+{
+    "name": "visualappeal/php-auto-update",
+    "description": "Autoupdater for PHP",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Tim Helfensdörfer",
+            "email": "tim@visualappeal.de"
+        }
+    ],
+    "minimum-stability": "stable",
+    "require": {
+        "ext-json": "*",
+        "ext-curl": "*",
+        "ext-zip": "*",
+        "php": ">=7.2.0",
+        "desarrolla2/cache": "^3.0",
+        "monolog/monolog": "^2.1",
+        "composer/semver": "^3.0",
+        "psr/log": "1.1.4"
+    },
+    "require-dev": {
+        "roave/security-advisories": "dev-master",
+        "phpunit/phpunit": "^9.5"
+    },
+    "autoload": {
+        "psr-4": {
+            "VisualAppeal\\": "src/"
+        }
+    },
+    "scripts": {
+        "test": "phpunit -c tests/UnitTests.xml"
+    },
+    "config": {
+        "sort-packages": true
+    }
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/docker-compose.yaml b/msd/vendor/visualappeal/php-auto-update/docker-compose.yaml
new file mode 100644
index 00000000..c421220c
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/docker-compose.yaml
@@ -0,0 +1,7 @@
+version: '3'
+
+services:
+  app:
+    build: .
+    ports:
+      - 8080:80
diff --git a/msd/vendor/visualappeal/php-auto-update/example/client/files/file1.php b/msd/vendor/visualappeal/php-auto-update/example/client/files/file1.php
new file mode 100644
index 00000000..b5266b12
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/example/client/files/file1.php
@@ -0,0 +1 @@
+This is file 1. Version 0.1.0
diff --git a/msd/vendor/visualappeal/php-auto-update/example/client/files/file2.php b/msd/vendor/visualappeal/php-auto-update/example/client/files/file2.php
new file mode 100644
index 00000000..ead23d83
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/example/client/files/file2.php
@@ -0,0 +1 @@
+This is file 2. Version 0.1.0
diff --git a/msd/vendor/visualappeal/php-auto-update/example/client/index.php b/msd/vendor/visualappeal/php-auto-update/example/client/index.php
new file mode 100644
index 00000000..9e6c4cc9
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/example/client/index.php
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<title>PHP Auto Update</title>
+
+		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
+	</head>
+	<body>
+		<div class="container mt-4">
+			<p>This is the test index.</p>
+
+			<p><a class="btn btn-primary" href="/example/client/update/index.php">Update now!</a></p>
+
+			<p>Contents of <code>somefile.php</code>:</p>
+			<pre><code><?php require(__DIR__ . '/somefile.php'); ?></code></pre>
+		</div>
+	</body>
+</html>
diff --git a/msd/vendor/visualappeal/php-auto-update/example/client/somefile.php b/msd/vendor/visualappeal/php-auto-update/example/client/somefile.php
new file mode 100644
index 00000000..669f2adb
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/example/client/somefile.php
@@ -0,0 +1 @@
+This is some file. Version 0.1.0
diff --git a/msd/vendor/visualappeal/php-auto-update/example/client/update/.gitignore b/msd/vendor/visualappeal/php-auto-update/example/client/update/.gitignore
new file mode 100644
index 00000000..0ebab7fa
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/example/client/update/.gitignore
@@ -0,0 +1,2 @@
+!.gitignore
+update.log
diff --git a/msd/vendor/visualappeal/php-auto-update/src/AutoUpdate.php b/msd/vendor/visualappeal/php-auto-update/src/AutoUpdate.php
new file mode 100644
index 00000000..426de098
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/src/AutoUpdate.php
@@ -0,0 +1,1019 @@
+<?php /** @noinspection PhpUnused */
+
+namespace VisualAppeal;
+
+use Exception;
+use RuntimeException;
+use ZipArchive;
+
+use Composer\Semver\Comparator;
+use Desarrolla2\Cache\CacheInterface;
+use Desarrolla2\Cache\NotCache;
+use Monolog\Logger;
+use Psr\Log\LoggerInterface;
+use Psr\SimpleCache\InvalidArgumentException;
+use VisualAppeal\Exceptions\DownloadException;
+use VisualAppeal\Exceptions\ParserException;
+
+/**
+ * Auto update class.
+ */
+class AutoUpdate {
+    /**
+     * The latest version.
+     *
+     * @var string
+     */
+    private $latestVersion;
+
+    /**
+     * Updates not yet installed.
+     *
+     * @var array
+     */
+    private $updates;
+
+    /**
+     * Cache for update requests.
+     *
+     * @var CacheInterface
+     */
+    private $cache;
+
+    /**
+     * Logger instance.
+     *
+     * @var LoggerInterface
+     */
+    private $log;
+
+    /**
+     * Result of simulated installation.
+     *
+     * @var array
+     */
+    private $simulationResults = array();
+
+    /**
+     * Temporary download directory.
+     *
+     * @var string
+     */
+    private $tempDir = '';
+
+    /**
+     * Install directory.
+     *
+     * @var string
+     */
+    private $installDir = '';
+
+    /**
+     * Update branch.
+     *
+     * @var string
+     */
+    private $branch = '';
+
+    /**
+     * Username authentication
+     *
+     * @var string
+     */
+    private $username = '';
+
+    /**
+     * Password authentication
+     *
+     * @var string
+     */
+    private $password = '';
+
+    /*
+     * Callbacks to be called when each update is finished
+     *
+     * @var array
+     */
+    private $onEachUpdateFinishCallbacks = [];
+
+    /*
+     * Callbacks to be called when all updates are finished
+     *
+     * @var array
+     */
+    private $onAllUpdateFinishCallbacks = [];
+
+    /**
+     * If curl should verify the host certificate.
+     *
+     * @var bool
+     */
+    private $sslVerifyHost = true;
+
+    /**
+     * Url to the update folder on the server.
+     *
+     * @var string
+     */
+    protected $updateUrl = 'https://example.com/updates/';
+
+    /**
+     * Version filename on the server.
+     *
+     * @var string
+     */
+    protected $updateFile = 'update.json';
+
+    /**
+     * Current version.
+     *
+     * @var string
+     */
+    protected $currentVersion;
+
+    /**
+     * Create new folders with these privileges.
+     *
+     * @var int
+     */
+    public $dirPermissions = 0755;
+
+    /**
+     * Update script filename.
+     *
+     * @var string
+     */
+    public $updateScriptName = '_upgrade.php';
+
+    /**
+     * How long the cache should be valid (in seconds).
+     *
+     * @var int
+     */
+    protected $cacheTtl = 3600;
+
+    /**
+     * No update available.
+     */
+    public const NO_UPDATE_AVAILABLE = 0;
+
+    /**
+     * Could not check for last version.
+     */
+    public const ERROR_VERSION_CHECK = 20;
+
+    /**
+     * Temp directory does not exist or is not writable.
+     */
+    public const ERROR_TEMP_DIR = 30;
+
+    /**
+     * Install directory does not exist or is not writable.
+     */
+    public const ERROR_INSTALL_DIR = 35;
+
+    /**
+     * Could not download update.
+     */
+    public const ERROR_DOWNLOAD_UPDATE = 40;
+
+    /**
+     * Could not delete zip update file.
+     */
+    public const ERROR_DELETE_TEMP_UPDATE = 50;
+
+    /**
+     * Error in simulated installation.
+     */
+    public const ERROR_SIMULATE = 70;
+
+    /**
+     * Create new instance
+     *
+     * @param string|null $tempDir
+     * @param string|null $installDir
+     * @param int $maxExecutionTime
+     */
+    public function __construct(?string $tempDir = null, ?string $installDir = null, int $maxExecutionTime = 60)
+    {
+        // Init logger
+        $this->log = new Logger('auto-update');
+
+        $this->setTempDir($tempDir ?? (__DIR__ . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR));
+        $this->setInstallDir($installDir ?? (__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR));
+
+        $this->latestVersion  = '0.0.0';
+        $this->currentVersion = '0.0.0';
+
+        // Init cache
+        $this->cache = new NotCache();
+
+        ini_set('max_execution_time', $maxExecutionTime);
+    }
+
+    /**
+     * Set the temporary download directory.
+     *
+     * @param string $dir
+     * @return bool
+     */
+    public function setTempDir(string $dir): bool
+    {
+        $dir = $this->addTrailingSlash($dir);
+
+        if (!is_dir($dir)) {
+            $this->log->debug(sprintf('Creating new temporary directory "%s"', $dir));
+
+            if (!mkdir($dir, 0755, true) && !is_dir($dir)) {
+                $this->log->critical(sprintf('Could not create temporary directory "%s"', $dir));
+
+                return false;
+            }
+        }
+
+        $this->tempDir = $dir;
+
+        return true;
+    }
+
+    /**
+     * Set the installation directory.
+     *
+     * @param string $dir
+     * @return bool
+     */
+    public function setInstallDir(string $dir): bool
+    {
+        $dir = $this->addTrailingSlash($dir);
+
+        if (!is_dir($dir)) {
+            $this->log->debug(sprintf('Creating new install directory "%s"', $dir));
+
+            if (!mkdir($dir, 0755, true) && !is_dir($dir)) {
+                $this->log->critical(sprintf('Could not create install directory "%s"', $dir));
+
+                return false;
+            }
+        }
+
+        $this->installDir = $dir;
+
+        return true;
+    }
+
+    /**
+     * Set the update filename.
+     *
+     * @param string $updateFile
+     * @return AutoUpdate
+     */
+    public function setUpdateFile(string $updateFile): AutoUpdate
+    {
+        $this->updateFile = $updateFile;
+
+        return $this;
+    }
+
+    /**
+     * Set the update filename.
+     *
+     * @param string $updateUrl
+     * @return AutoUpdate
+     */
+    public function setUpdateUrl(string $updateUrl): AutoUpdate
+    {
+        $this->updateUrl = $updateUrl;
+
+        return $this;
+    }
+
+    /**
+     * Set the update branch.
+     *
+     * @param string branch
+     * @return AutoUpdate
+     */
+    public function setBranch($branch): AutoUpdate
+    {
+        $this->branch = $branch;
+
+        return $this;
+    }
+
+    /**
+     * Set the cache component.
+     *
+     * @param CacheInterface $adapter See https://github.com/desarrolla2/Cache
+     * @param int $ttl
+     * @return AutoUpdate
+     */
+    public function setCache(CacheInterface $adapter, int $ttl): AutoUpdate
+    {
+        $this->cache    = $adapter;
+        $this->cacheTtl = $ttl;
+
+        return $this;
+    }
+
+    /**
+     * Set the version of the current installed software.
+     *
+     * @param string $currentVersion
+     * @return AutoUpdate
+     */
+    public function setCurrentVersion(string $currentVersion): AutoUpdate
+    {
+        $this->currentVersion = $currentVersion;
+
+        return $this;
+    }
+
+    /**
+     * Set username and password for basic authentication.
+     *
+     * @param string $username
+     * @param string $password
+     * @return AutoUpdate
+     */
+    public function setBasicAuth(string $username, string $password): AutoUpdate
+    {
+        $this->username = $username;
+        $this->password = $password;
+
+        return $this;
+    }
+
+    /**
+     * Set authentication header if username and password exist.
+     *
+     * @return null|resource
+     */
+    private function useBasicAuth()
+    {
+        if ($this->username && $this->password) {
+            return stream_context_create(array(
+                'http' => array(
+                    'header' => "Authorization: Basic " . base64_encode("$this->username:$this->password")
+                )
+            ));
+        }
+
+        return null;
+    }
+
+    /**
+     * Replace the logger internally used by the given logger instance.
+     *
+     * @param LoggerInterface $logger
+     * @return AutoUpdate
+     */
+    public function setLogger(LoggerInterface $logger): AutoUpdate
+    {
+        $this->log = $logger;
+
+        return $this;
+    }
+
+    /**
+     * Get the name of the latest version.
+     *
+     * @return string
+     */
+    public function getLatestVersion(): string
+    {
+        return $this->latestVersion;
+    }
+
+    /**
+     * Get an array of versions which will be installed.
+     *
+     * @return array
+     */
+    public function getVersionsToUpdate(): array
+    {
+        if (count($this->updates) > 0) {
+            return array_map(static function ($update) {
+                return $update['version'];
+            }, $this->updates);
+        }
+
+        return [];
+    }
+
+    /**
+     * Get the results of the last simulation.
+     *
+     * @return array
+     */
+    public function getSimulationResults(): array
+    {
+        return $this->simulationResults;
+    }
+
+    /**
+     * @return bool
+     */
+    public function getSslVerifyHost(): bool
+    {
+        return $this->sslVerifyHost;
+    }
+
+    /**
+     * @param bool $sslVerifyHost
+     * @return AutoUpdate
+     */
+    public function setSslVerifyHost(bool $sslVerifyHost): AutoUpdate
+    {
+        $this->sslVerifyHost = $sslVerifyHost;
+
+        return $this;
+    }
+
+    /**
+     * Check for a new version
+     *
+     * @param int $timeout Download timeout in seconds (Only applied for downloads via curl)
+     * @return int|bool
+     *         true: New version is available
+     *         false: Error while checking for update
+     *         int: Status code (i.e. AutoUpdate::NO_UPDATE_AVAILABLE)
+     * @throws DownloadException
+     * @throws InvalidArgumentException
+     * @throws ParserException
+     */
+    public function checkUpdate(int $timeout = 10)
+    {
+        $this->log->notice('Checking for a new update...');
+
+        // Reset previous updates
+        $this->latestVersion = '0.0.0';
+        $this->updates       = [];
+
+        $versions = $this->cache->get('update-versions');
+
+        // Create absolute url to update file
+        $updateFile = $this->updateUrl . '/' . $this->updateFile;
+        if (!empty($this->branch)) {
+            $updateFile .= '.' . $this->branch;
+        }
+
+        // Check if cache is empty
+        if ($versions === null || $versions === false) {
+            $this->log->debug(sprintf('Get new updates from %s', $updateFile));
+
+            // Read update file from update server
+            if (function_exists('curl_version') && $this->isValidUrl($updateFile)) {
+                $update = $this->downloadCurl($updateFile, $timeout);
+
+                if ($update === false) {
+                    $this->log->error(sprintf('Could not download update file "%s" via curl!', $updateFile));
+
+                    throw new DownloadException($updateFile);
+                }
+            } else {
+                $update = @file_get_contents($updateFile, false, $this->useBasicAuth());
+
+                if ($update === false) {
+                    $this->log->error(sprintf('Could not download update file "%s" via file_get_contents!',
+                        $updateFile));
+
+                    throw new DownloadException($updateFile);
+                }
+            }
+
+            // Parse update file
+            $updateFileExtension = substr(strrchr($this->updateFile, '.'), 1);
+            switch ($updateFileExtension) {
+                case 'ini':
+                    $versions = parse_ini_string($update, true);
+                    if (!is_array($versions)) {
+                        $this->log->error('Unable to parse ini update file!');
+
+                        throw new ParserException(sprintf('Could not parse update ini file %s!', $this->updateFile));
+                    }
+
+                    $versions = array_map(static function ($block) {
+                        return $block['url'] ?? false;
+                    }, $versions);
+
+                    break;
+                case 'json':
+                    $versions = (array) json_decode($update, false);
+                    if (!is_array($versions)) {
+                        $this->log->error('Unable to parse json update file!');
+
+                        throw new ParserException(sprintf('Could not parse update json file %s!', $this->updateFile));
+                    }
+
+                    break;
+                default:
+                    $this->log->error(sprintf('Unknown file extension "%s"', $updateFileExtension));
+
+                    throw new ParserException(sprintf('Unknown file extension for update file %s!', $this->updateFile));
+            }
+
+            $this->cache->set('update-versions', $versions, $this->cacheTtl);
+        } else {
+            $this->log->debug('Got updates from cache');
+        }
+
+        if (!is_array($versions)) {
+            $this->log->error(sprintf('Could not read versions from server %s', $updateFile));
+
+            return false;
+        }
+
+        // Check for latest version
+        foreach ($versions as $version => $updateUrl) {
+            if (Comparator::greaterThan($version, $this->currentVersion)) {
+                if (Comparator::greaterThan($version, $this->latestVersion)) {
+                    $this->latestVersion = $version;
+                }
+
+                $this->updates[] = [
+                    'version' => $version,
+                    'url'     => $updateUrl,
+                ];
+            }
+        }
+
+        // Sort versions to install
+        usort($this->updates, static function ($a, $b) {
+            if (Comparator::equalTo($a['version'], $b['version'])) {
+                return 0;
+            }
+
+            return Comparator::lessThan($a['version'], $b['version']) ? - 1 : 1;
+        });
+
+        if ($this->newVersionAvailable()) {
+            $this->log->debug(sprintf('New version "%s" available', $this->latestVersion));
+
+            return true;
+        }
+
+        $this->log->debug('No new version available');
+
+        return self::NO_UPDATE_AVAILABLE;
+    }
+
+    /**
+     * Check if a new version is available.
+     *
+     * @return bool
+     */
+    public function newVersionAvailable(): bool
+    {
+        return Comparator::greaterThan($this->latestVersion, $this->currentVersion);
+    }
+
+    /**
+     * Check if url is valid.
+     *
+     * @param string $url
+     * @return bool
+     */
+    protected function isValidUrl(string $url): bool
+    {
+        return (filter_var($url, FILTER_VALIDATE_URL) !== false);
+    }
+
+    /**
+     * Download file via curl.
+     *
+     * @param string $url URL to file
+     * @param int $timeout
+     * @return string|false
+     */
+    protected function downloadCurl(string $url, int $timeout = 10)
+    {
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $url);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $this->sslVerifyHost ? 2 : 0);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->sslVerifyHost);
+        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
+        $update = curl_exec($curl);
+
+        $success = true;
+        if (curl_error($curl)) {
+            $success = false;
+            $this->log->error(sprintf(
+                'Could not download update "%s" via curl: %s!',
+                $url,
+                curl_error($curl)
+            ));
+        }
+        curl_close($curl);
+
+        return ($success === true) ? $update : false;
+    }
+
+    /**
+     * Download the update
+     *
+     * @param string $updateUrl Url where to download from
+     * @param string $updateFile Path where to save the download
+     * @return bool
+     * @throws DownloadException
+     * @throws Exception
+     */
+    protected function downloadUpdate(string $updateUrl, string $updateFile): bool
+    {
+        $this->log->info(sprintf('Downloading update "%s" to "%s"', $updateUrl, $updateFile));
+        if (function_exists('curl_version') && $this->isValidUrl($updateUrl)) {
+            $update = $this->downloadCurl($updateUrl);
+            if ($update === false) {
+                return false;
+            }
+        } elseif (ini_get('allow_url_fopen')) {
+            $update = @file_get_contents($updateUrl, false, $this->useBasicAuth());
+
+            if ($update === false) {
+                $this->log->error(sprintf('Could not download update "%s"!', $updateUrl));
+
+                throw new DownloadException($updateUrl);
+            }
+        } else {
+            throw new RuntimeException('No valid download method found!');
+        }
+
+        $handle = fopen($updateFile, 'wb');
+        if (!$handle) {
+            $this->log->error(sprintf('Could not open file handle to save update to "%s"!', $updateFile));
+
+            return false;
+        }
+
+        if (!fwrite($handle, $update)) {
+            $this->log->error(sprintf('Could not write update to file "%s"!', $updateFile));
+            fclose($handle);
+
+            return false;
+        }
+
+        fclose($handle);
+
+        return true;
+    }
+
+    /**
+     * Simulate update process.
+     *
+     * @param string $updateFile
+     * @return bool
+     */
+    protected function simulateInstall(string $updateFile): bool
+    {
+        $this->log->notice('[SIMULATE] Install new version');
+        clearstatcache();
+
+        // Check if zip file could be opened
+        $zip = new ZipArchive();
+        $resource = $zip->open($updateFile);
+        if ($resource !== true) {
+            $this->log->error(sprintf('Could not open zip file "%s", error: %d', $updateFile, $resource));
+
+            return false;
+        }
+
+        $files           = [];
+        $simulateSuccess = true;
+
+        for ($i = 0; $i < $zip->numFiles; $i++) {
+            $fileStats        = $zip->statIndex($i);
+            $filename         = $fileStats['name'];
+            $foldername       = $this->installDir . dirname($filename);
+            $absoluteFilename = $this->installDir . $filename;
+
+            $files[$i] = [
+                'filename'          => $filename,
+                'foldername'        => $foldername,
+                'absolute_filename' => $absoluteFilename,
+            ];
+
+            $this->log->debug(sprintf('[SIMULATE] Updating file "%s"', $filename));
+
+            // Check if parent directory is writable
+            if (!is_dir($foldername)) {
+                if (!mkdir($foldername) && !is_dir($foldername)) {
+                    throw new RuntimeException(sprintf('Directory "%s" was not created', $foldername));
+                }
+                $this->log->debug(sprintf('[SIMULATE] Create directory "%s"', $foldername));
+                $files[$i]['parent_folder_exists'] = false;
+
+                $parent = dirname($foldername);
+                if (!is_writable($parent)) {
+                    $files[$i]['parent_folder_writable'] = false;
+
+                    $simulateSuccess = false;
+                    $this->log->warning(sprintf('[SIMULATE] Directory "%s" has to be writeable!', $parent));
+                } else {
+                    $files[$i]['parent_folder_writable'] = true;
+                }
+            }
+
+            // Skip if entry is a directory
+            if ($filename[strlen($filename) - 1] === DIRECTORY_SEPARATOR) {
+                continue;
+            }
+
+            // Write to file
+            if (file_exists($absoluteFilename)) {
+                $files[$i]['file_exists'] = true;
+                if (!is_writable($absoluteFilename)) {
+                    $files[$i]['file_writable'] = false;
+
+                    $simulateSuccess = false;
+                    $this->log->warning(sprintf('[SIMULATE] Could not overwrite "%s"!', $absoluteFilename));
+                }
+            } else {
+                $files[$i]['file_exists'] = false;
+
+                if (is_dir($foldername)) {
+                    if (!is_writable($foldername)) {
+                        $files[$i]['file_writable'] = false;
+
+                        $simulateSuccess = false;
+                        $this->log->warning(sprintf('[SIMULATE] The file "%s" could not be created!',
+                            $absoluteFilename));
+                    } else {
+                        $files[$i]['file_writable'] = true;
+                    }
+                } else {
+                    $files[$i]['file_writable'] = true;
+
+                    $this->log->debug(sprintf('[SIMULATE] The file "%s" could be created', $absoluteFilename));
+                }
+            }
+
+            if ($filename === $this->updateScriptName) {
+                $this->log->debug(sprintf('[SIMULATE] Update script "%s" found', $absoluteFilename));
+                $files[$i]['update_script'] = true;
+            } else {
+                $files[$i]['update_script'] = false;
+            }
+        }
+
+        $zip->close();
+
+        $this->simulationResults = $files;
+
+        return $simulateSuccess;
+    }
+
+    /**
+     * Install update.
+     *
+     * @param string $updateFile Path to the update file
+     * @param bool $simulateInstall Check for directory and file permissions instead of installing the update
+     * @param string $version
+     * @return bool
+     */
+    protected function install(string $updateFile, bool $simulateInstall, string $version): bool
+    {
+        $this->log->notice(sprintf('Trying to install update "%s"', $updateFile));
+
+        // Check if install should be simulated
+        if ($simulateInstall) {
+            if ($this->simulateInstall($updateFile)) {
+                $this->log->notice(sprintf('Simulation of update "%s" process succeeded', $version));
+
+                return true;
+            }
+
+            $this->log->critical(sprintf('Simulation of update  "%s" process failed!', $version));
+
+            return self::ERROR_SIMULATE;
+        }
+
+        clearstatcache();
+
+        // Install only if simulateInstall === false
+
+        // Check if zip file could be opened
+        $zip = new ZipArchive();
+        $resource = $zip->open($updateFile);
+        if ($resource !== true) {
+            $this->log->error(sprintf('Could not open zip file "%s", error: %d', $updateFile, $resource));
+
+            return false;
+        }
+
+        // Read every file from archive
+        for ($i = 0; $i < $zip->numFiles; $i++) {
+            $fileStats        = $zip->statIndex($i);
+            $filename         = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $fileStats['name']);
+            $foldername       = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR,
+                $this->installDir . dirname($filename));
+            $absoluteFilename = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->installDir . $filename);
+            $this->log->debug(sprintf('Updating file "%s"', $filename));
+
+            if (!is_dir($foldername) && !mkdir($foldername, $this->dirPermissions, true) && !is_dir($foldername)) {
+                $this->log->error(sprintf('Directory "%s" has to be writeable!', $foldername));
+
+                return false;
+            }
+
+            // Skip if entry is a directory
+            if ($filename[strlen($filename) - 1] === DIRECTORY_SEPARATOR) {
+                continue;
+            }
+
+            // Extract file
+            if ($zip->extractTo($this->installDir, $fileStats['name']) === false) {
+                $this->log->error(sprintf('Could not read zip entry "%s"', $fileStats['name']));
+                continue;
+            }
+
+            //If file is a update script, include
+            if ($filename === $this->updateScriptName) {
+                $this->log->debug(sprintf('Try to include update script "%s"', $absoluteFilename));
+                require($absoluteFilename);
+
+                $this->log->info(sprintf('Update script "%s" included!', $absoluteFilename));
+                if (!unlink($absoluteFilename)) {
+                    $this->log->warning(sprintf('Could not delete update script "%s"!', $absoluteFilename));
+                }
+            }
+        }
+
+        $zip->close();
+
+        $this->log->notice(sprintf('Update "%s" successfully installed', $version));
+
+        return true;
+    }
+
+    /**
+     * Update to the latest version
+     *
+     * @param bool $simulateInstall Check for directory and file permissions before copying files (Default: true)
+     * @param bool $deleteDownload Delete download after update (Default: true)
+     * @return integer|bool
+     * @throws DownloadException
+     * @throws ParserException
+     * @throws InvalidArgumentException
+     */
+    public function update(bool $simulateInstall = true, bool $deleteDownload = true)
+    {
+        $this->log->info('Trying to perform update');
+
+        // Check for latest version
+        if ($this->latestVersion === null || count($this->updates) === 0) {
+            $this->checkUpdate();
+        }
+
+        if ($this->latestVersion === null || count($this->updates) === 0) {
+            $this->log->error('Could not get latest version from server!');
+
+            return self::ERROR_VERSION_CHECK;
+        }
+
+        // Check if current version is up-to-date
+        if (!$this->newVersionAvailable()) {
+            $this->log->warning('No update available!');
+
+            return self::NO_UPDATE_AVAILABLE;
+        }
+
+        foreach ($this->updates as $update) {
+            $this->log->debug(sprintf('Update to version "%s"', $update['version']));
+
+            // Check for temp directory
+            if (empty($this->tempDir) || !is_dir($this->tempDir) || !is_writable($this->tempDir)) {
+                $this->log->critical(sprintf('Temporary directory "%s" does not exist or is not writeable!',
+                    $this->tempDir));
+
+                return self::ERROR_TEMP_DIR;
+            }
+
+            // Check for install directory
+            if (empty($this->installDir) || !is_dir($this->installDir) || !is_writable($this->installDir)) {
+                $this->log->critical(sprintf('Install directory "%s" does not exist or is not writeable!',
+                    $this->installDir));
+
+                return self::ERROR_INSTALL_DIR;
+            }
+
+            $updateFile = $this->tempDir . $update['version'] . '.zip';
+
+            // Download update
+            if (!is_file($updateFile)) {
+                if (!$this->downloadUpdate($update['url'], $updateFile)) {
+                    $this->log->critical(sprintf('Failed to download update from "%s" to "%s"!', $update['url'],
+                        $updateFile));
+
+                    return self::ERROR_DOWNLOAD_UPDATE;
+                }
+
+                $this->log->debug(sprintf('Latest update downloaded to "%s"', $updateFile));
+            } else {
+                $this->log->info(sprintf('Latest update already downloaded to "%s"', $updateFile));
+            }
+
+            // Install update
+            $result = $this->install($updateFile, $simulateInstall, $update['version']);
+            if ($result === true) {
+                $this->runOnEachUpdateFinishCallbacks($update['version'], $simulateInstall);
+                if ($deleteDownload) {
+                    $this->log->debug(sprintf('Trying to delete update file "%s" after successfull update',
+                        $updateFile));
+                    if (unlink($updateFile)) {
+                        $this->log->info(sprintf('Update file "%s" deleted after successfull update', $updateFile));
+                    } else {
+                        $this->log->error(sprintf('Could not delete update file "%s" after successfull update!',
+                            $updateFile));
+
+                        return self::ERROR_DELETE_TEMP_UPDATE;
+                    }
+                }
+            } else {
+                if ($deleteDownload) {
+                    $this->log->debug(sprintf('Trying to delete update file "%s" after failed update', $updateFile));
+                    if (unlink($updateFile)) {
+                        $this->log->info(sprintf('Update file "%s" deleted after failed update', $updateFile));
+                    } else {
+                        $this->log->error(sprintf('Could not delete update file "%s" after failed update!',
+                            $updateFile));
+                    }
+                }
+
+                return false;
+            }
+        }
+
+        $this->runOnAllUpdateFinishCallbacks($this->getVersionsToUpdate());
+
+        return true;
+    }
+
+    /**
+     * Add slash at the end of the path.
+     *
+     * @param string $dir
+     * @return string
+     */
+    public function addTrailingSlash(string $dir): string
+    {
+        if (substr($dir, - 1) !== DIRECTORY_SEPARATOR) {
+            $dir .= DIRECTORY_SEPARATOR;
+        }
+
+        return $dir;
+    }
+
+    /**
+     * Add callback which is executed after each update finished.
+     *
+     * @param callable $callback
+     * @return $this
+     */
+    public function onEachUpdateFinish(callable $callback): self
+    {
+        $this->onEachUpdateFinishCallbacks[] = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Add callback which is executed after all updates finished.
+     *
+     * @param callable $callback
+     * @return $this
+     */
+    public function setOnAllUpdateFinishCallbacks(callable $callback): self
+    {
+        $this->onAllUpdateFinishCallbacks[] = $callback;
+
+        return $this;
+    }
+
+    /**
+     * Run callbacks after each update finished.
+     *
+     * @param string $updateVersion
+     * @param bool $simulate
+     * @return void
+     */
+    private function runOnEachUpdateFinishCallbacks(string $updateVersion, bool $simulate): void
+    {
+        foreach ($this->onEachUpdateFinishCallbacks as $callback) {
+            $callback($updateVersion, $simulate);
+        }
+    }
+
+    /**
+     * Run callbacks after all updates finished.
+     *
+     * @param array $updatedVersions
+     * @return void
+     */
+    private function runOnAllUpdateFinishCallbacks(array $updatedVersions): void
+    {
+        foreach ($this->onAllUpdateFinishCallbacks as $callback) {
+            $callback($updatedVersions);
+        }
+    }
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/src/Exceptions/DownloadException.php b/msd/vendor/visualappeal/php-auto-update/src/Exceptions/DownloadException.php
new file mode 100644
index 00000000..48ef5935
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/src/Exceptions/DownloadException.php
@@ -0,0 +1,5 @@
+<?php namespace VisualAppeal\Exceptions;
+
+use Exception;
+
+class DownloadException extends Exception {}
diff --git a/msd/vendor/visualappeal/php-auto-update/src/Exceptions/ParserException.php b/msd/vendor/visualappeal/php-auto-update/src/Exceptions/ParserException.php
new file mode 100644
index 00000000..2478bc0a
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/src/Exceptions/ParserException.php
@@ -0,0 +1,5 @@
+<?php namespace VisualAppeal\Exceptions;
+
+use Exception;
+
+class ParserException extends Exception {}
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/AutoUpdateTest.php b/msd/vendor/visualappeal/php-auto-update/tests/AutoUpdateTest.php
new file mode 100644
index 00000000..d01bc0f9
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/AutoUpdateTest.php
@@ -0,0 +1,181 @@
+<?php
+
+require(__DIR__ . '/../vendor/autoload.php');
+
+use PHPUnit\Framework\TestCase;
+
+use VisualAppeal\AutoUpdate;
+use VisualAppeal\Exceptions\DownloadException;
+use VisualAppeal\Exceptions\ParserException;
+
+class AutoUpdateTest extends TestCase
+{
+    /**
+     * AutoUpdate instance.
+     *
+     * @var AutoUpdate
+     */
+    private $_update;
+
+    /**
+     * Setup the auto update.
+     */
+    protected function setUp(): void
+    {
+        $this->_update = new AutoUpdate(__DIR__ . DIRECTORY_SEPARATOR . 'temp', __DIR__ . DIRECTORY_SEPARATOR . 'install');
+        $this->_update->setCurrentVersion('0.1.0');
+        $this->_update->setUpdateUrl(__DIR__ . DIRECTORY_SEPARATOR . 'fixtures');
+        $logger = new Monolog\Logger("default");
+        $logger->pushHandler(new Monolog\Handler\StreamHandler(__DIR__ . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'update.log'));
+        $this->_update->setLogger($logger);
+    }
+
+    /**
+     * Unset the auto update.
+     */
+    protected function tearDown(): void
+    {
+        unset($this->_update);
+        $this->_update = null;
+    }
+
+    /**
+     * Test creation of class instance.
+     */
+    public function testInit(): void
+    {
+        self::assertInstanceOf(AutoUpdate::class, $this->_update);
+    }
+
+    /**
+     * Test if errors get catched if no update file was found.
+     *
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testErrorUpdateCheck(): void
+    {
+        $this->expectException(DownloadException::class);
+
+        $this->_update->setUpdateFile('404.json');
+        $this->_update->checkUpdate();
+
+        self::assertFalse($this->_update->newVersionAvailable());
+        self::assertCount(0, $this->_update->getVersionsToUpdate());
+    }
+
+    /**
+     * Test if new update is available with a json file.
+     *
+     * @throws DownloadException
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testJsonNewVersion(): void
+    {
+        $this->_update->setUpdateFile('updateAvailable.json');
+        $response = $this->_update->checkUpdate();
+
+        self::assertTrue($response);
+        self::assertTrue($this->_update->newVersionAvailable());
+        self::assertEquals('0.2.1', $this->_update->getLatestVersion());
+
+        $newVersions = $this->_update->getVersionsToUpdate();
+        self::assertCount(2, $newVersions);
+        self::assertEquals('0.2.0', $newVersions[0]);
+        self::assertEquals('0.2.1', $newVersions[1]);
+    }
+
+    /**
+     * Test if NO new update is available with a json file.
+     *
+     * @throws DownloadException
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testJsonNoNewVersion(): void
+    {
+        $this->_update->setUpdateFile('noUpdateAvailable.json');
+        $response = $this->_update->checkUpdate();
+
+        self::assertEquals(AutoUpdate::NO_UPDATE_AVAILABLE, $response);
+        self::assertFalse($this->_update->newVersionAvailable());
+        self::assertCount(0, $this->_update->getVersionsToUpdate());
+    }
+
+    /**
+     * Test if new update is available with a ini file.
+     *
+     * @throws DownloadException
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testIniNewVersion(): void
+    {
+        $this->_update->setUpdateFile('updateAvailable.ini');
+        $response = $this->_update->checkUpdate();
+
+        self::assertTrue($response);
+        self::assertTrue($this->_update->newVersionAvailable());
+        self::assertEquals('0.2.1', $this->_update->getLatestVersion());
+
+        $newVersions = $this->_update->getVersionsToUpdate();
+        self::assertCount(2, $newVersions);
+        self::assertEquals('0.2.0', $newVersions[0]);
+        self::assertEquals('0.2.1', $newVersions[1]);
+    }
+
+    /**
+     * Test if NO new update is available with a ini file.
+     *
+     * @throws DownloadException
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testIniNoNewVersion(): void
+    {
+        $this->_update->setUpdateFile('noUpdateAvailable.ini');
+        $response = $this->_update->checkUpdate();
+
+        self::assertEquals(AutoUpdate::NO_UPDATE_AVAILABLE, $response);
+        self::assertFalse($this->_update->newVersionAvailable());
+        self::assertCount(0, $this->_update->getVersionsToUpdate());
+    }
+
+    /**
+     * Ensure that a new dev version is available.
+     *
+     * @throws DownloadException
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testBranchDev(): void
+    {
+        $this->_update->setUpdateFile('updateAvailable.json');
+        $this->_update->setBranch('dev');
+        $response = $this->_update->checkUpdate();
+
+        self::assertTrue($response);
+    }
+
+    /**
+     * Ensure that no new master version is available
+     *
+     * @throws DownloadException
+     * @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
+     */
+    public function testBranchMaster(): void
+    {
+        $this->_update->setUpdateFile('noUpdateAvailable.json');
+        $this->_update->setBranch('master');
+        $response = $this->_update->checkUpdate();
+
+        self::assertEquals(AutoUpdate::NO_UPDATE_AVAILABLE, $response);
+    }
+
+    /**
+     * Test the trailing slash method.
+     */
+    public function testTrailingSlashes(): void
+    {
+        $dir = DIRECTORY_SEPARATOR . 'test';
+        self::assertEquals(DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR, $this->_update->addTrailingSlash($dir));
+
+        $dir = DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR;
+        self::assertEquals(DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR, $this->_update->addTrailingSlash($dir));
+    }
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/UnitTests.xml b/msd/vendor/visualappeal/php-auto-update/tests/UnitTests.xml
new file mode 100644
index 00000000..7e6fc025
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/UnitTests.xml
@@ -0,0 +1,7 @@
+<phpunit>
+	<testsuites>
+		<testsuite name="unit">
+			<directory>./</directory>
+		</testsuite>
+	</testsuites>
+</phpunit>
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.ini b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.ini
new file mode 100644
index 00000000..1a227522
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.ini
@@ -0,0 +1,8 @@
+[0.1.0]
+url = http://127.0.0.1:80/example/server/0.1.0.zip
+
+[0.0.1]
+url = http://127.0.0.1:80/example/server/0.0.1.zip
+
+[0.0.4]
+url = http://127.0.0.1:80/example/server/0.0.4.zip
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json
new file mode 100644
index 00000000..794a8a31
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json
@@ -0,0 +1,5 @@
+{
+	"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
+	"0.0.1": "http://127.0.0.1:80/example/server/0.0.1.zip",
+	"0.0.4": "http://127.0.0.1:80/example/server/0.0.4.zip"
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json.master b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json.master
new file mode 100644
index 00000000..794a8a31
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json.master
@@ -0,0 +1,5 @@
+{
+	"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
+	"0.0.1": "http://127.0.0.1:80/example/server/0.0.1.zip",
+	"0.0.4": "http://127.0.0.1:80/example/server/0.0.4.zip"
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.ini b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.ini
new file mode 100644
index 00000000..c63b84b0
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.ini
@@ -0,0 +1,8 @@
+[0.1.0]
+url = http://127.0.0.1:80/example/server/0.1.0.zip
+
+[0.2.0]
+url = http://127.0.0.1:80/example/server/0.2.0.zip
+
+[0.2.1]
+url = http://127.0.0.1:80/example/server/0.2.1.zip
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json
new file mode 100644
index 00000000..d478eb31
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json
@@ -0,0 +1,5 @@
+{
+	"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
+	"0.2.0": "http://127.0.0.1:80/example/server/0.2.0.zip",
+	"0.2.1": "http://127.0.0.1:80/example/server/0.2.1.zip"
+}
diff --git a/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json.dev b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json.dev
new file mode 100644
index 00000000..d478eb31
--- /dev/null
+++ b/msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json.dev
@@ -0,0 +1,5 @@
+{
+	"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
+	"0.2.0": "http://127.0.0.1:80/example/server/0.2.0.zip",
+	"0.2.1": "http://127.0.0.1:80/example/server/0.2.1.zip"
+}
diff --git a/msd/work/config/myoosdumper.conf.php b/msd/work/config/myoosdumper.conf.php
index 201b92b7..ff5e6023 100644
--- a/msd/work/config/myoosdumper.conf.php
+++ b/msd/work/config/myoosdumper.conf.php
@@ -1,5 +1,5 @@
 <?php
-#Vars - written at 2019-09-25
+#Vars - written at 2023-02-11
 $dbhost="localhost";
 $dbname="leitgedanken";
 $dbuser="lgadmin";
@@ -7,18 +7,18 @@ $dbpass="!S1ge1nA";
 $dbport=3306;
 $dbsocket="";
 $compression=1;
-$backup_path="/var/www/web360/htdocs/leitgedanken_utf8/msd/work/backup/";
-$logdatei="/var/www/web360/htdocs/leitgedanken_utf8/msd/work/log/mysqldump_perl.log.gz";
-$completelogdatei="/var/www/web360/htdocs/leitgedanken_utf8/msd/work/log/mysqldump_perl.complete.log.gz";
+$backup_path="/var/www/web360/htdocs/leitgedanken_php8/msd/work/backup/";
+$logdatei="/var/www/web360/htdocs/leitgedanken_php8/msd/work/log/myoosdumper_perl.log.gz";
+$completelogdatei="/var/www/web360/htdocs/leitgedanken_php8/msd/work/log/myoosdumper_perl.complete.log.gz";
 $sendmail_call="/usr/sbin/sendmail -t -i";
 $nl="\n";
 $cron_dbindex=0;
 $cron_printout=1;
-$cronmail=0;
+$cronmail=1;
 $cronmail_dump=0;
-$cronmailto="";
+$cronmailto="netblack\@gmx.de";
 $cronmailto_cc="";
-$cronmailfrom="";
+$cronmailfrom="Alexander Schwarz";
 $cron_use_sendmail=1;
 $cron_smtp="localhost";
 $cron_smtp_port="25";
@@ -26,17 +26,17 @@ $cron_smtp_port="25";
 @cron_dbpraefix_array=("");
 @cron_command_before_dump=("");
 @cron_command_after_dump=("");
-@ftp_server=("www2.ja-schwarz.de","aundj.homeftp.net","lg-on.de");
+@ftp_server=("www2.ja-schwarz.de","lg-on.de","");
 @ftp_port=(21,21,21);
 @ftp_mode=(0,0,0);
-@ftp_user=("backup","ali","web360");
-@ftp_pass=("7655843","7655843","60050101");
-@ftp_dir=("/backup/lg-on/","/ali/","/htdocs/leitgedanken_utf8/backup/dump/save/");
+@ftp_user=("backup","web360","");
+@ftp_pass=("!S1ge1nA","60050101","");
+@ftp_dir=("/backup/lg-on/","/htdocs/leitgedanken_php8/backup/dump/save/","/");
 @ftp_timeout=(30,30,30);
 @ftp_useSSL=(0,0,0);
-@ftp_transfer=(1,0,1);
+@ftp_transfer=(1,1,0);
 $mp=0;
-$multipart_groesse=0;
+$multipart_groesse=1048576;
 $email_maxsize=3145728;
 $auto_delete=1;
 $max_backup_files=20;
diff --git a/msd/work/config/myoosdumper.php b/msd/work/config/myoosdumper.php
index 90473ffd..e9c1b0b5 100644
--- a/msd/work/config/myoosdumper.php
+++ b/msd/work/config/myoosdumper.php
@@ -6,68 +6,109 @@ $config['dbuser'] = 'lgadmin';
 $config['dbpass'] = '!S1ge1nA';
 $config['dbport'] = '';
 $config['dbsocket'] = '';
-$config['manual_db'] = '';
+$config['manual_db'] = 'leitgedanken';
 $config['minspeed'] = '100';
 $config['maxspeed'] = '50000';
-$config['theme'] = 'msd';
+$config['theme'] = 'mod';
 $config['interface_server_caption'] = '1';
 $config['interface_server_captioncolor'] = '#ff9966';
 $config['interface_server_caption_position'] = '0';
 $config['interface_sqlboxsize'] = '70';
 $config['interface_table_compact'] = '0';
-$config['memory_limit'] = '60397978';
+$config['memory_limit'] = '90596966';
 $config['compression'] = '1';
 $config['processlist_refresh'] = '3000';
 $config['empty_db_before_restore'] = '1';
 $config['optimize_tables_beforedump'] = '1';
+$config['use_binary_container'] = '0';
 $config['stop_with_error'] = '1';
-$config['send_mail'] = '0';
+$config['send_mail'] = '1';
 $config['send_mail_dump'] = '0';
-$config['email_recipient'] = '';
+$config['email_recipient'] = 'netblack@gmx.de';
 $config['email_recipient_cc'] = '';
-$config['email_sender'] = '';
+$config['email_sender'] = 'Alexander Schwarz';
 $config['email_maxsize1'] = '3';
 $config['email_maxsize2'] = '2';
-$config['ftp_transfer']=array();
+$config['ftp_transfer'] = [];
 $config['ftp_transfer'][0] = '1';
-$config['ftp_transfer'][1] = '0';
-$config['ftp_transfer'][2] = '1';
-$config['ftp_timeout']=array();
+$config['ftp_transfer'][1] = '1';
+$config['ftp_transfer'][2] = '0';
+$config['ftp_timeout'] = [];
 $config['ftp_timeout'][0] = '30';
 $config['ftp_timeout'][1] = '30';
 $config['ftp_timeout'][2] = '30';
-$config['ftp_useSSL']=array();
+$config['ftp_useSSL'] = [];
 $config['ftp_useSSL'][0] = '0';
 $config['ftp_useSSL'][1] = '0';
 $config['ftp_useSSL'][2] = '0';
-$config['ftp_mode']=array();
+$config['ftp_mode'] = [];
 $config['ftp_mode'][0] = '0';
 $config['ftp_mode'][1] = '0';
 $config['ftp_mode'][2] = '0';
-$config['ftp_server']=array();
+$config['ftp_server'] = [];
 $config['ftp_server'][0] = 'www2.ja-schwarz.de';
-$config['ftp_server'][1] = 'aundj.homeftp.net';
-$config['ftp_server'][2] = 'lg-on.de';
-$config['ftp_port']=array();
+$config['ftp_server'][1] = 'lg-on.de';
+$config['ftp_server'][2] = '';
+$config['ftp_port'] = [];
 $config['ftp_port'][0] = '21';
 $config['ftp_port'][1] = '21';
 $config['ftp_port'][2] = '21';
-$config['ftp_user']=array();
+$config['ftp_user'] = [];
 $config['ftp_user'][0] = 'backup';
-$config['ftp_user'][1] = 'ali';
-$config['ftp_user'][2] = 'web360';
-$config['ftp_pass']=array();
-$config['ftp_pass'][0] = '7655843';
-$config['ftp_pass'][1] = '7655843';
-$config['ftp_pass'][2] = '60050101';
-$config['ftp_dir']=array();
+$config['ftp_user'][1] = 'web360';
+$config['ftp_user'][2] = '';
+$config['ftp_pass'] = [];
+$config['ftp_pass'][0] = '!S1ge1nA';
+$config['ftp_pass'][1] = '60050101';
+$config['ftp_pass'][2] = '';
+$config['ftp_dir'] = [];
 $config['ftp_dir'][0] = '/backup/lg-on/';
-$config['ftp_dir'][1] = '/ali/';
-$config['ftp_dir'][2] = '/htdocs/leitgedanken_utf8/backup/dump/save/';
+$config['ftp_dir'][1] = '/htdocs/leitgedanken_php8/backup/dump/save/';
+$config['ftp_dir'][2] = '/';
+$config['sftp_transfer'] = [];
+$config['sftp_transfer'][0] = '0';
+$config['sftp_transfer'][1] = '0';
+$config['sftp_transfer'][2] = '0';
+$config['sftp_timeout'] = [];
+$config['sftp_timeout'][0] = '30';
+$config['sftp_timeout'][1] = '30';
+$config['sftp_timeout'][2] = '30';
+$config['sftp_server'] = [];
+$config['sftp_server'][0] = '';
+$config['sftp_server'][1] = '';
+$config['sftp_server'][2] = '';
+$config['sftp_port'] = [];
+$config['sftp_port'][0] = '22';
+$config['sftp_port'][1] = '22';
+$config['sftp_port'][2] = '22';
+$config['sftp_user'] = [];
+$config['sftp_user'][0] = '';
+$config['sftp_user'][1] = '';
+$config['sftp_user'][2] = '';
+$config['sftp_pass'] = [];
+$config['sftp_pass'][0] = '';
+$config['sftp_pass'][1] = '';
+$config['sftp_pass'][2] = '';
+$config['sftp_dir'] = [];
+$config['sftp_dir'][0] = '/';
+$config['sftp_dir'][1] = '/';
+$config['sftp_dir'][2] = '/';
+$config['sftp_path_to_private_key'] = [];
+$config['sftp_path_to_private_key'][0] = '';
+$config['sftp_path_to_private_key'][1] = '';
+$config['sftp_path_to_private_key'][2] = '';
+$config['sftp_secret_passphrase_for_private_key'] = [];
+$config['sftp_secret_passphrase_for_private_key'][0] = '';
+$config['sftp_secret_passphrase_for_private_key'][1] = '';
+$config['sftp_secret_passphrase_for_private_key'][2] = '';
+$config['sftp_fingerprint'] = [];
+$config['sftp_fingerprint'][0] = '';
+$config['sftp_fingerprint'][1] = '';
+$config['sftp_fingerprint'][2] = '';
 $config['multi_part'] = '0';
-$config['multipartgroesse1'] = '0';
-$config['multipartgroesse2'] = '0';
-$config['multipart_groesse'] = '0';
+$config['multipartgroesse1'] = '1';
+$config['multipartgroesse2'] = '2';
+$config['multipart_groesse'] = '1048576';
 $config['auto_delete'] = '1';
 $config['max_backup_files'] = '20';
 $config['cron_perlpath'] = '/usr/bin/perl';
@@ -87,32 +128,35 @@ $config['log_maxsize2'] = '2';
 $config['log_maxsize'] = '1048576';
 $config['cron_dbindex'] = '1';
 $config['email_maxsize'] = '3145728';
-$config['cron_execution_path'] = 'msd_cron/';
+$config['cron_execution_path'] = 'mod_cron/';
 $config['sql_limit'] = '30';
 $config['bb_width'] = '300';
 $config['bb_textcolor'] = '#000000';
-$databases['Name']=array();
+$config['sftp'] = [];
+$config['sftp'][0] = '0';
+$config['sftp'][1] = '0';
+$databases['Name'] = [];
 $databases['Name'][0] = 'information_schema';
 $databases['Name'][1] = 'leitgedanken';
-$databases['praefix']=array();
+$databases['praefix'] = [];
 $databases['praefix'][0] = '';
 $databases['praefix'][1] = '';
-$databases['command_before_dump']=array();
+$databases['command_before_dump'] = [];
 $databases['command_before_dump'][0] = '';
 $databases['command_before_dump'][1] = '';
-$databases['command_after_dump']=array();
+$databases['command_after_dump'] = [];
 $databases['command_after_dump'][0] = '';
 $databases['command_after_dump'][1] = '';
 $databases['db_selected_index'] = '1';
 $databases['db_actual'] = 'leitgedanken';
-$databases['multi']=array();
+$databases['multi'] = [];
 $databases['multi'][0] = 'leitgedanken';
-$databases['multi_praefix']=array();
+$databases['multi_praefix'] = [];
 $databases['multi_praefix'][0] = '';
 $databases['multisetting'] = 'leitgedanken';
-$databases['multi_commandbeforedump']=array();
+$databases['multi_commandbeforedump'] = [];
 $databases['multi_commandbeforedump'][0] = '';
-$databases['multi_commandafterdump']=array();
+$databases['multi_commandafterdump'] = [];
 $databases['multi_commandafterdump'][0] = '';
 $databases['multisetting_praefix'] = '';
 $databases['multisetting_commandbeforedump'] = '';
diff --git a/msd/work/log/mysqldump.log.gz b/msd/work/log/mysqldump.log.gz
deleted file mode 100644
index e0ea2d6b..00000000
Binary files a/msd/work/log/mysqldump.log.gz and /dev/null differ
diff --git a/msd/work/log/mysqldump_perl.complete.log.gz b/msd/work/log/mysqldump_perl.complete.log.gz
deleted file mode 100644
index bd831658..00000000
Binary files a/msd/work/log/mysqldump_perl.complete.log.gz and /dev/null differ
diff --git a/msd/work/log/mysqldump_perl.log.gz b/msd/work/log/mysqldump_perl.log.gz
deleted file mode 100644
index 29660fe3..00000000
Binary files a/msd/work/log/mysqldump_perl.log.gz and /dev/null differ