git subrepo commit (merge) mailcow/src/mailcow-dockerized

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "02ae5285"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "649a5c01"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: I870ad468fba026cc5abf3c5699ed1e12ff28b32b
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/CHANGELOG.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/CHANGELOG.md
new file mode 100644
index 0000000..3341328
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/CHANGELOG.md
@@ -0,0 +1,169 @@
+CHANGELOG
+=========
+
+5.3
+---
+
+ * Add `translation:pull` and `translation:push` commands to manage translations with third-party providers
+ * Add `TranslatorBagInterface::getCatalogues` method
+ * Add support to load XLIFF string in `XliffFileLoader`
+
+5.2.0
+-----
+
+ * added support for calling `trans` with ICU formatted messages
+ * added `PseudoLocalizationTranslator`
+ * added `TranslatableMessage` objects that represent a message that can be translated
+ * added the `t()` function to easily create `TranslatableMessage` objects
+ * Added support for extracting messages from `TranslatableMessage` objects
+
+5.1.0
+-----
+
+ * added support for `name` attribute on `unit` element from xliff2 to be used as a translation key instead of always the `source` element
+
+5.0.0
+-----
+
+ * removed support for using `null` as the locale in `Translator`
+ * removed `TranslatorInterface`
+ * removed `MessageSelector`
+ * removed `ChoiceMessageFormatterInterface`
+ * removed `PluralizationRule`
+ * removed `Interval`
+ * removed `transChoice()` methods, use the trans() method instead with a %count% parameter
+ * removed `FileDumper::setBackup()` and `TranslationWriter::disableBackup()`
+ * removed `MessageFormatter::choiceFormat()`
+ * added argument `$filename` to `PhpExtractor::parseTokens()`
+ * removed support for implicit STDIN usage in the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.
+
+4.4.0
+-----
+
+ * deprecated support for using `null` as the locale in `Translator`
+ * deprecated accepting STDIN implicitly when using the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.
+ * Marked the `TranslationDataCollector` class as `@final`.
+
+4.3.0
+-----
+
+ * Improved Xliff 1.2 loader to load the original file's metadata
+ * Added `TranslatorPathsPass`
+
+4.2.0
+-----
+
+ * Started using ICU parent locales as fallback locales.
+ * allow using the ICU message format using domains with the "+intl-icu" suffix
+ * deprecated `Translator::transChoice()` in favor of using `Translator::trans()` with a `%count%` parameter
+ * deprecated `TranslatorInterface` in favor of `Symfony\Contracts\Translation\TranslatorInterface`
+ * deprecated `MessageSelector`, `Interval` and `PluralizationRules`; use `IdentityTranslator` instead
+ * Added `IntlFormatter` and `IntlFormatterInterface`
+ * added support for multiple files and directories in `XliffLintCommand`
+ * Marked `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` as internal
+
+4.1.0
+-----
+
+ * The `FileDumper::setBackup()` method is deprecated.
+ * The `TranslationWriter::disableBackup()` method is deprecated.
+ * The `XliffFileDumper` will write "name" on the "unit" node when dumping XLIFF 2.0.
+
+4.0.0
+-----
+
+ * removed the backup feature of the `FileDumper` class
+ * removed `TranslationWriter::writeTranslations()` method
+ * removed support for passing `MessageSelector` instances to the constructor of the `Translator` class
+
+3.4.0
+-----
+
+ * Added `TranslationDumperPass`
+ * Added `TranslationExtractorPass`
+ * Added `TranslatorPass`
+ * Added `TranslationReader` and `TranslationReaderInterface`
+ * Added `<notes>` section to the Xliff 2.0 dumper.
+ * Improved Xliff 2.0 loader to load `<notes>` section.
+ * Added `TranslationWriterInterface`
+ * Deprecated `TranslationWriter::writeTranslations` in favor of `TranslationWriter::write`
+ * added support for adding custom message formatter and decoupling the default one.
+ * Added `PhpExtractor`
+ * Added `PhpStringTokenParser`
+
+3.2.0
+-----
+
+ * Added support for escaping `|` in plural translations with double pipe.
+
+3.1.0
+-----
+
+ * Deprecated the backup feature of the file dumper classes.
+
+3.0.0
+-----
+
+ * removed `FileDumper::format()` method.
+ * Changed the visibility of the locale property in `Translator` from protected to private.
+
+2.8.0
+-----
+
+ * deprecated FileDumper::format(), overwrite FileDumper::formatCatalogue() instead.
+ * deprecated Translator::getMessages(), rely on TranslatorBagInterface::getCatalogue() instead.
+ * added `FileDumper::formatCatalogue` which allows format the catalogue without dumping it into file.
+ * added option `json_encoding` to JsonFileDumper
+ * added options `as_tree`, `inline` to YamlFileDumper
+ * added support for XLIFF 2.0.
+ * added support for XLIFF target and tool attributes.
+ * added message parameters to DataCollectorTranslator.
+ * [DEPRECATION] The `DiffOperation` class has been deprecated and
+   will be removed in Symfony 3.0, since its operation has nothing to do with 'diff',
+   so the class name is misleading. The `TargetOperation` class should be used for
+   this use-case instead.
+
+2.7.0
+-----
+
+ * added DataCollectorTranslator for collecting the translated messages.
+
+2.6.0
+-----
+
+ * added possibility to cache catalogues
+ * added TranslatorBagInterface
+ * added LoggingTranslator
+ * added Translator::getMessages() for retrieving the message catalogue as an array
+
+2.5.0
+-----
+
+ * added relative file path template to the file dumpers
+ * added optional backup to the file dumpers
+ * changed IcuResFileDumper to extend FileDumper
+
+2.3.0
+-----
+
+ * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
+ * added Translator::getFallbackLocales()
+ * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method
+
+2.2.0
+-----
+
+ * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
+ * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
+   throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
+   and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
+ * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
+   (IcuDatFileLoader, IcuResFileLoader and QtFileLoader)
+
+2.1.0
+-----
+
+ * added support for more than one fallback locale
+ * added support for extracting translation messages from templates (Twig and PHP)
+ * added dumpers for translation catalogs
+ * added support for QT, gettext, and ResourceBundles
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/AbstractOperation.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/AbstractOperation.php
new file mode 100644
index 0000000..9869fbb
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/AbstractOperation.php
@@ -0,0 +1,192 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\LogicException;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Base catalogues binary operation class.
+ *
+ * A catalogue binary operation performs operation on
+ * source (the left argument) and target (the right argument) catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractOperation implements OperationInterface
+{
+    public const OBSOLETE_BATCH = 'obsolete';
+    public const NEW_BATCH = 'new';
+    public const ALL_BATCH = 'all';
+
+    protected $source;
+    protected $target;
+    protected $result;
+
+    /**
+     * @var array|null The domains affected by this operation
+     */
+    private $domains;
+
+    /**
+     * This array stores 'all', 'new' and 'obsolete' messages for all valid domains.
+     *
+     * The data structure of this array is as follows:
+     *
+     *     [
+     *         'domain 1' => [
+     *             'all' => [...],
+     *             'new' => [...],
+     *             'obsolete' => [...]
+     *         ],
+     *         'domain 2' => [
+     *             'all' => [...],
+     *             'new' => [...],
+     *             'obsolete' => [...]
+     *         ],
+     *         ...
+     *     ]
+     *
+     * @var array The array that stores 'all', 'new' and 'obsolete' messages
+     */
+    protected $messages;
+
+    /**
+     * @throws LogicException
+     */
+    public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+    {
+        if ($source->getLocale() !== $target->getLocale()) {
+            throw new LogicException('Operated catalogues must belong to the same locale.');
+        }
+
+        $this->source = $source;
+        $this->target = $target;
+        $this->result = new MessageCatalogue($source->getLocale());
+        $this->messages = [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomains()
+    {
+        if (null === $this->domains) {
+            $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
+        }
+
+        return $this->domains;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMessages(string $domain)
+    {
+        if (!\in_array($domain, $this->getDomains())) {
+            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
+        }
+
+        if (!isset($this->messages[$domain][self::ALL_BATCH])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain][self::ALL_BATCH];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getNewMessages(string $domain)
+    {
+        if (!\in_array($domain, $this->getDomains())) {
+            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
+        }
+
+        if (!isset($this->messages[$domain][self::NEW_BATCH])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain][self::NEW_BATCH];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getObsoleteMessages(string $domain)
+    {
+        if (!\in_array($domain, $this->getDomains())) {
+            throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
+        }
+
+        if (!isset($this->messages[$domain][self::OBSOLETE_BATCH])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain][self::OBSOLETE_BATCH];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResult()
+    {
+        foreach ($this->getDomains() as $domain) {
+            if (!isset($this->messages[$domain])) {
+                $this->processDomain($domain);
+            }
+        }
+
+        return $this->result;
+    }
+
+    /**
+     * @param self::*_BATCH $batch
+     */
+    public function moveMessagesToIntlDomainsIfPossible(string $batch = self::ALL_BATCH): void
+    {
+        // If MessageFormatter class does not exists, intl domains are not supported.
+        if (!class_exists(\MessageFormatter::class)) {
+            return;
+        }
+
+        foreach ($this->getDomains() as $domain) {
+            $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+            switch ($batch) {
+                case self::OBSOLETE_BATCH: $messages = $this->getObsoleteMessages($domain); break;
+                case self::NEW_BATCH: $messages = $this->getNewMessages($domain); break;
+                case self::ALL_BATCH: $messages = $this->getMessages($domain); break;
+                default: throw new \InvalidArgumentException(sprintf('$batch argument must be one of ["%s", "%s", "%s"].', self::ALL_BATCH, self::NEW_BATCH, self::OBSOLETE_BATCH));
+            }
+
+            if (!$messages || (!$this->source->all($intlDomain) && $this->source->all($domain))) {
+                continue;
+            }
+
+            $result = $this->getResult();
+            $allIntlMessages = $result->all($intlDomain);
+            $currentMessages = array_diff_key($messages, $result->all($domain));
+            $result->replace($currentMessages, $domain);
+            $result->replace($allIntlMessages + $messages, $intlDomain);
+        }
+    }
+
+    /**
+     * Performs operation on source and target catalogues for the given domain and
+     * stores the results.
+     *
+     * @param string $domain The domain which the operation will be performed for
+     */
+    abstract protected function processDomain(string $domain);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/MergeOperation.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/MergeOperation.php
new file mode 100644
index 0000000..87db2fb
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/MergeOperation.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Merge operation between two catalogues as follows:
+ * all = source ∪ target = {x: x ∈ source ∨ x ∈ target}
+ * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
+ * obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ source ∧ x ∉ target} = ∅
+ * Basically, the result contains messages from both catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class MergeOperation extends AbstractOperation
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function processDomain(string $domain)
+    {
+        $this->messages[$domain] = [
+            'all' => [],
+            'new' => [],
+            'obsolete' => [],
+        ];
+        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+
+        foreach ($this->source->all($domain) as $id => $message) {
+            $this->messages[$domain]['all'][$id] = $message;
+            $d = $this->source->defines($id, $intlDomain) ? $intlDomain : $domain;
+            $this->result->add([$id => $message], $d);
+            if (null !== $keyMetadata = $this->source->getMetadata($id, $d)) {
+                $this->result->setMetadata($id, $keyMetadata, $d);
+            }
+        }
+
+        foreach ($this->target->all($domain) as $id => $message) {
+            if (!$this->source->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->messages[$domain]['new'][$id] = $message;
+                $d = $this->target->defines($id, $intlDomain) ? $intlDomain : $domain;
+                $this->result->add([$id => $message], $d);
+                if (null !== $keyMetadata = $this->target->getMetadata($id, $d)) {
+                    $this->result->setMetadata($id, $keyMetadata, $d);
+                }
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/OperationInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/OperationInterface.php
new file mode 100644
index 0000000..9ffac88
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/OperationInterface.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Represents an operation on catalogue(s).
+ *
+ * An instance of this interface performs an operation on one or more catalogues and
+ * stores intermediate and final results of the operation.
+ *
+ * The first catalogue in its argument(s) is called the 'source catalogue' or 'source' and
+ * the following results are stored:
+ *
+ * Messages: also called 'all', are valid messages for the given domain after the operation is performed.
+ *
+ * New Messages: also called 'new' (new = all ∖ source = {x: x ∈ all ∧ x ∉ source}).
+ *
+ * Obsolete Messages: also called 'obsolete' (obsolete = source ∖ all = {x: x ∈ source ∧ x ∉ all}).
+ *
+ * Result: also called 'result', is the resulting catalogue for the given domain that holds the same messages as 'all'.
+ *
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+interface OperationInterface
+{
+    /**
+     * Returns domains affected by operation.
+     *
+     * @return array
+     */
+    public function getDomains();
+
+    /**
+     * Returns all valid messages ('all') after operation.
+     *
+     * @return array
+     */
+    public function getMessages(string $domain);
+
+    /**
+     * Returns new messages ('new') after operation.
+     *
+     * @return array
+     */
+    public function getNewMessages(string $domain);
+
+    /**
+     * Returns obsolete messages ('obsolete') after operation.
+     *
+     * @return array
+     */
+    public function getObsoleteMessages(string $domain);
+
+    /**
+     * Returns resulting catalogue ('result').
+     *
+     * @return MessageCatalogueInterface
+     */
+    public function getResult();
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/TargetOperation.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/TargetOperation.php
new file mode 100644
index 0000000..399d917
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Catalogue/TargetOperation.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Target operation between two catalogues:
+ * intersection = source ∩ target = {x: x ∈ source ∧ x ∈ target}
+ * all = intersection ∪ (target ∖ intersection) = target
+ * new = all ∖ source = {x: x ∈ target ∧ x ∉ source}
+ * obsolete = source ∖ all = source ∖ target = {x: x ∈ source ∧ x ∉ target}
+ * Basically, the result contains messages from the target catalogue.
+ *
+ * @author Michael Lee <michael.lee@zerustech.com>
+ */
+class TargetOperation extends AbstractOperation
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function processDomain(string $domain)
+    {
+        $this->messages[$domain] = [
+            'all' => [],
+            'new' => [],
+            'obsolete' => [],
+        ];
+        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+
+        // For 'all' messages, the code can't be simplified as ``$this->messages[$domain]['all'] = $target->all($domain);``,
+        // because doing so will drop messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
+        //
+        // For 'new' messages, the code can't be simplified as ``array_diff_assoc($this->target->all($domain), $this->source->all($domain));``
+        // because doing so will not exclude messages like {x: x ∈ target ∧ x ∉ source.all ∧ x ∈ source.fallback}
+        //
+        // For 'obsolete' messages, the code can't be simplified as ``array_diff_assoc($this->source->all($domain), $this->target->all($domain))``
+        // because doing so will not exclude messages like {x: x ∈ source ∧ x ∉ target.all ∧ x ∈ target.fallback}
+
+        foreach ($this->source->all($domain) as $id => $message) {
+            if ($this->target->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $d = $this->target->defines($id, $intlDomain) ? $intlDomain : $domain;
+                $this->result->add([$id => $message], $d);
+                if (null !== $keyMetadata = $this->source->getMetadata($id, $d)) {
+                    $this->result->setMetadata($id, $keyMetadata, $d);
+                }
+            } else {
+                $this->messages[$domain]['obsolete'][$id] = $message;
+            }
+        }
+
+        foreach ($this->target->all($domain) as $id => $message) {
+            if (!$this->source->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->messages[$domain]['new'][$id] = $message;
+                $d = $this->target->defines($id, $intlDomain) ? $intlDomain : $domain;
+                $this->result->add([$id => $message], $d);
+                if (null !== $keyMetadata = $this->target->getMetadata($id, $d)) {
+                    $this->result->setMetadata($id, $keyMetadata, $d);
+                }
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPullCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPullCommand.php
new file mode 100644
index 0000000..0ec02ca
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPullCommand.php
@@ -0,0 +1,157 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Translation\Catalogue\TargetOperation;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Provider\TranslationProviderCollection;
+use Symfony\Component\Translation\Reader\TranslationReaderInterface;
+use Symfony\Component\Translation\Writer\TranslationWriterInterface;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class TranslationPullCommand extends Command
+{
+    use TranslationTrait;
+
+    protected static $defaultName = 'translation:pull';
+    protected static $defaultDescription = 'Pull translations from a given provider.';
+
+    private $providerCollection;
+    private $writer;
+    private $reader;
+    private $defaultLocale;
+    private $transPaths;
+    private $enabledLocales;
+
+    public function __construct(TranslationProviderCollection $providerCollection, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, array $transPaths = [], array $enabledLocales = [])
+    {
+        $this->providerCollection = $providerCollection;
+        $this->writer = $writer;
+        $this->reader = $reader;
+        $this->defaultLocale = $defaultLocale;
+        $this->transPaths = $transPaths;
+        $this->enabledLocales = $enabledLocales;
+
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $keys = $this->providerCollection->keys();
+        $defaultProvider = 1 === \count($keys) ? $keys[0] : null;
+
+        $this
+            ->setDefinition([
+                new InputArgument('provider', null !== $defaultProvider ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The provider to pull translations from.', $defaultProvider),
+                new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with provider ones (it will delete not synchronized messages).'),
+                new InputOption('intl-icu', null, InputOption::VALUE_NONE, 'Associated to --force option, it will write messages in "%domain%+intl-icu.%locale%.xlf" files.'),
+                new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull.'),
+                new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to pull.'),
+                new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format.', 'xlf12'),
+            ])
+            ->setHelp(<<<'EOF'
+The <info>%command.name%</> command pulls translations from the given provider. Only
+new translations are pulled, existing ones are not overwritten.
+
+You can overwrite existing translations (and remove the missing ones on local side) by using the <comment>--force</> flag:
+
+  <info>php %command.full_name% --force provider</>
+
+Full example:
+
+  <info>php %command.full_name% provider --force --domains=messages,validators --locales=en</>
+
+This command pulls all translations associated with the <comment>messages</> and <comment>validators</> domains for the <comment>en</> locale.
+Local translations for the specified domains and locale are deleted if they're not present on the provider and overwritten if it's the case.
+Local translations for others domains and locales are ignored.
+EOF
+            )
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+
+        $provider = $this->providerCollection->get($input->getArgument('provider'));
+        $force = $input->getOption('force');
+        $intlIcu = $input->getOption('intl-icu');
+        $locales = $input->getOption('locales') ?: $this->enabledLocales;
+        $domains = $input->getOption('domains');
+        $format = $input->getOption('format');
+        $xliffVersion = '1.2';
+
+        if ($intlIcu && !$force) {
+            $io->note('--intl-icu option only has an effect when used with --force. Here, it will be ignored.');
+        }
+
+        switch ($format) {
+            case 'xlf20': $xliffVersion = '2.0';
+            // no break
+            case 'xlf12': $format = 'xlf';
+        }
+
+        $writeOptions = [
+            'path' => end($this->transPaths),
+            'xliff_version' => $xliffVersion,
+        ];
+
+        if (!$domains) {
+            $domains = $provider->getDomains();
+        }
+
+        $providerTranslations = $provider->read($domains, $locales);
+
+        if ($force) {
+            foreach ($providerTranslations->getCatalogues() as $catalogue) {
+                $operation = new TargetOperation((new MessageCatalogue($catalogue->getLocale())), $catalogue);
+                if ($intlIcu) {
+                    $operation->moveMessagesToIntlDomainsIfPossible();
+                }
+                $this->writer->write($operation->getResult(), $format, $writeOptions);
+            }
+
+            $io->success(sprintf('Local translations has been updated from "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+            return 0;
+        }
+
+        $localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
+
+        // Append pulled translations to local ones.
+        $localTranslations->addBag($providerTranslations->diff($localTranslations));
+
+        foreach ($localTranslations->getCatalogues() as $catalogue) {
+            $this->writer->write($catalogue, $format, $writeOptions);
+        }
+
+        $io->success(sprintf('New translations from "%s" has been written locally (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+        return 0;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPushCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPushCommand.php
new file mode 100644
index 0000000..b28d3e1
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationPushCommand.php
@@ -0,0 +1,158 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Translation\Provider\TranslationProviderCollection;
+use Symfony\Component\Translation\Reader\TranslationReaderInterface;
+use Symfony\Component\Translation\TranslatorBag;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class TranslationPushCommand extends Command
+{
+    use TranslationTrait;
+
+    protected static $defaultName = 'translation:push';
+    protected static $defaultDescription = 'Push translations to a given provider.';
+
+    private $providers;
+    private $reader;
+    private $transPaths;
+    private $enabledLocales;
+
+    public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
+    {
+        $this->providers = $providers;
+        $this->reader = $reader;
+        $this->transPaths = $transPaths;
+        $this->enabledLocales = $enabledLocales;
+
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $keys = $this->providers->keys();
+        $defaultProvider = 1 === \count($keys) ? $keys[0] : null;
+
+        $this
+            ->setDefinition([
+                new InputArgument('provider', null !== $defaultProvider ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The provider to push translations to.', $defaultProvider),
+                new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with local ones (it will delete not synchronized messages).'),
+                new InputOption('delete-missing', null, InputOption::VALUE_NONE, 'Delete translations available on provider but not locally.'),
+                new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to push.'),
+                new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to push.', $this->enabledLocales),
+            ])
+            ->setHelp(<<<'EOF'
+The <info>%command.name%</> command pushes translations to the given provider. Only new
+translations are pushed, existing ones are not overwritten.
+
+You can overwrite existing translations by using the <comment>--force</> flag:
+
+  <info>php %command.full_name% --force provider</>
+
+You can delete provider translations which are not present locally by using the <comment>--delete-missing</> flag:
+
+  <info>php %command.full_name% --delete-missing provider</>
+
+Full example:
+
+  <info>php %command.full_name% provider --force --delete-missing --domains=messages,validators --locales=en</>
+
+This command pushes all translations associated with the <comment>messages</> and <comment>validators</> domains for the <comment>en</> locale.
+Provider translations for the specified domains and locale are deleted if they're not present locally and overwritten if it's the case.
+Provider translations for others domains and locales are ignored.
+EOF
+            )
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $provider = $this->providers->get($input->getArgument('provider'));
+
+        if (!$this->enabledLocales) {
+            throw new InvalidArgumentException(sprintf('You must define "framework.translator.enabled_locales" or "framework.translator.providers.%s.locales" config key in order to work with translation providers.', parse_url($provider, \PHP_URL_SCHEME)));
+        }
+
+        $io = new SymfonyStyle($input, $output);
+        $domains = $input->getOption('domains');
+        $locales = $input->getOption('locales');
+        $force = $input->getOption('force');
+        $deleteMissing = $input->getOption('delete-missing');
+
+        $localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
+
+        if (!$domains) {
+            $domains = $this->getDomainsFromTranslatorBag($localTranslations);
+        }
+
+        if (!$deleteMissing && $force) {
+            $provider->write($localTranslations);
+
+            $io->success(sprintf('All local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+            return 0;
+        }
+
+        $providerTranslations = $provider->read($domains, $locales);
+
+        if ($deleteMissing) {
+            $provider->delete($providerTranslations->diff($localTranslations));
+
+            $io->success(sprintf('Missing translations on "%s" has been deleted (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+            // Read provider translations again, after missing translations deletion,
+            // to avoid push freshly deleted translations.
+            $providerTranslations = $provider->read($domains, $locales);
+        }
+
+        $translationsToWrite = $localTranslations->diff($providerTranslations);
+
+        if ($force) {
+            $translationsToWrite->addBag($localTranslations->intersect($providerTranslations));
+        }
+
+        $provider->write($translationsToWrite);
+
+        $io->success(sprintf('%s local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', $force ? 'All' : 'New', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
+
+        return 0;
+    }
+
+    private function getDomainsFromTranslatorBag(TranslatorBag $translatorBag): array
+    {
+        $domains = [];
+
+        foreach ($translatorBag->getCatalogues() as $catalogue) {
+            $domains += $catalogue->getDomains();
+        }
+
+        return array_unique($domains);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationTrait.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationTrait.php
new file mode 100644
index 0000000..6a2b1ba
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/TranslationTrait.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+use Symfony\Component\Translation\TranslatorBag;
+
+/**
+ * @internal
+ */
+trait TranslationTrait
+{
+    private function readLocalTranslations(array $locales, array $domains, array $transPaths): TranslatorBag
+    {
+        $bag = new TranslatorBag();
+
+        foreach ($locales as $locale) {
+            $catalogue = new MessageCatalogue($locale);
+            foreach ($transPaths as $path) {
+                $this->reader->read($path, $catalogue);
+            }
+
+            if ($domains) {
+                foreach ($domains as $domain) {
+                    $catalogue = $this->filterCatalogue($catalogue, $domain);
+                    $bag->addCatalogue($catalogue);
+                }
+            } else {
+                $bag->addCatalogue($catalogue);
+            }
+        }
+
+        return $bag;
+    }
+
+    private function filterCatalogue(MessageCatalogue $catalogue, string $domain): MessageCatalogue
+    {
+        $filteredCatalogue = new MessageCatalogue($catalogue->getLocale());
+
+        // extract intl-icu messages only
+        $intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
+        if ($intlMessages = $catalogue->all($intlDomain)) {
+            $filteredCatalogue->add($intlMessages, $intlDomain);
+        }
+
+        // extract all messages and subtract intl-icu messages
+        if ($messages = array_diff($catalogue->all($domain), $intlMessages)) {
+            $filteredCatalogue->add($messages, $domain);
+        }
+        foreach ($catalogue->getResources() as $resource) {
+            $filteredCatalogue->addResource($resource);
+        }
+
+        if ($metadata = $catalogue->getMetadata('', $intlDomain)) {
+            foreach ($metadata as $k => $v) {
+                $filteredCatalogue->setMetadata($k, $v, $intlDomain);
+            }
+        }
+
+        if ($metadata = $catalogue->getMetadata('', $domain)) {
+            foreach ($metadata as $k => $v) {
+                $filteredCatalogue->setMetadata($k, $v, $domain);
+            }
+        }
+
+        return $filteredCatalogue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/XliffLintCommand.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/XliffLintCommand.php
new file mode 100644
index 0000000..4117d87
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Command/XliffLintCommand.php
@@ -0,0 +1,267 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Util\XliffUtils;
+
+/**
+ * Validates XLIFF files syntax and outputs encountered errors.
+ *
+ * @author Grégoire Pineau <lyrixx@lyrixx.info>
+ * @author Robin Chalas <robin.chalas@gmail.com>
+ * @author Javier Eguiluz <javier.eguiluz@gmail.com>
+ */
+class XliffLintCommand extends Command
+{
+    protected static $defaultName = 'lint:xliff';
+    protected static $defaultDescription = 'Lint an XLIFF file and outputs encountered errors';
+
+    private $format;
+    private $displayCorrectFiles;
+    private $directoryIteratorProvider;
+    private $isReadableProvider;
+    private $requireStrictFileNames;
+
+    public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null, bool $requireStrictFileNames = true)
+    {
+        parent::__construct($name);
+
+        $this->directoryIteratorProvider = $directoryIteratorProvider;
+        $this->isReadableProvider = $isReadableProvider;
+        $this->requireStrictFileNames = $requireStrictFileNames;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this
+            ->setDescription(self::$defaultDescription)
+            ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
+            ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
+            ->setHelp(<<<EOF
+The <info>%command.name%</info> command lints an XLIFF file and outputs to STDOUT
+the first encountered syntax error.
+
+You can validates XLIFF contents passed from STDIN:
+
+  <info>cat filename | php %command.full_name% -</info>
+
+You can also validate the syntax of a file:
+
+  <info>php %command.full_name% filename</info>
+
+Or of a whole directory:
+
+  <info>php %command.full_name% dirname</info>
+  <info>php %command.full_name% dirname --format=json</info>
+
+EOF
+            )
+        ;
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $io = new SymfonyStyle($input, $output);
+        $filenames = (array) $input->getArgument('filename');
+        $this->format = $input->getOption('format');
+        $this->displayCorrectFiles = $output->isVerbose();
+
+        if (['-'] === $filenames) {
+            return $this->display($io, [$this->validate(file_get_contents('php://stdin'))]);
+        }
+
+        if (!$filenames) {
+            throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
+        }
+
+        $filesInfo = [];
+        foreach ($filenames as $filename) {
+            if (!$this->isReadable($filename)) {
+                throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
+            }
+
+            foreach ($this->getFiles($filename) as $file) {
+                $filesInfo[] = $this->validate(file_get_contents($file), $file);
+            }
+        }
+
+        return $this->display($io, $filesInfo);
+    }
+
+    private function validate(string $content, string $file = null): array
+    {
+        $errors = [];
+
+        // Avoid: Warning DOMDocument::loadXML(): Empty string supplied as input
+        if ('' === trim($content)) {
+            return ['file' => $file, 'valid' => true];
+        }
+
+        $internal = libxml_use_internal_errors(true);
+
+        $document = new \DOMDocument();
+        $document->loadXML($content);
+
+        if (null !== $targetLanguage = $this->getTargetLanguageFromFile($document)) {
+            $normalizedLocalePattern = sprintf('(%s|%s)', preg_quote($targetLanguage, '/'), preg_quote(str_replace('-', '_', $targetLanguage), '/'));
+            // strict file names require translation files to be named '____.locale.xlf'
+            // otherwise, both '____.locale.xlf' and 'locale.____.xlf' are allowed
+            // also, the regexp matching must be case-insensitive, as defined for 'target-language' values
+            // http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#target-language
+            $expectedFilenamePattern = $this->requireStrictFileNames ? sprintf('/^.*\.(?i:%s)\.(?:xlf|xliff)/', $normalizedLocalePattern) : sprintf('/^(?:.*\.(?i:%s)|(?i:%s)\..*)\.(?:xlf|xliff)/', $normalizedLocalePattern, $normalizedLocalePattern);
+
+            if (0 === preg_match($expectedFilenamePattern, basename($file))) {
+                $errors[] = [
+                    'line' => -1,
+                    'column' => -1,
+                    'message' => sprintf('There is a mismatch between the language included in the file name ("%s") and the "%s" value used in the "target-language" attribute of the file.', basename($file), $targetLanguage),
+                ];
+            }
+        }
+
+        foreach (XliffUtils::validateSchema($document) as $xmlError) {
+            $errors[] = [
+                'line' => $xmlError['line'],
+                'column' => $xmlError['column'],
+                'message' => $xmlError['message'],
+            ];
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internal);
+
+        return ['file' => $file, 'valid' => 0 === \count($errors), 'messages' => $errors];
+    }
+
+    private function display(SymfonyStyle $io, array $files)
+    {
+        switch ($this->format) {
+            case 'txt':
+                return $this->displayTxt($io, $files);
+            case 'json':
+                return $this->displayJson($io, $files);
+            default:
+                throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
+        }
+    }
+
+    private function displayTxt(SymfonyStyle $io, array $filesInfo)
+    {
+        $countFiles = \count($filesInfo);
+        $erroredFiles = 0;
+
+        foreach ($filesInfo as $info) {
+            if ($info['valid'] && $this->displayCorrectFiles) {
+                $io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
+            } elseif (!$info['valid']) {
+                ++$erroredFiles;
+                $io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
+                $io->listing(array_map(function ($error) {
+                    // general document errors have a '-1' line number
+                    return -1 === $error['line'] ? $error['message'] : sprintf('Line %d, Column %d: %s', $error['line'], $error['column'], $error['message']);
+                }, $info['messages']));
+            }
+        }
+
+        if (0 === $erroredFiles) {
+            $io->success(sprintf('All %d XLIFF files contain valid syntax.', $countFiles));
+        } else {
+            $io->warning(sprintf('%d XLIFF files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles));
+        }
+
+        return min($erroredFiles, 1);
+    }
+
+    private function displayJson(SymfonyStyle $io, array $filesInfo)
+    {
+        $errors = 0;
+
+        array_walk($filesInfo, function (&$v) use (&$errors) {
+            $v['file'] = (string) $v['file'];
+            if (!$v['valid']) {
+                ++$errors;
+            }
+        });
+
+        $io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));
+
+        return min($errors, 1);
+    }
+
+    private function getFiles(string $fileOrDirectory)
+    {
+        if (is_file($fileOrDirectory)) {
+            yield new \SplFileInfo($fileOrDirectory);
+
+            return;
+        }
+
+        foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
+            if (!\in_array($file->getExtension(), ['xlf', 'xliff'])) {
+                continue;
+            }
+
+            yield $file;
+        }
+    }
+
+    private function getDirectoryIterator(string $directory)
+    {
+        $default = function ($directory) {
+            return new \RecursiveIteratorIterator(
+                new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
+                \RecursiveIteratorIterator::LEAVES_ONLY
+            );
+        };
+
+        if (null !== $this->directoryIteratorProvider) {
+            return ($this->directoryIteratorProvider)($directory, $default);
+        }
+
+        return $default($directory);
+    }
+
+    private function isReadable(string $fileOrDirectory)
+    {
+        $default = function ($fileOrDirectory) {
+            return is_readable($fileOrDirectory);
+        };
+
+        if (null !== $this->isReadableProvider) {
+            return ($this->isReadableProvider)($fileOrDirectory, $default);
+        }
+
+        return $default($fileOrDirectory);
+    }
+
+    private function getTargetLanguageFromFile(\DOMDocument $xliffContents): ?string
+    {
+        foreach ($xliffContents->getElementsByTagName('file')[0]->attributes ?? [] as $attribute) {
+            if ('target-language' === $attribute->nodeName) {
+                return $attribute->nodeValue;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollector/TranslationDataCollector.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollector/TranslationDataCollector.php
new file mode 100644
index 0000000..f8480ad
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollector/TranslationDataCollector.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DataCollector;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\DataCollector\DataCollector;
+use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
+use Symfony\Component\Translation\DataCollectorTranslator;
+use Symfony\Component\VarDumper\Cloner\Data;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ *
+ * @final
+ */
+class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
+{
+    private $translator;
+
+    public function __construct(DataCollectorTranslator $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function lateCollect()
+    {
+        $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());
+
+        $this->data += $this->computeCount($messages);
+        $this->data['messages'] = $messages;
+
+        $this->data = $this->cloneVar($this->data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function collect(Request $request, Response $response, \Throwable $exception = null)
+    {
+        $this->data['locale'] = $this->translator->getLocale();
+        $this->data['fallback_locales'] = $this->translator->getFallbackLocales();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function reset()
+    {
+        $this->data = [];
+    }
+
+    /**
+     * @return array|Data
+     */
+    public function getMessages()
+    {
+        return $this->data['messages'] ?? [];
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountMissings()
+    {
+        return $this->data[DataCollectorTranslator::MESSAGE_MISSING] ?? 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountFallbacks()
+    {
+        return $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] ?? 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountDefines()
+    {
+        return $this->data[DataCollectorTranslator::MESSAGE_DEFINED] ?? 0;
+    }
+
+    public function getLocale()
+    {
+        return !empty($this->data['locale']) ? $this->data['locale'] : null;
+    }
+
+    /**
+     * @internal
+     */
+    public function getFallbackLocales()
+    {
+        return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'translation';
+    }
+
+    private function sanitizeCollectedMessages(array $messages)
+    {
+        $result = [];
+        foreach ($messages as $key => $message) {
+            $messageId = $message['locale'].$message['domain'].$message['id'];
+
+            if (!isset($result[$messageId])) {
+                $message['count'] = 1;
+                $message['parameters'] = !empty($message['parameters']) ? [$message['parameters']] : [];
+                $messages[$key]['translation'] = $this->sanitizeString($message['translation']);
+                $result[$messageId] = $message;
+            } else {
+                if (!empty($message['parameters'])) {
+                    $result[$messageId]['parameters'][] = $message['parameters'];
+                }
+
+                ++$result[$messageId]['count'];
+            }
+
+            unset($messages[$key]);
+        }
+
+        return $result;
+    }
+
+    private function computeCount(array $messages)
+    {
+        $count = [
+            DataCollectorTranslator::MESSAGE_DEFINED => 0,
+            DataCollectorTranslator::MESSAGE_MISSING => 0,
+            DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0,
+        ];
+
+        foreach ($messages as $message) {
+            ++$count[$message['state']];
+        }
+
+        return $count;
+    }
+
+    private function sanitizeString(string $string, int $length = 80)
+    {
+        $string = trim(preg_replace('/\s+/', ' ', $string));
+
+        if (false !== $encoding = mb_detect_encoding($string, null, true)) {
+            if (mb_strlen($string, $encoding) > $length) {
+                return mb_substr($string, 0, $length - 3, $encoding).'...';
+            }
+        } elseif (\strlen($string) > $length) {
+            return substr($string, 0, $length - 3).'...';
+        }
+
+        return $string;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollectorTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollectorTranslator.php
new file mode 100644
index 0000000..c7d3597
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DataCollectorTranslator.php
@@ -0,0 +1,171 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface, WarmableInterface
+{
+    public const MESSAGE_DEFINED = 0;
+    public const MESSAGE_MISSING = 1;
+    public const MESSAGE_EQUALS_FALLBACK = 2;
+
+    /**
+     * @var TranslatorInterface|TranslatorBagInterface
+     */
+    private $translator;
+
+    private $messages = [];
+
+    /**
+     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
+     */
+    public function __construct(TranslatorInterface $translator)
+    {
+        if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
+            throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
+        }
+
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
+        $this->collectMessage($locale, $domain, $id, $trans, $parameters);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $this->translator->setLocale($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        return $this->translator->getCatalogue($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return $this->translator->getCatalogues();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return string[]
+     */
+    public function warmUp(string $cacheDir)
+    {
+        if ($this->translator instanceof WarmableInterface) {
+            return (array) $this->translator->warmUp($cacheDir);
+        }
+
+        return [];
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @return array The fallback locales
+     */
+    public function getFallbackLocales()
+    {
+        if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
+            return $this->translator->getFallbackLocales();
+        }
+
+        return [];
+    }
+
+    /**
+     * Passes through all unknown calls onto the translator object.
+     */
+    public function __call(string $method, array $args)
+    {
+        return $this->translator->{$method}(...$args);
+    }
+
+    /**
+     * @return array
+     */
+    public function getCollectedMessages()
+    {
+        return $this->messages;
+    }
+
+    private function collectMessage(?string $locale, ?string $domain, string $id, string $translation, ?array $parameters = [])
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $catalogue = $this->translator->getCatalogue($locale);
+        $locale = $catalogue->getLocale();
+        $fallbackLocale = null;
+        if ($catalogue->defines($id, $domain)) {
+            $state = self::MESSAGE_DEFINED;
+        } elseif ($catalogue->has($id, $domain)) {
+            $state = self::MESSAGE_EQUALS_FALLBACK;
+
+            $fallbackCatalogue = $catalogue->getFallbackCatalogue();
+            while ($fallbackCatalogue) {
+                if ($fallbackCatalogue->defines($id, $domain)) {
+                    $fallbackLocale = $fallbackCatalogue->getLocale();
+                    break;
+                }
+                $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
+            }
+        } else {
+            $state = self::MESSAGE_MISSING;
+        }
+
+        $this->messages[] = [
+            'locale' => $locale,
+            'fallbackLocale' => $fallbackLocale,
+            'domain' => $domain,
+            'id' => $id,
+            'translation' => $translation,
+            'parameters' => $parameters,
+            'state' => $state,
+            'transChoiceNumber' => isset($parameters['%count%']) && is_numeric($parameters['%count%']) ? $parameters['%count%'] : null,
+        ];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php
new file mode 100644
index 0000000..6d78342
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationDumperPass.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Adds tagged translation.formatter services to translation writer.
+ */
+class TranslationDumperPass implements CompilerPassInterface
+{
+    private $writerServiceId;
+    private $dumperTag;
+
+    public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper')
+    {
+        if (1 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->writerServiceId = $writerServiceId;
+        $this->dumperTag = $dumperTag;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->writerServiceId)) {
+            return;
+        }
+
+        $definition = $container->getDefinition($this->writerServiceId);
+
+        foreach ($container->findTaggedServiceIds($this->dumperTag, true) as $id => $attributes) {
+            $definition->addMethodCall('addDumper', [$attributes[0]['alias'], new Reference($id)]);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php
new file mode 100644
index 0000000..fab6b20
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslationExtractorPass.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * Adds tagged translation.extractor services to translation extractor.
+ */
+class TranslationExtractorPass implements CompilerPassInterface
+{
+    private $extractorServiceId;
+    private $extractorTag;
+
+    public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor')
+    {
+        if (0 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->extractorServiceId = $extractorServiceId;
+        $this->extractorTag = $extractorTag;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->extractorServiceId)) {
+            return;
+        }
+
+        $definition = $container->getDefinition($this->extractorServiceId);
+
+        foreach ($container->findTaggedServiceIds($this->extractorTag, true) as $id => $attributes) {
+            if (!isset($attributes[0]['alias'])) {
+                throw new RuntimeException(sprintf('The alias for the tag "translation.extractor" of service "%s" must be set.', $id));
+            }
+
+            $definition->addMethodCall('addExtractor', [$attributes[0]['alias'], new Reference($id)]);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPass.php
new file mode 100644
index 0000000..c6a1306
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPass.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+
+class TranslatorPass implements CompilerPassInterface
+{
+    private $translatorServiceId;
+    private $readerServiceId;
+    private $loaderTag;
+    private $debugCommandServiceId;
+    private $updateCommandServiceId;
+
+    public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update')
+    {
+        if (0 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->translatorServiceId = $translatorServiceId;
+        $this->readerServiceId = $readerServiceId;
+        $this->loaderTag = $loaderTag;
+        $this->debugCommandServiceId = $debugCommandServiceId;
+        $this->updateCommandServiceId = $updateCommandServiceId;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->translatorServiceId)) {
+            return;
+        }
+
+        $loaders = [];
+        $loaderRefs = [];
+        foreach ($container->findTaggedServiceIds($this->loaderTag, true) as $id => $attributes) {
+            $loaderRefs[$id] = new Reference($id);
+            $loaders[$id][] = $attributes[0]['alias'];
+            if (isset($attributes[0]['legacy-alias'])) {
+                $loaders[$id][] = $attributes[0]['legacy-alias'];
+            }
+        }
+
+        if ($container->hasDefinition($this->readerServiceId)) {
+            $definition = $container->getDefinition($this->readerServiceId);
+            foreach ($loaders as $id => $formats) {
+                foreach ($formats as $format) {
+                    $definition->addMethodCall('addLoader', [$format, $loaderRefs[$id]]);
+                }
+            }
+        }
+
+        $container
+            ->findDefinition($this->translatorServiceId)
+            ->replaceArgument(0, ServiceLocatorTagPass::register($container, $loaderRefs))
+            ->replaceArgument(3, $loaders)
+        ;
+
+        if (!$container->hasParameter('twig.default_path')) {
+            return;
+        }
+
+        $paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(1));
+        if ($container->hasDefinition($this->debugCommandServiceId)) {
+            $definition = $container->getDefinition($this->debugCommandServiceId);
+            $definition->replaceArgument(4, $container->getParameter('twig.default_path'));
+
+            if (\count($definition->getArguments()) > 6) {
+                $definition->replaceArgument(6, $paths);
+            }
+        }
+        if ($container->hasDefinition($this->updateCommandServiceId)) {
+            $definition = $container->getDefinition($this->updateCommandServiceId);
+            $definition->replaceArgument(5, $container->getParameter('twig.default_path'));
+
+            if (\count($definition->getArguments()) > 7) {
+                $definition->replaceArgument(7, $paths);
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php
new file mode 100644
index 0000000..85b0fa4
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/DependencyInjection/TranslatorPathsPass.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DependencyInjection;
+
+use Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ServiceLocator;
+
+/**
+ * @author Yonel Ceruto <yonelceruto@gmail.com>
+ */
+class TranslatorPathsPass extends AbstractRecursivePass
+{
+    private $translatorServiceId;
+    private $debugCommandServiceId;
+    private $updateCommandServiceId;
+    private $resolverServiceId;
+    private $level = 0;
+    private $paths = [];
+    private $definitions = [];
+    private $controllers = [];
+
+    public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update', string $resolverServiceId = 'argument_resolver.service')
+    {
+        if (0 < \func_num_args()) {
+            trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
+        }
+
+        $this->translatorServiceId = $translatorServiceId;
+        $this->debugCommandServiceId = $debugCommandServiceId;
+        $this->updateCommandServiceId = $updateCommandServiceId;
+        $this->resolverServiceId = $resolverServiceId;
+    }
+
+    public function process(ContainerBuilder $container)
+    {
+        if (!$container->hasDefinition($this->translatorServiceId)) {
+            return;
+        }
+
+        foreach ($this->findControllerArguments($container) as $controller => $argument) {
+            $id = substr($controller, 0, strpos($controller, ':') ?: \strlen($controller));
+            if ($container->hasDefinition($id)) {
+                [$locatorRef] = $argument->getValues();
+                $this->controllers[(string) $locatorRef][$container->getDefinition($id)->getClass()] = true;
+            }
+        }
+
+        try {
+            parent::process($container);
+
+            $paths = [];
+            foreach ($this->paths as $class => $_) {
+                if (($r = $container->getReflectionClass($class)) && !$r->isInterface()) {
+                    $paths[] = $r->getFileName();
+                    foreach ($r->getTraits() as $trait) {
+                        $paths[] = $trait->getFileName();
+                    }
+                }
+            }
+            if ($paths) {
+                if ($container->hasDefinition($this->debugCommandServiceId)) {
+                    $definition = $container->getDefinition($this->debugCommandServiceId);
+                    $definition->replaceArgument(6, array_merge($definition->getArgument(6), $paths));
+                }
+                if ($container->hasDefinition($this->updateCommandServiceId)) {
+                    $definition = $container->getDefinition($this->updateCommandServiceId);
+                    $definition->replaceArgument(7, array_merge($definition->getArgument(7), $paths));
+                }
+            }
+        } finally {
+            $this->level = 0;
+            $this->paths = [];
+            $this->definitions = [];
+        }
+    }
+
+    protected function processValue($value, bool $isRoot = false)
+    {
+        if ($value instanceof Reference) {
+            if ((string) $value === $this->translatorServiceId) {
+                for ($i = $this->level - 1; $i >= 0; --$i) {
+                    $class = $this->definitions[$i]->getClass();
+
+                    if (ServiceLocator::class === $class) {
+                        if (!isset($this->controllers[$this->currentId])) {
+                            continue;
+                        }
+                        foreach ($this->controllers[$this->currentId] as $class => $_) {
+                            $this->paths[$class] = true;
+                        }
+                    } else {
+                        $this->paths[$class] = true;
+                    }
+
+                    break;
+                }
+            }
+
+            return $value;
+        }
+
+        if ($value instanceof Definition) {
+            $this->definitions[$this->level++] = $value;
+            $value = parent::processValue($value, $isRoot);
+            unset($this->definitions[--$this->level]);
+
+            return $value;
+        }
+
+        return parent::processValue($value, $isRoot);
+    }
+
+    private function findControllerArguments(ContainerBuilder $container): array
+    {
+        if ($container->hasDefinition($this->resolverServiceId)) {
+            $argument = $container->getDefinition($this->resolverServiceId)->getArgument(0);
+            if ($argument instanceof Reference) {
+                $argument = $container->getDefinition($argument);
+            }
+
+            return $argument->getArgument(0);
+        }
+
+        if ($container->hasDefinition('debug.'.$this->resolverServiceId)) {
+            $argument = $container->getDefinition('debug.'.$this->resolverServiceId)->getArgument(0);
+            if ($argument instanceof Reference) {
+                $argument = $container->getDefinition($argument);
+            }
+            $argument = $argument->getArgument(0);
+            if ($argument instanceof Reference) {
+                $argument = $container->getDefinition($argument);
+            }
+
+            return $argument->getArgument(0);
+        }
+
+        return [];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/CsvFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/CsvFileDumper.php
new file mode 100644
index 0000000..0c8589a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/CsvFileDumper.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * CsvFileDumper generates a csv formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class CsvFileDumper extends FileDumper
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $handle = fopen('php://memory', 'r+');
+
+        foreach ($messages->all($domain) as $source => $target) {
+            fputcsv($handle, [$source, $target], $this->delimiter, $this->enclosure);
+        }
+
+        rewind($handle);
+        $output = stream_get_contents($handle);
+        fclose($handle);
+
+        return $output;
+    }
+
+    /**
+     * Sets the delimiter and escape character for CSV.
+     */
+    public function setCsvControl(string $delimiter = ';', string $enclosure = '"')
+    {
+        $this->delimiter = $delimiter;
+        $this->enclosure = $enclosure;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'csv';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/DumperInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/DumperInterface.php
new file mode 100644
index 0000000..7cdaef5
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/DumperInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * DumperInterface is the interface implemented by all translation dumpers.
+ * There is no common option.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface DumperInterface
+{
+    /**
+     * Dumps the message catalogue.
+     *
+     * @param array $options Options that are used by the dumper
+     */
+    public function dump(MessageCatalogue $messages, array $options = []);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/FileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/FileDumper.php
new file mode 100644
index 0000000..e257e72
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/FileDumper.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
+ *
+ * Options:
+ * - path (mandatory): the directory where the files should be saved
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+abstract class FileDumper implements DumperInterface
+{
+    /**
+     * A template for the relative paths to files.
+     *
+     * @var string
+     */
+    protected $relativePathTemplate = '%domain%.%locale%.%extension%';
+
+    /**
+     * Sets the template for the relative paths to files.
+     *
+     * @param string $relativePathTemplate A template for the relative paths to files
+     */
+    public function setRelativePathTemplate(string $relativePathTemplate)
+    {
+        $this->relativePathTemplate = $relativePathTemplate;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dump(MessageCatalogue $messages, array $options = [])
+    {
+        if (!\array_key_exists('path', $options)) {
+            throw new InvalidArgumentException('The file dumper needs a path option.');
+        }
+
+        // save a file for each domain
+        foreach ($messages->getDomains() as $domain) {
+            $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
+            if (!file_exists($fullpath)) {
+                $directory = \dirname($fullpath);
+                if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
+                    throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
+                }
+            }
+
+            $intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX;
+            $intlMessages = $messages->all($intlDomain);
+
+            if ($intlMessages) {
+                $intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale());
+                file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options));
+
+                $messages->replace([], $intlDomain);
+
+                try {
+                    if ($messages->all($domain)) {
+                        file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
+                    }
+                    continue;
+                } finally {
+                    $messages->replace($intlMessages, $intlDomain);
+                }
+            }
+
+            file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
+        }
+    }
+
+    /**
+     * Transforms a domain of a message catalogue to its string representation.
+     *
+     * @return string representation
+     */
+    abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []);
+
+    /**
+     * Gets the file extension of the dumper.
+     *
+     * @return string file extension
+     */
+    abstract protected function getExtension();
+
+    /**
+     * Gets the relative file path using the template.
+     */
+    private function getRelativePath(string $domain, string $locale): string
+    {
+        return strtr($this->relativePathTemplate, [
+            '%domain%' => $domain,
+            '%locale%' => $locale,
+            '%extension%' => $this->getExtension(),
+        ]);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IcuResFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IcuResFileDumper.php
new file mode 100644
index 0000000..cdc5991
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IcuResFileDumper.php
@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IcuResFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $relativePathTemplate = '%domain%/%locale%.%extension%';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $data = $indexes = $resources = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $indexes .= pack('v', \strlen($data) + 28);
+            $data .= $source."\0";
+        }
+
+        $data .= $this->writePadding($data);
+
+        $keyTop = $this->getPosition($data);
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $resources .= pack('V', $this->getPosition($data));
+
+            $data .= pack('V', \strlen($target))
+                .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8')
+                .$this->writePadding($data)
+                  ;
+        }
+
+        $resOffset = $this->getPosition($data);
+
+        $data .= pack('v', \count($messages->all($domain)))
+            .$indexes
+            .$this->writePadding($data)
+            .$resources
+              ;
+
+        $bundleTop = $this->getPosition($data);
+
+        $root = pack('V7',
+            $resOffset + (2 << 28), // Resource Offset + Resource Type
+            6,                      // Index length
+            $keyTop,                        // Index keys top
+            $bundleTop,                     // Index resources top
+            $bundleTop,                     // Index bundle top
+            \count($messages->all($domain)), // Index max table length
+            0                               // Index attributes
+        );
+
+        $header = pack('vC2v4C12@32',
+            32,                     // Header size
+            0xDA, 0x27,             // Magic number 1 and 2
+            20, 0, 0, 2,            // Rest of the header, ..., Size of a char
+            0x52, 0x65, 0x73, 0x42, // Data format identifier
+            1, 2, 0, 0,             // Data version
+            1, 4, 0, 0              // Unicode version
+        );
+
+        return $header.$root.$data;
+    }
+
+    private function writePadding(string $data): ?string
+    {
+        $padding = \strlen($data) % 4;
+
+        return $padding ? str_repeat("\xAA", 4 - $padding) : null;
+    }
+
+    private function getPosition(string $data)
+    {
+        return (\strlen($data) + 28) / 4;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'res';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IniFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IniFileDumper.php
new file mode 100644
index 0000000..93c900a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/IniFileDumper.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IniFileDumper generates an ini formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IniFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $output = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $escapeTarget = str_replace('"', '\"', $target);
+            $output .= $source.'="'.$escapeTarget."\"\n";
+        }
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'ini';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/JsonFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/JsonFileDumper.php
new file mode 100644
index 0000000..34c0b56
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/JsonFileDumper.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * JsonFileDumper generates an json formatted string representation of a message catalogue.
+ *
+ * @author singles
+ */
+class JsonFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $flags = $options['json_encoding'] ?? \JSON_PRETTY_PRINT;
+
+        return json_encode($messages->all($domain), $flags);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'json';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/MoFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/MoFileDumper.php
new file mode 100644
index 0000000..54d0da8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/MoFileDumper.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Loader\MoFileLoader;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * MoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class MoFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $sources = $targets = $sourceOffsets = $targetOffsets = '';
+        $offsets = [];
+        $size = 0;
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $offsets[] = array_map('strlen', [$sources, $source, $targets, $target]);
+            $sources .= "\0".$source;
+            $targets .= "\0".$target;
+            ++$size;
+        }
+
+        $header = [
+            'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
+            'formatRevision' => 0,
+            'count' => $size,
+            'offsetId' => MoFileLoader::MO_HEADER_SIZE,
+            'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
+            'sizeHashes' => 0,
+            'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
+        ];
+
+        $sourcesSize = \strlen($sources);
+        $sourcesStart = $header['offsetHashes'] + 1;
+
+        foreach ($offsets as $offset) {
+            $sourceOffsets .= $this->writeLong($offset[1])
+                          .$this->writeLong($offset[0] + $sourcesStart);
+            $targetOffsets .= $this->writeLong($offset[3])
+                          .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
+        }
+
+        $output = implode('', array_map([$this, 'writeLong'], $header))
+               .$sourceOffsets
+               .$targetOffsets
+               .$sources
+               .$targets
+                ;
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'mo';
+    }
+
+    private function writeLong($str): string
+    {
+        return pack('V*', $str);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PhpFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PhpFileDumper.php
new file mode 100644
index 0000000..6163b52
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PhpFileDumper.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PhpFileDumper generates PHP files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class PhpFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        return "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'php';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PoFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PoFileDumper.php
new file mode 100644
index 0000000..0d82281
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/PoFileDumper.php
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class PoFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $output = 'msgid ""'."\n";
+        $output .= 'msgstr ""'."\n";
+        $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n";
+        $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n";
+        $output .= '"Language: '.$messages->getLocale().'\n"'."\n";
+        $output .= "\n";
+
+        $newLine = false;
+        foreach ($messages->all($domain) as $source => $target) {
+            if ($newLine) {
+                $output .= "\n";
+            } else {
+                $newLine = true;
+            }
+            $metadata = $messages->getMetadata($source, $domain);
+
+            if (isset($metadata['comments'])) {
+                $output .= $this->formatComments($metadata['comments']);
+            }
+            if (isset($metadata['flags'])) {
+                $output .= $this->formatComments(implode(',', (array) $metadata['flags']), ',');
+            }
+            if (isset($metadata['sources'])) {
+                $output .= $this->formatComments(implode(' ', (array) $metadata['sources']), ':');
+            }
+
+            $sourceRules = $this->getStandardRules($source);
+            $targetRules = $this->getStandardRules($target);
+            if (2 == \count($sourceRules) && [] !== $targetRules) {
+                $output .= sprintf('msgid "%s"'."\n", $this->escape($sourceRules[0]));
+                $output .= sprintf('msgid_plural "%s"'."\n", $this->escape($sourceRules[1]));
+                foreach ($targetRules as $i => $targetRule) {
+                    $output .= sprintf('msgstr[%d] "%s"'."\n", $i, $this->escape($targetRule));
+                }
+            } else {
+                $output .= sprintf('msgid "%s"'."\n", $this->escape($source));
+                $output .= sprintf('msgstr "%s"'."\n", $this->escape($target));
+            }
+        }
+
+        return $output;
+    }
+
+    private function getStandardRules(string $id)
+    {
+        // Partly copied from TranslatorTrait::trans.
+        $parts = [];
+        if (preg_match('/^\|++$/', $id)) {
+            $parts = explode('|', $id);
+        } elseif (preg_match_all('/(?:\|\||[^\|])++/', $id, $matches)) {
+            $parts = $matches[0];
+        }
+
+        $intervalRegexp = <<<'EOF'
+/^(?P<interval>
+    ({\s*
+        (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
+    \s*})
+
+        |
+
+    (?P<left_delimiter>[\[\]])
+        \s*
+        (?P<left>-Inf|\-?\d+(\.\d+)?)
+        \s*,\s*
+        (?P<right>\+?Inf|\-?\d+(\.\d+)?)
+        \s*
+    (?P<right_delimiter>[\[\]])
+)\s*(?P<message>.*?)$/xs
+EOF;
+
+        $standardRules = [];
+        foreach ($parts as $part) {
+            $part = trim(str_replace('||', '|', $part));
+
+            if (preg_match($intervalRegexp, $part)) {
+                // Explicit rule is not a standard rule.
+                return [];
+            } else {
+                $standardRules[] = $part;
+            }
+        }
+
+        return $standardRules;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'po';
+    }
+
+    private function escape(string $str): string
+    {
+        return addcslashes($str, "\0..\37\42\134");
+    }
+
+    private function formatComments($comments, string $prefix = ''): ?string
+    {
+        $output = null;
+
+        foreach ((array) $comments as $comment) {
+            $output .= sprintf('#%s %s'."\n", $prefix, $comment);
+        }
+
+        return $output;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/QtFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/QtFileDumper.php
new file mode 100644
index 0000000..406e9f0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/QtFileDumper.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtFileDumper generates ts files from a message catalogue.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QtFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+        $ts = $dom->appendChild($dom->createElement('TS'));
+        $context = $ts->appendChild($dom->createElement('context'));
+        $context->appendChild($dom->createElement('name', $domain));
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $message = $context->appendChild($dom->createElement('message'));
+            $metadata = $messages->getMetadata($source, $domain);
+            if (isset($metadata['sources'])) {
+                foreach ((array) $metadata['sources'] as $location) {
+                    $loc = explode(':', $location, 2);
+                    $location = $message->appendChild($dom->createElement('location'));
+                    $location->setAttribute('filename', $loc[0]);
+                    if (isset($loc[1])) {
+                        $location->setAttribute('line', $loc[1]);
+                    }
+                }
+            }
+            $message->appendChild($dom->createElement('source', $source));
+            $message->appendChild($dom->createElement('translation', $target));
+        }
+
+        return $dom->saveXML();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'ts';
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/XliffFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/XliffFileDumper.php
new file mode 100644
index 0000000..f7dbdcd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/XliffFileDumper.php
@@ -0,0 +1,203 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * XliffFileDumper generates xliff files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class XliffFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        $xliffVersion = '1.2';
+        if (\array_key_exists('xliff_version', $options)) {
+            $xliffVersion = $options['xliff_version'];
+        }
+
+        if (\array_key_exists('default_locale', $options)) {
+            $defaultLocale = $options['default_locale'];
+        } else {
+            $defaultLocale = \Locale::getDefault();
+        }
+
+        if ('1.2' === $xliffVersion) {
+            return $this->dumpXliff1($defaultLocale, $messages, $domain, $options);
+        }
+        if ('2.0' === $xliffVersion) {
+            return $this->dumpXliff2($defaultLocale, $messages, $domain);
+        }
+
+        throw new InvalidArgumentException(sprintf('No support implemented for dumping XLIFF version "%s".', $xliffVersion));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'xlf';
+    }
+
+    private function dumpXliff1(string $defaultLocale, MessageCatalogue $messages, ?string $domain, array $options = [])
+    {
+        $toolInfo = ['tool-id' => 'symfony', 'tool-name' => 'Symfony'];
+        if (\array_key_exists('tool_info', $options)) {
+            $toolInfo = array_merge($toolInfo, $options['tool_info']);
+        }
+
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+
+        $xliff = $dom->appendChild($dom->createElement('xliff'));
+        $xliff->setAttribute('version', '1.2');
+        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
+
+        $xliffFile = $xliff->appendChild($dom->createElement('file'));
+        $xliffFile->setAttribute('source-language', str_replace('_', '-', $defaultLocale));
+        $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
+        $xliffFile->setAttribute('datatype', 'plaintext');
+        $xliffFile->setAttribute('original', 'file.ext');
+
+        $xliffHead = $xliffFile->appendChild($dom->createElement('header'));
+        $xliffTool = $xliffHead->appendChild($dom->createElement('tool'));
+        foreach ($toolInfo as $id => $value) {
+            $xliffTool->setAttribute($id, $value);
+        }
+
+        $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
+        foreach ($messages->all($domain) as $source => $target) {
+            $translation = $dom->createElement('trans-unit');
+
+            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
+            $translation->setAttribute('resname', $source);
+
+            $s = $translation->appendChild($dom->createElement('source'));
+            $s->appendChild($dom->createTextNode($source));
+
+            // Does the target contain characters requiring a CDATA section?
+            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
+
+            $targetElement = $dom->createElement('target');
+            $metadata = $messages->getMetadata($source, $domain);
+            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
+                foreach ($metadata['target-attributes'] as $name => $value) {
+                    $targetElement->setAttribute($name, $value);
+                }
+            }
+            $t = $translation->appendChild($targetElement);
+            $t->appendChild($text);
+
+            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
+                foreach ($metadata['notes'] as $note) {
+                    if (!isset($note['content'])) {
+                        continue;
+                    }
+
+                    $n = $translation->appendChild($dom->createElement('note'));
+                    $n->appendChild($dom->createTextNode($note['content']));
+
+                    if (isset($note['priority'])) {
+                        $n->setAttribute('priority', $note['priority']);
+                    }
+
+                    if (isset($note['from'])) {
+                        $n->setAttribute('from', $note['from']);
+                    }
+                }
+            }
+
+            $xliffBody->appendChild($translation);
+        }
+
+        return $dom->saveXML();
+    }
+
+    private function dumpXliff2(string $defaultLocale, MessageCatalogue $messages, ?string $domain)
+    {
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+
+        $xliff = $dom->appendChild($dom->createElement('xliff'));
+        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:2.0');
+        $xliff->setAttribute('version', '2.0');
+        $xliff->setAttribute('srcLang', str_replace('_', '-', $defaultLocale));
+        $xliff->setAttribute('trgLang', str_replace('_', '-', $messages->getLocale()));
+
+        $xliffFile = $xliff->appendChild($dom->createElement('file'));
+        if (str_ends_with($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
+            $xliffFile->setAttribute('id', substr($domain, 0, -\strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)).'.'.$messages->getLocale());
+        } else {
+            $xliffFile->setAttribute('id', $domain.'.'.$messages->getLocale());
+        }
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $translation = $dom->createElement('unit');
+            $translation->setAttribute('id', strtr(substr(base64_encode(hash('sha256', $source, true)), 0, 7), '/+', '._'));
+
+            if (\strlen($source) <= 80) {
+                $translation->setAttribute('name', $source);
+            }
+
+            $metadata = $messages->getMetadata($source, $domain);
+
+            // Add notes section
+            if ($this->hasMetadataArrayInfo('notes', $metadata)) {
+                $notesElement = $dom->createElement('notes');
+                foreach ($metadata['notes'] as $note) {
+                    $n = $dom->createElement('note');
+                    $n->appendChild($dom->createTextNode($note['content'] ?? ''));
+                    unset($note['content']);
+
+                    foreach ($note as $name => $value) {
+                        $n->setAttribute($name, $value);
+                    }
+                    $notesElement->appendChild($n);
+                }
+                $translation->appendChild($notesElement);
+            }
+
+            $segment = $translation->appendChild($dom->createElement('segment'));
+
+            $s = $segment->appendChild($dom->createElement('source'));
+            $s->appendChild($dom->createTextNode($source));
+
+            // Does the target contain characters requiring a CDATA section?
+            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
+
+            $targetElement = $dom->createElement('target');
+            if ($this->hasMetadataArrayInfo('target-attributes', $metadata)) {
+                foreach ($metadata['target-attributes'] as $name => $value) {
+                    $targetElement->setAttribute($name, $value);
+                }
+            }
+            $t = $segment->appendChild($targetElement);
+            $t->appendChild($text);
+
+            $xliffFile->appendChild($translation);
+        }
+
+        return $dom->saveXML();
+    }
+
+    private function hasMetadataArrayInfo(string $key, array $metadata = null): bool
+    {
+        return is_iterable($metadata[$key] ?? null);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/YamlFileDumper.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/YamlFileDumper.php
new file mode 100644
index 0000000..0b21e8c
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Dumper/YamlFileDumper.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\Exception\LogicException;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Util\ArrayConverter;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileDumper generates yaml files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class YamlFileDumper extends FileDumper
+{
+    private $extension;
+
+    public function __construct(string $extension = 'yml')
+    {
+        $this->extension = $extension;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = [])
+    {
+        if (!class_exists(Yaml::class)) {
+            throw new LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
+        }
+
+        $data = $messages->all($domain);
+
+        if (isset($options['as_tree']) && $options['as_tree']) {
+            $data = ArrayConverter::expandToTree($data);
+        }
+
+        if (isset($options['inline']) && ($inline = (int) $options['inline']) > 0) {
+            return Yaml::dump($data, $inline);
+        }
+
+        return Yaml::dump($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return $this->extension;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ExceptionInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..8f9c54e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ExceptionInterface extends \Throwable
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/IncompleteDsnException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/IncompleteDsnException.php
new file mode 100644
index 0000000..cb0ce02
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/IncompleteDsnException.php
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+class IncompleteDsnException extends InvalidArgumentException
+{
+    public function __construct(string $message, string $dsn = null, \Throwable $previous = null)
+    {
+        if ($dsn) {
+            $message = sprintf('Invalid "%s" provider DSN: ', $dsn).$message;
+        }
+
+        parent::__construct($message, 0, $previous);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidArgumentException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..90d0669
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidArgumentException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Base InvalidArgumentException for the Translation component.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidResourceException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidResourceException.php
new file mode 100644
index 0000000..cf07943
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/InvalidResourceException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource cannot be loaded.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/LogicException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/LogicException.php
new file mode 100644
index 0000000..9019c7e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/LogicException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Base LogicException for Translation component.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class LogicException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/MissingRequiredOptionException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/MissingRequiredOptionException.php
new file mode 100644
index 0000000..2b5f808
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/MissingRequiredOptionException.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * @author Oskar Stark <oskarstark@googlemail.com>
+ */
+class MissingRequiredOptionException extends IncompleteDsnException
+{
+    public function __construct(string $option, string $dsn = null, \Throwable $previous = null)
+    {
+        $message = sprintf('The option "%s" is required but missing.', $option);
+
+        parent::__construct($message, $dsn, $previous);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/NotFoundResourceException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/NotFoundResourceException.php
new file mode 100644
index 0000000..cff73ae
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/NotFoundResourceException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource does not exist.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderException.php
new file mode 100644
index 0000000..659c6d7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderException.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+use Symfony\Contracts\HttpClient\ResponseInterface;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @experimental in 5.3
+ */
+class ProviderException extends RuntimeException implements ProviderExceptionInterface
+{
+    private $response;
+    private $debug;
+
+    public function __construct(string $message, ResponseInterface $response, int $code = 0, \Exception $previous = null)
+    {
+        $this->response = $response;
+        $this->debug .= $response->getInfo('debug') ?? '';
+
+        parent::__construct($message, $code, $previous);
+    }
+
+    public function getResponse(): ResponseInterface
+    {
+        return $this->response;
+    }
+
+    public function getDebug(): string
+    {
+        return $this->debug;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderExceptionInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderExceptionInterface.php
new file mode 100644
index 0000000..8cf1c51
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/ProviderExceptionInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @experimental in 5.3
+ */
+interface ProviderExceptionInterface extends ExceptionInterface
+{
+    /*
+     * Returns debug info coming from the Symfony\Contracts\HttpClient\ResponseInterface
+     */
+    public function getDebug(): string;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/RuntimeException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/RuntimeException.php
new file mode 100644
index 0000000..dcd7940
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/RuntimeException.php
@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Base RuntimeException for the Translation component.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/UnsupportedSchemeException.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/UnsupportedSchemeException.php
new file mode 100644
index 0000000..7fbaa8f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Exception/UnsupportedSchemeException.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+use Symfony\Component\Translation\Bridge;
+use Symfony\Component\Translation\Provider\Dsn;
+
+class UnsupportedSchemeException extends LogicException
+{
+    private const SCHEME_TO_PACKAGE_MAP = [
+        'crowdin' => [
+            'class' => Bridge\Crowdin\CrowdinProviderFactory::class,
+            'package' => 'symfony/crowdin-translation-provider',
+        ],
+        'loco' => [
+            'class' => Bridge\Loco\LocoProviderFactory::class,
+            'package' => 'symfony/loco-translation-provider',
+        ],
+        'lokalise' => [
+            'class' => Bridge\Lokalise\LokaliseProviderFactory::class,
+            'package' => 'symfony/lokalise-translation-provider',
+        ],
+    ];
+
+    public function __construct(Dsn $dsn, string $name = null, array $supported = [])
+    {
+        $provider = $dsn->getScheme();
+        if (false !== $pos = strpos($provider, '+')) {
+            $provider = substr($provider, 0, $pos);
+        }
+        $package = self::SCHEME_TO_PACKAGE_MAP[$provider] ?? null;
+        if ($package && !class_exists($package['class'])) {
+            parent::__construct(sprintf('Unable to synchronize translations via "%s" as the provider is not installed; try running "composer require %s".', $provider, $package['package']));
+
+            return;
+        }
+
+        $message = sprintf('The "%s" scheme is not supported', $dsn->getScheme());
+        if ($name && $supported) {
+            $message .= sprintf('; supported schemes for translation provider "%s" are: "%s"', $name, implode('", "', $supported));
+        }
+
+        parent::__construct($message.'.');
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/AbstractFileExtractor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/AbstractFileExtractor.php
new file mode 100644
index 0000000..729dd17
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/AbstractFileExtractor.php
@@ -0,0 +1,76 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * Base class used by classes that extract translation messages from files.
+ *
+ * @author Marcos D. Sánchez <marcosdsanchez@gmail.com>
+ */
+abstract class AbstractFileExtractor
+{
+    /**
+     * @param string|iterable $resource Files, a file or a directory
+     *
+     * @return iterable
+     */
+    protected function extractFiles($resource)
+    {
+        if (is_iterable($resource)) {
+            $files = [];
+            foreach ($resource as $file) {
+                if ($this->canBeExtracted($file)) {
+                    $files[] = $this->toSplFileInfo($file);
+                }
+            }
+        } elseif (is_file($resource)) {
+            $files = $this->canBeExtracted($resource) ? [$this->toSplFileInfo($resource)] : [];
+        } else {
+            $files = $this->extractFromDirectory($resource);
+        }
+
+        return $files;
+    }
+
+    private function toSplFileInfo(string $file): \SplFileInfo
+    {
+        return new \SplFileInfo($file);
+    }
+
+    /**
+     * @return bool
+     *
+     * @throws InvalidArgumentException
+     */
+    protected function isFile(string $file)
+    {
+        if (!is_file($file)) {
+            throw new InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
+        }
+
+        return true;
+    }
+
+    /**
+     * @return bool
+     */
+    abstract protected function canBeExtracted(string $file);
+
+    /**
+     * @param string|array $resource Files, a file or a directory
+     *
+     * @return iterable files to be extracted
+     */
+    abstract protected function extractFromDirectory($resource);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ChainExtractor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ChainExtractor.php
new file mode 100644
index 0000000..95dcf15
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ChainExtractor.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ChainExtractor extracts translation messages from template files.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class ChainExtractor implements ExtractorInterface
+{
+    /**
+     * The extractors.
+     *
+     * @var ExtractorInterface[]
+     */
+    private $extractors = [];
+
+    /**
+     * Adds a loader to the translation extractor.
+     */
+    public function addExtractor(string $format, ExtractorInterface $extractor)
+    {
+        $this->extractors[$format] = $extractor;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setPrefix(string $prefix)
+    {
+        foreach ($this->extractors as $extractor) {
+            $extractor->setPrefix($prefix);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function extract($directory, MessageCatalogue $catalogue)
+    {
+        foreach ($this->extractors as $extractor) {
+            $extractor->extract($directory, $catalogue);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ExtractorInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ExtractorInterface.php
new file mode 100644
index 0000000..e1db8a9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/ExtractorInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * Extracts translation messages from a directory or files to the catalogue.
+ * New found messages are injected to the catalogue using the prefix.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface ExtractorInterface
+{
+    /**
+     * Extracts translation messages from files, a file or a directory to the catalogue.
+     *
+     * @param string|iterable<string> $resource Files, a file or a directory
+     */
+    public function extract($resource, MessageCatalogue $catalogue);
+
+    /**
+     * Sets the prefix that should be used for new found messages.
+     */
+    public function setPrefix(string $prefix);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpExtractor.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpExtractor.php
new file mode 100644
index 0000000..c5efb5f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpExtractor.php
@@ -0,0 +1,336 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PhpExtractor extracts translation messages from a PHP template.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class PhpExtractor extends AbstractFileExtractor implements ExtractorInterface
+{
+    public const MESSAGE_TOKEN = 300;
+    public const METHOD_ARGUMENTS_TOKEN = 1000;
+    public const DOMAIN_TOKEN = 1001;
+
+    /**
+     * Prefix for new found message.
+     *
+     * @var string
+     */
+    private $prefix = '';
+
+    /**
+     * The sequence that captures translation messages.
+     *
+     * @var array
+     */
+    protected $sequences = [
+        [
+            '->',
+            'trans',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            '->',
+            'trans',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            'new',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            'new',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            'new',
+            '\\',
+            'Symfony',
+            '\\',
+            'Component',
+            '\\',
+            'Translation',
+            '\\',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            'new',
+            '\Symfony\Component\Translation\TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            'new',
+            '\\',
+            'Symfony',
+            '\\',
+            'Component',
+            '\\',
+            'Translation',
+            '\\',
+            'TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            'new',
+            '\Symfony\Component\Translation\TranslatableMessage',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+        [
+            't',
+            '(',
+            self::MESSAGE_TOKEN,
+            ',',
+            self::METHOD_ARGUMENTS_TOKEN,
+            ',',
+            self::DOMAIN_TOKEN,
+        ],
+        [
+            't',
+            '(',
+            self::MESSAGE_TOKEN,
+        ],
+    ];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function extract($resource, MessageCatalogue $catalog)
+    {
+        $files = $this->extractFiles($resource);
+        foreach ($files as $file) {
+            $this->parseTokens(token_get_all(file_get_contents($file)), $catalog, $file);
+
+            gc_mem_caches();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setPrefix(string $prefix)
+    {
+        $this->prefix = $prefix;
+    }
+
+    /**
+     * Normalizes a token.
+     *
+     * @param mixed $token
+     *
+     * @return string|null
+     */
+    protected function normalizeToken($token)
+    {
+        if (isset($token[1]) && 'b"' !== $token) {
+            return $token[1];
+        }
+
+        return $token;
+    }
+
+    /**
+     * Seeks to a non-whitespace token.
+     */
+    private function seekToNextRelevantToken(\Iterator $tokenIterator)
+    {
+        for (; $tokenIterator->valid(); $tokenIterator->next()) {
+            $t = $tokenIterator->current();
+            if (\T_WHITESPACE !== $t[0]) {
+                break;
+            }
+        }
+    }
+
+    private function skipMethodArgument(\Iterator $tokenIterator)
+    {
+        $openBraces = 0;
+
+        for (; $tokenIterator->valid(); $tokenIterator->next()) {
+            $t = $tokenIterator->current();
+
+            if ('[' === $t[0] || '(' === $t[0]) {
+                ++$openBraces;
+            }
+
+            if (']' === $t[0] || ')' === $t[0]) {
+                --$openBraces;
+            }
+
+            if ((0 === $openBraces && ',' === $t[0]) || (-1 === $openBraces && ')' === $t[0])) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Extracts the message from the iterator while the tokens
+     * match allowed message tokens.
+     */
+    private function getValue(\Iterator $tokenIterator)
+    {
+        $message = '';
+        $docToken = '';
+        $docPart = '';
+
+        for (; $tokenIterator->valid(); $tokenIterator->next()) {
+            $t = $tokenIterator->current();
+            if ('.' === $t) {
+                // Concatenate with next token
+                continue;
+            }
+            if (!isset($t[1])) {
+                break;
+            }
+
+            switch ($t[0]) {
+                case \T_START_HEREDOC:
+                    $docToken = $t[1];
+                    break;
+                case \T_ENCAPSED_AND_WHITESPACE:
+                case \T_CONSTANT_ENCAPSED_STRING:
+                    if ('' === $docToken) {
+                        $message .= PhpStringTokenParser::parse($t[1]);
+                    } else {
+                        $docPart = $t[1];
+                    }
+                    break;
+                case \T_END_HEREDOC:
+                    if ($indentation = strspn($t[1], ' ')) {
+                        $docPartWithLineBreaks = $docPart;
+                        $docPart = '';
+
+                        foreach (preg_split('~(\r\n|\n|\r)~', $docPartWithLineBreaks, -1, \PREG_SPLIT_DELIM_CAPTURE) as $str) {
+                            if (\in_array($str, ["\r\n", "\n", "\r"], true)) {
+                                $docPart .= $str;
+                            } else {
+                                $docPart .= substr($str, $indentation);
+                            }
+                        }
+                    }
+
+                    $message .= PhpStringTokenParser::parseDocString($docToken, $docPart);
+                    $docToken = '';
+                    $docPart = '';
+                    break;
+                case \T_WHITESPACE:
+                    break;
+                default:
+                    break 2;
+            }
+        }
+
+        return $message;
+    }
+
+    /**
+     * Extracts trans message from PHP tokens.
+     */
+    protected function parseTokens(array $tokens, MessageCatalogue $catalog, string $filename)
+    {
+        $tokenIterator = new \ArrayIterator($tokens);
+
+        for ($key = 0; $key < $tokenIterator->count(); ++$key) {
+            foreach ($this->sequences as $sequence) {
+                $message = '';
+                $domain = 'messages';
+                $tokenIterator->seek($key);
+
+                foreach ($sequence as $sequenceKey => $item) {
+                    $this->seekToNextRelevantToken($tokenIterator);
+
+                    if ($this->normalizeToken($tokenIterator->current()) === $item) {
+                        $tokenIterator->next();
+                        continue;
+                    } elseif (self::MESSAGE_TOKEN === $item) {
+                        $message = $this->getValue($tokenIterator);
+
+                        if (\count($sequence) === ($sequenceKey + 1)) {
+                            break;
+                        }
+                    } elseif (self::METHOD_ARGUMENTS_TOKEN === $item) {
+                        $this->skipMethodArgument($tokenIterator);
+                    } elseif (self::DOMAIN_TOKEN === $item) {
+                        $domainToken = $this->getValue($tokenIterator);
+                        if ('' !== $domainToken) {
+                            $domain = $domainToken;
+                        }
+
+                        break;
+                    } else {
+                        break;
+                    }
+                }
+
+                if ($message) {
+                    $catalog->set($message, $this->prefix.$message, $domain);
+                    $metadata = $catalog->getMetadata($message, $domain) ?? [];
+                    $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $filename);
+                    $metadata['sources'][] = $normalizedFilename.':'.$tokens[$key][2];
+                    $catalog->setMetadata($message, $metadata, $domain);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * @return bool
+     *
+     * @throws \InvalidArgumentException
+     */
+    protected function canBeExtracted(string $file)
+    {
+        return $this->isFile($file) && 'php' === pathinfo($file, \PATHINFO_EXTENSION);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function extractFromDirectory($directory)
+    {
+        $finder = new Finder();
+
+        return $finder->files()->name('*.php')->in($directory);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpStringTokenParser.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpStringTokenParser.php
new file mode 100644
index 0000000..1d82caf
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Extractor/PhpStringTokenParser.php
@@ -0,0 +1,142 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+/*
+ * The following is derived from code at http://github.com/nikic/PHP-Parser
+ *
+ * Copyright (c) 2011 by Nikita Popov
+ *
+ * Some rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *
+ *     * The names of the contributors may not be used to endorse or
+ *       promote products derived from this software without specific
+ *       prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+class PhpStringTokenParser
+{
+    protected static $replacements = [
+        '\\' => '\\',
+        '$' => '$',
+        'n' => "\n",
+        'r' => "\r",
+        't' => "\t",
+        'f' => "\f",
+        'v' => "\v",
+        'e' => "\x1B",
+    ];
+
+    /**
+     * Parses a string token.
+     *
+     * @param string $str String token content
+     *
+     * @return string The parsed string
+     */
+    public static function parse(string $str)
+    {
+        $bLength = 0;
+        if ('b' === $str[0]) {
+            $bLength = 1;
+        }
+
+        if ('\'' === $str[$bLength]) {
+            return str_replace(
+                ['\\\\', '\\\''],
+                ['\\', '\''],
+                substr($str, $bLength + 1, -1)
+            );
+        } else {
+            return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
+        }
+    }
+
+    /**
+     * Parses escape sequences in strings (all string types apart from single quoted).
+     *
+     * @param string      $str   String without quotes
+     * @param string|null $quote Quote type
+     *
+     * @return string String with escape sequences parsed
+     */
+    public static function parseEscapeSequences(string $str, string $quote = null)
+    {
+        if (null !== $quote) {
+            $str = str_replace('\\'.$quote, $quote, $str);
+        }
+
+        return preg_replace_callback(
+            '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~',
+            [__CLASS__, 'parseCallback'],
+            $str
+        );
+    }
+
+    private static function parseCallback(array $matches): string
+    {
+        $str = $matches[1];
+
+        if (isset(self::$replacements[$str])) {
+            return self::$replacements[$str];
+        } elseif ('x' === $str[0] || 'X' === $str[0]) {
+            return \chr(hexdec($str));
+        } else {
+            return \chr(octdec($str));
+        }
+    }
+
+    /**
+     * Parses a constant doc string.
+     *
+     * @param string $startToken Doc string start token content (<<<SMTHG)
+     * @param string $str        String token content
+     *
+     * @return string Parsed string
+     */
+    public static function parseDocString(string $startToken, string $str)
+    {
+        // strip last newline (thanks tokenizer for sticking it into the string!)
+        $str = preg_replace('~(\r\n|\n|\r)$~', '', $str);
+
+        // nowdoc string
+        if (str_contains($startToken, '\'')) {
+            return $str;
+        }
+
+        return self::parseEscapeSequences($str, null);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatter.php
new file mode 100644
index 0000000..f7f1c36
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatter.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\LogicException;
+
+/**
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class IntlFormatter implements IntlFormatterInterface
+{
+    private $hasMessageFormatter;
+    private $cache = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatIntl(string $message, string $locale, array $parameters = []): string
+    {
+        // MessageFormatter constructor throws an exception if the message is empty
+        if ('' === $message) {
+            return '';
+        }
+
+        if (!$formatter = $this->cache[$locale][$message] ?? null) {
+            if (!($this->hasMessageFormatter ?? $this->hasMessageFormatter = class_exists(\MessageFormatter::class))) {
+                throw new LogicException('Cannot parse message translation: please install the "intl" PHP extension or the "symfony/polyfill-intl-messageformatter" package.');
+            }
+            try {
+                $this->cache[$locale][$message] = $formatter = new \MessageFormatter($locale, $message);
+            } catch (\IntlException $e) {
+                throw new InvalidArgumentException(sprintf('Invalid message format (error #%d): ', intl_get_error_code()).intl_get_error_message(), 0, $e);
+            }
+        }
+
+        foreach ($parameters as $key => $value) {
+            if (\in_array($key[0] ?? null, ['%', '{'], true)) {
+                unset($parameters[$key]);
+                $parameters[trim($key, '%{ }')] = $value;
+            }
+        }
+
+        if (false === $message = $formatter->format($parameters)) {
+            throw new InvalidArgumentException(sprintf('Unable to format message (error #%s): ', $formatter->getErrorCode()).$formatter->getErrorMessage());
+        }
+
+        return $message;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatterInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatterInterface.php
new file mode 100644
index 0000000..02fc6ac
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/IntlFormatterInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+/**
+ * Formats ICU message patterns.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+interface IntlFormatterInterface
+{
+    /**
+     * Formats a localized message using rules defined by ICU MessageFormat.
+     *
+     * @see http://icu-project.org/apiref/icu4c/classMessageFormat.html#details
+     */
+    public function formatIntl(string $message, string $locale, array $parameters = []): string;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatter.php
new file mode 100644
index 0000000..0407964
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatter.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+use Symfony\Component\Translation\IdentityTranslator;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+// Help opcache.preload discover always-needed symbols
+class_exists(IntlFormatter::class);
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class MessageFormatter implements MessageFormatterInterface, IntlFormatterInterface
+{
+    private $translator;
+    private $intlFormatter;
+
+    /**
+     * @param TranslatorInterface|null $translator An identity translator to use as selector for pluralization
+     */
+    public function __construct(TranslatorInterface $translator = null, IntlFormatterInterface $intlFormatter = null)
+    {
+        $this->translator = $translator ?? new IdentityTranslator();
+        $this->intlFormatter = $intlFormatter ?? new IntlFormatter();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(string $message, string $locale, array $parameters = [])
+    {
+        if ($this->translator instanceof TranslatorInterface) {
+            return $this->translator->trans($message, $parameters, null, $locale);
+        }
+
+        return strtr($message, $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function formatIntl(string $message, string $locale, array $parameters = []): string
+    {
+        return $this->intlFormatter->formatIntl($message, $locale, $parameters);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatterInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatterInterface.php
new file mode 100644
index 0000000..b85dbfd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Formatter/MessageFormatterInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Formatter;
+
+/**
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+interface MessageFormatterInterface
+{
+    /**
+     * Formats a localized message pattern with given arguments.
+     *
+     * @param string $message    The message (may also be an object that can be cast to string)
+     * @param string $locale     The message locale
+     * @param array  $parameters An array of parameters for the message
+     *
+     * @return string
+     */
+    public function format(string $message, string $locale, array $parameters = []);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/IdentityTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/IdentityTranslator.php
new file mode 100644
index 0000000..46875ed
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/IdentityTranslator.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+use Symfony\Contracts\Translation\TranslatorTrait;
+
+/**
+ * IdentityTranslator does not translate anything.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class IdentityTranslator implements TranslatorInterface, LocaleAwareInterface
+{
+    use TranslatorTrait;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LICENSE b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LICENSE
new file mode 100644
index 0000000..9ff2d0d
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2021 Fabien Potencier
+
+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/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/ArrayLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/ArrayLoader.php
new file mode 100644
index 0000000..0758da8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/ArrayLoader.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ArrayLoader loads translations from a PHP array.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ArrayLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        $resource = $this->flatten($resource);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($resource, $domain);
+
+        return $catalogue;
+    }
+
+    /**
+     * Flattens an nested array of translations.
+     *
+     * The scheme used is:
+     *   'key' => ['key2' => ['key3' => 'value']]
+     * Becomes:
+     *   'key.key2.key3' => 'value'
+     */
+    private function flatten(array $messages): array
+    {
+        $result = [];
+        foreach ($messages as $key => $value) {
+            if (\is_array($value)) {
+                foreach ($this->flatten($value) as $k => $v) {
+                    $result[$key.'.'.$k] = $v;
+                }
+            } else {
+                $result[$key] = $value;
+            }
+        }
+
+        return $result;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/CsvFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/CsvFileLoader.php
new file mode 100644
index 0000000..8d5d4db
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/CsvFileLoader.php
@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+
+/**
+ * CsvFileLoader loads translations from CSV files.
+ *
+ * @author Saša Stamenković <umpirsky@gmail.com>
+ */
+class CsvFileLoader extends FileLoader
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+    private $escape = '\\';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $messages = [];
+
+        try {
+            $file = new \SplFileObject($resource, 'rb');
+        } catch (\RuntimeException $e) {
+            throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
+        }
+
+        $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
+        $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
+
+        foreach ($file as $data) {
+            if (false === $data) {
+                continue;
+            }
+
+            if ('#' !== substr($data[0], 0, 1) && isset($data[1]) && 2 === \count($data)) {
+                $messages[$data[0]] = $data[1];
+            }
+        }
+
+        return $messages;
+    }
+
+    /**
+     * Sets the delimiter, enclosure, and escape character for CSV.
+     */
+    public function setCsvControl(string $delimiter = ';', string $enclosure = '"', string $escape = '\\')
+    {
+        $this->delimiter = $delimiter;
+        $this->enclosure = $enclosure;
+        $this->escape = $escape;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/FileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/FileLoader.php
new file mode 100644
index 0000000..4725ea6
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/FileLoader.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+abstract class FileLoader extends ArrayLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = $this->loadResource($resource);
+
+        // empty resource
+        if (null === $messages) {
+            $messages = [];
+        }
+
+        // not an array
+        if (!\is_array($messages)) {
+            throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists(FileResource::class)) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * @return array
+     *
+     * @throws InvalidResourceException if stream content has an invalid format
+     */
+    abstract protected function loadResource(string $resource);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuDatFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuDatFileLoader.php
new file mode 100644
index 0000000..2a1aecc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuDatFileLoader.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuDatFileLoader extends IcuResFileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!stream_is_local($resource.'.dat')) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource.'.dat')) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $rb = new \ResourceBundle($locale, $resource);
+        } catch (\Exception $e) {
+            $rb = null;
+        }
+
+        if (!$rb) {
+            throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+
+        if (class_exists(FileResource::class)) {
+            $catalogue->addResource(new FileResource($resource.'.dat'));
+        }
+
+        return $catalogue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuResFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuResFileLoader.php
new file mode 100644
index 0000000..64bbd3e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IcuResFileLoader.php
@@ -0,0 +1,91 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\DirectoryResource;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuResFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!is_dir($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $rb = new \ResourceBundle($locale, $resource);
+        } catch (\Exception $e) {
+            $rb = null;
+        }
+
+        if (!$rb) {
+            throw new InvalidResourceException(sprintf('Cannot load resource "%s".', $resource));
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+
+        if (class_exists(DirectoryResource::class)) {
+            $catalogue->addResource(new DirectoryResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Flattens an ResourceBundle.
+     *
+     * The scheme used is:
+     *   key { key2 { key3 { "value" } } }
+     * Becomes:
+     *   'key.key2.key3' => 'value'
+     *
+     * This function takes an array by reference and will modify it
+     *
+     * @param \ResourceBundle $rb       The ResourceBundle that will be flattened
+     * @param array           $messages Used internally for recursive calls
+     * @param string          $path     Current path being parsed, used internally for recursive calls
+     *
+     * @return array the flattened ResourceBundle
+     */
+    protected function flatten(\ResourceBundle $rb, array &$messages = [], string $path = null)
+    {
+        foreach ($rb as $key => $value) {
+            $nodePath = $path ? $path.'.'.$key : $key;
+            if ($value instanceof \ResourceBundle) {
+                $this->flatten($value, $messages, $nodePath);
+            } else {
+                $messages[$nodePath] = $value;
+            }
+        }
+
+        return $messages;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IniFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IniFileLoader.php
new file mode 100644
index 0000000..7398f77
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/IniFileLoader.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+/**
+ * IniFileLoader loads translations from an ini file.
+ *
+ * @author stealth35
+ */
+class IniFileLoader extends FileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        return parse_ini_file($resource, true);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/JsonFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/JsonFileLoader.php
new file mode 100644
index 0000000..5aefba0
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/JsonFileLoader.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+
+/**
+ * JsonFileLoader loads translations from an json file.
+ *
+ * @author singles
+ */
+class JsonFileLoader extends FileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $messages = [];
+        if ($data = file_get_contents($resource)) {
+            $messages = json_decode($data, true);
+
+            if (0 < $errorCode = json_last_error()) {
+                throw new InvalidResourceException('Error parsing JSON: '.$this->getJSONErrorMessage($errorCode));
+            }
+        }
+
+        return $messages;
+    }
+
+    /**
+     * Translates JSON_ERROR_* constant into meaningful message.
+     */
+    private function getJSONErrorMessage(int $errorCode): string
+    {
+        switch ($errorCode) {
+            case \JSON_ERROR_DEPTH:
+                return 'Maximum stack depth exceeded';
+            case \JSON_ERROR_STATE_MISMATCH:
+                return 'Underflow or the modes mismatch';
+            case \JSON_ERROR_CTRL_CHAR:
+                return 'Unexpected control character found';
+            case \JSON_ERROR_SYNTAX:
+                return 'Syntax error, malformed JSON';
+            case \JSON_ERROR_UTF8:
+                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+            default:
+                return 'Unknown error';
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/LoaderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/LoaderInterface.php
new file mode 100644
index 0000000..2073f2b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/LoaderInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * LoaderInterface is the interface implemented by all translation loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderInterface
+{
+    /**
+     * Loads a locale.
+     *
+     * @param mixed  $resource A resource
+     * @param string $locale   A locale
+     * @param string $domain   The domain
+     *
+     * @return MessageCatalogue A MessageCatalogue instance
+     *
+     * @throws NotFoundResourceException when the resource cannot be found
+     * @throws InvalidResourceException  when the resource cannot be loaded
+     */
+    public function load($resource, string $locale, string $domain = 'messages');
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/MoFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/MoFileLoader.php
new file mode 100644
index 0000000..0ff6549
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/MoFileLoader.php
@@ -0,0 +1,140 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ */
+class MoFileLoader extends FileLoader
+{
+    /**
+     * Magic used for validating the format of an MO file as well as
+     * detecting if the machine used to create that file was little endian.
+     */
+    public const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;
+
+    /**
+     * Magic used for validating the format of an MO file as well as
+     * detecting if the machine used to create that file was big endian.
+     */
+    public const MO_BIG_ENDIAN_MAGIC = 0xde120495;
+
+    /**
+     * The size of the header of an MO file in bytes.
+     */
+    public const MO_HEADER_SIZE = 28;
+
+    /**
+     * Parses machine object (MO) format, independent of the machine's endian it
+     * was created on. Both 32bit and 64bit systems are supported.
+     *
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $stream = fopen($resource, 'r');
+
+        $stat = fstat($stream);
+
+        if ($stat['size'] < self::MO_HEADER_SIZE) {
+            throw new InvalidResourceException('MO stream content has an invalid format.');
+        }
+        $magic = unpack('V1', fread($stream, 4));
+        $magic = hexdec(substr(dechex(current($magic)), -8));
+
+        if (self::MO_LITTLE_ENDIAN_MAGIC == $magic) {
+            $isBigEndian = false;
+        } elseif (self::MO_BIG_ENDIAN_MAGIC == $magic) {
+            $isBigEndian = true;
+        } else {
+            throw new InvalidResourceException('MO stream content has an invalid format.');
+        }
+
+        // formatRevision
+        $this->readLong($stream, $isBigEndian);
+        $count = $this->readLong($stream, $isBigEndian);
+        $offsetId = $this->readLong($stream, $isBigEndian);
+        $offsetTranslated = $this->readLong($stream, $isBigEndian);
+        // sizeHashes
+        $this->readLong($stream, $isBigEndian);
+        // offsetHashes
+        $this->readLong($stream, $isBigEndian);
+
+        $messages = [];
+
+        for ($i = 0; $i < $count; ++$i) {
+            $pluralId = null;
+            $translated = null;
+
+            fseek($stream, $offsetId + $i * 8);
+
+            $length = $this->readLong($stream, $isBigEndian);
+            $offset = $this->readLong($stream, $isBigEndian);
+
+            if ($length < 1) {
+                continue;
+            }
+
+            fseek($stream, $offset);
+            $singularId = fread($stream, $length);
+
+            if (str_contains($singularId, "\000")) {
+                [$singularId, $pluralId] = explode("\000", $singularId);
+            }
+
+            fseek($stream, $offsetTranslated + $i * 8);
+            $length = $this->readLong($stream, $isBigEndian);
+            $offset = $this->readLong($stream, $isBigEndian);
+
+            if ($length < 1) {
+                continue;
+            }
+
+            fseek($stream, $offset);
+            $translated = fread($stream, $length);
+
+            if (str_contains($translated, "\000")) {
+                $translated = explode("\000", $translated);
+            }
+
+            $ids = ['singular' => $singularId, 'plural' => $pluralId];
+            $item = compact('ids', 'translated');
+
+            if (!empty($item['ids']['singular'])) {
+                $id = $item['ids']['singular'];
+                if (isset($item['ids']['plural'])) {
+                    $id .= '|'.$item['ids']['plural'];
+                }
+                $messages[$id] = stripcslashes(implode('|', (array) $item['translated']));
+            }
+        }
+
+        fclose($stream);
+
+        return array_filter($messages);
+    }
+
+    /**
+     * Reads an unsigned long from stream respecting endianness.
+     *
+     * @param resource $stream
+     */
+    private function readLong($stream, bool $isBigEndian): int
+    {
+        $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
+        $result = current($result);
+
+        return (int) substr($result, -8);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PhpFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PhpFileLoader.php
new file mode 100644
index 0000000..85f1090
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PhpFileLoader.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+/**
+ * PhpFileLoader loads translations from PHP files returning an array of translations.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PhpFileLoader extends FileLoader
+{
+    private static $cache = [];
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        if ([] === self::$cache && \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN) && (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) {
+            self::$cache = null;
+        }
+
+        if (null === self::$cache) {
+            return require $resource;
+        }
+
+        if (isset(self::$cache[$resource])) {
+            return self::$cache[$resource];
+        }
+
+        return self::$cache[$resource] = require $resource;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PoFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PoFileLoader.php
new file mode 100644
index 0000000..ee143e2
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/PoFileLoader.php
@@ -0,0 +1,149 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD https://github.com/UnionOfRAD/lithium
+ * @copyright Copyright (c) 2012, Clemens Tolboom
+ */
+class PoFileLoader extends FileLoader
+{
+    /**
+     * Parses portable object (PO) format.
+     *
+     * From https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
+     * we should be able to parse files having:
+     *
+     * white-space
+     * #  translator-comments
+     * #. extracted-comments
+     * #: reference...
+     * #, flag...
+     * #| msgid previous-untranslated-string
+     * msgid untranslated-string
+     * msgstr translated-string
+     *
+     * extra or different lines are:
+     *
+     * #| msgctxt previous-context
+     * #| msgid previous-untranslated-string
+     * msgctxt context
+     *
+     * #| msgid previous-untranslated-string-singular
+     * #| msgid_plural previous-untranslated-string-plural
+     * msgid untranslated-string-singular
+     * msgid_plural untranslated-string-plural
+     * msgstr[0] translated-string-case-0
+     * ...
+     * msgstr[N] translated-string-case-n
+     *
+     * The definition states:
+     * - white-space and comments are optional.
+     * - msgid "" that an empty singleline defines a header.
+     *
+     * This parser sacrifices some features of the reference implementation the
+     * differences to that implementation are as follows.
+     * - No support for comments spanning multiple lines.
+     * - Translator and extracted comments are treated as being the same type.
+     * - Message IDs are allowed to have other encodings as just US-ASCII.
+     *
+     * Items with an empty id are ignored.
+     *
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        $stream = fopen($resource, 'r');
+
+        $defaults = [
+            'ids' => [],
+            'translated' => null,
+        ];
+
+        $messages = [];
+        $item = $defaults;
+        $flags = [];
+
+        while ($line = fgets($stream)) {
+            $line = trim($line);
+
+            if ('' === $line) {
+                // Whitespace indicated current item is done
+                if (!\in_array('fuzzy', $flags)) {
+                    $this->addMessage($messages, $item);
+                }
+                $item = $defaults;
+                $flags = [];
+            } elseif ('#,' === substr($line, 0, 2)) {
+                $flags = array_map('trim', explode(',', substr($line, 2)));
+            } elseif ('msgid "' === substr($line, 0, 7)) {
+                // We start a new msg so save previous
+                // TODO: this fails when comments or contexts are added
+                $this->addMessage($messages, $item);
+                $item = $defaults;
+                $item['ids']['singular'] = substr($line, 7, -1);
+            } elseif ('msgstr "' === substr($line, 0, 8)) {
+                $item['translated'] = substr($line, 8, -1);
+            } elseif ('"' === $line[0]) {
+                $continues = isset($item['translated']) ? 'translated' : 'ids';
+
+                if (\is_array($item[$continues])) {
+                    end($item[$continues]);
+                    $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
+                } else {
+                    $item[$continues] .= substr($line, 1, -1);
+                }
+            } elseif ('msgid_plural "' === substr($line, 0, 14)) {
+                $item['ids']['plural'] = substr($line, 14, -1);
+            } elseif ('msgstr[' === substr($line, 0, 7)) {
+                $size = strpos($line, ']');
+                $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
+            }
+        }
+        // save last item
+        if (!\in_array('fuzzy', $flags)) {
+            $this->addMessage($messages, $item);
+        }
+        fclose($stream);
+
+        return $messages;
+    }
+
+    /**
+     * Save a translation item to the messages.
+     *
+     * A .po file could contain by error missing plural indexes. We need to
+     * fix these before saving them.
+     */
+    private function addMessage(array &$messages, array $item)
+    {
+        if (!empty($item['ids']['singular'])) {
+            $id = stripcslashes($item['ids']['singular']);
+            if (isset($item['ids']['plural'])) {
+                $id .= '|'.stripcslashes($item['ids']['plural']);
+            }
+
+            $translated = (array) $item['translated'];
+            // PO are by definition indexed so sort by index.
+            ksort($translated);
+            // Make sure every index is filled.
+            end($translated);
+            $count = key($translated);
+            // Fill missing spots with '-'.
+            $empties = array_fill(0, $count + 1, '-');
+            $translated += $empties;
+            ksort($translated);
+
+            $messages[$id] = stripcslashes(implode('|', $translated));
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/QtFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/QtFileLoader.php
new file mode 100644
index 0000000..9cf2fe9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/QtFileLoader.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtFileLoader loads translations from QT Translations XML files.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QtFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!class_exists(XmlUtils::class)) {
+            throw new RuntimeException('Loading translations from the QT format requires the Symfony Config component.');
+        }
+
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $dom = XmlUtils::loadFile($resource);
+        } catch (\InvalidArgumentException $e) {
+            throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
+        }
+
+        $internalErrors = libxml_use_internal_errors(true);
+        libxml_clear_errors();
+
+        $xpath = new \DOMXPath($dom);
+        $nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');
+
+        $catalogue = new MessageCatalogue($locale);
+        if (1 == $nodes->length) {
+            $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
+            foreach ($translations as $translation) {
+                $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue;
+
+                if (!empty($translationValue)) {
+                    $catalogue->set(
+                        (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
+                        $translationValue,
+                        $domain
+                    );
+                }
+                $translation = $translation->nextSibling;
+            }
+
+            if (class_exists(FileResource::class)) {
+                $catalogue->addResource(new FileResource($resource));
+            }
+        }
+
+        libxml_use_internal_errors($internalErrors);
+
+        return $catalogue;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/XliffFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/XliffFileLoader.php
new file mode 100644
index 0000000..35ad33e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/XliffFileLoader.php
@@ -0,0 +1,232 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Config\Util\Exception\InvalidXmlException;
+use Symfony\Component\Config\Util\Exception\XmlParsingException;
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Util\XliffUtils;
+
+/**
+ * XliffFileLoader loads translations from XLIFF files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class XliffFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, string $locale, string $domain = 'messages')
+    {
+        if (!class_exists(XmlUtils::class)) {
+            throw new RuntimeException('Loading translations from the Xliff format requires the Symfony Config component.');
+        }
+
+        if (!$this->isXmlString($resource)) {
+            if (!stream_is_local($resource)) {
+                throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+            }
+
+            if (!file_exists($resource)) {
+                throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+            }
+
+            if (!is_file($resource)) {
+                throw new InvalidResourceException(sprintf('This is neither a file nor an XLIFF string "%s".', $resource));
+            }
+        }
+
+        try {
+            if ($this->isXmlString($resource)) {
+                $dom = XmlUtils::parse($resource);
+            } else {
+                $dom = XmlUtils::loadFile($resource);
+            }
+        } catch (\InvalidArgumentException | XmlParsingException | InvalidXmlException $e) {
+            throw new InvalidResourceException(sprintf('Unable to load "%s": ', $resource).$e->getMessage(), $e->getCode(), $e);
+        }
+
+        if ($errors = XliffUtils::validateSchema($dom)) {
+            throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: ', $resource).XliffUtils::getErrorsAsString($errors));
+        }
+
+        $catalogue = new MessageCatalogue($locale);
+        $this->extract($dom, $catalogue, $domain);
+
+        if (is_file($resource) && class_exists(FileResource::class)) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    private function extract(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
+    {
+        $xliffVersion = XliffUtils::getVersionNumber($dom);
+
+        if ('1.2' === $xliffVersion) {
+            $this->extractXliff1($dom, $catalogue, $domain);
+        }
+
+        if ('2.0' === $xliffVersion) {
+            $this->extractXliff2($dom, $catalogue, $domain);
+        }
+    }
+
+    /**
+     * Extract messages and metadata from DOMDocument into a MessageCatalogue.
+     */
+    private function extractXliff1(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
+    {
+        $xml = simplexml_import_dom($dom);
+        $encoding = $dom->encoding ? strtoupper($dom->encoding) : null;
+
+        $namespace = 'urn:oasis:names:tc:xliff:document:1.2';
+        $xml->registerXPathNamespace('xliff', $namespace);
+
+        foreach ($xml->xpath('//xliff:file') as $file) {
+            $fileAttributes = $file->attributes();
+
+            $file->registerXPathNamespace('xliff', $namespace);
+
+            foreach ($file->xpath('.//xliff:trans-unit') as $translation) {
+                $attributes = $translation->attributes();
+
+                if (!(isset($attributes['resname']) || isset($translation->source))) {
+                    continue;
+                }
+
+                $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
+                // If the xlf file has another encoding specified, try to convert it because
+                // simple_xml will always return utf-8 encoded values
+                $target = $this->utf8ToCharset((string) ($translation->target ?? $translation->source), $encoding);
+
+                $catalogue->set((string) $source, $target, $domain);
+
+                $metadata = [
+                    'source' => (string) $translation->source,
+                    'file' => [
+                        'original' => (string) $fileAttributes['original'],
+                    ],
+                ];
+                if ($notes = $this->parseNotesMetadata($translation->note, $encoding)) {
+                    $metadata['notes'] = $notes;
+                }
+
+                if (isset($translation->target) && $translation->target->attributes()) {
+                    $metadata['target-attributes'] = [];
+                    foreach ($translation->target->attributes() as $key => $value) {
+                        $metadata['target-attributes'][$key] = (string) $value;
+                    }
+                }
+
+                if (isset($attributes['id'])) {
+                    $metadata['id'] = (string) $attributes['id'];
+                }
+
+                $catalogue->setMetadata((string) $source, $metadata, $domain);
+            }
+        }
+    }
+
+    private function extractXliff2(\DOMDocument $dom, MessageCatalogue $catalogue, string $domain)
+    {
+        $xml = simplexml_import_dom($dom);
+        $encoding = $dom->encoding ? strtoupper($dom->encoding) : null;
+
+        $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:2.0');
+
+        foreach ($xml->xpath('//xliff:unit') as $unit) {
+            foreach ($unit->segment as $segment) {
+                $attributes = $unit->attributes();
+                $source = $attributes['name'] ?? $segment->source;
+
+                // If the xlf file has another encoding specified, try to convert it because
+                // simple_xml will always return utf-8 encoded values
+                $target = $this->utf8ToCharset((string) ($segment->target ?? $segment->source), $encoding);
+
+                $catalogue->set((string) $source, $target, $domain);
+
+                $metadata = [];
+                if (isset($segment->target) && $segment->target->attributes()) {
+                    $metadata['target-attributes'] = [];
+                    foreach ($segment->target->attributes() as $key => $value) {
+                        $metadata['target-attributes'][$key] = (string) $value;
+                    }
+                }
+
+                if (isset($unit->notes)) {
+                    $metadata['notes'] = [];
+                    foreach ($unit->notes->note as $noteNode) {
+                        $note = [];
+                        foreach ($noteNode->attributes() as $key => $value) {
+                            $note[$key] = (string) $value;
+                        }
+                        $note['content'] = (string) $noteNode;
+                        $metadata['notes'][] = $note;
+                    }
+                }
+
+                $catalogue->setMetadata((string) $source, $metadata, $domain);
+            }
+        }
+    }
+
+    /**
+     * Convert a UTF8 string to the specified encoding.
+     */
+    private function utf8ToCharset(string $content, string $encoding = null): string
+    {
+        if ('UTF-8' !== $encoding && !empty($encoding)) {
+            return mb_convert_encoding($content, $encoding, 'UTF-8');
+        }
+
+        return $content;
+    }
+
+    private function parseNotesMetadata(\SimpleXMLElement $noteElement = null, string $encoding = null): array
+    {
+        $notes = [];
+
+        if (null === $noteElement) {
+            return $notes;
+        }
+
+        /** @var \SimpleXMLElement $xmlNote */
+        foreach ($noteElement as $xmlNote) {
+            $noteAttributes = $xmlNote->attributes();
+            $note = ['content' => $this->utf8ToCharset((string) $xmlNote, $encoding)];
+            if (isset($noteAttributes['priority'])) {
+                $note['priority'] = (int) $noteAttributes['priority'];
+            }
+
+            if (isset($noteAttributes['from'])) {
+                $note['from'] = (string) $noteAttributes['from'];
+            }
+
+            $notes[] = $note;
+        }
+
+        return $notes;
+    }
+
+    private function isXmlString(string $resource): bool
+    {
+        return 0 === strpos($resource, '<?xml');
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/YamlFileLoader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..8588e18
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Loader/YamlFileLoader.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\LogicException;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser as YamlParser;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileLoader loads translations from Yaml files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class YamlFileLoader extends FileLoader
+{
+    private $yamlParser;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadResource(string $resource)
+    {
+        if (null === $this->yamlParser) {
+            if (!class_exists(\Symfony\Component\Yaml\Parser::class)) {
+                throw new LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
+            }
+
+            $this->yamlParser = new YamlParser();
+        }
+
+        try {
+            $messages = $this->yamlParser->parseFile($resource, Yaml::PARSE_CONSTANT);
+        } catch (ParseException $e) {
+            throw new InvalidResourceException(sprintf('The file "%s" does not contain valid YAML: ', $resource).$e->getMessage(), 0, $e);
+        }
+
+        if (null !== $messages && !\is_array($messages)) {
+            throw new InvalidResourceException(sprintf('Unable to load file "%s".', $resource));
+        }
+
+        return $messages ?: [];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LoggingTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LoggingTranslator.php
new file mode 100644
index 0000000..bb93435
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/LoggingTranslator.php
@@ -0,0 +1,135 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
+{
+    /**
+     * @var TranslatorInterface|TranslatorBagInterface
+     */
+    private $translator;
+
+    private $logger;
+
+    /**
+     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
+     */
+    public function __construct(TranslatorInterface $translator, LoggerInterface $logger)
+    {
+        if (!$translator instanceof TranslatorBagInterface || !$translator instanceof LocaleAwareInterface) {
+            throw new InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface, TranslatorBagInterface and LocaleAwareInterface.', get_debug_type($translator)));
+        }
+
+        $this->translator = $translator;
+        $this->logger = $logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        $trans = $this->translator->trans($id = (string) $id, $parameters, $domain, $locale);
+        $this->log($id, $domain, $locale);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $prev = $this->translator->getLocale();
+        $this->translator->setLocale($locale);
+        if ($prev === $locale) {
+            return;
+        }
+
+        $this->logger->debug(sprintf('The locale of the translator has changed from "%s" to "%s".', $prev, $locale));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        return $this->translator->getCatalogue($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return $this->translator->getCatalogues();
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @return array The fallback locales
+     */
+    public function getFallbackLocales()
+    {
+        if ($this->translator instanceof Translator || method_exists($this->translator, 'getFallbackLocales')) {
+            return $this->translator->getFallbackLocales();
+        }
+
+        return [];
+    }
+
+    /**
+     * Passes through all unknown calls onto the translator object.
+     */
+    public function __call(string $method, array $args)
+    {
+        return $this->translator->{$method}(...$args);
+    }
+
+    /**
+     * Logs for missing translations.
+     */
+    private function log(string $id, ?string $domain, ?string $locale)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $catalogue = $this->translator->getCatalogue($locale);
+        if ($catalogue->defines($id, $domain)) {
+            return;
+        }
+
+        if ($catalogue->has($id, $domain)) {
+            $this->logger->debug('Translation use fallback catalogue.', ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]);
+        } else {
+            $this->logger->warning('Translation not found.', ['id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()]);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogue.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogue.php
new file mode 100644
index 0000000..ff49b5a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogue.php
@@ -0,0 +1,314 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+use Symfony\Component\Translation\Exception\LogicException;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
+{
+    private $messages = [];
+    private $metadata = [];
+    private $resources = [];
+    private $locale;
+    private $fallbackCatalogue;
+    private $parent;
+
+    /**
+     * @param array $messages An array of messages classified by domain
+     */
+    public function __construct(string $locale, array $messages = [])
+    {
+        $this->locale = $locale;
+        $this->messages = $messages;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomains()
+    {
+        $domains = [];
+
+        foreach ($this->messages as $domain => $messages) {
+            if (str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+                $domain = substr($domain, 0, -\strlen(self::INTL_DOMAIN_SUFFIX));
+            }
+            $domains[$domain] = $domain;
+        }
+
+        return array_values($domains);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function all(string $domain = null)
+    {
+        if (null !== $domain) {
+            // skip messages merge if intl-icu requested explicitly
+            if (str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+                return $this->messages[$domain] ?? [];
+            }
+
+            return ($this->messages[$domain.self::INTL_DOMAIN_SUFFIX] ?? []) + ($this->messages[$domain] ?? []);
+        }
+
+        $allMessages = [];
+
+        foreach ($this->messages as $domain => $messages) {
+            if (str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+                $domain = substr($domain, 0, -\strlen(self::INTL_DOMAIN_SUFFIX));
+                $allMessages[$domain] = $messages + ($allMessages[$domain] ?? []);
+            } else {
+                $allMessages[$domain] = ($allMessages[$domain] ?? []) + $messages;
+            }
+        }
+
+        return $allMessages;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set(string $id, string $translation, string $domain = 'messages')
+    {
+        $this->add([$id => $translation], $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has(string $id, string $domain = 'messages')
+    {
+        if (isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
+            return true;
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->has($id, $domain);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function defines(string $id, string $domain = 'messages')
+    {
+        return isset($this->messages[$domain][$id]) || isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get(string $id, string $domain = 'messages')
+    {
+        if (isset($this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id])) {
+            return $this->messages[$domain.self::INTL_DOMAIN_SUFFIX][$id];
+        }
+
+        if (isset($this->messages[$domain][$id])) {
+            return $this->messages[$domain][$id];
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->get($id, $domain);
+        }
+
+        return $id;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function replace(array $messages, string $domain = 'messages')
+    {
+        unset($this->messages[$domain], $this->messages[$domain.self::INTL_DOMAIN_SUFFIX]);
+
+        $this->add($messages, $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function add(array $messages, string $domain = 'messages')
+    {
+        if (!isset($this->messages[$domain])) {
+            $this->messages[$domain] = [];
+        }
+        $intlDomain = $domain;
+        if (!str_ends_with($domain, self::INTL_DOMAIN_SUFFIX)) {
+            $intlDomain .= self::INTL_DOMAIN_SUFFIX;
+        }
+        foreach ($messages as $id => $message) {
+            if (isset($this->messages[$intlDomain]) && \array_key_exists($id, $this->messages[$intlDomain])) {
+                $this->messages[$intlDomain][$id] = $message;
+            } else {
+                $this->messages[$domain][$id] = $message;
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        if ($catalogue->getLocale() !== $this->locale) {
+            throw new LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s".', $catalogue->getLocale(), $this->locale));
+        }
+
+        foreach ($catalogue->all() as $domain => $messages) {
+            if ($intlMessages = $catalogue->all($domain.self::INTL_DOMAIN_SUFFIX)) {
+                $this->add($intlMessages, $domain.self::INTL_DOMAIN_SUFFIX);
+                $messages = array_diff_key($messages, $intlMessages);
+            }
+            $this->add($messages, $domain);
+        }
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+
+        if ($catalogue instanceof MetadataAwareInterface) {
+            $metadata = $catalogue->getMetadata('', '');
+            $this->addMetadata($metadata);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        // detect circular references
+        $c = $catalogue;
+        while ($c = $c->getFallbackCatalogue()) {
+            if ($c->getLocale() === $this->getLocale()) {
+                throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+            }
+        }
+
+        $c = $this;
+        do {
+            if ($c->getLocale() === $catalogue->getLocale()) {
+                throw new LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+            }
+
+            foreach ($catalogue->getResources() as $resource) {
+                $c->addResource($resource);
+            }
+        } while ($c = $c->parent);
+
+        $catalogue->parent = $this;
+        $this->fallbackCatalogue = $catalogue;
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFallbackCatalogue()
+    {
+        return $this->fallbackCatalogue;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResources()
+    {
+        return array_values($this->resources);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addResource(ResourceInterface $resource)
+    {
+        $this->resources[$resource->__toString()] = $resource;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata(string $key = '', string $domain = 'messages')
+    {
+        if ('' == $domain) {
+            return $this->metadata;
+        }
+
+        if (isset($this->metadata[$domain])) {
+            if ('' == $key) {
+                return $this->metadata[$domain];
+            }
+
+            if (isset($this->metadata[$domain][$key])) {
+                return $this->metadata[$domain][$key];
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMetadata(string $key, $value, string $domain = 'messages')
+    {
+        $this->metadata[$domain][$key] = $value;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMetadata(string $key = '', string $domain = 'messages')
+    {
+        if ('' == $domain) {
+            $this->metadata = [];
+        } elseif ('' == $key) {
+            unset($this->metadata[$domain]);
+        } else {
+            unset($this->metadata[$domain][$key]);
+        }
+    }
+
+    /**
+     * Adds current values with the new values.
+     *
+     * @param array $values Values to add
+     */
+    private function addMetadata(array $values)
+    {
+        foreach ($values as $domain => $keys) {
+            foreach ($keys as $key => $value) {
+                $this->setMetadata($key, $value, $domain);
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogueInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogueInterface.php
new file mode 100644
index 0000000..5d83bd8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MessageCatalogueInterface.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * MessageCatalogueInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MessageCatalogueInterface
+{
+    public const INTL_DOMAIN_SUFFIX = '+intl-icu';
+
+    /**
+     * Gets the catalogue locale.
+     *
+     * @return string The locale
+     */
+    public function getLocale();
+
+    /**
+     * Gets the domains.
+     *
+     * @return array An array of domains
+     */
+    public function getDomains();
+
+    /**
+     * Gets the messages within a given domain.
+     *
+     * If $domain is null, it returns all messages.
+     *
+     * @param string $domain The domain name
+     *
+     * @return array An array of messages
+     */
+    public function all(string $domain = null);
+
+    /**
+     * Sets a message translation.
+     *
+     * @param string $id          The message id
+     * @param string $translation The messages translation
+     * @param string $domain      The domain name
+     */
+    public function set(string $id, string $translation, string $domain = 'messages');
+
+    /**
+     * Checks if a message has a translation.
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return bool true if the message has a translation, false otherwise
+     */
+    public function has(string $id, string $domain = 'messages');
+
+    /**
+     * Checks if a message has a translation (it does not take into account the fallback mechanism).
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return bool true if the message has a translation, false otherwise
+     */
+    public function defines(string $id, string $domain = 'messages');
+
+    /**
+     * Gets a message translation.
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return string The message translation
+     */
+    public function get(string $id, string $domain = 'messages');
+
+    /**
+     * Sets translations for a given domain.
+     *
+     * @param array  $messages An array of translations
+     * @param string $domain   The domain name
+     */
+    public function replace(array $messages, string $domain = 'messages');
+
+    /**
+     * Adds translations for a given domain.
+     *
+     * @param array  $messages An array of translations
+     * @param string $domain   The domain name
+     */
+    public function add(array $messages, string $domain = 'messages');
+
+    /**
+     * Merges translations from the given Catalogue into the current one.
+     *
+     * The two catalogues must have the same locale.
+     */
+    public function addCatalogue(self $catalogue);
+
+    /**
+     * Merges translations from the given Catalogue into the current one
+     * only when the translation does not exist.
+     *
+     * This is used to provide default translations when they do not exist for the current locale.
+     */
+    public function addFallbackCatalogue(self $catalogue);
+
+    /**
+     * Gets the fallback catalogue.
+     *
+     * @return self|null A MessageCatalogueInterface instance or null when no fallback has been set
+     */
+    public function getFallbackCatalogue();
+
+    /**
+     * Returns an array of resources loaded to build this collection.
+     *
+     * @return ResourceInterface[] An array of resources
+     */
+    public function getResources();
+
+    /**
+     * Adds a resource for this collection.
+     */
+    public function addResource(ResourceInterface $resource);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MetadataAwareInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MetadataAwareInterface.php
new file mode 100644
index 0000000..2216eed
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/MetadataAwareInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * MetadataAwareInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MetadataAwareInterface
+{
+    /**
+     * Gets metadata for the given domain and key.
+     *
+     * Passing an empty domain will return an array with all metadata indexed by
+     * domain and then by key. Passing an empty key will return an array with all
+     * metadata for the given domain.
+     *
+     * @return mixed The value that was set or an array with the domains/keys or null
+     */
+    public function getMetadata(string $key = '', string $domain = 'messages');
+
+    /**
+     * Adds metadata to a message domain.
+     *
+     * @param mixed $value
+     */
+    public function setMetadata(string $key, $value, string $domain = 'messages');
+
+    /**
+     * Deletes metadata for the given key and domain.
+     *
+     * Passing an empty domain will delete all metadata. Passing an empty key will
+     * delete all metadata for the given domain.
+     */
+    public function deleteMetadata(string $key = '', string $domain = 'messages');
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/AbstractProviderFactory.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/AbstractProviderFactory.php
new file mode 100644
index 0000000..17442fd
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/AbstractProviderFactory.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\IncompleteDsnException;
+
+abstract class AbstractProviderFactory implements ProviderFactoryInterface
+{
+    public function supports(Dsn $dsn): bool
+    {
+        return \in_array($dsn->getScheme(), $this->getSupportedSchemes(), true);
+    }
+
+    /**
+     * @return string[]
+     */
+    abstract protected function getSupportedSchemes(): array;
+
+    protected function getUser(Dsn $dsn): string
+    {
+        if (null === $user = $dsn->getUser()) {
+            throw new IncompleteDsnException('User is not set.', $dsn->getOriginalDsn());
+        }
+
+        return $user;
+    }
+
+    protected function getPassword(Dsn $dsn): string
+    {
+        if (null === $password = $dsn->getPassword()) {
+            throw new IncompleteDsnException('Password is not set.', $dsn->getOriginalDsn());
+        }
+
+        return $password;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/Dsn.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/Dsn.php
new file mode 100644
index 0000000..820cabf
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/Dsn.php
@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\MissingRequiredOptionException;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Oskar Stark <oskarstark@googlemail.com>
+ */
+final class Dsn
+{
+    private $scheme;
+    private $host;
+    private $user;
+    private $password;
+    private $port;
+    private $path;
+    private $options;
+    private $originalDsn;
+
+    public function __construct(string $dsn)
+    {
+        $this->originalDsn = $dsn;
+
+        if (false === $parsedDsn = parse_url($dsn)) {
+            throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN is invalid.', $dsn));
+        }
+
+        if (!isset($parsedDsn['scheme'])) {
+            throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN must contain a scheme.', $dsn));
+        }
+        $this->scheme = $parsedDsn['scheme'];
+
+        if (!isset($parsedDsn['host'])) {
+            throw new InvalidArgumentException(sprintf('The "%s" translation provider DSN must contain a host (use "default" by default).', $dsn));
+        }
+        $this->host = $parsedDsn['host'];
+
+        $this->user = '' !== ($parsedDsn['user'] ?? '') ? urldecode($parsedDsn['user']) : null;
+        $this->password = '' !== ($parsedDsn['pass'] ?? '') ? urldecode($parsedDsn['pass']) : null;
+        $this->port = $parsedDsn['port'] ?? null;
+        $this->path = $parsedDsn['path'] ?? null;
+        parse_str($parsedDsn['query'] ?? '', $this->options);
+    }
+
+    public function getScheme(): string
+    {
+        return $this->scheme;
+    }
+
+    public function getHost(): string
+    {
+        return $this->host;
+    }
+
+    public function getUser(): ?string
+    {
+        return $this->user;
+    }
+
+    public function getPassword(): ?string
+    {
+        return $this->password;
+    }
+
+    public function getPort(int $default = null): ?int
+    {
+        return $this->port ?? $default;
+    }
+
+    public function getOption(string $key, $default = null)
+    {
+        return $this->options[$key] ?? $default;
+    }
+
+    public function getRequiredOption(string $key)
+    {
+        if (!\array_key_exists($key, $this->options) || '' === trim($this->options[$key])) {
+            throw new MissingRequiredOptionException($key);
+        }
+
+        return $this->options[$key];
+    }
+
+    public function getOptions(): array
+    {
+        return $this->options;
+    }
+
+    public function getPath(): ?string
+    {
+        return $this->path;
+    }
+
+    public function getOriginalDsn(): string
+    {
+        return $this->originalDsn;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/FilteringProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/FilteringProvider.php
new file mode 100644
index 0000000..0307cda
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/FilteringProvider.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\TranslatorBag;
+use Symfony\Component\Translation\TranslatorBagInterface;
+
+/**
+ * Filters domains and locales between the Translator config values and those specific to each provider.
+ *
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+class FilteringProvider implements ProviderInterface
+{
+    private $provider;
+    private $locales;
+    private $domains;
+
+    public function __construct(ProviderInterface $provider, array $locales, array $domains = [])
+    {
+        $this->provider = $provider;
+        $this->locales = $locales;
+        $this->domains = $domains;
+    }
+
+    public function __toString(): string
+    {
+        return (string) $this->provider;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function write(TranslatorBagInterface $translatorBag): void
+    {
+        $this->provider->write($translatorBag);
+    }
+
+    public function read(array $domains, array $locales): TranslatorBag
+    {
+        $domains = !$this->domains ? $domains : array_intersect($this->domains, $domains);
+        $locales = array_intersect($this->locales, $locales);
+
+        return $this->provider->read($domains, $locales);
+    }
+
+    public function delete(TranslatorBagInterface $translatorBag): void
+    {
+        $this->provider->delete($translatorBag);
+    }
+
+    public function getDomains(): array
+    {
+        return $this->domains;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProvider.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProvider.php
new file mode 100644
index 0000000..785fcaa
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProvider.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\TranslatorBag;
+use Symfony\Component\Translation\TranslatorBagInterface;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+class NullProvider implements ProviderInterface
+{
+    public function __toString(): string
+    {
+        return 'null';
+    }
+
+    public function write(TranslatorBagInterface $translatorBag, bool $override = false): void
+    {
+    }
+
+    public function read(array $domains, array $locales): TranslatorBag
+    {
+        return new TranslatorBag();
+    }
+
+    public function delete(TranslatorBagInterface $translatorBag): void
+    {
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProviderFactory.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProviderFactory.php
new file mode 100644
index 0000000..6ddbd85
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/NullProviderFactory.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class NullProviderFactory extends AbstractProviderFactory
+{
+    public function create(Dsn $dsn): ProviderInterface
+    {
+        if ('null' === $dsn->getScheme()) {
+            return new NullProvider();
+        }
+
+        throw new UnsupportedSchemeException($dsn, 'null', $this->getSupportedSchemes());
+    }
+
+    protected function getSupportedSchemes(): array
+    {
+        return ['null'];
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderFactoryInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderFactoryInterface.php
new file mode 100644
index 0000000..3fd4494
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderFactoryInterface.php
@@ -0,0 +1,26 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\IncompleteDsnException;
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+
+interface ProviderFactoryInterface
+{
+    /**
+     * @throws UnsupportedSchemeException
+     * @throws IncompleteDsnException
+     */
+    public function create(Dsn $dsn): ProviderInterface;
+
+    public function supports(Dsn $dsn): bool;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderInterface.php
new file mode 100644
index 0000000..a32193f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/ProviderInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\TranslatorBag;
+use Symfony\Component\Translation\TranslatorBagInterface;
+
+interface ProviderInterface
+{
+    public function __toString(): string;
+
+    /**
+     * Translations available in the TranslatorBag only must be created.
+     * Translations available in both the TranslatorBag and on the provider
+     * must be overwritten.
+     * Translations available on the provider only must be kept.
+     */
+    public function write(TranslatorBagInterface $translatorBag): void;
+
+    public function read(array $domains, array $locales): TranslatorBag;
+
+    public function delete(TranslatorBagInterface $translatorBag): void;
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollection.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollection.php
new file mode 100644
index 0000000..9963cb9
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollection.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+final class TranslationProviderCollection
+{
+    private $providers;
+
+    /**
+     * @param array<string, ProviderInterface> $providers
+     */
+    public function __construct(iterable $providers)
+    {
+        $this->providers = [];
+        foreach ($providers as $name => $provider) {
+            $this->providers[$name] = $provider;
+        }
+    }
+
+    public function __toString(): string
+    {
+        return '['.implode(',', array_keys($this->providers)).']';
+    }
+
+    public function has(string $name): bool
+    {
+        return isset($this->providers[$name]);
+    }
+
+    public function get(string $name): ProviderInterface
+    {
+        if (!$this->has($name)) {
+            throw new InvalidArgumentException(sprintf('Provider "%s" not found. Available: "%s".', $name, (string) $this));
+        }
+
+        return $this->providers[$name];
+    }
+
+    public function keys(): array
+    {
+        return array_keys($this->providers);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollectionFactory.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollectionFactory.php
new file mode 100644
index 0000000..43f4a34
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Provider/TranslationProviderCollectionFactory.php
@@ -0,0 +1,59 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Provider;
+
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+
+/**
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @experimental in 5.3
+ */
+class TranslationProviderCollectionFactory
+{
+    private $factories;
+    private $enabledLocales;
+
+    /**
+     * @param ProviderFactoryInterface[] $factories
+     */
+    public function __construct(iterable $factories, array $enabledLocales)
+    {
+        $this->factories = $factories;
+        $this->enabledLocales = $enabledLocales;
+    }
+
+    public function fromConfig(array $config): TranslationProviderCollection
+    {
+        $providers = [];
+        foreach ($config as $name => $currentConfig) {
+            $providers[$name] = $this->fromDsnObject(
+                new Dsn($currentConfig['dsn']),
+                !$currentConfig['locales'] ? $this->enabledLocales : $currentConfig['locales'],
+                !$currentConfig['domains'] ? [] : $currentConfig['domains']
+            );
+        }
+
+        return new TranslationProviderCollection($providers);
+    }
+
+    public function fromDsnObject(Dsn $dsn, array $locales, array $domains = []): ProviderInterface
+    {
+        foreach ($this->factories as $factory) {
+            if ($factory->supports($dsn)) {
+                return new FilteringProvider($factory->create($dsn), $locales, $domains);
+            }
+        }
+
+        throw new UnsupportedSchemeException($dsn);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/PseudoLocalizationTranslator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/PseudoLocalizationTranslator.php
new file mode 100644
index 0000000..49f122e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/PseudoLocalizationTranslator.php
@@ -0,0 +1,364 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * This translator should only be used in a development environment.
+ */
+final class PseudoLocalizationTranslator implements TranslatorInterface
+{
+    private const EXPANSION_CHARACTER = '~';
+
+    private $translator;
+    private $accents;
+    private $expansionFactor;
+    private $brackets;
+    private $parseHTML;
+    private $localizableHTMLAttributes;
+
+    /**
+     * Available options:
+     *  * accents:
+     *      type: boolean
+     *      default: true
+     *      description: replace ASCII characters of the translated string with accented versions or similar characters
+     *      example: if true, "foo" => "ƒöö".
+     *
+     *  * expansion_factor:
+     *      type: float
+     *      default: 1
+     *      validation: it must be greater than or equal to 1
+     *      description: expand the translated string by the given factor with spaces and tildes
+     *      example: if 2, "foo" => "~foo ~"
+     *
+     *  * brackets:
+     *      type: boolean
+     *      default: true
+     *      description: wrap the translated string with brackets
+     *      example: if true, "foo" => "[foo]"
+     *
+     *  * parse_html:
+     *      type: boolean
+     *      default: false
+     *      description: parse the translated string as HTML - looking for HTML tags has a performance impact but allows to preserve them from alterations - it also allows to compute the visible translated string length which is useful to correctly expand ot when it contains HTML
+     *      warning: unclosed tags are unsupported, they will be fixed (closed) by the parser - eg, "foo <div>bar" => "foo <div>bar</div>"
+     *
+     *  * localizable_html_attributes:
+     *      type: string[]
+     *      default: []
+     *      description: the list of HTML attributes whose values can be altered - it is only useful when the "parse_html" option is set to true
+     *      example: if ["title"], and with the "accents" option set to true, "<a href="#" title="Go to your profile">Profile</a>" => "<a href="#" title="Ĝö ţö ýöûŕ þŕöƒîļé">Þŕöƒîļé</a>" - if "title" was not in the "localizable_html_attributes" list, the title attribute data would be left unchanged.
+     */
+    public function __construct(TranslatorInterface $translator, array $options = [])
+    {
+        $this->translator = $translator;
+        $this->accents = $options['accents'] ?? true;
+
+        if (1.0 > ($this->expansionFactor = $options['expansion_factor'] ?? 1.0)) {
+            throw new \InvalidArgumentException('The expansion factor must be greater than or equal to 1.');
+        }
+
+        $this->brackets = $options['brackets'] ?? true;
+
+        $this->parseHTML = $options['parse_html'] ?? false;
+        if ($this->parseHTML && !$this->accents && 1.0 === $this->expansionFactor) {
+            $this->parseHTML = false;
+        }
+
+        $this->localizableHTMLAttributes = $options['localizable_html_attributes'] ?? [];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        $trans = '';
+        $visibleText = '';
+
+        foreach ($this->getParts($this->translator->trans($id, $parameters, $domain, $locale)) as [$visible, $localizable, $text]) {
+            if ($visible) {
+                $visibleText .= $text;
+            }
+
+            if (!$localizable) {
+                $trans .= $text;
+
+                continue;
+            }
+
+            $this->addAccents($trans, $text);
+        }
+
+        $this->expand($trans, $visibleText);
+
+        $this->addBrackets($trans);
+
+        return $trans;
+    }
+
+    public function getLocale(): string
+    {
+        return $this->translator->getLocale();
+    }
+
+    private function getParts(string $originalTrans): array
+    {
+        if (!$this->parseHTML) {
+            return [[true, true, $originalTrans]];
+        }
+
+        $html = mb_convert_encoding($originalTrans, 'HTML-ENTITIES', mb_detect_encoding($originalTrans, null, true) ?: 'UTF-8');
+
+        $useInternalErrors = libxml_use_internal_errors(true);
+
+        $dom = new \DOMDocument();
+        $dom->loadHTML('<trans>'.$html.'</trans>');
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($useInternalErrors);
+
+        return $this->parseNode($dom->childNodes->item(1)->childNodes->item(0)->childNodes->item(0));
+    }
+
+    private function parseNode(\DOMNode $node): array
+    {
+        $parts = [];
+
+        foreach ($node->childNodes as $childNode) {
+            if (!$childNode instanceof \DOMElement) {
+                $parts[] = [true, true, $childNode->nodeValue];
+
+                continue;
+            }
+
+            $parts[] = [false, false, '<'.$childNode->tagName];
+
+            /** @var \DOMAttr $attribute */
+            foreach ($childNode->attributes as $attribute) {
+                $parts[] = [false, false, ' '.$attribute->nodeName.'="'];
+
+                $localizableAttribute = \in_array($attribute->nodeName, $this->localizableHTMLAttributes, true);
+                foreach (preg_split('/(&(?:amp|quot|#039|lt|gt);+)/', htmlspecialchars($attribute->nodeValue, \ENT_QUOTES, 'UTF-8'), -1, \PREG_SPLIT_DELIM_CAPTURE) as $i => $match) {
+                    if ('' === $match) {
+                        continue;
+                    }
+
+                    $parts[] = [false, $localizableAttribute && 0 === $i % 2, $match];
+                }
+
+                $parts[] = [false, false, '"'];
+            }
+
+            $parts[] = [false, false, '>'];
+
+            $parts = array_merge($parts, $this->parseNode($childNode, $parts));
+
+            $parts[] = [false, false, '</'.$childNode->tagName.'>'];
+        }
+
+        return $parts;
+    }
+
+    private function addAccents(string &$trans, string $text): void
+    {
+        $trans .= $this->accents ? strtr($text, [
+            ' ' => ' ',
+            '!' => '¡',
+            '"' => '″',
+            '#' => '♯',
+            '$' => '€',
+            '%' => '‰',
+            '&' => '⅋',
+            '\'' => '´',
+            '(' => '{',
+            ')' => '}',
+            '*' => '⁎',
+            '+' => '⁺',
+            ',' => '،',
+            '-' => '‐',
+            '.' => '·',
+            '/' => '⁄',
+            '0' => '⓪',
+            '1' => '①',
+            '2' => '②',
+            '3' => '③',
+            '4' => '④',
+            '5' => '⑤',
+            '6' => '⑥',
+            '7' => '⑦',
+            '8' => '⑧',
+            '9' => '⑨',
+            ':' => '∶',
+            ';' => '⁏',
+            '<' => '≤',
+            '=' => '≂',
+            '>' => '≥',
+            '?' => '¿',
+            '@' => '՞',
+            'A' => 'Å',
+            'B' => 'Ɓ',
+            'C' => 'Ç',
+            'D' => 'Ð',
+            'E' => 'É',
+            'F' => 'Ƒ',
+            'G' => 'Ĝ',
+            'H' => 'Ĥ',
+            'I' => 'Î',
+            'J' => 'Ĵ',
+            'K' => 'Ķ',
+            'L' => 'Ļ',
+            'M' => 'Ṁ',
+            'N' => 'Ñ',
+            'O' => 'Ö',
+            'P' => 'Þ',
+            'Q' => 'Ǫ',
+            'R' => 'Ŕ',
+            'S' => 'Š',
+            'T' => 'Ţ',
+            'U' => 'Û',
+            'V' => 'Ṽ',
+            'W' => 'Ŵ',
+            'X' => 'Ẋ',
+            'Y' => 'Ý',
+            'Z' => 'Ž',
+            '[' => '⁅',
+            '\\' => '∖',
+            ']' => '⁆',
+            '^' => '˄',
+            '_' => '‿',
+            '`' => '‵',
+            'a' => 'å',
+            'b' => 'ƀ',
+            'c' => 'ç',
+            'd' => 'ð',
+            'e' => 'é',
+            'f' => 'ƒ',
+            'g' => 'ĝ',
+            'h' => 'ĥ',
+            'i' => 'î',
+            'j' => 'ĵ',
+            'k' => 'ķ',
+            'l' => 'ļ',
+            'm' => 'ɱ',
+            'n' => 'ñ',
+            'o' => 'ö',
+            'p' => 'þ',
+            'q' => 'ǫ',
+            'r' => 'ŕ',
+            's' => 'š',
+            't' => 'ţ',
+            'u' => 'û',
+            'v' => 'ṽ',
+            'w' => 'ŵ',
+            'x' => 'ẋ',
+            'y' => 'ý',
+            'z' => 'ž',
+            '{' => '(',
+            '|' => '¦',
+            '}' => ')',
+            '~' => '˞',
+        ]) : $text;
+    }
+
+    private function expand(string &$trans, string $visibleText): void
+    {
+        if (1.0 >= $this->expansionFactor) {
+            return;
+        }
+
+        $visibleLength = $this->strlen($visibleText);
+        $missingLength = (int) (ceil($visibleLength * $this->expansionFactor)) - $visibleLength;
+        if ($this->brackets) {
+            $missingLength -= 2;
+        }
+
+        if (0 >= $missingLength) {
+            return;
+        }
+
+        $words = [];
+        $wordsCount = 0;
+        foreach (preg_split('/ +/', $visibleText, -1, \PREG_SPLIT_NO_EMPTY) as $word) {
+            $wordLength = $this->strlen($word);
+
+            if ($wordLength >= $missingLength) {
+                continue;
+            }
+
+            if (!isset($words[$wordLength])) {
+                $words[$wordLength] = 0;
+            }
+
+            ++$words[$wordLength];
+            ++$wordsCount;
+        }
+
+        if (!$words) {
+            $trans .= 1 === $missingLength ? self::EXPANSION_CHARACTER : ' '.str_repeat(self::EXPANSION_CHARACTER, $missingLength - 1);
+
+            return;
+        }
+
+        arsort($words, \SORT_NUMERIC);
+
+        $longestWordLength = max(array_keys($words));
+
+        while (true) {
+            $r = mt_rand(1, $wordsCount);
+
+            foreach ($words as $length => $count) {
+                $r -= $count;
+                if ($r <= 0) {
+                    break;
+                }
+            }
+
+            $trans .= ' '.str_repeat(self::EXPANSION_CHARACTER, $length);
+
+            $missingLength -= $length + 1;
+
+            if (0 === $missingLength) {
+                return;
+            }
+
+            while ($longestWordLength >= $missingLength) {
+                $wordsCount -= $words[$longestWordLength];
+                unset($words[$longestWordLength]);
+
+                if (!$words) {
+                    $trans .= 1 === $missingLength ? self::EXPANSION_CHARACTER : ' '.str_repeat(self::EXPANSION_CHARACTER, $missingLength - 1);
+
+                    return;
+                }
+
+                $longestWordLength = max(array_keys($words));
+            }
+        }
+    }
+
+    private function addBrackets(string &$trans): void
+    {
+        if (!$this->brackets) {
+            return;
+        }
+
+        $trans = '['.$trans.']';
+    }
+
+    private function strlen(string $s): int
+    {
+        return false === ($encoding = mb_detect_encoding($s, null, true)) ? \strlen($s) : mb_strlen($s, $encoding);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/README.md
new file mode 100644
index 0000000..720bee3
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/README.md
@@ -0,0 +1,33 @@
+Translation Component
+=====================
+
+The Translation component provides tools to internationalize your application.
+
+Getting Started
+---------------
+
+```
+$ composer require symfony/translation
+```
+
+```php
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+$translator = new Translator('fr_FR');
+$translator->addLoader('array', new ArrayLoader());
+$translator->addResource('array', [
+    'Hello World!' => 'Bonjour !',
+], 'fr_FR');
+
+echo $translator->trans('Hello World!'); // outputs « Bonjour ! »
+```
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/translation.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+   [send Pull Requests](https://github.com/symfony/symfony/pulls)
+   in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReader.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReader.php
new file mode 100644
index 0000000..9e51b15
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReader.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Reader;
+
+use Symfony\Component\Finder\Finder;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationReader reads translation messages from translation files.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class TranslationReader implements TranslationReaderInterface
+{
+    /**
+     * Loaders used for import.
+     *
+     * @var array
+     */
+    private $loaders = [];
+
+    /**
+     * Adds a loader to the translation extractor.
+     *
+     * @param string $format The format of the loader
+     */
+    public function addLoader(string $format, LoaderInterface $loader)
+    {
+        $this->loaders[$format] = $loader;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function read(string $directory, MessageCatalogue $catalogue)
+    {
+        if (!is_dir($directory)) {
+            return;
+        }
+
+        foreach ($this->loaders as $format => $loader) {
+            // load any existing translation files
+            $finder = new Finder();
+            $extension = $catalogue->getLocale().'.'.$format;
+            $files = $finder->files()->name('*.'.$extension)->in($directory);
+            foreach ($files as $file) {
+                $domain = substr($file->getFilename(), 0, -1 * \strlen($extension) - 1);
+                $catalogue->addCatalogue($loader->load($file->getPathname(), $catalogue->getLocale(), $domain));
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReaderInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReaderInterface.php
new file mode 100644
index 0000000..bc37204
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Reader/TranslationReaderInterface.php
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Reader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationReader reads translation messages from translation files.
+ *
+ * @author Tobias Nyholm <tobias.nyholm@gmail.com>
+ */
+interface TranslationReaderInterface
+{
+    /**
+     * Reads translation messages from a directory to the catalogue.
+     */
+    public function read(string $directory, MessageCatalogue $catalogue);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/bin/translation-status.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/bin/translation-status.php
new file mode 100644
index 0000000..4e0723b
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/bin/translation-status.php
@@ -0,0 +1,207 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+$usageInstructions = <<<END
+
+  Usage instructions
+  -------------------------------------------------------------------------------
+
+  $ cd symfony-code-root-directory/
+
+  # show the translation status of all locales
+  $ php translation-status.php
+
+  # show the translation status of all locales and all their missing translations
+  $ php translation-status.php -v
+
+  # show the status of a single locale
+  $ php translation-status.php fr
+
+  # show the status of a single locale and all its missing translations
+  $ php translation-status.php fr -v
+
+END;
+
+$config = [
+    // if TRUE, the full list of missing translations is displayed
+    'verbose_output' => false,
+    // NULL = analyze all locales
+    'locale_to_analyze' => null,
+    // the reference files all the other translations are compared to
+    'original_files' => [
+        'src/Symfony/Component/Form/Resources/translations/validators.en.xlf',
+        'src/Symfony/Component/Security/Core/Resources/translations/security.en.xlf',
+        'src/Symfony/Component/Validator/Resources/translations/validators.en.xlf',
+    ],
+];
+
+$argc = $_SERVER['argc'];
+$argv = $_SERVER['argv'];
+
+if ($argc > 3) {
+    echo str_replace('translation-status.php', $argv[0], $usageInstructions);
+    exit(1);
+}
+
+foreach (array_slice($argv, 1) as $argumentOrOption) {
+    if (str_starts_with($argumentOrOption, '-')) {
+        $config['verbose_output'] = true;
+    } else {
+        $config['locale_to_analyze'] = $argumentOrOption;
+    }
+}
+
+foreach ($config['original_files'] as $originalFilePath) {
+    if (!file_exists($originalFilePath)) {
+        echo sprintf('The following file does not exist. Make sure that you execute this command at the root dir of the Symfony code repository.%s  %s', \PHP_EOL, $originalFilePath);
+        exit(1);
+    }
+}
+
+$totalMissingTranslations = 0;
+
+foreach ($config['original_files'] as $originalFilePath) {
+    $translationFilePaths = findTranslationFiles($originalFilePath, $config['locale_to_analyze']);
+    $translationStatus = calculateTranslationStatus($originalFilePath, $translationFilePaths);
+
+    $totalMissingTranslations += array_sum(array_map(function ($translation) {
+        return count($translation['missingKeys']);
+    }, array_values($translationStatus)));
+
+    printTranslationStatus($originalFilePath, $translationStatus, $config['verbose_output']);
+}
+
+exit($totalMissingTranslations > 0 ? 1 : 0);
+
+function findTranslationFiles($originalFilePath, $localeToAnalyze)
+{
+    $translations = [];
+
+    $translationsDir = dirname($originalFilePath);
+    $originalFileName = basename($originalFilePath);
+    $translationFileNamePattern = str_replace('.en.', '.*.', $originalFileName);
+
+    $translationFiles = glob($translationsDir.'/'.$translationFileNamePattern, \GLOB_NOSORT);
+    sort($translationFiles);
+    foreach ($translationFiles as $filePath) {
+        $locale = extractLocaleFromFilePath($filePath);
+
+        if (null !== $localeToAnalyze && $locale !== $localeToAnalyze) {
+            continue;
+        }
+
+        $translations[$locale] = $filePath;
+    }
+
+    return $translations;
+}
+
+function calculateTranslationStatus($originalFilePath, $translationFilePaths)
+{
+    $translationStatus = [];
+    $allTranslationKeys = extractTranslationKeys($originalFilePath);
+
+    foreach ($translationFilePaths as $locale => $translationPath) {
+        $translatedKeys = extractTranslationKeys($translationPath);
+        $missingKeys = array_diff_key($allTranslationKeys, $translatedKeys);
+
+        $translationStatus[$locale] = [
+            'total' => count($allTranslationKeys),
+            'translated' => count($translatedKeys),
+            'missingKeys' => $missingKeys,
+        ];
+    }
+
+    return $translationStatus;
+}
+
+function printTranslationStatus($originalFilePath, $translationStatus, $verboseOutput)
+{
+    printTitle($originalFilePath);
+    printTable($translationStatus, $verboseOutput);
+    echo \PHP_EOL.\PHP_EOL;
+}
+
+function extractLocaleFromFilePath($filePath)
+{
+    $parts = explode('.', $filePath);
+
+    return $parts[count($parts) - 2];
+}
+
+function extractTranslationKeys($filePath)
+{
+    $translationKeys = [];
+    $contents = new \SimpleXMLElement(file_get_contents($filePath));
+
+    foreach ($contents->file->body->{'trans-unit'} as $translationKey) {
+        $translationId = (string) $translationKey['id'];
+        $translationKey = (string) $translationKey->source;
+
+        $translationKeys[$translationId] = $translationKey;
+    }
+
+    return $translationKeys;
+}
+
+function printTitle($title)
+{
+    echo $title.\PHP_EOL;
+    echo str_repeat('=', strlen($title)).\PHP_EOL.\PHP_EOL;
+}
+
+function printTable($translations, $verboseOutput)
+{
+    if (0 === count($translations)) {
+        echo 'No translations found';
+
+        return;
+    }
+    $longestLocaleNameLength = max(array_map('strlen', array_keys($translations)));
+
+    foreach ($translations as $locale => $translation) {
+        if ($translation['translated'] > $translation['total']) {
+            textColorRed();
+        } elseif ($translation['translated'] === $translation['total']) {
+            textColorGreen();
+        }
+
+        echo sprintf('| Locale: %-'.$longestLocaleNameLength.'s | Translated: %d/%d', $locale, $translation['translated'], $translation['total']).\PHP_EOL;
+
+        textColorNormal();
+
+        if (true === $verboseOutput && count($translation['missingKeys']) > 0) {
+            echo str_repeat('-', 80).\PHP_EOL;
+            echo '| Missing Translations:'.\PHP_EOL;
+
+            foreach ($translation['missingKeys'] as $id => $content) {
+                echo sprintf('|   (id=%s) %s', $id, $content).\PHP_EOL;
+            }
+
+            echo str_repeat('-', 80).\PHP_EOL;
+        }
+    }
+}
+
+function textColorGreen()
+{
+    echo "\033[32m";
+}
+
+function textColorRed()
+{
+    echo "\033[31m";
+}
+
+function textColorNormal()
+{
+    echo "\033[0m";
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/data/parents.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/data/parents.json
new file mode 100644
index 0000000..a67458a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/data/parents.json
@@ -0,0 +1,140 @@
+{
+    "az_Cyrl": "root",
+    "bs_Cyrl": "root",
+    "en_150": "en_001",
+    "en_AG": "en_001",
+    "en_AI": "en_001",
+    "en_AT": "en_150",
+    "en_AU": "en_001",
+    "en_BB": "en_001",
+    "en_BE": "en_150",
+    "en_BM": "en_001",
+    "en_BS": "en_001",
+    "en_BW": "en_001",
+    "en_BZ": "en_001",
+    "en_CA": "en_001",
+    "en_CC": "en_001",
+    "en_CH": "en_150",
+    "en_CK": "en_001",
+    "en_CM": "en_001",
+    "en_CX": "en_001",
+    "en_CY": "en_001",
+    "en_DE": "en_150",
+    "en_DG": "en_001",
+    "en_DK": "en_150",
+    "en_DM": "en_001",
+    "en_ER": "en_001",
+    "en_FI": "en_150",
+    "en_FJ": "en_001",
+    "en_FK": "en_001",
+    "en_FM": "en_001",
+    "en_GB": "en_001",
+    "en_GD": "en_001",
+    "en_GG": "en_001",
+    "en_GH": "en_001",
+    "en_GI": "en_001",
+    "en_GM": "en_001",
+    "en_GY": "en_001",
+    "en_HK": "en_001",
+    "en_IE": "en_001",
+    "en_IL": "en_001",
+    "en_IM": "en_001",
+    "en_IN": "en_001",
+    "en_IO": "en_001",
+    "en_JE": "en_001",
+    "en_JM": "en_001",
+    "en_KE": "en_001",
+    "en_KI": "en_001",
+    "en_KN": "en_001",
+    "en_KY": "en_001",
+    "en_LC": "en_001",
+    "en_LR": "en_001",
+    "en_LS": "en_001",
+    "en_MG": "en_001",
+    "en_MO": "en_001",
+    "en_MS": "en_001",
+    "en_MT": "en_001",
+    "en_MU": "en_001",
+    "en_MW": "en_001",
+    "en_MY": "en_001",
+    "en_NA": "en_001",
+    "en_NF": "en_001",
+    "en_NG": "en_001",
+    "en_NL": "en_150",
+    "en_NR": "en_001",
+    "en_NU": "en_001",
+    "en_NZ": "en_001",
+    "en_PG": "en_001",
+    "en_PH": "en_001",
+    "en_PK": "en_001",
+    "en_PN": "en_001",
+    "en_PW": "en_001",
+    "en_RW": "en_001",
+    "en_SB": "en_001",
+    "en_SC": "en_001",
+    "en_SD": "en_001",
+    "en_SE": "en_150",
+    "en_SG": "en_001",
+    "en_SH": "en_001",
+    "en_SI": "en_150",
+    "en_SL": "en_001",
+    "en_SS": "en_001",
+    "en_SX": "en_001",
+    "en_SZ": "en_001",
+    "en_TC": "en_001",
+    "en_TK": "en_001",
+    "en_TO": "en_001",
+    "en_TT": "en_001",
+    "en_TV": "en_001",
+    "en_TZ": "en_001",
+    "en_UG": "en_001",
+    "en_VC": "en_001",
+    "en_VG": "en_001",
+    "en_VU": "en_001",
+    "en_WS": "en_001",
+    "en_ZA": "en_001",
+    "en_ZM": "en_001",
+    "en_ZW": "en_001",
+    "es_AR": "es_419",
+    "es_BO": "es_419",
+    "es_BR": "es_419",
+    "es_BZ": "es_419",
+    "es_CL": "es_419",
+    "es_CO": "es_419",
+    "es_CR": "es_419",
+    "es_CU": "es_419",
+    "es_DO": "es_419",
+    "es_EC": "es_419",
+    "es_GT": "es_419",
+    "es_HN": "es_419",
+    "es_MX": "es_419",
+    "es_NI": "es_419",
+    "es_PA": "es_419",
+    "es_PE": "es_419",
+    "es_PR": "es_419",
+    "es_PY": "es_419",
+    "es_SV": "es_419",
+    "es_US": "es_419",
+    "es_UY": "es_419",
+    "es_VE": "es_419",
+    "ff_Adlm": "root",
+    "nb": "no",
+    "nn": "no",
+    "pa_Arab": "root",
+    "pt_AO": "pt_PT",
+    "pt_CH": "pt_PT",
+    "pt_CV": "pt_PT",
+    "pt_GQ": "pt_PT",
+    "pt_GW": "pt_PT",
+    "pt_LU": "pt_PT",
+    "pt_MO": "pt_PT",
+    "pt_MZ": "pt_PT",
+    "pt_ST": "pt_PT",
+    "pt_TL": "pt_PT",
+    "sd_Deva": "root",
+    "sr_Latn": "root",
+    "uz_Arab": "root",
+    "uz_Cyrl": "root",
+    "zh_Hant": "root",
+    "zh_Hant_MO": "zh_Hant_HK"
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/functions.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/functions.php
new file mode 100644
index 0000000..901d2f8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/functions.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+if (!\function_exists(t::class)) {
+    /**
+     * @author Nate Wiebe <nate@northern.co>
+     */
+    function t(string $message, array $parameters = [], string $domain = null): TranslatableMessage
+    {
+        return new TranslatableMessage($message, $parameters, $domain);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd
new file mode 100644
index 0000000..dface62
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-1.2-strict.xsd
@@ -0,0 +1,2223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+May-19-2004:
+- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements
+to <choice> itself.
+- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
+<alt-trans>.
+
+Oct-2005
+- updated version info to 1.2
+- equiv-trans attribute to <trans-unit> element
+- merged-trans attribute for <group> element
+- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source>
+- Create a new value "seg" for the mtype attribute of the <mrk> element
+- Add mid as an optional attribute for the <alt-trans> element
+
+Nov-14-2005
+- Changed name attribute for <context-group> from required to optional
+- Added extension point at <xliff>
+
+Jan-9-2006
+- Added alttranstype type attribute to <alt-trans>, and values
+
+Jan-10-2006
+- Corrected error with overwritten purposeValueList
+- Corrected name="AttrType_Version",  attribute should have been "name"
+
+-->
+<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
+  <!-- Import for xml:lang and xml:space -->
+  <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+  <!-- Attributes Lists -->
+  <xsd:simpleType name="XTend">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="x-[^\s]+"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="context-typeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="database">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a database content.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="element">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="elementtitle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="linenumber">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="numparams">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="paramnotes">
+        <xsd:annotation>
+          <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="record">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="recordtitle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sourcefile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="count-typeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="num-usages">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="repetition">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="total">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a total count.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="InlineDelimitersValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="bold">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="italic">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="underlined">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="link">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="InlinePlaceholdersValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="image">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a inline image.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pb">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a page break.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="lb">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a line break.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="mime-typeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="datatypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="asp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="c">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cdf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cfm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cpp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="csharp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cstring">
+        <xsd:annotation>
+          <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="csv">
+        <xsd:annotation>
+          <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="database">
+        <xsd:annotation>
+          <xsd:documentation>Indicates database data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="documentfooter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="documentheader">
+        <xsd:annotation>
+          <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="filedialog">
+        <xsd:annotation>
+          <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="form">
+        <xsd:annotation>
+          <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="html">
+        <xsd:annotation>
+          <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="htmlbody">
+        <xsd:annotation>
+          <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ini">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="interleaf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javaclass">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javapropertyresourcebundle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javalistresourcebundle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javascript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="jscript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="layout">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="lisp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="margin">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menufile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="messagefile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mif">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mimetype">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mo">
+        <xsd:annotation>
+          <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="msglib">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pagefooter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pageheader">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="parameters">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pascal">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="php">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="plaintext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="po">
+        <xsd:annotation>
+          <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="report">
+        <xsd:annotation>
+          <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="resources">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="resx">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rtf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sgml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sgmldtd">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="svg">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="vbscript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="warning">
+        <xsd:annotation>
+          <xsd:documentation>Indicates warning message.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="winres">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xhtml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xmldtd">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xsl">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xul">
+        <xsd:annotation>
+          <xsd:documentation>Indicates XUL elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="mtypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="abbrev">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="abbreviated-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="abbreviation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="acronym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="appellation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="collocation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="common-name">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="datetime">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="equation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="expanded-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="formula">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="head-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="initialism">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="international-scientific-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="internationalism">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="logical-expression">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="materials-management-unit">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="name">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="near-synonym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="part-number">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="phrase">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="phraseological-unit">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="protected">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="romanized-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="seg">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="set-phrase">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="short-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sku">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="standard-text">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="symbol">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="synonym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="synonymous-phrase">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="term">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="transcribed-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="transliterated-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="truncated-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="variant">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="restypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="auto3state">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="autocheckbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="autoradiobutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bitmap">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="button">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="caption">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cell">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkboxmenuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkedlistbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="colorchooser">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="combobox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="comboboxexitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="comboboxitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="component">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="contextmenu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a context menu.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ctext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cursor">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="datetimepicker">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="defpushbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dialog">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a dialog box.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dlginit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="edit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="file">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a filename.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="filechooser">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a file dialog.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="fn">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a footnote.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="font">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a font name.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="footer">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a footer.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="frame">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a frame object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="grid">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="groupbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="header">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a header item.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="heading">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="hedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="hscrollbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="icon">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="iedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="keywords">
+        <xsd:annotation>
+          <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="label">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a label object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="linklabel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="list">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="listbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="listitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ltext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menubar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menuseparator">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="message">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="monthcalendar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a calendar control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="numericupdown">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="panel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="popupmenu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pushbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pushbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="radio">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a radio button object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="radiobuttonmenuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rcdata">
+        <xsd:annotation>
+          <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="row">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a row in a table.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rtext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="scrollpane">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="separator">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="shortcut">
+        <xsd:annotation>
+          <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="spinner">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="splitter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="state3">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="statusbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="string">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tabcontrol">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="table">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="textbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="togglebutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="toolbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tooltip">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="trackbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tree">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="uri">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="userbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="usercontrol">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="var">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="versioninfo">
+        <xsd:annotation>
+          <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="vscrollbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="window">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a graphical window.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="size-unitValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="byte">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="char">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="col">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dlgunit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="em">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ex">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="glyph">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="in">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in inches.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="percent">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pixel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="point">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in point.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="row">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="stateValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="final">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the terminating state.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-adaptation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-l10n">
+        <xsd:annotation>
+          <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-adaptation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-l10n">
+        <xsd:annotation>
+          <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-translation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-translation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="new">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="signed-off">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="translated">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="state-qualifierValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="exact-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="fuzzy-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="id-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-glossary">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-inherited">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-mt">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-repository">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-tm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mt-suggestion">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-grammar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-inaccurate">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-length">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-spelling">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tm-suggestion">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="unitValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="word">
+        <xsd:annotation>
+          <xsd:documentation>Refers to words.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="page">
+        <xsd:annotation>
+          <xsd:documentation>Refers to pages.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="trans-unit">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bin-unit">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="glyph">
+        <xsd:annotation>
+          <xsd:documentation>Refers to glyphs.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="item">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="instance">
+        <xsd:annotation>
+          <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="character">
+        <xsd:annotation>
+          <xsd:documentation>Refers to characters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="line">
+        <xsd:annotation>
+          <xsd:documentation>Refers to lines.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sentence">
+        <xsd:annotation>
+          <xsd:documentation>Refers to sentences.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="paragraph">
+        <xsd:annotation>
+          <xsd:documentation>Refers to paragraphs.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="segment">
+        <xsd:annotation>
+          <xsd:documentation>Refers to segments.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="placeable">
+        <xsd:annotation>
+          <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="priorityValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:positiveInteger">
+      <xsd:enumeration value="1">
+        <xsd:annotation>
+          <xsd:documentation>Highest priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="2">
+        <xsd:annotation>
+          <xsd:documentation>High priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="3">
+        <xsd:annotation>
+          <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="4">
+        <xsd:annotation>
+          <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="5">
+        <xsd:annotation>
+          <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="6">
+        <xsd:annotation>
+          <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="7">
+        <xsd:annotation>
+          <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="8">
+        <xsd:annotation>
+          <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="9">
+        <xsd:annotation>
+          <xsd:documentation>Low priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="10">
+        <xsd:annotation>
+          <xsd:documentation>Lowest priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="reformatValueYesNo">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="yes">
+        <xsd:annotation>
+          <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="no">
+        <xsd:annotation>
+          <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="reformatValueList">
+    <xsd:list>
+      <xsd:simpleType>
+        <xsd:union memberTypes="xlf:XTend">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="coord">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-x">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-y">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-cx">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-cy">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-name">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-size">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-weight">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="css-style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="ex-style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:union>
+      </xsd:simpleType>
+    </xsd:list>
+  </xsd:simpleType>
+  <xsd:simpleType name="purposeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="information">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="location">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="alttranstypeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="proposal">
+        <xsd:annotation>
+          <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="previous-version">
+        <xsd:annotation>
+          <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected">
+        <xsd:annotation>
+          <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="reference">
+        <xsd:annotation>
+          <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="accepted">
+        <xsd:annotation>
+          <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <!-- Other Types -->
+  <xsd:complexType name="ElemType_ExternalReference">
+    <xsd:choice>
+      <xsd:element ref="xlf:internal-file"/>
+      <xsd:element ref="xlf:external-file"/>
+    </xsd:choice>
+  </xsd:complexType>
+  <xsd:simpleType name="AttrType_purpose">
+    <xsd:list>
+      <xsd:simpleType>
+        <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
+      </xsd:simpleType>
+    </xsd:list>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_datatype">
+    <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_restype">
+    <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_alttranstype">
+    <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_context-type">
+    <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_state">
+    <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_state-qualifier">
+    <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_count-type">
+    <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_InlineDelimiters">
+    <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_InlinePlaceholders">
+    <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_size-unit">
+    <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_mtype">
+    <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_unit">
+    <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_priority">
+    <xsd:union memberTypes="xlf:priorityValueList"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_reformat">
+    <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_YesNo">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="yes"/>
+      <xsd:enumeration value="no"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Position">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="open"/>
+      <xsd:enumeration value="close"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_assoc">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="preceding"/>
+      <xsd:enumeration value="following"/>
+      <xsd:enumeration value="both"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_annotates">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="source"/>
+      <xsd:enumeration value="target"/>
+      <xsd:enumeration value="general"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Coordinates">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Version">
+    <xsd:annotation>
+      <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="1.2"/>
+      <xsd:enumeration value="1.1"/>
+      <xsd:enumeration value="1.0"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <!-- Groups -->
+  <xsd:group name="ElemGroup_TextContent">
+    <xsd:choice>
+      <xsd:element ref="xlf:g"/>
+      <xsd:element ref="xlf:bpt"/>
+      <xsd:element ref="xlf:ept"/>
+      <xsd:element ref="xlf:ph"/>
+      <xsd:element ref="xlf:it"/>
+      <xsd:element ref="xlf:mrk"/>
+      <xsd:element ref="xlf:x"/>
+      <xsd:element ref="xlf:bx"/>
+      <xsd:element ref="xlf:ex"/>
+    </xsd:choice>
+  </xsd:group>
+  <xsd:attributeGroup name="AttrGroup_TextContent">
+    <xsd:attribute name="id" type="xsd:string" use="required"/>
+    <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+    <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
+    <xsd:anyAttribute namespace="##other" processContents="strict"/>
+  </xsd:attributeGroup>
+  <!-- XLIFF Structure -->
+  <xsd:element name="xliff">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+        <xsd:element ref="xlf:file"/>
+      </xsd:sequence>
+      <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="file">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" ref="xlf:header"/>
+        <xsd:element ref="xlf:body"/>
+      </xsd:sequence>
+      <xsd:attribute name="original" type="xsd:string" use="required"/>
+      <xsd:attribute name="source-language" type="xsd:language" use="required"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute ref="xml:space" use="optional"/>
+      <xsd:attribute name="category" type="xsd:string" use="optional"/>
+      <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
+      <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
+      <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_group_id">
+      <xsd:selector xpath=".//xlf:group"/>
+      <xsd:field xpath="@id"/>
+    </xsd:unique>
+    <xsd:key name="K_unit_id">
+      <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
+      <xsd:field xpath="@id"/>
+    </xsd:key>
+    <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
+      <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
+      <xsd:field xpath="@xid"/>
+    </xsd:keyref>
+    <xsd:key name="K_tool-id">
+      <xsd:selector xpath="xlf:header/xlf:tool"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:key>
+    <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath="."/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:key name="K_count-group_name">
+      <xsd:selector xpath=".//xlf:count-group"/>
+      <xsd:field xpath="@name"/>
+    </xsd:key>
+    <xsd:unique name="U_context-group_name">
+      <xsd:selector xpath=".//xlf:context-group"/>
+      <xsd:field xpath="@name"/>
+    </xsd:unique>
+    <xsd:key name="K_phase-name">
+      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+      <xsd:field xpath="@phase-name"/>
+    </xsd:key>
+    <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
+      <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
+      <xsd:field xpath="@phase-name"/>
+    </xsd:keyref>
+    <xsd:unique name="U_uid">
+      <xsd:selector xpath=".//xlf:external-file"/>
+      <xsd:field xpath="@uid"/>
+    </xsd:unique>
+  </xsd:element>
+  <xsd:element name="header">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
+        <xsd:element minOccurs="0" ref="xlf:phase-group"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
+          <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:tool"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="internal-file">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="form" type="xsd:string"/>
+          <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="external-file">
+    <xsd:complexType>
+      <xsd:attribute name="href" type="xsd:string" use="required"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+      <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="note">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute ref="xml:lang" use="optional"/>
+          <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
+          <xsd:attribute name="from" type="xsd:string" use="optional"/>
+          <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="phase-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:element ref="xlf:phase"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="phase">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:note"/>
+      </xsd:sequence>
+      <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="process-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="count-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:count"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="count">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
+          <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+          <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="context-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:element ref="xlf:context"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="context">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
+          <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
+          <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="tool">
+    <xsd:complexType mixed="true">
+      <xsd:sequence>
+        <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
+      <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="body">
+    <xsd:complexType>
+      <xsd:choice maxOccurs="unbounded" minOccurs="0">
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+      </xsd:choice>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="group">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:sequence>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+          <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+        </xsd:sequence>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+        </xsd:choice>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+      <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="trans-unit">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="xlf:source"/>
+        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+        <xsd:element minOccurs="0" ref="xlf:target"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element ref="xlf:context-group"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:alt-trans"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="required"/>
+      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+      <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_tu_segsrc_mid">
+      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
+      <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="source">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_source_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_source_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="seg-source">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_segsrc_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_segsrc_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="target">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_target_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_target_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="alt-trans">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" ref="xlf:source"/>
+        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+        <xsd:element maxOccurs="1" ref="xlf:target"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:attribute name="origin" type="xsd:string" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_at_segsrc_mid">
+      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
+      <xsd:selector xpath="./xlf:target/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="bin-unit">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="xlf:bin-source"/>
+        <xsd:element minOccurs="0" ref="xlf:bin-target"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element ref="xlf:context-group"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:trans-unit"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="required"/>
+      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
+      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bin-source">
+    <xsd:complexType>
+      <xsd:choice>
+        <xsd:element ref="xlf:internal-file"/>
+        <xsd:element ref="xlf:external-file"/>
+      </xsd:choice>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bin-target">
+    <xsd:complexType>
+      <xsd:choice>
+        <xsd:element ref="xlf:internal-file"/>
+        <xsd:element ref="xlf:external-file"/>
+      </xsd:choice>
+      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
+      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <!-- Element for inline codes -->
+  <xsd:element name="g">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="x">
+    <xsd:complexType>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bx">
+    <xsd:complexType>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ex">
+    <xsd:complexType>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ph">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bpt">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ept">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="it">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="sub">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="mrk">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
+      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="comment" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-2.0.xsd b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-2.0.xsd
new file mode 100644
index 0000000..963232f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xliff-core-2.0.xsd
@@ -0,0 +1,411 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    XLIFF Version 2.0
+    OASIS Standard
+    05 August 2014
+    Copyright (c) OASIS Open 2014. All rights reserved.
+    Source: http://docs.oasis-open.org/xliff/xliff-core/v2.0/os/schemas/
+     -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified"
+    xmlns:xlf="urn:oasis:names:tc:xliff:document:2.0"
+    targetNamespace="urn:oasis:names:tc:xliff:document:2.0">
+
+  <!-- Import -->
+
+  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+      schemaLocation="informativeCopiesOf3rdPartySchemas/w3c/xml.xsd"/>
+
+  <!-- Element Group -->
+
+  <xs:group name="inline">
+    <xs:choice>
+      <xs:element ref="xlf:cp"/>
+      <xs:element ref="xlf:ph"/>
+      <xs:element ref="xlf:pc"/>
+      <xs:element ref="xlf:sc"/>
+      <xs:element ref="xlf:ec"/>
+      <xs:element ref="xlf:mrk"/>
+      <xs:element ref="xlf:sm"/>
+      <xs:element ref="xlf:em"/>
+    </xs:choice>
+  </xs:group>
+
+  <!-- Attribute Types -->
+
+  <xs:simpleType name="yesNo">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="yes"/>
+      <xs:enumeration value="no"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="yesNoFirstNo">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="yes"/>
+      <xs:enumeration value="firstNo"/>
+      <xs:enumeration value="no"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="dirValue">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="ltr"/>
+      <xs:enumeration value="rtl"/>
+      <xs:enumeration value="auto"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="appliesTo">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="source"/>
+      <xs:enumeration value="target"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="userDefinedValue">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="[^\s:]+:[^\s:]+"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="attrType_type">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="fmt"/>
+      <xs:enumeration value="ui"/>
+      <xs:enumeration value="quote"/>
+      <xs:enumeration value="link"/>
+      <xs:enumeration value="image"/>
+      <xs:enumeration value="other"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="typeForMrkValues">
+    <xs:restriction base="xs:NMTOKEN">
+      <xs:enumeration value="generic"/>
+      <xs:enumeration value="comment"/>
+      <xs:enumeration value="term"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="attrType_typeForMrk">
+    <xs:union memberTypes="xlf:typeForMrkValues xlf:userDefinedValue"/>
+  </xs:simpleType>
+
+  <xs:simpleType name="priorityValue">
+    <xs:restriction base="xs:positiveInteger">
+      <xs:minInclusive value="1"/>
+      <xs:maxInclusive value="10"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="stateType">
+    <xs:restriction base="xs:string">
+      <xs:enumeration value="initial"/>
+      <xs:enumeration value="translated"/>
+      <xs:enumeration value="reviewed"/>
+      <xs:enumeration value="final"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <!-- Structural Elements -->
+
+  <xs:element name="xliff">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:file"/>
+      </xs:sequence>
+      <xs:attribute name="version" use="required"/>
+      <xs:attribute name="srcLang" use="required"/>
+      <xs:attribute name="trgLang" use="optional"/>
+      <xs:attribute ref="xml:space" use="optional" default="default"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="file">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:skeleton"/>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
+        <xs:choice minOccurs="1" maxOccurs="unbounded">
+          <xs:element ref="xlf:unit"/>
+          <xs:element ref="xlf:group"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="original" use="optional"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue" default="auto"/>
+      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue" default="auto"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="skeleton">
+    <xs:complexType mixed="true">
+      <xs:sequence>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+      </xs:sequence>
+      <xs:attribute name="href" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="group">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+          <xs:element ref="xlf:unit"/>
+          <xs:element ref="xlf:group"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="name" use="optional"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="unit">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"
+            processContents="lax"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:notes"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:originalData"/>
+        <xs:choice minOccurs="1" maxOccurs="unbounded">
+          <xs:element ref="xlf:segment"/>
+          <xs:element ref="xlf:ignorable"/>
+        </xs:choice>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="name" use="optional"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="srcDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="trgDir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:attribute name="type" use="optional" type="xlf:userDefinedValue"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="segment">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
+      </xs:sequence>
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="canResegment" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="state" use="optional" type="xlf:stateType" default="initial"/>
+      <xs:attribute name="subState" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="ignorable">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="1" ref="xlf:source"/>
+        <xs:element minOccurs="0" maxOccurs="1" ref="xlf:target"/>
+      </xs:sequence>
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="notes">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:note"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="note">
+    <xs:complexType mixed="true">
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="appliesTo" use="optional" type="xlf:appliesTo"/>
+      <xs:attribute name="category" use="optional"/>
+      <xs:attribute name="priority" use="optional" type="xlf:priorityValue" default="1"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="originalData">
+    <xs:complexType mixed="false">
+      <xs:sequence>
+        <xs:element minOccurs="1" maxOccurs="unbounded" ref="xlf:data"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="data">
+    <xs:complexType mixed="true">
+      <xs:sequence>
+        <xs:element minOccurs="0" maxOccurs="unbounded" ref="xlf:cp"/>
+      </xs:sequence>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue" default="auto"/>
+      <xs:attribute ref="xml:space" use="optional" fixed="preserve"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="source">
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute ref="xml:lang" use="optional"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="target">
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute ref="xml:lang" use="optional"/>
+      <xs:attribute ref="xml:space" use="optional"/>
+      <xs:attribute name="order" use="optional" type="xs:positiveInteger"/>
+    </xs:complexType>
+  </xs:element>
+
+  <!-- Inline Elements -->
+
+  <xs:element name="cp">
+    <!-- Code Point -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="hex" use="required" type="xs:hexBinary"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="ph">
+    <!-- Placeholder -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="disp" use="optional"/>
+      <xs:attribute name="equiv" use="optional"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="pc">
+    <!-- Paired Code -->
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dispEnd" use="optional"/>
+      <xs:attribute name="dispStart" use="optional"/>
+      <xs:attribute name="equivEnd" use="optional"/>
+      <xs:attribute name="equivStart" use="optional"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRefEnd" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRefStart" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="subFlowsEnd" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subFlowsStart" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="sc">
+    <!-- Start Code -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="disp" use="optional"/>
+      <xs:attribute name="equiv" use="optional"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
+      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="ec">
+    <!-- End Code -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="canCopy" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canDelete" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canOverlap" use="optional" type="xlf:yesNo" default="yes"/>
+      <xs:attribute name="canReorder" use="optional" type="xlf:yesNoFirstNo" default="yes"/>
+      <xs:attribute name="copyOf" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dataRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="dir" use="optional" type="xlf:dirValue"/>
+      <xs:attribute name="disp" use="optional"/>
+      <xs:attribute name="equiv" use="optional"/>
+      <xs:attribute name="id" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="isolated" use="optional" type="xlf:yesNo" default="no"/>
+      <xs:attribute name="startRef" use="optional" type="xs:NMTOKEN"/>
+      <xs:attribute name="subFlows" use="optional" type="xs:NMTOKENS"/>
+      <xs:attribute name="subType" use="optional" type="xlf:userDefinedValue"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_type"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="mrk">
+    <!-- Annotation Marker -->
+    <xs:complexType mixed="true">
+      <xs:group ref="xlf:inline" minOccurs="0" maxOccurs="unbounded"/>
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
+      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
+      <xs:attribute name="value" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="sm">
+    <!-- Start Annotation Marker -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="id" use="required" type="xs:NMTOKEN"/>
+      <xs:attribute name="translate" use="optional" type="xlf:yesNo"/>
+      <xs:attribute name="type" use="optional" type="xlf:attrType_typeForMrk"/>
+      <xs:attribute name="ref" use="optional" type="xs:anyURI"/>
+      <xs:attribute name="value" use="optional"/>
+      <xs:anyAttribute namespace="##other" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="em">
+    <!-- End Annotation Marker -->
+    <xs:complexType mixed="false">
+      <xs:attribute name="startRef" use="required" type="xs:NMTOKEN"/>
+    </xs:complexType>
+  </xs:element>
+
+</xs:schema>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xml.xsd b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xml.xsd
new file mode 100644
index 0000000..a46162a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Resources/schemas/xml.xsd
@@ -0,0 +1,309 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+  xmlns ="http://www.w3.org/1999/xhtml"
+  xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+    <h1>About the XML namespace</h1>
+
+    <div class="bodytext">
+     <p>
+
+      This schema document describes the XML namespace, in a form
+      suitable for import by other schema documents.
+     </p>
+     <p>
+      See <a href="http://www.w3.org/XML/1998/namespace.html">
+      http://www.w3.org/XML/1998/namespace.html</a> and
+      <a href="http://www.w3.org/TR/REC-xml">
+      http://www.w3.org/TR/REC-xml</a> for information 
+      about this namespace.
+     </p>
+
+     <p>
+      Note that local names in this namespace are intended to be
+      defined only by the World Wide Web Consortium or its subgroups.
+      The names currently defined in this namespace are listed below.
+      They should not be used with conflicting semantics by any Working
+      Group, specification, or document instance.
+     </p>
+     <p>   
+      See further below in this document for more information about <a
+      href="#usage">how to refer to this schema document from your own
+      XSD schema documents</a> and about <a href="#nsversioning">the
+      namespace-versioning policy governing this schema document</a>.
+     </p>
+    </div>
+   </div>
+
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>lang (as an attribute name)</h3>
+      <p>
+
+       denotes an attribute whose value
+       is a language code for the natural language of the content of
+       any element; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML specification.</p>
+     
+    </div>
+    <div>
+     <h4>Notes</h4>
+     <p>
+      Attempting to install the relevant ISO 2- and 3-letter
+      codes as the enumerated possible values is probably never
+      going to be a realistic possibility.  
+     </p>
+     <p>
+
+      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+      and the IANA language subtag registry at
+      <a href="http://www.iana.org/assignments/language-subtag-registry">
+       http://www.iana.org/assignments/language-subtag-registry</a>
+      for further information.
+     </p>
+     <p>
+
+      The union allows for the 'un-declaration' of xml:lang with
+      the empty string.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:union memberTypes="xs:language">
+    <xs:simpleType>    
+     <xs:restriction base="xs:string">
+      <xs:enumeration value=""/>
+
+     </xs:restriction>
+    </xs:simpleType>
+   </xs:union>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+  <xs:annotation>
+   <xs:documentation>
+
+    <div>
+     
+      <h3>space (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose
+       value is a keyword indicating what whitespace processing
+       discipline is intended for the content of the element; its
+       value is inherited.  This name is reserved by virtue of its
+       definition in the XML specification.</p>
+     
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+
+   <xs:restriction base="xs:NCName">
+    <xs:enumeration value="default"/>
+    <xs:enumeration value="preserve"/>
+   </xs:restriction>
+  </xs:simpleType>
+ </xs:attribute>
+ 
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+   <xs:documentation>
+
+    <div>
+     
+      <h3>base (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose value
+       provides a URI to be used as the base for interpreting any
+       relative URIs in the scope of the element on which it
+       appears; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML Base specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+      for information about this attribute.
+     </p>
+
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ 
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>id (as an attribute name)</h3> 
+      <p>
+
+       denotes an attribute whose value
+       should be interpreted as if declared to be of type ID.
+       This name is reserved by virtue of its definition in the
+       xml:id specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+  <xs:attribute ref="xml:base"/>
+  <xs:attribute ref="xml:lang"/>
+  <xs:attribute ref="xml:space"/>
+  <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+
+  <xs:documentation>
+   <div>
+   
+    <h3>Father (in any context at all)</h3> 
+
+    <div class="bodytext">
+     <p>
+      denotes Jon Bosak, the chair of 
+      the original XML Working Group.  This name is reserved by 
+      the following decision of the W3C XML Plenary and 
+      XML Coordination groups:
+     </p>
+     <blockquote>
+       <p>
+
+	In appreciation for his vision, leadership and
+	dedication the W3C XML Plenary on this 10th day of
+	February, 2000, reserves for Jon Bosak in perpetuity
+	the XML name "xml:Father".
+       </p>
+     </blockquote>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+
+   <div xml:id="usage" id="usage">
+    <h2><a name="usage">About this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      This schema defines attributes and an attribute group suitable
+      for use by schemas wishing to allow <code>xml:base</code>,
+      <code>xml:lang</code>, <code>xml:space</code> or
+      <code>xml:id</code> attributes on elements they define.
+     </p>
+
+     <p>
+      To enable this, such a schema must import this schema for
+      the XML namespace, e.g. as follows:
+     </p>
+     <pre>
+          &lt;schema.. .>
+          .. .
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+     </pre>
+     <p>
+      or
+     </p>
+     <pre>
+
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+     </pre>
+     <p>
+      Subsequently, qualified reference to any of the attributes or the
+      group defined below will have the desired effect, e.g.
+     </p>
+     <pre>
+          &lt;type.. .>
+          .. .
+           &lt;attributeGroup ref="xml:specialAttrs"/>
+     </pre>
+     <p>
+      will define a type which will schema-validate an instance element
+      with any of those attributes.
+     </p>
+
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div id="nsversioning" xml:id="nsversioning">
+    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      In keeping with the XML Schema WG's standard versioning
+      policy, this schema document will persist at
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd</a>.
+     </p>
+     <p>
+      At the date of issue it can also be found at
+      <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd</a>.
+     </p>
+
+     <p>
+      The schema document at that URI may however change in the future,
+      in order to remain compatible with the latest version of XML
+      Schema itself, or with the XML namespace itself.  In other words,
+      if the XML Schema or XML namespaces change, the version of this
+      document at <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd 
+      </a> 
+      will change accordingly; the version at 
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd 
+      </a> 
+      will not change.
+     </p>
+     <p>
+
+      Previous dated (and unchanging) versions of this schema 
+      document are at:
+     </p>
+     <ul>
+      <li><a href="http://www.w3.org/2009/01/xml.xsd">
+	http://www.w3.org/2009/01/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2007/08/xml.xsd">
+	http://www.w3.org/2007/08/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2004/10/xml.xsd">
+
+	http://www.w3.org/2004/10/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2001/03/xml.xsd">
+	http://www.w3.org/2001/03/xml.xsd</a></li>
+     </ul>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderFactoryTestCase.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderFactoryTestCase.php
new file mode 100644
index 0000000..6d5f4b7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderFactoryTestCase.php
@@ -0,0 +1,147 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Test;
+
+use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpClient\MockHttpClient;
+use Symfony\Component\Translation\Dumper\XliffFileDumper;
+use Symfony\Component\Translation\Exception\IncompleteDsnException;
+use Symfony\Component\Translation\Exception\UnsupportedSchemeException;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Provider\Dsn;
+use Symfony\Component\Translation\Provider\ProviderFactoryInterface;
+use Symfony\Contracts\HttpClient\HttpClientInterface;
+
+/**
+ * A test case to ease testing a translation provider factory.
+ *
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @internal
+ */
+abstract class ProviderFactoryTestCase extends TestCase
+{
+    protected $client;
+    protected $logger;
+    protected $defaultLocale;
+    protected $loader;
+    protected $xliffFileDumper;
+
+    abstract public function createFactory(): ProviderFactoryInterface;
+
+    /**
+     * @return iterable<array{0: bool, 1: string}>
+     */
+    abstract public function supportsProvider(): iterable;
+
+    /**
+     * @return iterable<array{0: string, 1: string, 2: TransportInterface}>
+     */
+    abstract public function createProvider(): iterable;
+
+    /**
+     * @return iterable<array{0: string, 1: string|null}>
+     */
+    public function unsupportedSchemeProvider(): iterable
+    {
+        return [];
+    }
+
+    /**
+     * @return iterable<array{0: string, 1: string|null}>
+     */
+    public function incompleteDsnProvider(): iterable
+    {
+        return [];
+    }
+
+    /**
+     * @dataProvider supportsProvider
+     */
+    public function testSupports(bool $expected, string $dsn)
+    {
+        $factory = $this->createFactory();
+
+        $this->assertSame($expected, $factory->supports(new Dsn($dsn)));
+    }
+
+    /**
+     * @dataProvider createProvider
+     */
+    public function testCreate(string $expected, string $dsn)
+    {
+        $factory = $this->createFactory();
+        $provider = $factory->create(new Dsn($dsn));
+
+        $this->assertSame($expected, (string) $provider);
+    }
+
+    /**
+     * @dataProvider unsupportedSchemeProvider
+     */
+    public function testUnsupportedSchemeException(string $dsn, string $message = null)
+    {
+        $factory = $this->createFactory();
+
+        $dsn = new Dsn($dsn);
+
+        $this->expectException(UnsupportedSchemeException::class);
+        if (null !== $message) {
+            $this->expectExceptionMessage($message);
+        }
+
+        $factory->create($dsn);
+    }
+
+    /**
+     * @dataProvider incompleteDsnProvider
+     */
+    public function testIncompleteDsnException(string $dsn, string $message = null)
+    {
+        $factory = $this->createFactory();
+
+        $dsn = new Dsn($dsn);
+
+        $this->expectException(IncompleteDsnException::class);
+        if (null !== $message) {
+            $this->expectExceptionMessage($message);
+        }
+
+        $factory->create($dsn);
+    }
+
+    protected function getClient(): HttpClientInterface
+    {
+        return $this->client ?? $this->client = new MockHttpClient();
+    }
+
+    protected function getLogger(): LoggerInterface
+    {
+        return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
+    }
+
+    protected function getDefaultLocale(): string
+    {
+        return $this->defaultLocale ?? $this->defaultLocale = 'en';
+    }
+
+    protected function getLoader(): LoaderInterface
+    {
+        return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class);
+    }
+
+    protected function getXliffFileDumper(): XliffFileDumper
+    {
+        return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderTestCase.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderTestCase.php
new file mode 100644
index 0000000..238fd96
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Test/ProviderTestCase.php
@@ -0,0 +1,86 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Test;
+
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpClient\MockHttpClient;
+use Symfony\Component\Translation\Dumper\XliffFileDumper;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Provider\ProviderInterface;
+use Symfony\Contracts\HttpClient\HttpClientInterface;
+
+/**
+ * A test case to ease testing a translation provider.
+ *
+ * @author Mathieu Santostefano <msantostefano@protonmail.com>
+ *
+ * @internal
+ */
+abstract class ProviderTestCase extends TestCase
+{
+    protected $client;
+    protected $logger;
+    protected $defaultLocale;
+    protected $loader;
+    protected $xliffFileDumper;
+
+    abstract public function createProvider(HttpClientInterface $client, LoaderInterface $loader, LoggerInterface $logger, string $defaultLocale, string $endpoint): ProviderInterface;
+
+    /**
+     * @return iterable<array{0: string, 1: ProviderInterface}>
+     */
+    abstract public function toStringProvider(): iterable;
+
+    /**
+     * @dataProvider toStringProvider
+     */
+    public function testToString(ProviderInterface $provider, string $expected)
+    {
+        $this->assertSame($expected, (string) $provider);
+    }
+
+    protected function getClient(): MockHttpClient
+    {
+        return $this->client ?? $this->client = new MockHttpClient();
+    }
+
+    /**
+     * @return LoaderInterface&MockObject
+     */
+    protected function getLoader(): LoaderInterface
+    {
+        return $this->loader ?? $this->loader = $this->createMock(LoaderInterface::class);
+    }
+
+    /**
+     * @return LoaderInterface&MockObject
+     */
+    protected function getLogger(): LoggerInterface
+    {
+        return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
+    }
+
+    protected function getDefaultLocale(): string
+    {
+        return $this->defaultLocale ?? $this->defaultLocale = 'en';
+    }
+
+    /**
+     * @return LoaderInterface&MockObject
+     */
+    protected function getXliffFileDumper(): XliffFileDumper
+    {
+        return $this->xliffFileDumper ?? $this->xliffFileDumper = $this->createMock(XliffFileDumper::class);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatableMessage.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatableMessage.php
new file mode 100644
index 0000000..82ae6d7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatableMessage.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Contracts\Translation\TranslatableInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Nate Wiebe <nate@northern.co>
+ */
+class TranslatableMessage implements TranslatableInterface
+{
+    private $message;
+    private $parameters;
+    private $domain;
+
+    public function __construct(string $message, array $parameters = [], string $domain = null)
+    {
+        $this->message = $message;
+        $this->parameters = $parameters;
+        $this->domain = $domain;
+    }
+
+    public function __toString(): string
+    {
+        return $this->getMessage();
+    }
+
+    public function getMessage(): string
+    {
+        return $this->message;
+    }
+
+    public function getParameters(): array
+    {
+        return $this->parameters;
+    }
+
+    public function getDomain(): ?string
+    {
+        return $this->domain;
+    }
+
+    public function trans(TranslatorInterface $translator, string $locale = null): string
+    {
+        return $translator->trans($this->getMessage(), $this->getParameters(), $this->getDomain(), $locale);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Translator.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Translator.php
new file mode 100644
index 0000000..9a63956
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Translator.php
@@ -0,0 +1,490 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\ConfigCacheFactory;
+use Symfony\Component\Config\ConfigCacheFactoryInterface;
+use Symfony\Component\Config\ConfigCacheInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\Formatter\IntlFormatterInterface;
+use Symfony\Component\Translation\Formatter\MessageFormatter;
+use Symfony\Component\Translation\Formatter\MessageFormatterInterface;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Contracts\Translation\LocaleAwareInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+// Help opcache.preload discover always-needed symbols
+class_exists(MessageCatalogue::class);
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface
+{
+    /**
+     * @var MessageCatalogueInterface[]
+     */
+    protected $catalogues = [];
+
+    /**
+     * @var string
+     */
+    private $locale;
+
+    /**
+     * @var array
+     */
+    private $fallbackLocales = [];
+
+    /**
+     * @var LoaderInterface[]
+     */
+    private $loaders = [];
+
+    /**
+     * @var array
+     */
+    private $resources = [];
+
+    /**
+     * @var MessageFormatterInterface
+     */
+    private $formatter;
+
+    /**
+     * @var string
+     */
+    private $cacheDir;
+
+    /**
+     * @var bool
+     */
+    private $debug;
+
+    private $cacheVary;
+
+    /**
+     * @var ConfigCacheFactoryInterface|null
+     */
+    private $configCacheFactory;
+
+    /**
+     * @var array|null
+     */
+    private $parentLocales;
+
+    private $hasIntlFormatter;
+
+    /**
+     * @throws InvalidArgumentException If a locale contains invalid characters
+     */
+    public function __construct(string $locale, MessageFormatterInterface $formatter = null, string $cacheDir = null, bool $debug = false, array $cacheVary = [])
+    {
+        $this->setLocale($locale);
+
+        if (null === $formatter) {
+            $formatter = new MessageFormatter();
+        }
+
+        $this->formatter = $formatter;
+        $this->cacheDir = $cacheDir;
+        $this->debug = $debug;
+        $this->cacheVary = $cacheVary;
+        $this->hasIntlFormatter = $formatter instanceof IntlFormatterInterface;
+    }
+
+    public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
+    {
+        $this->configCacheFactory = $configCacheFactory;
+    }
+
+    /**
+     * Adds a Loader.
+     *
+     * @param string $format The name of the loader (@see addResource())
+     */
+    public function addLoader(string $format, LoaderInterface $loader)
+    {
+        $this->loaders[$format] = $loader;
+    }
+
+    /**
+     * Adds a Resource.
+     *
+     * @param string $format   The name of the loader (@see addLoader())
+     * @param mixed  $resource The resource name
+     *
+     * @throws InvalidArgumentException If the locale contains invalid characters
+     */
+    public function addResource(string $format, $resource, string $locale, string $domain = null)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $this->assertValidLocale($locale);
+        $locale ?: $locale = class_exists(\Locale::class) ? \Locale::getDefault() : 'en';
+
+        $this->resources[$locale][] = [$format, $resource, $domain];
+
+        if (\in_array($locale, $this->fallbackLocales)) {
+            $this->catalogues = [];
+        } else {
+            unset($this->catalogues[$locale]);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setLocale(string $locale)
+    {
+        $this->assertValidLocale($locale);
+        $this->locale = $locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLocale()
+    {
+        return $this->locale ?: (class_exists(\Locale::class) ? \Locale::getDefault() : 'en');
+    }
+
+    /**
+     * Sets the fallback locales.
+     *
+     * @throws InvalidArgumentException If a locale contains invalid characters
+     */
+    public function setFallbackLocales(array $locales)
+    {
+        // needed as the fallback locales are linked to the already loaded catalogues
+        $this->catalogues = [];
+
+        foreach ($locales as $locale) {
+            $this->assertValidLocale($locale);
+        }
+
+        $this->fallbackLocales = $this->cacheVary['fallback_locales'] = $locales;
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @internal
+     */
+    public function getFallbackLocales(): array
+    {
+        return $this->fallbackLocales;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans(?string $id, array $parameters = [], string $domain = null, string $locale = null)
+    {
+        if (null === $id || '' === $id) {
+            return '';
+        }
+
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $catalogue = $this->getCatalogue($locale);
+        $locale = $catalogue->getLocale();
+        while (!$catalogue->defines($id, $domain)) {
+            if ($cat = $catalogue->getFallbackCatalogue()) {
+                $catalogue = $cat;
+                $locale = $catalogue->getLocale();
+            } else {
+                break;
+            }
+        }
+
+        $len = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX);
+        if ($this->hasIntlFormatter
+            && ($catalogue->defines($id, $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)
+            || (\strlen($domain) > $len && 0 === substr_compare($domain, MessageCatalogue::INTL_DOMAIN_SUFFIX, -$len, $len)))
+        ) {
+            return $this->formatter->formatIntl($catalogue->get($id, $domain), $locale, $parameters);
+        }
+
+        return $this->formatter->format($catalogue->get($id, $domain), $locale, $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        if (!$locale) {
+            $locale = $this->getLocale();
+        } else {
+            $this->assertValidLocale($locale);
+        }
+
+        if (!isset($this->catalogues[$locale])) {
+            $this->loadCatalogue($locale);
+        }
+
+        return $this->catalogues[$locale];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return array_values($this->catalogues);
+    }
+
+    /**
+     * Gets the loaders.
+     *
+     * @return array LoaderInterface[]
+     */
+    protected function getLoaders()
+    {
+        return $this->loaders;
+    }
+
+    protected function loadCatalogue(string $locale)
+    {
+        if (null === $this->cacheDir) {
+            $this->initializeCatalogue($locale);
+        } else {
+            $this->initializeCacheCatalogue($locale);
+        }
+    }
+
+    protected function initializeCatalogue(string $locale)
+    {
+        $this->assertValidLocale($locale);
+
+        try {
+            $this->doLoadCatalogue($locale);
+        } catch (NotFoundResourceException $e) {
+            if (!$this->computeFallbackLocales($locale)) {
+                throw $e;
+            }
+        }
+        $this->loadFallbackCatalogues($locale);
+    }
+
+    private function initializeCacheCatalogue(string $locale): void
+    {
+        if (isset($this->catalogues[$locale])) {
+            /* Catalogue already initialized. */
+            return;
+        }
+
+        $this->assertValidLocale($locale);
+        $cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale),
+            function (ConfigCacheInterface $cache) use ($locale) {
+                $this->dumpCatalogue($locale, $cache);
+            }
+        );
+
+        if (isset($this->catalogues[$locale])) {
+            /* Catalogue has been initialized as it was written out to cache. */
+            return;
+        }
+
+        /* Read catalogue from cache. */
+        $this->catalogues[$locale] = include $cache->getPath();
+    }
+
+    private function dumpCatalogue(string $locale, ConfigCacheInterface $cache): void
+    {
+        $this->initializeCatalogue($locale);
+        $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);
+
+        $content = sprintf(<<<EOF
+<?php
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+\$catalogue = new MessageCatalogue('%s', %s);
+
+%s
+return \$catalogue;
+
+EOF
+            ,
+            $locale,
+            var_export($this->getAllMessages($this->catalogues[$locale]), true),
+            $fallbackContent
+        );
+
+        $cache->write($content, $this->catalogues[$locale]->getResources());
+    }
+
+    private function getFallbackContent(MessageCatalogue $catalogue): string
+    {
+        $fallbackContent = '';
+        $current = '';
+        $replacementPattern = '/[^a-z0-9_]/i';
+        $fallbackCatalogue = $catalogue->getFallbackCatalogue();
+        while ($fallbackCatalogue) {
+            $fallback = $fallbackCatalogue->getLocale();
+            $fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
+            $currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
+
+            $fallbackContent .= sprintf(<<<'EOF'
+$catalogue%s = new MessageCatalogue('%s', %s);
+$catalogue%s->addFallbackCatalogue($catalogue%s);
+
+EOF
+                ,
+                $fallbackSuffix,
+                $fallback,
+                var_export($this->getAllMessages($fallbackCatalogue), true),
+                $currentSuffix,
+                $fallbackSuffix
+            );
+            $current = $fallbackCatalogue->getLocale();
+            $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
+        }
+
+        return $fallbackContent;
+    }
+
+    private function getCatalogueCachePath(string $locale): string
+    {
+        return $this->cacheDir.'/catalogue.'.$locale.'.'.strtr(substr(base64_encode(hash('sha256', serialize($this->cacheVary), true)), 0, 7), '/', '_').'.php';
+    }
+
+    /**
+     * @internal
+     */
+    protected function doLoadCatalogue(string $locale): void
+    {
+        $this->catalogues[$locale] = new MessageCatalogue($locale);
+
+        if (isset($this->resources[$locale])) {
+            foreach ($this->resources[$locale] as $resource) {
+                if (!isset($this->loaders[$resource[0]])) {
+                    if (\is_string($resource[1])) {
+                        throw new RuntimeException(sprintf('No loader is registered for the "%s" format when loading the "%s" resource.', $resource[0], $resource[1]));
+                    }
+
+                    throw new RuntimeException(sprintf('No loader is registered for the "%s" format.', $resource[0]));
+                }
+                $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
+            }
+        }
+    }
+
+    private function loadFallbackCatalogues(string $locale): void
+    {
+        $current = $this->catalogues[$locale];
+
+        foreach ($this->computeFallbackLocales($locale) as $fallback) {
+            if (!isset($this->catalogues[$fallback])) {
+                $this->initializeCatalogue($fallback);
+            }
+
+            $fallbackCatalogue = new MessageCatalogue($fallback, $this->getAllMessages($this->catalogues[$fallback]));
+            foreach ($this->catalogues[$fallback]->getResources() as $resource) {
+                $fallbackCatalogue->addResource($resource);
+            }
+            $current->addFallbackCatalogue($fallbackCatalogue);
+            $current = $fallbackCatalogue;
+        }
+    }
+
+    protected function computeFallbackLocales(string $locale)
+    {
+        if (null === $this->parentLocales) {
+            $this->parentLocales = json_decode(file_get_contents(__DIR__.'/Resources/data/parents.json'), true);
+        }
+
+        $locales = [];
+        foreach ($this->fallbackLocales as $fallback) {
+            if ($fallback === $locale) {
+                continue;
+            }
+
+            $locales[] = $fallback;
+        }
+
+        while ($locale) {
+            $parent = $this->parentLocales[$locale] ?? null;
+
+            if ($parent) {
+                $locale = 'root' !== $parent ? $parent : null;
+            } elseif (\function_exists('locale_parse')) {
+                $localeSubTags = locale_parse($locale);
+                $locale = null;
+                if (1 < \count($localeSubTags)) {
+                    array_pop($localeSubTags);
+                    $locale = locale_compose($localeSubTags) ?: null;
+                }
+            } elseif ($i = strrpos($locale, '_') ?: strrpos($locale, '-')) {
+                $locale = substr($locale, 0, $i);
+            } else {
+                $locale = null;
+            }
+
+            if (null !== $locale) {
+                array_unshift($locales, $locale);
+            }
+        }
+
+        return array_unique($locales);
+    }
+
+    /**
+     * Asserts that the locale is valid, throws an Exception if not.
+     *
+     * @throws InvalidArgumentException If the locale contains invalid characters
+     */
+    protected function assertValidLocale(string $locale)
+    {
+        if (!preg_match('/^[a-z0-9@_\\.\\-]*$/i', (string) $locale)) {
+            throw new InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
+        }
+    }
+
+    /**
+     * Provides the ConfigCache factory implementation, falling back to a
+     * default implementation if necessary.
+     */
+    private function getConfigCacheFactory(): ConfigCacheFactoryInterface
+    {
+        if (!$this->configCacheFactory) {
+            $this->configCacheFactory = new ConfigCacheFactory($this->debug);
+        }
+
+        return $this->configCacheFactory;
+    }
+
+    private function getAllMessages(MessageCatalogueInterface $catalogue): array
+    {
+        $allMessages = [];
+
+        foreach ($catalogue->all() as $domain => $messages) {
+            if ($intlMessages = $catalogue->all($domain.MessageCatalogue::INTL_DOMAIN_SUFFIX)) {
+                $allMessages[$domain.MessageCatalogue::INTL_DOMAIN_SUFFIX] = $intlMessages;
+                $messages = array_diff_key($messages, $intlMessages);
+            }
+            if ($messages) {
+                $allMessages[$domain] = $messages;
+            }
+        }
+
+        return $allMessages;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBag.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBag.php
new file mode 100644
index 0000000..c655578
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBag.php
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Translation\Catalogue\AbstractOperation;
+use Symfony\Component\Translation\Catalogue\TargetOperation;
+
+final class TranslatorBag implements TranslatorBagInterface
+{
+    /** @var MessageCatalogue[] */
+    private $catalogues = [];
+
+    public function addCatalogue(MessageCatalogue $catalogue): void
+    {
+        if (null !== $existingCatalogue = $this->getCatalogue($catalogue->getLocale())) {
+            $catalogue->addCatalogue($existingCatalogue);
+        }
+
+        $this->catalogues[$catalogue->getLocale()] = $catalogue;
+    }
+
+    public function addBag(TranslatorBagInterface $bag): void
+    {
+        foreach ($bag->getCatalogues() as $catalogue) {
+            $this->addCatalogue($catalogue);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue(string $locale = null)
+    {
+        if (null === $locale || !isset($this->catalogues[$locale])) {
+            $this->catalogues[$locale] = new MessageCatalogue($locale);
+        }
+
+        return $this->catalogues[$locale];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogues(): array
+    {
+        return array_values($this->catalogues);
+    }
+
+    public function diff(TranslatorBagInterface $diffBag): self
+    {
+        $diff = new self();
+
+        foreach ($this->catalogues as $locale => $catalogue) {
+            if (null === $diffCatalogue = $diffBag->getCatalogue($locale)) {
+                $diff->addCatalogue($catalogue);
+
+                continue;
+            }
+
+            $operation = new TargetOperation($diffCatalogue, $catalogue);
+            $operation->moveMessagesToIntlDomainsIfPossible(AbstractOperation::NEW_BATCH);
+            $newCatalogue = new MessageCatalogue($locale);
+
+            foreach ($operation->getDomains() as $domain) {
+                $newCatalogue->add($operation->getNewMessages($domain), $domain);
+            }
+
+            $diff->addCatalogue($newCatalogue);
+        }
+
+        return $diff;
+    }
+
+    public function intersect(TranslatorBagInterface $intersectBag): self
+    {
+        $diff = new self();
+
+        foreach ($this->catalogues as $locale => $catalogue) {
+            if (null === $intersectCatalogue = $intersectBag->getCatalogue($locale)) {
+                continue;
+            }
+
+            $operation = new TargetOperation($catalogue, $intersectCatalogue);
+            $operation->moveMessagesToIntlDomainsIfPossible(AbstractOperation::OBSOLETE_BATCH);
+            $obsoleteCatalogue = new MessageCatalogue($locale);
+
+            foreach ($operation->getDomains() as $domain) {
+                $obsoleteCatalogue->add($operation->getObsoleteMessages($domain), $domain);
+            }
+
+            $diff->addCatalogue($obsoleteCatalogue);
+        }
+
+        return $diff;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBagInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBagInterface.php
new file mode 100644
index 0000000..4228977
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/TranslatorBagInterface.php
@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+
+/**
+ * TranslatorBagInterface.
+ *
+ * @method MessageCatalogueInterface[] getCatalogues() Returns all catalogues of the instance
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+interface TranslatorBagInterface
+{
+    /**
+     * Gets the catalogue by locale.
+     *
+     * @param string|null $locale The locale or null to use the default
+     *
+     * @return MessageCatalogueInterface
+     *
+     * @throws InvalidArgumentException If the locale contains invalid characters
+     */
+    public function getCatalogue(string $locale = null);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/ArrayConverter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/ArrayConverter.php
new file mode 100644
index 0000000..acfbfc3
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/ArrayConverter.php
@@ -0,0 +1,99 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Util;
+
+/**
+ * ArrayConverter generates tree like structure from a message catalogue.
+ * e.g. this
+ *   'foo.bar1' => 'test1',
+ *   'foo.bar2' => 'test2'
+ * converts to follows:
+ *   foo:
+ *     bar1: test1
+ *     bar2: test2.
+ *
+ * @author Gennady Telegin <gtelegin@gmail.com>
+ */
+class ArrayConverter
+{
+    /**
+     * Converts linear messages array to tree-like array.
+     * For example this array('foo.bar' => 'value') will be converted to ['foo' => ['bar' => 'value']].
+     *
+     * @param array $messages Linear messages array
+     *
+     * @return array Tree-like messages array
+     */
+    public static function expandToTree(array $messages)
+    {
+        $tree = [];
+
+        foreach ($messages as $id => $value) {
+            $referenceToElement = &self::getElementByPath($tree, explode('.', $id));
+
+            $referenceToElement = $value;
+
+            unset($referenceToElement);
+        }
+
+        return $tree;
+    }
+
+    private static function &getElementByPath(array &$tree, array $parts)
+    {
+        $elem = &$tree;
+        $parentOfElem = null;
+
+        foreach ($parts as $i => $part) {
+            if (isset($elem[$part]) && \is_string($elem[$part])) {
+                /* Process next case:
+                 *    'foo': 'test1',
+                 *    'foo.bar': 'test2'
+                 *
+                 * $tree['foo'] was string before we found array {bar: test2}.
+                 *  Treat new element as string too, e.g. add $tree['foo.bar'] = 'test2';
+                 */
+                $elem = &$elem[implode('.', \array_slice($parts, $i))];
+                break;
+            }
+            $parentOfElem = &$elem;
+            $elem = &$elem[$part];
+        }
+
+        if ($elem && \is_array($elem) && $parentOfElem) {
+            /* Process next case:
+             *    'foo.bar': 'test1'
+             *    'foo': 'test2'
+             *
+             * $tree['foo'] was array = {bar: 'test1'} before we found string constant `foo`.
+             * Cancel treating $tree['foo'] as array and cancel back it expansion,
+             *  e.g. make it $tree['foo.bar'] = 'test1' again.
+             */
+            self::cancelExpand($parentOfElem, $part, $elem);
+        }
+
+        return $elem;
+    }
+
+    private static function cancelExpand(array &$tree, string $prefix, array $node)
+    {
+        $prefix .= '.';
+
+        foreach ($node as $id => $value) {
+            if (\is_string($value)) {
+                $tree[$prefix.$id] = $value;
+            } else {
+                self::cancelExpand($tree, $prefix.$id, $value);
+            }
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/XliffUtils.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/XliffUtils.php
new file mode 100644
index 0000000..e4373a7
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Util/XliffUtils.php
@@ -0,0 +1,196 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Util;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+
+/**
+ * Provides some utility methods for XLIFF translation files, such as validating
+ * their contents according to the XSD schema.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class XliffUtils
+{
+    /**
+     * Gets xliff file version based on the root "version" attribute.
+     *
+     * Defaults to 1.2 for backwards compatibility.
+     *
+     * @throws InvalidArgumentException
+     */
+    public static function getVersionNumber(\DOMDocument $dom): string
+    {
+        /** @var \DOMNode $xliff */
+        foreach ($dom->getElementsByTagName('xliff') as $xliff) {
+            $version = $xliff->attributes->getNamedItem('version');
+            if ($version) {
+                return $version->nodeValue;
+            }
+
+            $namespace = $xliff->attributes->getNamedItem('xmlns');
+            if ($namespace) {
+                if (0 !== substr_compare('urn:oasis:names:tc:xliff:document:', $namespace->nodeValue, 0, 34)) {
+                    throw new InvalidArgumentException(sprintf('Not a valid XLIFF namespace "%s".', $namespace));
+                }
+
+                return substr($namespace, 34);
+            }
+        }
+
+        // Falls back to v1.2
+        return '1.2';
+    }
+
+    /**
+     * Validates and parses the given file into a DOMDocument.
+     *
+     * @throws InvalidResourceException
+     */
+    public static function validateSchema(\DOMDocument $dom): array
+    {
+        $xliffVersion = static::getVersionNumber($dom);
+        $internalErrors = libxml_use_internal_errors(true);
+        if ($shouldEnable = self::shouldEnableEntityLoader()) {
+            $disableEntities = libxml_disable_entity_loader(false);
+        }
+        try {
+            $isValid = @$dom->schemaValidateSource(self::getSchema($xliffVersion));
+            if (!$isValid) {
+                return self::getXmlErrors($internalErrors);
+            }
+        } finally {
+            if ($shouldEnable) {
+                libxml_disable_entity_loader($disableEntities);
+            }
+        }
+
+        $dom->normalizeDocument();
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return [];
+    }
+
+    private static function shouldEnableEntityLoader(): bool
+    {
+        // Version prior to 8.0 can be enabled without deprecation
+        if (\PHP_VERSION_ID < 80000) {
+            return true;
+        }
+
+        static $dom, $schema;
+        if (null === $dom) {
+            $dom = new \DOMDocument();
+            $dom->loadXML('<?xml version="1.0"?><test/>');
+
+            $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+            register_shutdown_function(static function () use ($tmpfile) {
+                @unlink($tmpfile);
+            });
+            $schema = '<?xml version="1.0" encoding="utf-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:include schemaLocation="file:///'.str_replace('\\', '/', $tmpfile).'" />
+</xsd:schema>';
+            file_put_contents($tmpfile, '<?xml version="1.0" encoding="utf-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:element name="test" type="testType" />
+  <xsd:complexType name="testType"/>
+</xsd:schema>');
+        }
+
+        return !@$dom->schemaValidateSource($schema);
+    }
+
+    public static function getErrorsAsString(array $xmlErrors): string
+    {
+        $errorsAsString = '';
+
+        foreach ($xmlErrors as $error) {
+            $errorsAsString .= sprintf("[%s %s] %s (in %s - line %d, column %d)\n",
+                \LIBXML_ERR_WARNING === $error['level'] ? 'WARNING' : 'ERROR',
+                $error['code'],
+                $error['message'],
+                $error['file'],
+                $error['line'],
+                $error['column']
+            );
+        }
+
+        return $errorsAsString;
+    }
+
+    private static function getSchema(string $xliffVersion): string
+    {
+        if ('1.2' === $xliffVersion) {
+            $schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-1.2-strict.xsd');
+            $xmlUri = 'http://www.w3.org/2001/xml.xsd';
+        } elseif ('2.0' === $xliffVersion) {
+            $schemaSource = file_get_contents(__DIR__.'/../Resources/schemas/xliff-core-2.0.xsd');
+            $xmlUri = 'informativeCopiesOf3rdPartySchemas/w3c/xml.xsd';
+        } else {
+            throw new InvalidArgumentException(sprintf('No support implemented for loading XLIFF version "%s".', $xliffVersion));
+        }
+
+        return self::fixXmlLocation($schemaSource, $xmlUri);
+    }
+
+    /**
+     * Internally changes the URI of a dependent xsd to be loaded locally.
+     */
+    private static function fixXmlLocation(string $schemaSource, string $xmlUri): string
+    {
+        $newPath = str_replace('\\', '/', __DIR__).'/../Resources/schemas/xml.xsd';
+        $parts = explode('/', $newPath);
+        $locationstart = 'file:///';
+        if (0 === stripos($newPath, 'phar://')) {
+            $tmpfile = tempnam(sys_get_temp_dir(), 'symfony');
+            if ($tmpfile) {
+                copy($newPath, $tmpfile);
+                $parts = explode('/', str_replace('\\', '/', $tmpfile));
+            } else {
+                array_shift($parts);
+                $locationstart = 'phar:///';
+            }
+        }
+
+        $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
+        $newPath = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts));
+
+        return str_replace($xmlUri, $newPath, $schemaSource);
+    }
+
+    /**
+     * Returns the XML errors of the internal XML parser.
+     */
+    private static function getXmlErrors(bool $internalErrors): array
+    {
+        $errors = [];
+        foreach (libxml_get_errors() as $error) {
+            $errors[] = [
+                'level' => \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+                'code' => $error->code,
+                'message' => trim($error->message),
+                'file' => $error->file ?: 'n/a',
+                'line' => $error->line,
+                'column' => $error->column,
+            ];
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return $errors;
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriter.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriter.php
new file mode 100644
index 0000000..0a349b8
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriter.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Writer;
+
+use Symfony\Component\Translation\Dumper\DumperInterface;
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\Exception\RuntimeException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationWriter writes translation messages.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class TranslationWriter implements TranslationWriterInterface
+{
+    private $dumpers = [];
+
+    /**
+     * Adds a dumper to the writer.
+     */
+    public function addDumper(string $format, DumperInterface $dumper)
+    {
+        $this->dumpers[$format] = $dumper;
+    }
+
+    /**
+     * Obtains the list of supported formats.
+     *
+     * @return array
+     */
+    public function getFormats()
+    {
+        return array_keys($this->dumpers);
+    }
+
+    /**
+     * Writes translation from the catalogue according to the selected format.
+     *
+     * @param string $format  The format to use to dump the messages
+     * @param array  $options Options that are passed to the dumper
+     *
+     * @throws InvalidArgumentException
+     */
+    public function write(MessageCatalogue $catalogue, string $format, array $options = [])
+    {
+        if (!isset($this->dumpers[$format])) {
+            throw new InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format));
+        }
+
+        // get the right dumper
+        $dumper = $this->dumpers[$format];
+
+        if (isset($options['path']) && !is_dir($options['path']) && !@mkdir($options['path'], 0777, true) && !is_dir($options['path'])) {
+            throw new RuntimeException(sprintf('Translation Writer was not able to create directory "%s".', $options['path']));
+        }
+
+        // save
+        $dumper->dump($catalogue, $options);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriterInterface.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriterInterface.php
new file mode 100644
index 0000000..4321309
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/Writer/TranslationWriterInterface.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Writer;
+
+use Symfony\Component\Translation\Exception\InvalidArgumentException;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * TranslationWriter writes translation messages.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface TranslationWriterInterface
+{
+    /**
+     * Writes translation from the catalogue according to the selected format.
+     *
+     * @param string $format  The format to use to dump the messages
+     * @param array  $options Options that are passed to the dumper
+     *
+     * @throws InvalidArgumentException
+     */
+    public function write(MessageCatalogue $catalogue, string $format, array $options = []);
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/composer.json
new file mode 100644
index 0000000..de84e16
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/symfony/translation/composer.json
@@ -0,0 +1,60 @@
+{
+    "name": "symfony/translation",
+    "type": "library",
+    "description": "Provides tools to internationalize your application",
+    "keywords": [],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.2.5",
+        "symfony/deprecation-contracts": "^2.1",
+        "symfony/polyfill-mbstring": "~1.0",
+        "symfony/polyfill-php80": "^1.16",
+        "symfony/translation-contracts": "^2.3"
+    },
+    "require-dev": {
+        "symfony/config": "^4.4|^5.0",
+        "symfony/console": "^4.4|^5.0",
+        "symfony/dependency-injection": "^5.0",
+        "symfony/http-kernel": "^5.0",
+        "symfony/intl": "^4.4|^5.0",
+        "symfony/polyfill-intl-icu": "^1.21",
+        "symfony/service-contracts": "^1.1.2|^2",
+        "symfony/yaml": "^4.4|^5.0",
+        "symfony/finder": "^4.4|^5.0",
+        "psr/log": "^1|^2|^3"
+    },
+    "conflict": {
+        "symfony/config": "<4.4",
+        "symfony/dependency-injection": "<5.0",
+        "symfony/http-kernel": "<5.0",
+        "symfony/twig-bundle": "<5.0",
+        "symfony/yaml": "<4.4"
+    },
+    "provide": {
+        "symfony/translation-implementation": "2.3"
+    },
+    "suggest": {
+        "symfony/config": "",
+        "symfony/yaml": "",
+        "psr/log-implementation": "To use logging capability in translator"
+    },
+    "autoload": {
+        "files": [ "Resources/functions.php" ],
+        "psr-4": { "Symfony\\Component\\Translation\\": "" },
+        "exclude-from-classmap": [
+            "/Tests/"
+        ]
+    },
+    "minimum-stability": "dev"
+}