diff --git a/.gitignore b/.gitignore index 0fca4d1..449347d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ admin/storage/cache/ admin/storage/geoip/ admin/storage/stats.json +# Runtime-compiled theme assets +public/themes/ + # Temporary files *.tmp *.temp diff --git a/AGENTS.md b/AGENTS.md index 1e1ed16..8a1ed74 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ ## Build & Run - **Run Server**: `php -S localhost:8080 cms/router.php` (router nodig voor clean URLs) - **Lint PHP**: `find . -name "*.php" -not -path "./vendor/*" -exec php -l {} \;` -- **Dependencies**: Composer vereist voor CommonMark. Geen NPM. +- **Dependencies**: Composer vereist voor CommonMark, Twig en scssphp. Geen NPM. - **Admin Console**: Toegankelijk op `/admin.php` (standaard login: `admin` / `admin`) ## Project Structuur @@ -17,24 +17,29 @@ codepress/ │ ├── core/ │ │ ├── class/ │ │ │ ├── CodePressCMS.php # Hoofd CMS class +│ │ │ ├── ThemeManager.php # Thema-resolver + Twig render + SCSS compile │ │ │ ├── Logger.php # Logging systeem -│ │ │ └── SimpleTemplate.php # Mustache-style template engine +│ │ │ └── SimpleTemplate.php # Legacy Mustache-style engine (niet meer gebruikt) │ │ ├── plugin/ │ │ │ ├── PluginManager.php # Plugin loader │ │ │ └── CMSAPI.php # API voor plugins │ │ ├── config.php # Config loader (leest config.json) │ │ └── index.php # Bootstrap (autoloader, requires) │ ├── lang/ # Taalbestanden (nl.php, en.php) -│ ├── templates/ # Mustache templates -│ │ ├── layout.mustache # Hoofd layout (bevat inline CSS) -│ │ ├── assets/ -│ │ │ ├── header.mustache -│ │ │ ├── navigation.mustache -│ │ │ └── footer.mustache -│ │ ├── markdown_content.mustache -│ │ ├── php_content.mustache -│ │ └── html_content.mustache -│ └── router.php # PHP dev server router +│ └── router.php # PHP dev server router (serveert ook /themes/) +├── themes/ # Dynamische thema's (volledig zelfstandig) +│ ├── default/ # Standaard thema +│ │ ├── theme.json # { title, default_layout, layout→.twig mapping, kleuren } +│ │ ├── base.twig # Hoofd layout (head, header, nav, footer) +│ │ ├── full_content.twig # Layout: volledige breedte +│ │ ├── left_sidebar.twig # Layout: sidebar links +│ │ ├── right_sidebar.twig # Layout: sidebar rechts +│ │ ├── custom1.twig # Layout: custom +│ │ ├── partials/ # header.twig, navigation.twig, footer.twig +│ │ ├── css/theme.scss # SCSS bron (runtime gecompileerd) +│ │ └── js/theme.js # Thema JavaScript +│ ├── demo/ # Demo thema (zelfde structuur, andere look) +│ └── test/ # Test thema ├── admin/ # Admin paneel │ ├── config/ │ │ ├── app.php # Admin app configuratie @@ -53,6 +58,7 @@ codepress/ │ │ ├── config.php │ │ ├── plugins.php │ │ ├── plugin-config.php +│ │ ├── theme.php │ │ └── users.php │ └── storage/logs/ # Admin logs ├── cli/ # CLI scripts & tests @@ -86,7 +92,7 @@ codepress/ - Admin entry point + routing: `public/admin.php` - Admin authenticatie: `admin/src/AdminAuth.php` - **Content**: Stored in `content/`. Supports `.md` (Markdown), `.php` (Dynamic), `.html` (Static). -- **Templating**: Mustache-style `{{placeholder}}` in `templates/layout.mustache` via `SimpleTemplate.php`. +- **Templating**: Twig templates in `themes//`. `ThemeManager` rendert via Twig en compileert `css/theme.scss` runtime naar `public/themes//theme.css`. Layout gekozen via frontmatter `layout:` key; onbekende layouts vallen terug op `default_layout` in `theme.json`. - **Navigation**: Auto-generated from directory structure. Folders require an index file to be clickable in breadcrumbs. - **Security**: - Always use `htmlspecialchars()` for outputting user/content data @@ -115,5 +121,5 @@ codepress/ ## Bekende aandachtspunten - LSP errors over "Undefined function" in PHP files zijn vals-positief (standaard PHP functies worden niet herkend door de LSP). Negeer deze. - Zie `TODO.md` voor alle openstaande verbeteringen en nieuwe features. -- `vendor/` map bevat Composer dependencies (CommonMark, Mustache). Niet handmatig wijzigen. +- `vendor/` map bevat Composer dependencies (CommonMark, Twig, scssphp, Mustache). Niet handmatig wijzigen. - `admin/config/admin.json` bevat wachtwoord-hashes. Niet committen met echte productie-wachtwoorden. diff --git a/README.en.md b/README.en.md index 5bdd13f..40cecca 100644 --- a/README.en.md +++ b/README.en.md @@ -49,13 +49,20 @@ codepress/ │ │ ├── config.php # Configuration loader │ │ └── index.php # Bootstrap (autoloader) │ ├── lang/ # Language files (nl.php, en.php) -│ ├── templates/ # Mustache templates -│ │ ├── layout.mustache -│ │ ├── assets/ (header, navigation, footer) -│ │ ├── markdown_content.mustache -│ │ ├── php_content.mustache -│ │ └── html_content.mustache -│ └── router.php # PHP dev server router +│ └── router.php # PHP dev server router (also serves /themes/) +├── themes/ # Dynamic themes (fully self-contained) +│ ├── default/ # Default theme +│ │ ├── theme.json # { title, default_layout, layout→.twig mapping, colors } +│ │ ├── base.twig # Main layout +│ │ ├── full_content.twig # Layout: full width +│ │ ├── left_sidebar.twig # Layout: sidebar left +│ │ ├── right_sidebar.twig # Layout: sidebar right +│ │ ├── custom1.twig # Layout: custom +│ │ ├── partials/ # header, navigation, footer +│ │ ├── css/theme.scss # SCSS source (compiled at runtime) +│ │ └── js/theme.js # Theme JavaScript +│ ├── demo/ # Demo theme +│ └── test/ # Test theme ├── admin/ # Admin panel │ ├── config/ │ │ ├── app.php # Admin configuration @@ -96,7 +103,6 @@ codepress/ { "site_title": "CodePress", "content_dir": "content", - "templates_dir": "cms/templates", "default_page": "index", "active_theme": "default", "language": { diff --git a/README.md b/README.md index d8ce397..c2451ab 100644 --- a/README.md +++ b/README.md @@ -49,13 +49,20 @@ codepress/ │ │ ├── config.php # Config loader │ │ └── index.php # Bootstrap (autoloader) │ ├── lang/ # Taalbestanden (nl.php, en.php) -│ ├── templates/ # Mustache templates -│ │ ├── layout.mustache -│ │ ├── assets/ (header, navigation, footer) -│ │ ├── markdown_content.mustache -│ │ ├── php_content.mustache -│ │ └── html_content.mustache -│ └── router.php # PHP dev server router +│ └── router.php # PHP dev server router (serveert ook /themes/) +├── themes/ # Dynamische thema's (volledig zelfstandig) +│ ├── default/ # Standaard thema +│ │ ├── theme.json # { title, default_layout, layout→.twig mapping, kleuren } +│ │ ├── base.twig # Hoofd layout +│ │ ├── full_content.twig # Layout: volledige breedte +│ │ ├── left_sidebar.twig # Layout: sidebar links +│ │ ├── right_sidebar.twig # Layout: sidebar rechts +│ │ ├── custom1.twig # Layout: custom +│ │ ├── partials/ # header, navigation, footer +│ │ ├── css/theme.scss # SCSS bron (runtime gecompileerd) +│ │ └── js/theme.js # Thema JavaScript +│ ├── demo/ # Demo thema +│ └── test/ # Test thema ├── admin/ # Admin paneel │ ├── config/ │ │ ├── app.php # Admin configuratie @@ -96,7 +103,6 @@ codepress/ { "site_title": "CodePress", "content_dir": "content", - "templates_dir": "cms/templates", "default_page": "index", "active_theme": "default", "language": { diff --git a/admin/templates/layout.php b/admin/templates/layout.php index ce787fb..e4f112d 100644 --- a/admin/templates/layout.php +++ b/admin/templates/layout.php @@ -171,6 +171,11 @@ $layoutSidebarColor = $layoutThemeConfig['header_color'] ?? '#0a369d'; case 'theme': require __DIR__ . '/pages/theme.php'; break; + + case 'theme-new': + require __DIR__ . '/pages/theme-new.php'; + break; + case 'plugins': require __DIR__ . '/pages/plugins.php'; break; diff --git a/admin/templates/pages/config.php b/admin/templates/pages/config.php index 9ffa94d..68060e7 100644 --- a/admin/templates/pages/config.php +++ b/admin/templates/pages/config.php @@ -95,9 +95,9 @@ value="">
- - + +
@@ -140,6 +140,84 @@ +
+
+ Logging +
+
+ +
+ > + +
+ +
+
+ + +
Kies Syslog om logregels naar een externe syslog-server te sturen. Logregels worden altijd ook lokaal opgeslagen.
+
+
+ +
+
+ + +
Vul de host van de syslog-server in (bijv. 192.168.1.10 of logs.example.com).
+
+
+ + +
+
+ + +
Categorie van de logbron (bijv. local0local7 voor eigen applicaties).
+
+
+ +
+ + +
+ +
+ + +
+ 'Admin activiteiten', + 'requests' => 'Requests (pagina bezoeken)', + 'errors' => 'Fouten & waarschuwingen', + 'security' => 'Beveiliging', + 'content' => 'Content wijzigingen', + 'system' => 'Systeem', + ]; + foreach ($eventLabels as $key => $label): + ?> +
+
+ > + +
+
+ +
+
+
+
+ diff --git a/admin/templates/pages/content-edit.php b/admin/templates/pages/content-edit.php index c87540f..4c7542f 100644 --- a/admin/templates/pages/content-edit.php +++ b/admin/templates/pages/content-edit.php @@ -18,11 +18,17 @@
diff --git a/admin/templates/pages/content-new.php b/admin/templates/pages/content-new.php index ed20c6c..b93dfe7 100644 --- a/admin/templates/pages/content-new.php +++ b/admin/templates/pages/content-new.php @@ -28,11 +28,17 @@
diff --git a/admin/templates/pages/logs.php b/admin/templates/pages/logs.php index bac2c78..50c38ce 100644 --- a/admin/templates/pages/logs.php +++ b/admin/templates/pages/logs.php @@ -1,117 +1,79 @@

Logs

- - -
- -
-
- regels -
- Download - Wissen +
+
+
+
+ +
-
-
-
- -

Geen activiteiten geregistreerd.

- - - - - - - - - - - - - - - - - - - - -
TijdNiveauIPBericht
- +
+ +
-
+
+ + +
+
+ + +
+
+ + +
+
+
- -
-
- regels - -
-
-
- -

Geen requests geregistreerd.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TijdIPLandPaginaType / GebruikerStatusTaalUser agentReferrer
- - - - - - - - - - Geblokkeerd - - - - OK - - - 50 ? '…' : '' ?> 30 ? '…' : '' ?>
- -
-
+
+ regels +
+
+
+ +

Geen logregels gevonden.

+ + + + + + + + + + + + + + + + + + + + + + +
TijdGebeurtenisNiveauIPBericht
+
-
\ No newline at end of file +
diff --git a/admin/templates/pages/theme-new.php b/admin/templates/pages/theme-new.php new file mode 100644 index 0000000..3359b72 --- /dev/null +++ b/admin/templates/pages/theme-new.php @@ -0,0 +1,38 @@ +

Nieuw thema aanmaken

+ +
+ + +
+ +
+ + +
+ + +
Alleen letters, cijfers, streepjes en underscores. Begin met een letter. Wordt gebruikt als mapnaam.
+
+ +
+ Wat wordt er aangemaakt? +
    +
  • themes/ThemaNaam/theme.json — Configuratie (default template + template mapping)
  • +
  • themes/ThemaNaam/base.twig — Hoofd layout
  • +
  • themes/ThemaNaam/*.twig — Layout-sjablonen
  • +
  • themes/ThemaNaam/partials/ — header, navigation, footer
  • +
  • themes/ThemaNaam/css/theme.scss — Styling (kleuren, hoogtes, achtergrond)
  • +
  • themes/ThemaNaam/js/theme.js — Thema JavaScript
  • +
  • themes/ThemaNaam/theme.png — Voorbeeldafbeelding
  • +
+

Het nieuwe thema wordt gekopieerd van het standaard thema. Pas daarna de SCSS-kleuren en sjablonen aan naar wens.

+
+
+ + +
diff --git a/admin/templates/pages/theme.php b/admin/templates/pages/theme.php index dd434fc..710f3c3 100644 --- a/admin/templates/pages/theme.php +++ b/admin/templates/pages/theme.php @@ -1,283 +1,104 @@ - +
+

Thema's

+ + Nieuwe thema + +
- -
-

Bewerk thema:

- - Terug - -
- -
-
-
- - - - -
-
- - +
+
+
Thema-ontwikkelaarshandleiding
+

Een thema is een volledig zelfstandige map en moet aan de volgende eisen voldoen:

+
+
+
+ +
+ Mapstructuur
+ themes/Naam/theme.json + Elke thema-map moet een theme.json bevatten.
- -
-
-
-
Header
-
-
- -
- - -
-
-
- -
- - -
-
-
-
-
-
-
-
Navigatie
-
-
- -
- - -
-
-
- -
- - -
-
-
-
-
-
-
-
Sidebar
-
-
- -
- - -
-
-
- -
- - -
-
-
-
+
+
+
+ +
+ Sjablonen (Twig)
+ base.twig + *.twig + Layout-sjablonen die via config.default_template en template worden gekozen.
- -
-
-
-
Hoogte balken
-
-
- - -
-
- - -
-
-
-
-
-
-
Header achtergrond afbeelding
-
-
- - - Toegestaan: JPG, PNG, GIF, WebP, SVG -
-
- -
- -
- -
-
- Huidig: - -
-
- - -
-
- -
-
- -
- - % -
- 100% = volledig zichtbaar, 50% = half doorzichtig, 0% = onzichtbaar -
-
-
+
+
+
+ +
+ Styling & voorbeeld
+ css/theme.scss + theme.png + Kleuren/hoogtes in SCSS, een theme.png voorbeeld voor de selectie.
- -
- - Annuleren -
- -
-
- - - - -
-

Thema's

- -
- -
-
-
-
- - -
- - -
-
- -
-
+
$themeData): ?> +
-
-
-
-
- - Actief - +
+
+
+ + Voorbeeld thema <?= htmlspecialchars($themeData['title'] ?? $themeData['name'] ?? $themeName) ?>
- - -
-
- Header: - - -
-
- Navigatie: - - -
-
- Sidebar: - - -
-
- - -
-
- Header: px · Navigatie: px -
- -
- Achtergrond: % zichtbaar - - - -
- -
- -
- - Bewerken - - -
- - - - -
- +
+ +
+ + Actief + +
+ +
- - - + diff --git a/cms/core/class/CodePressCMS.php b/cms/core/class/CodePressCMS.php index 390656c..25b3a46 100644 --- a/cms/core/class/CodePressCMS.php +++ b/cms/core/class/CodePressCMS.php @@ -591,7 +591,7 @@ class CodePressCMS { } } - $authorWebsite = $this->config['author']['website'] ?? ''; + $authorWebsite = $this->normalizeUrl($this->config['author']['website'] ?? ''); if ($authorWebsite !== '') { $authorHost = parse_url($authorWebsite, PHP_URL_HOST); if ($authorHost) { @@ -602,6 +602,25 @@ class CodePressCMS { return array_values(array_unique(array_filter($hosts))); } + /** + * Normalize a URL: if no scheme is present, prepend https://. + * Handles hostnames stored without protocol (e.g. "noorlander.info"). + * + * @param string $url Raw URL or hostname + * @return string Normalized absolute URL, or '' if empty + */ + private function normalizeUrl(string $url): string + { + $url = trim($url); + if ($url === '') { + return ''; + } + if (!preg_match('#^[a-zA-Z][a-zA-Z0-9+.\-]*://#', $url)) { + return 'https://' . $url; + } + return $url; + } + /** * Parse Markdown content to HTML using League CommonMark * @@ -1140,7 +1159,7 @@ class CodePressCMS { 'is_guide_page' => isset($_GET['guide']), 'lang_switch_url' => '', 'author_name' => $this->config['author']['name'] ?? 'CodePress Developer', - 'author_website' => $this->config['author']['website'] ?? '#', + 'author_website' => $this->normalizeUrl($this->config['author']['website'] ?? '') ?: '#', 'author_git' => 'https://git.noorlander.info/E.Noorlander', 'seo_description' => $this->config['seo']['description'] ?? 'CodePress CMS - Lightweight file-based content management system', 'seo_keywords' => $this->config['seo']['keywords'] ?? 'cms, php, content management, file-based', @@ -1156,8 +1175,6 @@ class CodePressCMS { 'nav_height' => $this->config['theme']['nav_height'] ?? '42', 'sidebar_background' => $this->config['theme']['sidebar_background'] ?? '#f8f9fa', 'sidebar_border' => $this->config['theme']['sidebar_border'] ?? '#dee2e6', - 'background_image_css' => $this->getBackgroundImageCss(), - 'background_image_opacity' => $this->getBackgroundImageOpacity(), // Language 'current_lang' => $this->currentLanguage, 'current_lang_upper' => strtoupper($this->currentLanguage), @@ -1216,36 +1233,21 @@ class CodePressCMS { // Don't show site title link on guide page $templateData['show_site_link'] = !$this->isContentDirEmpty() && !isset($_GET['guide']); - // Load and render all templates with data - $layoutTemplate = file_get_contents($this->config['templates_dir'] . '/layout.mustache'); - $headerTemplate = file_get_contents($this->config['templates_dir'] . '/assets/header.mustache'); - $navigationTemplate = file_get_contents($this->config['templates_dir'] . '/assets/navigation.mustache'); - $footerTemplate = file_get_contents($this->config['templates_dir'] . '/assets/footer.mustache'); - - // Determine content type and load appropriate template - $contentType = $this->getContentType($page); - $contentTemplateFile = $this->config['templates_dir'] . '/' . $contentType . '_content.mustache'; - $contentTemplate = file_exists($contentTemplateFile) ? file_get_contents($contentTemplateFile) : '
{{{content}}}
'; - + // Map legacy frontmatter layout values to theme template keys + $layoutKey = $this->mapLayoutToThemeKey($layout); + + // Add theme asset URLs to template data + $themeManager = new ThemeManager($this->config); + $templateData['theme_title'] = $themeManager->getTitle(); + $templateData['theme_css_url'] = $themeManager->getCssUrl(); + $templateData['theme_js_url'] = $themeManager->getJsUrl(); + $templateData['theme_config'] = $themeManager->getConfig(); + + // Render the page through the active theme + $renderedLayout = $themeManager->render($layoutKey, $templateData); - - // Render all templates with data - $renderedHeader = SimpleTemplate::render($headerTemplate, $templateData); - $renderedNavigation = SimpleTemplate::render($navigationTemplate, $templateData); - $renderedFooter = SimpleTemplate::render($footerTemplate, $templateData); - $renderedContent = SimpleTemplate::render($contentTemplate, $templateData); - - // Replace partials in layout - $finalTemplate = str_replace('{{>header}}', $renderedHeader, $layoutTemplate); - $finalTemplate = str_replace('{{>navigation}}', $renderedNavigation, $finalTemplate); - $finalTemplate = str_replace('{{>footer}}', $renderedFooter, $finalTemplate); - $finalTemplate = str_replace('{{>content_template}}', $renderedContent, $finalTemplate); - - // Render the final layout with all template data - $renderedLayout = SimpleTemplate::render($finalTemplate, $templateData); - echo $renderedLayout; - + $this->pluginManager->doAction('onAfterRender', $renderedLayout); } @@ -1371,6 +1373,25 @@ class CodePressCMS { return $html; } + /** + * Map a frontmatter layout value to a theme template key. + * + * Legacy values are translated to the new theme keys. Unknown values + * are passed through so ThemeManager can fall back to default_layout. + * + * @param string $layout Layout value from page metadata + * @return string Theme template key + */ + private function mapLayoutToThemeKey(string $layout): string { + return match ($layout) { + 'content' => 'full_content', + 'sidebar-content', 'content-sidebar' => 'left_sidebar', + 'content-sidebar-reverse' => 'right_sidebar', + 'sidebar' => 'custom1', + default => $layout, + }; + } + /** * Determine content type for current page * @@ -1540,24 +1561,6 @@ class CodePressCMS { return false; } - private function getBackgroundImageCss(): string - { - $bg = $this->config['theme']['background_image'] ?? ''; - if (empty($bg)) { - return 'none'; - } - if (str_starts_with($bg, 'http')) { - return 'url(' . $bg . ')'; - } - return 'url(/themes/' . $bg . ')'; - } - - private function getBackgroundImageOpacity(): int - { - $opacity = intval($this->config['theme']['background_image_opacity'] ?? 100); - return max(0, min(100, $opacity)); - } - private function processContent(string $content): string { return str_replace('-/assets/', '/-assets/', $content); diff --git a/cms/core/class/LogManager.php b/cms/core/class/LogManager.php new file mode 100644 index 0000000..5009e71 --- /dev/null +++ b/cms/core/class/LogManager.php @@ -0,0 +1,365 @@ + date('Y-m-d H:i:s'), + 'event' => $event, + 'level' => $level, + 'message' => $message, + 'ip' => $context['ip'] ?? (class_exists('RequestLogger') ? RequestLogger::getClientIp() : ''), + 'context' => $context, + ]; + + $driver = self::getDriver(); + + // Always store locally (sqlite or file fallback) so the dynamic log + // in the admin always has entries. + if ($driver === 'sqlite') { + self::writeSqlite($entry); + } else { + self::writeFile($entry); + } + + // Additionally forward to a remote syslog server if one is configured. + $syslogHost = trim(self::$config['syslog_host'] ?? ''); + if ($syslogHost !== '') { + self::writeSyslog($entry); + } + } + + /** + * Send a log entry to a remote syslog server over UDP. + */ + private static function writeSyslog(array $entry): void + { + $host = trim(self::$config['syslog_host'] ?? ''); + $port = (int)(self::$config['syslog_port'] ?? 514); + $facility = self::syslogFacility(self::$config['syslog_facility'] ?? 'local0'); + $ident = self::$config['syslog_ident'] ?? 'codepress'; + + $severity = self::syslogSeverity($entry['level']); + $pri = ($facility * 8) + $severity; + + $msg = '<' . $pri . '>' . date('M d H:i:s') . ' ' . $ident . '[' . getmypid() . ']: ' + . '[' . $entry['event'] . '] [' . $entry['level'] . '] ' . $entry['message']; + + $sock = @fsockopen('udp://' . $host, $port, $errno, $errstr, 2); + if ($sock) { + @fwrite($sock, $msg . "\n"); + @fclose($sock); + } + } + + /** + * Store a log entry in the SQLite database. + */ + private static function writeSqlite(array $entry): void + { + $pdo = self::getPdo(); + if ($pdo === null) { + // SQLite failed -> fall back to file + self::writeFile($entry); + return; + } + + try { + $stmt = $pdo->prepare( + 'INSERT INTO logs (time, event, level, message, ip, context) VALUES (:time, :event, :level, :message, :ip, :context)' + ); + $stmt->execute([ + ':time' => $entry['time'], + ':event' => $entry['event'], + ':level' => $entry['level'], + ':message' => $entry['message'], + ':ip' => $entry['ip'], + ':context' => json_encode($entry['context']), + ]); + } catch (\Throwable $e) { + self::writeFile($entry); + } + } + + /** + * Append a log entry to a plain text file (fallback driver). + */ + private static function writeFile(array $entry): void + { + $dir = dirname(self::$dbPath); + if (!is_dir($dir)) { + @mkdir($dir, 0755, true); + } + $file = $dir . '/codepress.log'; + $line = '[' . $entry['time'] . '] [' . $entry['event'] . '] [' . $entry['level'] . '] [' + . $entry['ip'] . '] ' . $entry['message'] . "\n"; + @file_put_contents($file, $line, FILE_APPEND | LOCK_EX); + } + + /** + * Get (and lazily create) the PDO connection to the SQLite database. + */ + private static function getPdo(): ?\PDO + { + if (self::$pdo !== null) { + return self::$pdo; + } + if (!self::sqliteAvailable()) { + return null; + } + + $dir = dirname(self::$dbPath); + if (!is_dir($dir)) { + @mkdir($dir, 0755, true); + } + + try { + self::$pdo = new \PDO('sqlite:' . self::$dbPath); + self::$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + self::$pdo->exec( + 'CREATE TABLE IF NOT EXISTS logs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + time TEXT NOT NULL, + event TEXT NOT NULL, + level TEXT NOT NULL, + message TEXT NOT NULL, + ip TEXT, + context TEXT + )' + ); + self::$pdo->exec('CREATE INDEX IF NOT EXISTS idx_logs_event ON logs (event)'); + self::$pdo->exec('CREATE INDEX IF NOT EXISTS idx_logs_time ON logs (time)'); + return self::$pdo; + } catch (\Throwable $e) { + self::$pdo = null; + return null; + } + } + + /** + * Whether the SQLite PDO driver is available. + */ + private static function sqliteAvailable(): bool + { + return class_exists('PDO') && in_array('sqlite', \PDO::getAvailableDrivers(), true); + } + + /** + * Map a facility name to its syslog numeric value. + */ + private static function syslogFacility(string $facility): int + { + $map = [ + 'kern' => 0, 'user' => 1, 'mail' => 2, 'daemon' => 3, + 'auth' => 4, 'syslog' => 5, 'lpr' => 6, 'news' => 7, + 'uucp' => 8, 'cron' => 9, 'authpriv' => 10, 'ftp' => 11, + 'local0' => 16, 'local1' => 17, 'local2' => 18, 'local3' => 19, + 'local4' => 20, 'local5' => 21, 'local6' => 22, 'local7' => 23, + ]; + return $map[$facility] ?? 16; + } + + /** + * Map a log level to its syslog severity value. + */ + private static function syslogSeverity(string $level): int + { + $map = [ + 'debug' => 7, + 'info' => 6, + 'notice' => 5, + 'warning' => 4, + 'error' => 3, + 'critical' => 2, + 'alert' => 1, + 'emergency' => 0, + ]; + return $map[strtolower($level)] ?? 6; + } + + /** + * Query recent log entries from the active store. + * + * @param int $limit Number of entries to return + * @param string|null $event Optional event filter + * @param string|null $level Optional level filter (info, warning, error, ...) + * @param string|null $search Optional text search on the message + * @return array List of log entries (newest first) + */ + public static function getLogs(int $limit = 200, ?string $event = null, ?string $level = null, ?string $search = null): array + { + $driver = self::getDriver(); + + if ($driver === 'sqlite') { + $pdo = self::getPdo(); + if ($pdo !== null) { + try { + $sql = 'SELECT time, event, level, message, ip FROM logs'; + $conds = []; + $params = []; + if ($event !== null && $event !== '') { + $conds[] = 'event = :event'; + $params[':event'] = $event; + } + if ($level !== null && $level !== '') { + $conds[] = 'level = :level'; + $params[':level'] = $level; + } + if ($search !== null && $search !== '') { + $conds[] = 'message LIKE :search'; + $params[':search'] = '%' . $search . '%'; + } + if (!empty($conds)) { + $sql .= ' WHERE ' . implode(' AND ', $conds); + } + $sql .= ' ORDER BY id DESC LIMIT ' . (int)$limit; + $stmt = $pdo->prepare($sql); + $stmt->execute($params); + return $stmt->fetchAll(\PDO::FETCH_ASSOC); + } catch (\Throwable $e) { + return []; + } + } + } + + // File fallback + $dir = dirname(self::$dbPath); + $file = $dir . '/codepress.log'; + if (!file_exists($file)) { + return []; + } + $lines = file($file); + $lines = array_slice($lines, -$limit); + $logs = []; + foreach ($lines as $line) { + if (preg_match('/^\[([^\]]+)\] \[([^\]]+)\] \[([^\]]+)\] \[([^\]]+)\] (.+)$/', trim($line), $m)) { + if ($event !== null && $event !== '' && $m[2] !== $event) { + continue; + } + if ($level !== null && $level !== '' && $m[3] !== $level) { + continue; + } + if ($search !== null && $search !== '' && stripos($m[5], $search) === false) { + continue; + } + $logs[] = [ + 'time' => $m[1], + 'event' => $m[2], + 'level' => $m[3], + 'ip' => $m[4], + 'message' => $m[5], + ]; + } + } + return array_reverse($logs); + } + + /** + * Clear all stored log entries. + */ + public static function clear(): void + { + $driver = self::getDriver(); + if ($driver === 'sqlite') { + $pdo = self::getPdo(); + if ($pdo !== null) { + try { + $pdo->exec('DELETE FROM logs'); + return; + } catch (\Throwable $e) { + // fall through to file + } + } + } + $dir = dirname(self::$dbPath); + $file = $dir . '/codepress.log'; + if (file_exists($file)) { + @file_put_contents($file, ''); + } + } +} diff --git a/cms/core/class/Logger.php b/cms/core/class/Logger.php index d4592e3..69ddf7a 100644 --- a/cms/core/class/Logger.php +++ b/cms/core/class/Logger.php @@ -98,6 +98,14 @@ class Logger { // Write to file with error suppression (graceful degradation) @file_put_contents(self::$logFile, $line, FILE_APPEND | LOCK_EX); + + // Route through the dynamic log manager (errors/system events) + if (class_exists('LogManager')) { + $event = ($level === self::ERROR || $level === self::WARNING) + ? LogManager::EVENT_ERRORS + : LogManager::EVENT_SYSTEM; + LogManager::log($event, strtolower($level), $message, $context); + } } /** diff --git a/cms/core/class/RequestLogger.php b/cms/core/class/RequestLogger.php index 3c8b635..edb0f80 100644 --- a/cms/core/class/RequestLogger.php +++ b/cms/core/class/RequestLogger.php @@ -44,6 +44,79 @@ class RequestLogger return $ip; } + /** + * Check whether an IP matches any entry in a list of IPs/CIDR ranges. + * + * Supports exact IPv4/IPv6 addresses and CIDR notation (e.g. 192.168.0.0/16). + * + * @param string $ip The client IP to test + * @param array $list List of IPs and/or CIDR ranges + * @return bool True if the IP matches any entry + */ + public static function ipMatchesList(string $ip, array $list): bool + { + $ip = trim($ip); + if ($ip === '') { + return false; + } + $isV6 = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false; + $packed = $isV6 ? inet_pton($ip) : inet_pton($ip); + + foreach ($list as $entry) { + $entry = trim((string)$entry); + if ($entry === '') { + continue; + } + + // Exact match + if ($entry === $ip) { + return true; + } + + // CIDR notation + if (strpos($entry, '/') !== false) { + [$subnet, $bits] = array_pad(explode('/', $entry, 2), 2, null); + $subnet = trim($subnet); + $subnetPacked = inet_pton($subnet); + if ($subnetPacked === false || $packed === false) { + continue; + } + // Ensure both are the same address family + if (strlen($subnetPacked) !== strlen($packed)) { + continue; + } + $maxBits = strlen($packed) * 8; + $bits = (int)$bits; + if ($bits < 0 || $bits > $maxBits) { + continue; + } + if ($bits === 0) { + return true; + } + $fullBytes = intdiv($bits, 8); + $remainingBits = $bits % 8; + $match = true; + for ($i = 0; $i < $fullBytes; $i++) { + if ($subnetPacked[$i] !== $packed[$i]) { + $match = false; + break; + } + } + if ($match && $remainingBits > 0) { + $mask = 0xFF << (8 - $remainingBits); + if ((ord($subnetPacked[$fullBytes]) & $mask) !== (ord($packed[$fullBytes]) & $mask)) { + $match = false; + } + } + if ($match) { + return true; + } + } + } + + return false; + } + public static function getClientIp(): string { $headerKeys = [ diff --git a/cms/core/class/ThemeManager.php b/cms/core/class/ThemeManager.php new file mode 100644 index 0000000..6d0c852 --- /dev/null +++ b/cms/core/class/ThemeManager.php @@ -0,0 +1,203 @@ +config = $config; + $this->themeDir = $config['theme_dir'] ?? (__DIR__ . '/../../../themes/' . ($config['active_theme'] ?? 'default')); + $this->themeConfig = $config['theme'] ?? []; + $this->compiledCssDir = __DIR__ . '/../../../public/themes'; + + $loader = new FilesystemLoader($this->themeDir); + $this->twig = new Environment($loader, [ + 'cache' => false, + 'autoescape' => false, + ]); + } + + /** + * Get the absolute path of the active theme directory + */ + public function getThemeDir(): string { + return $this->themeDir; + } + + /** + * Get the raw theme.json config array + */ + public function getThemeConfig(): array { + return $this->themeConfig; + } + + /** + * Get the theme title (from theme.json 'title' or 'name') + */ + public function getTitle(): string { + return $this->themeConfig['title'] ?? $this->themeConfig['name'] ?? basename($this->themeDir); + } + + /** + * Get the theme config section (default_template, background settings, etc.) + */ + public function getConfig(): array { + return $this->themeConfig['config'] ?? []; + } + + /** + * Get the theme template section (layout key => .twig file mapping) + */ + public function getTemplates(): array { + return $this->themeConfig['template'] ?? []; + } + + /** + * Resolve the .twig template file for a requested layout. + * + * Templates are defined in theme.json under the "template" section: + * { "template": { "full_content": "full_content.twig", ... } } + * The default template is defined in the "config" section: + * { "config": { "default_template": "full_content", ... } } + * + * Priority: + * 1. If the layout is a known key in the "template" section, use its mapped file. + * 2. Otherwise fall back to config.default_template. + * 3. Final safety net: full_content.twig. + * + * @param string $layout Requested layout key (e.g. 'left_sidebar') + * @return string Template name usable by the Twig loader + */ + public function getTemplateForLayout(string $layout): string { + $layout = trim($layout); + $templates = $this->getTemplates(); + + if ($layout !== '' && isset($templates[$layout])) { + $file = $templates[$layout]; + if ($this->templateExists($file)) { + return $file; + } + } + + $config = $this->getConfig(); + $default = $config['default_template'] ?? 'full_content'; + if (isset($templates[$default])) { + $file = $templates[$default]; + if ($this->templateExists($file)) { + return $file; + } + } + + return 'full_content.twig'; + } + + /** + * Get the list of available layout keys defined in the "template" section. + * + * @return array List of layout keys + */ + public function getLayouts(): array { + return array_keys($this->getTemplates()); + } + + /** + * Check whether a template file exists in the theme directory + */ + private function templateExists(string $file): bool { + $path = $this->themeDir . '/' . ltrim($file, '/'); + return is_file($path); + } + + /** + * Render a layout template with the given data. + * + * @param string $layout Requested layout key + * @param array $data Template variables + * @return string Rendered HTML + */ + public function render(string $layout, array $data): string { + $template = $this->getTemplateForLayout($layout); + return $this->twig->render($template, $data); + } + + /** + * Compile the theme's SCSS to CSS (cached by source mtime). + * + * @return string|null Absolute path to the compiled CSS, or null if none + */ + public function compileCss(): ?string { + $scssFile = $this->themeDir . '/css/theme.scss'; + if (!is_file($scssFile)) { + return null; + } + + $themeName = basename($this->themeDir); + $outDir = $this->compiledCssDir . '/' . $themeName; + $outFile = $outDir . '/theme.css'; + $cacheFile = $outDir . '/.mtime'; + + $mtime = filemtime($scssFile); + if (is_file($outFile) && is_file($cacheFile) && (int)file_get_contents($cacheFile) === $mtime) { + return $outFile; + } + + if (!is_dir($outDir)) { + mkdir($outDir, 0755, true); + } + + try { + $compiler = new Compiler(); + $compiler->setImportPaths($this->themeDir . '/css'); + $css = $compiler->compileString(file_get_contents($scssFile))->getCss(); + file_put_contents($outFile, $css); + file_put_contents($cacheFile, (string)$mtime); + return $outFile; + } catch (\Throwable $e) { + error_log('ThemeManager SCSS compile error: ' . $e->getMessage()); + return null; + } + } + + /** + * Get the public URL for the compiled theme CSS, or null if unavailable. + */ + public function getCssUrl(): ?string { + $compiled = $this->compileCss(); + if ($compiled === null) { + return null; + } + return '/themes/' . basename($this->themeDir) . '/theme.css'; + } + + /** + * Get the public URL for the theme JS, or null if unavailable. + */ + public function getJsUrl(): ?string { + $jsFile = $this->themeDir . '/js/theme.js'; + if (!is_file($jsFile)) { + return null; + } + return '/themes/' . basename($this->themeDir) . '/js/theme.js'; + } +} diff --git a/cms/core/config.php b/cms/core/config.php index 8440fc0..6b89eea 100644 --- a/cms/core/config.php +++ b/cms/core/config.php @@ -12,7 +12,6 @@ if (!file_exists($configJsonPath)) { $defaultConfig = [ 'site_title' => 'CodePress', 'content_dir' => 'content', - 'templates_dir' => 'cms/templates', 'active_theme' => 'default', 'default_page' => 'auto', 'language' => [ @@ -25,7 +24,7 @@ if (!file_exists($configJsonPath)) { ], 'author' => [ 'name' => 'E. Noorlander', - 'website' => 'https://noorlander.info' + 'website' => 'noorlander.info' ], 'show_version' => true, 'enabled_plugins' => ['MQTTTracker', 'HTMLBlock'], @@ -54,7 +53,29 @@ if (!file_exists($configJsonPath)) { 'geoip_api_url' => '', 'geoip_api_key' => '', 'retention_days' => 400, - 'excluded_ips' => [] + 'excluded_ips' => [ + '192.168.0.0/16', + '10.0.0.0/8', + '172.16.0.0/12', + '127.0.0.1', + '::1' + ] + ], + 'logging' => [ + 'enabled' => true, + 'driver' => 'sqlite', + 'syslog_host' => '', + 'syslog_port' => 514, + 'syslog_facility' => 'local0', + 'syslog_ident' => 'codepress', + 'events' => [ + 'admin' => true, + 'requests' => true, + 'errors' => true, + 'security' => true, + 'content' => true, + 'system' => true + ] ] ]; @file_put_contents($configJsonPath, json_encode($defaultConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); @@ -88,25 +109,50 @@ if (file_exists($configJsonPath)) { 'geoip_api_url' => '', 'geoip_api_key' => '', 'retention_days' => 400, - 'excluded_ips' => [], + 'excluded_ips' => [ + '192.168.0.0/16', + '10.0.0.0/8', + '172.16.0.0/12', + '127.0.0.1', + '::1' + ], + ], + 'logging' => [ + 'enabled' => true, + 'driver' => 'sqlite', + 'syslog_host' => '', + 'syslog_port' => 514, + 'syslog_facility' => 'local0', + 'syslog_ident' => 'codepress', + 'events' => [ + 'admin' => true, + 'requests' => true, + 'errors' => true, + 'security' => true, + 'content' => true, + 'system' => true + ], ], ]; foreach ($sectionDefaults as $section => $defaults) { $config[$section] = array_merge($defaults, is_array($config[$section] ?? null) ? $config[$section] : []); } + // Ensure the private/loopback IP defaults are present when the list is empty + if (empty($config['analytics']['excluded_ips'])) { + $config['analytics']['excluded_ips'] = $sectionDefaults['analytics']['excluded_ips']; + } + // Convert relative paths to absolute $projectRoot = __DIR__ . '/../../'; if (isset($config['content_dir']) && strpos($config['content_dir'], '/') !== 0) { $config['content_dir'] = $projectRoot . $config['content_dir']; } - if (isset($config['templates_dir']) && strpos($config['templates_dir'], '/') !== 0) { - $config['templates_dir'] = $projectRoot . $config['templates_dir']; - } // Load active theme $activeTheme = $config['active_theme'] ?? 'default'; $themeDir = __DIR__ . '/../../themes/' . $activeTheme; + $config['theme_dir'] = $themeDir; $themeFile = $themeDir . '/theme.json'; if (file_exists($themeFile)) { $themeConfig = json_decode(file_get_contents($themeFile), true); @@ -123,6 +169,5 @@ if (file_exists($configJsonPath)) { return [ 'site_title' => 'CodePress', 'content_dir' => __DIR__ . '/../../content', - 'templates_dir' => __DIR__ . '/../templates', 'default_page' => 'auto' ]; \ No newline at end of file diff --git a/cms/core/index.php b/cms/core/index.php index 128ccaf..d3b305d 100644 --- a/cms/core/index.php +++ b/cms/core/index.php @@ -40,9 +40,11 @@ require_once 'class/RequestLogger.php'; require_once 'class/GeoIP.php'; require_once 'class/Analytics.php'; require_once 'class/SimpleTemplate.php'; +require_once 'class/ThemeManager.php'; // Load Logger class - structured logging with log levels require_once 'class/Logger.php'; +require_once 'class/LogManager.php'; // Load Plugin system require_once 'plugin/CMSAPI.php'; diff --git a/cms/router.php b/cms/router.php index ace1ce4..ce9de12 100644 --- a/cms/router.php +++ b/cms/router.php @@ -30,6 +30,26 @@ if (is_file($filePath)) { return true; } +// Serve theme assets from the themes/ directory (e.g. /themes/default/js/theme.js) +if (preg_match('#^/themes/([^/]+)/(.+)$#', $path, $m)) { + $themeName = $m[1]; + $themeRel = $m[2]; + $themesDir = __DIR__ . '/../themes'; + $themeFile = $themesDir . '/' . $themeName . '/' . $themeRel; + $realThemes = realpath($themesDir); + $realFile = realpath($themeFile); + if ($realFile && $realThemes && strpos($realFile, $realThemes) === 0 && is_file($realFile)) { + $ext = strtolower(pathinfo($realFile, PATHINFO_EXTENSION)); + if (isset($mimeTypes[$ext])) { + header('Content-Type: ' . $mimeTypes[$ext]); + } + readfile($realFile); + return true; + } + http_response_code(404); + return true; +} + // Admin routes: /admin/login → admin.php?route=login if (preg_match('#^/admin(?:/(.+))?$#', $path, $m)) { $_GET['route'] = $m[1] ?? 'dashboard'; diff --git a/cms/templates/html_content.mustache b/cms/templates/html_content.mustache deleted file mode 100644 index ca92073..0000000 --- a/cms/templates/html_content.mustache +++ /dev/null @@ -1,5 +0,0 @@ -
-
- {{{content}}} -
-
\ No newline at end of file diff --git a/cms/templates/layout.mustache b/cms/templates/layout.mustache deleted file mode 100644 index 0ea2fb2..0000000 --- a/cms/templates/layout.mustache +++ /dev/null @@ -1,552 +0,0 @@ - - - - - - {{page_title}} - {{site_title}} - - - - - - - - - - - - - - - {{#block_ai_bots}} - - - {{/block_ai_bots}} - {{#block_search_engines}} - - {{/block_search_engines}} - - - - - - - - - - - - - - - - - - - - - - - - {{>header}} - - - - - -
- {{#sidebar_content}} - {{#equal layout "sidebar-content"}} -
- -
-
- {{>content_template}} -
-
-
- {{/equal}} - - {{#equal layout "content"}} -
-
-
- {{>content_template}} -
-
-
- {{/equal}} - - {{#equal layout "sidebar"}} -
- -
- {{/equal}} - - {{#equal layout "content-sidebar"}} -
-
-
- {{>content_template}} -
-
- -
- {{/equal}} - - {{#equal layout "content-sidebar-reverse"}} -
-
-
- {{>content_template}} -
-
- -
- {{/equal}} - {{/sidebar_content}} - {{^sidebar_content}} -
-
-
- {{>content_template}} -
-
-
- {{/sidebar_content}} -
- -
- {{>footer}} -
- - - - - \ No newline at end of file diff --git a/cms/templates/markdown_content.mustache b/cms/templates/markdown_content.mustache deleted file mode 100644 index d51360e..0000000 --- a/cms/templates/markdown_content.mustache +++ /dev/null @@ -1,5 +0,0 @@ -
-
- {{{content}}} -
-
\ No newline at end of file diff --git a/cms/templates/php_content.mustache b/cms/templates/php_content.mustache deleted file mode 100644 index b7dc2dc..0000000 --- a/cms/templates/php_content.mustache +++ /dev/null @@ -1,5 +0,0 @@ -
-
- {{{content}}} -
-
\ No newline at end of file diff --git a/composer.json b/composer.json index 4ebc5c9..7d5f02b 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,8 @@ "mustache/mustache": "^3.0", "league/commonmark": "^2.7", "php-mqtt/client": "^2.0", - "geoip2/geoip2": "^2.13" + "geoip2/geoip2": "^2.13", + "twig/twig": "^3.28", + "scssphp/scssphp": "^2.1" } } diff --git a/composer.lock b/composer.lock index d098c64..abb80ae 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,80 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ca2f778e274e1087d5066837f53bcd23", + "content-hash": "6e4a8489683f5f6b5dc744684ad52fdf", "packages": [ + { + "name": "composer/ca-bundle", + "version": "1.5.13", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "c008272789979f709f7fcb32c2ecf1d2db5e84e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/c008272789979f709f7fcb32c2ecf1d2db5e84e5", + "reference": "c008272789979f709f7fcb32c2ecf1d2db5e84e5", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.5.13" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2026-07-18T12:35:13+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -81,6 +153,64 @@ }, "time": "2024-07-08T12:26:09+00:00" }, + { + "name": "geoip2/geoip2", + "version": "v2.13.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/GeoIP2-php.git", + "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/6a41d8fbd6b90052bc34dff3b4252d0f88067b23", + "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23", + "shasum": "" + }, + "require": { + "ext-json": "*", + "maxmind-db/reader": "~1.8", + "maxmind/web-service-common": "~0.8", + "php": ">=7.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "3.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "GeoIp2\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind GeoIP2 PHP API", + "homepage": "https://github.com/maxmind/GeoIP2-php", + "keywords": [ + "IP", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "support": { + "issues": "https://github.com/maxmind/GeoIP2-php/issues", + "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.13.0" + }, + "time": "2022-08-05T20:32:58+00:00" + }, { "name": "league/commonmark", "version": "2.8.0", @@ -270,6 +400,303 @@ ], "time": "2022-12-11T20:36:23+00:00" }, + { + "name": "league/uri", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.8.1", + "php": "^8.1", + "psr/http-factory": "^1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "URN", + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc2141", + "rfc3986", + "rfc3987", + "rfc6570", + "rfc8141", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-15T20:22:25+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.8.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-08T20:05:35+00:00" + }, + { + "name": "maxmind-db/reader", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", + "reference": "2194f58d0f024ce923e685cdf92af3daf9951908" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/2194f58d0f024ce923e685cdf92af3daf9951908", + "reference": "2194f58d0f024ce923e685cdf92af3daf9951908", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "ext-maxminddb": "<1.11.1 || >=2.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": ">=8.0.0,<10.0.0", + "squizlabs/php_codesniffer": "4.*" + }, + "suggest": { + "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups", + "maxmind-db/reader-ext": "C extension for significantly faster IP lookups (install via PIE: pie install maxmind-db/reader-ext)" + }, + "type": "library", + "autoload": { + "psr-4": { + "MaxMind\\Db\\": "src/MaxMind/Db" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind DB Reader API", + "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", + "keywords": [ + "database", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "support": { + "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", + "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.13.1" + }, + "time": "2025-11-21T22:24:26+00:00" + }, + { + "name": "maxmind/web-service-common", + "version": "v0.11.1", + "source": { + "type": "git", + "url": "https://github.com/maxmind/web-service-common-php.git", + "reference": "c309236b5a5555b96cf560089ec3cead12d845d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/c309236b5a5555b96cf560089ec3cead12d845d2", + "reference": "c309236b5a5555b96cf560089ec3cead12d845d2", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0.3", + "ext-curl": "*", + "ext-json": "*", + "php": ">=8.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "^10.0", + "squizlabs/php_codesniffer": "4.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "MaxMind\\Exception\\": "src/Exception", + "MaxMind\\WebService\\": "src/WebService" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory Oschwald", + "email": "goschwald@maxmind.com" + } + ], + "description": "Internal MaxMind Web Service API", + "homepage": "https://github.com/maxmind/web-service-common-php", + "support": { + "issues": "https://github.com/maxmind/web-service-common-php/issues", + "source": "https://github.com/maxmind/web-service-common-php/tree/v0.11.1" + }, + "time": "2026-01-13T17:56:03+00:00" + }, { "name": "mustache/mustache", "version": "v3.0.0", @@ -647,6 +1074,114 @@ }, "time": "2019-01-08T18:20:26+00:00" }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, { "name": "psr/log", "version": "3.0.2", @@ -697,6 +1232,142 @@ }, "time": "2024-09-11T13:17:53+00:00" }, + { + "name": "scssphp/scssphp", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/scssphp/scssphp.git", + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/d8450c2baf5fb07d00374999d0ea51276974d1b6", + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", + "php": ">=8.1", + "scssphp/source-span": "^1.1", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0 || ^8.0" + }, + "require-dev": { + "jgthms/bulma": "~0.9.4", + "jiripudil/phpstan-sealed-classes": "^1.3", + "phpstan/phpstan": "^2.1.31", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpunit/phpunit": "^9.5.6", + "sass/sass-spec": "*", + "squizlabs/php_codesniffer": "^3.13", + "symfony/phpunit-bridge": "^7.3 || ^8.0", + "symfony/polyfill-php84": "^1.33", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0", + "thoughtbot/bourbon": "^7.0", + "twbs/bootstrap": "^5.3", + "twbs/bootstrap4": "4.6.1", + "zurb/foundation": "~6.7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "ScssPhp\\ScssPhp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "homepage": "https://github.com/robocoder" + }, + { + "name": "Cédric Morin", + "email": "cedric@yterium.com", + "homepage": "https://github.com/Cerdic" + } + ], + "description": "scssphp is a compiler for SCSS written in PHP.", + "homepage": "https://scssphp.github.io/scssphp/", + "keywords": [ + "css", + "less", + "sass", + "scss", + "stylesheet" + ], + "support": { + "issues": "https://github.com/scssphp/scssphp/issues", + "source": "https://github.com/scssphp/scssphp/tree/v2.1.0" + }, + "time": "2025-11-21T17:27:59+00:00" + }, + { + "name": "scssphp/source-span", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/scssphp/source-span.git", + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scssphp/source-span/zipball/37d653206daf11da1ee60b333984101bc4c27ba2", + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", + "php": ">=8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpunit/phpunit": "^9.5.6", + "squizlabs/php_codesniffer": "~3.5", + "symfony/phpunit-bridge": "^6.4 || ^7.3 || ^8.0", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "SourceSpan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "homepage": "https://github.com/stof" + } + ], + "description": "Provides a representation for source code locations and spans.", + "keywords": [ + "parsing" + ], + "support": { + "issues": "https://github.com/scssphp/source-span/issues", + "source": "https://github.com/scssphp/source-span/tree/v1.1.0" + }, + "time": "2025-11-21T16:28:19+00:00" + }, { "name": "symfony/deprecation-contracts", "version": "v3.6.0", @@ -764,6 +1435,240 @@ ], "time": "2024-09-25T14:21:43+00:00" }, + { + "name": "symfony/filesystem", + "version": "v8.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "17856b7a222664a26a5ea1cb06ee0721c2438217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/17856b7a222664a26a5ea1cb06ee0721c2438217", + "reference": "17856b7a222664a26a5ea1cb06ee0721c2438217", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v8.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-07-22T15:42:13+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, { "name": "symfony/polyfill-php80", "version": "v1.33.0", @@ -847,6 +1752,86 @@ } ], "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "twig/twig", + "version": "v3.28.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", + "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "php-cs-fixer/shim": "^3.0@stable", + "phpstan/phpstan": "^2.0@stable", + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.28.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2026-07-03T20:44:34+00:00" } ], "packages-dev": [], diff --git a/config.json.example b/config.json.example index 2575f04..43916d5 100644 --- a/config.json.example +++ b/config.json.example @@ -1,7 +1,6 @@ { "site_title": "CodePress", "content_dir": "content", - "templates_dir": "cms/templates", "active_theme": "default", "default_page": "auto", "language": { @@ -17,7 +16,7 @@ }, "author": { "name": "E. Noorlander", - "website": "https://noorlander.info" + "website": "noorlander.info" }, "show_version": true, "enabled_plugins": [ @@ -48,6 +47,29 @@ "geoip_mmdb_path": "", "geoip_api_url": "", "geoip_api_key": "", - "retention_days": 400 + "retention_days": 400, + "excluded_ips": [ + "192.168.0.0/16", + "10.0.0.0/8", + "172.16.0.0/12", + "127.0.0.1", + "::1" + ] + }, + "logging": { + "enabled": true, + "driver": "sqlite", + "syslog_host": "", + "syslog_port": 514, + "syslog_facility": "local0", + "syslog_ident": "codepress", + "events": { + "admin": true, + "requests": true, + "errors": true, + "security": true, + "content": true, + "system": true + } } } diff --git a/docs/TODO.md b/docs/TODO.md index 0b9f8fb..52ffb28 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -27,7 +27,7 @@ - [x] **Breadcrumb titels ongeescaped** - `$title` direct in HTML zonder `htmlspecialchars()` (`CodePressCMS.php:1197`) - [x] **Zoekresultaat-URLs missen `&lang=`** - Taalparameter ontbreekt (`CodePressCMS.php:264`) - [x] **Operator precedence bug** - `!$x ?? true` evalueert als `(!$x) ?? true` (`MQTTTracker.php:131`) -- [ ] **Taalwisselaar verliest pagina** - Wisselen van taal navigeert altijd naar homepage (`header.mustache:22`) +- [ ] **Taalwisselaar verliest pagina** - Wisselen van taal navigeert altijd naar homepage (`partials/header.twig`) - [ ] **ctime is geen creatietijd op Linux** - `stat()` ctime is inode-wijzigingstijd (`CodePressCMS.php:400`) - [ ] **getGuidePage() dupliceert markdown parsing** - Zelfde CommonMark setup als `parseMarkdown()` (`CodePressCMS.php:854`) - [ ] **HTMLBlock ontbrekende `
`** - Niet-gesloten tags bij null-check (`HTMLBlock.php:68`) @@ -36,7 +36,7 @@ ## Laag - [x] **Hardcoded 'Ga naar'** - Niet vertaalbaar in `autoLinkPageTitles()` (`CodePressCMS.php:587`) -- [x] **HTML lang attribuut** - `` hardcoded i.p.v. dynamisch (`layout.mustache:2`) +- [x] **HTML lang attribuut** - `` hardcoded i.p.v. dynamisch (`base.twig`) - [x] **console.log in productie** - Debug log in app.js (`app.js:54`) - [x] **Event listener leak** - N globale click listeners in forEach loop (`app.js:85`) - [x] **Sidebar toggle aria** - Ontbrekende `aria-label` en `aria-expanded` (`CodePressCMS.php:1171`) diff --git a/guide/en.codepress.md b/guide/en.codepress.md index 333426d..0da7af6 100644 --- a/guide/en.codepress.md +++ b/guide/en.codepress.md @@ -58,8 +58,8 @@ codepress/ │ ├── core/ │ │ ├── class/ │ │ │ ├── CodePressCMS.php # Main CMS class (content, navigation, search) +│ │ │ ├── ThemeManager.php # Theme resolver + Twig render + SCSS compile │ │ │ ├── Logger.php # Structured logging system -│ │ │ ├── SimpleTemplate.php # Mustache-style template engine │ │ │ ├── Analytics.php # Visitor statistics │ │ │ ├── BotGuard.php # Bot/AI/scraper detection │ │ │ ├── GeoIP.php # Country lookup by IP @@ -73,13 +73,21 @@ codepress/ │ ├── lang/ # Language files │ │ ├── nl.php # Dutch translations │ │ └── en.php # English translations -│ ├── templates/ # Mustache templates -│ │ ├── layout.mustache # Main layout (CSS, structure) -│ │ ├── assets/ # Header, navigation, footer partials -│ │ ├── markdown_content.mustache -│ │ ├── php_content.mustache -│ │ └── html_content.mustache -│ └── router.php # PHP dev server router +│ └── router.php # PHP dev server router (also serves /themes/) +├── themes/ # Dynamic themes (fully self-contained) +│ ├── default/ # Default theme +│ │ ├── theme.json # { title, config.default_template, template→.twig mapping } +│ │ ├── base.twig # Main layout (head, header, nav, footer) +│ │ ├── full_content.twig # Layout: full width +│ │ ├── left_sidebar.twig # Layout: sidebar left +│ │ ├── right_sidebar.twig # Layout: sidebar right +│ │ ├── custom1.twig # Layout: custom +│ │ ├── partials/ # header.twig, navigation.twig, footer.twig +│ │ ├── css/theme.scss # Colors, heights, background (compiled at runtime) +│ │ ├── js/theme.js # Theme JavaScript +│ │ └── theme.png # Preview image +│ ├── demo/ # Demo theme (same structure, different look) +│ └── test/ # Test theme ├── admin/ # Admin panel │ ├── config/ │ │ ├── app.php # Admin app configuration (paths, timezone) @@ -124,12 +132,19 @@ codepress/ │ ├── assets/ # CSS, JS, favicons │ │ ├── codemirror/ # CodeMirror editor (minified JS/CSS) │ │ └── css/js/ # Bootstrap, icons, app CSS/JS -│ ├── themes/ # Uploaded theme backgrounds +│ ├── themes/ # Runtime compiled theme CSS (public/themes) │ └── manifest.json / sw.js # PWA support -├── themes/ # Theme definitions +├── themes/ # Dynamic themes (fully self-contained) │ ├── default/ # Default theme -│ │ └── theme.json # Colors, heights, background -│ └── ... # Other themes +│ │ ├── theme.json # Title, default template, template mapping +│ │ ├── base.twig # Main layout +│ │ ├── *.twig # Layout templates (full_content, left_sidebar, ...) +│ │ ├── partials/ # header, navigation, footer +│ │ ├── css/theme.scss # Colors, heights, background +│ │ ├── js/theme.js # Theme JavaScript +│ │ └── theme.png # Preview image +│ ├── demo/ # Demo theme +│ └── test/ # Test theme ├── config.json # Site configuration ├── version.php # Version information └── vendor/ # Composer dependencies @@ -301,7 +316,6 @@ This is useful for your own IP address or internal monitoring tools. { "site_title": "CodePress", "content_dir": "content", - "templates_dir": "cms\/templates", "default_page": "index", "active_theme": "default", "language": { @@ -336,32 +350,64 @@ This is useful for your own IP address or internal monitoring tools. ### Themes -Themes are managed via the admin panel at `/admin/theme`. You can create, activate, adjust colors, upload background images, and delete themes. +Themes are managed via the admin panel at `/admin/theme`. This is a selection page: pick the active theme and click "Activate theme". Each theme is a fully self-contained folder in `themes/` with its own Twig templates, SCSS and JavaScript. + +#### Theme structure (`themes//`) + +``` +themes// +├── theme.json # Title, default template, template mapping +├── base.twig # Main layout (head, header, nav, footer) +├── full_content.twig # Layout: full width +├── left_sidebar.twig # Layout: sidebar left +├── right_sidebar.twig # Layout: sidebar right +├── custom1.twig # Layout: custom +├── partials/ # header.twig, navigation.twig, footer.twig +├── css/theme.scss # Colors, heights, background (compiled at runtime) +├── js/theme.js # Theme JavaScript +└── theme.png # Preview image (shown in admin) +``` #### Theme Configuration (`themes//theme.json`) ```json { - "name": "Default", - "header_color": "#0a369d", - "header_font_color": "#ffffff", - "header_height": "56", - "navigation_color": "#2754b4", - "navigation_font_color": "#ffffff", - "nav_height": "42", - "sidebar_background": "#f8f9fa", - "sidebar_border": "#dee2e6", - "background_image": "", - "background_image_opacity": "100" + "title": "default", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig" + } } ``` +- **`config.default_template`**: the default template used when a page requests an unknown layout. +- **`template`**: the layout-key → `.twig` file mapping. A theme can have multiple template pages. + +Colors, heights and background are **not** set in `theme.json` but in `css/theme.scss`: + +```scss +$header-bg: #0a369d; +$header-font: #ffffff; +$header-height: 56px; +$nav-bg: #2754b4; +$nav-font: #ffffff; +$nav-height: 42px; +$sidebar-bg: #f8f9fa; +$sidebar-border: #dee2e6; +$header-bg-image: none; // optional header background +$header-bg-opacity: 1; +``` + +The SCSS is compiled at runtime into `public/themes//theme.css`. + #### How to create a new theme -1. Go to `/admin/theme` -2. Enter a name and click "Create" -3. Adjust colors, heights and background -4. Activate the theme +Themes are created manually: copy the `themes/default/` folder to `themes//`, adjust the SCSS colors and templates, and add a `theme.png` preview. The theme is then available on `/admin/theme` to activate. ### Security @@ -418,10 +464,23 @@ Country detection via three sources: ### Logging -The admin console maintains two logs, viewable at `/admin/logs`: +The admin console maintains logs, viewable at `/admin/logs`: - **Activity log** (`admin/storage/logs/admin.log`) — admin actions like creating, editing, deleting pages, enabling/disabling plugins, changing configuration. - **Request log** (`admin/storage/logs/requests.log`) — every page view on the website, including IP, page, domain, language, user agent, and referrer. +- **Dynamic log** — structured log entries via `LogManager`, with event type, level, IP, and message. + +#### Configuring dynamic logging + +Via `/admin/config` → **Logging** you can configure how and what is recorded: + +- **Storage**: `SQLite` (default) or `Syslog`. +- **Syslog server**: if a host is provided, log entries are sent to that server over UDP. Leave empty to use SQLite. +- **Facility**: the category of the log source in syslog. `local0`–`local7` are for your own applications; `daemon`, `user`, and `auth` are standard system categories. +- **Syslog ident**: the name that appears in the log message (e.g. `codepress`). +- **Events**: choose which types are recorded — `admin`, `requests`, `errors`, `security`, `content`, `system`. + +If no syslog server is configured, SQLite is always used (with a file fallback if SQLite is unavailable). The dashboard shows the last 20 entries of each log. Click "View all →" for the full list, where you can also download or clear. @@ -523,6 +582,8 @@ This guide is also built into the admin panel via `/admin/guide`, with support f ### Templates +Templates are Twig files per theme in `themes//`. `ThemeManager` renders them and compiles `css/theme.scss` at runtime into `public/themes//theme.css`. + #### Template Variables **Site Info** - `site_title`, `author_name`, `author_website`, `author_git` @@ -531,36 +592,39 @@ This guide is also built into the admin panel via `/admin/guide`, with support f **Navigation** - `menu`, `breadcrumb`, `homepage` -**Theme (from theme.json)** - `header_color`, `header_font_color`, `header_height`, `navigation_color`, `navigation_font_color`, `nav_height`, `sidebar_background`, `sidebar_border`, `background_image_css`, `background_image_opacity` +**Theme** - `theme_title`, `theme_css_url`, `theme_js_url`, `theme_config` (config from theme.json) **Language** - `current_lang`, `current_lang_upper`, `t_*` (translated strings) #### Layout Options -Use YAML frontmatter to select layout: +Use YAML frontmatter to select the template. The layout key references a template in the active theme: ```yaml --- title: My Page -layout: sidebar-content +layout: left_sidebar plugins: HTMLBlock --- ``` #### Available Layouts -- `sidebar-content` - Sidebar left, content right (default) -- `content` - Content only (full width) -- `sidebar` - Sidebar only -- `content-sidebar` - Content left, sidebar right -- `content-sidebar-reverse` - Content right, sidebar left +The available layouts are defined by the `template` section of the active theme (`themes//theme.json`). The default theme includes: + +- `full_content` - Content only (full width) +- `left_sidebar` - Sidebar left, content right +- `right_sidebar` - Content left, sidebar right +- `custom1` - Custom layout + +If a page requests an unknown layout, the `default_template` from the theme's `config` is used. #### Meta Data ```yaml --- title: Page Title -layout: content-sidebar +layout: left_sidebar description: Page description author: Author Name date: 2025-11-26 diff --git a/guide/nl.codepress.md b/guide/nl.codepress.md index 23f839c..7b3a354 100644 --- a/guide/nl.codepress.md +++ b/guide/nl.codepress.md @@ -58,8 +58,8 @@ codepress/ │ ├── core/ │ │ ├── class/ │ │ │ ├── CodePressCMS.php # Hoofd CMS class (content, navigatie, search) +│ │ │ ├── ThemeManager.php # Thema-resolver + Twig render + SCSS compile │ │ │ ├── Logger.php # Gestructureerd logging systeem -│ │ │ ├── SimpleTemplate.php # Mustache-style template engine │ │ │ ├── Analytics.php # Bezoekersstatistieken │ │ │ ├── BotGuard.php # Bot/AI/scraper detectie │ │ │ ├── GeoIP.php # Landbepaling op basis van IP @@ -73,13 +73,21 @@ codepress/ │ ├── lang/ # Taalbestanden │ │ ├── nl.php # Nederlandse vertalingen │ │ └── en.php # Engelse vertalingen -│ ├── templates/ # Mustache templates -│ │ ├── layout.mustache # Hoofd layout (CSS, structuur) -│ │ ├── assets/ # Header, navigation, footer partials -│ │ ├── markdown_content.mustache -│ │ ├── php_content.mustache -│ │ └── html_content.mustache -│ └── router.php # PHP dev server router +│ └── router.php # PHP dev server router (serveert ook /themes/) +├── themes/ # Dynamische thema's (volledig zelfstandig) +│ ├── default/ # Standaard thema +│ │ ├── theme.json # { title, config.default_template, template→.twig mapping } +│ │ ├── base.twig # Hoofd layout (head, header, nav, footer) +│ │ ├── full_content.twig # Layout: volledige breedte +│ │ ├── left_sidebar.twig # Layout: sidebar links +│ │ ├── right_sidebar.twig # Layout: sidebar rechts +│ │ ├── custom1.twig # Layout: custom +│ │ ├── partials/ # header.twig, navigation.twig, footer.twig +│ │ ├── css/theme.scss # Kleuren, hoogtes, achtergrond (runtime gecompileerd) +│ │ ├── js/theme.js # Thema JavaScript +│ │ └── theme.png # Voorbeeldafbeelding +│ ├── demo/ # Demo thema (zelfde structuur, andere look) +│ └── test/ # Test thema ├── admin/ # Admin paneel │ ├── config/ │ │ ├── app.php # Admin app configuratie (paden, timezone) @@ -124,12 +132,19 @@ codepress/ │ ├── assets/ # CSS, JS, favicons │ │ ├── codemirror/ # CodeMirror editor (minified JS/CSS) │ │ └── css/js/ # Bootstrap, icons, app CSS/JS -│ ├── themes/ # Geuploade theme achtergronden +│ ├── themes/ # Runtime gecompileerde thema CSS (public/themes) │ └── manifest.json / sw.js # PWA ondersteuning -├── themes/ # Thema definities +├── themes/ # Dynamische thema's (volledig zelfstandig) │ ├── default/ # Standaard thema -│ │ └── theme.json # Kleuren, hoogtes, achtergrond -│ └── ... # Andere thema's +│ │ ├── theme.json # Titel, default template, template mapping +│ │ ├── base.twig # Hoofd layout +│ │ ├── *.twig # Layout-sjablonen (full_content, left_sidebar, ...) +│ │ ├── partials/ # header, navigation, footer +│ │ ├── css/theme.scss # Kleuren, hoogtes, achtergrond +│ │ ├── js/theme.js # Thema JavaScript +│ │ └── theme.png # Voorbeeldafbeelding +│ ├── demo/ # Demo thema +│ └── test/ # Test thema ├── config.json # Site configuratie ├── version.php # Versie informatie └── vendor/ # Composer dependencies @@ -302,7 +317,6 @@ Dit is handig voor je eigen IP-adres of dat van interne monitoring tools. { "site_title": "CodePress", "content_dir": "content", - "templates_dir": "cms\/templates", "default_page": "index", "active_theme": "default", "language": { @@ -337,32 +351,64 @@ Dit is handig voor je eigen IP-adres of dat van interne monitoring tools. ### Thema's -Thema's worden beheerd via het admin paneel op `/admin/theme`. Je kunt thema's aanmaken, activeren, kleuren aanpassen, achtergrondafbeeldingen uploaden en verwijderen. +Thema's worden beheerd via het admin paneel op `/admin/theme`. Dit is een selectiepagina: kies het actieve thema en klik "Thema activeren". Elk thema is een volledig zelfstandige map in `themes/` met eigen Twig-sjablonen, SCSS en JavaScript. + +#### Thema-structuur (`themes//`) + +``` +themes// +├── theme.json # Titel, default template, template mapping +├── base.twig # Hoofd layout (head, header, nav, footer) +├── full_content.twig # Layout: volledige breedte +├── left_sidebar.twig # Layout: sidebar links +├── right_sidebar.twig # Layout: sidebar rechts +├── custom1.twig # Layout: custom +├── partials/ # header.twig, navigation.twig, footer.twig +├── css/theme.scss # Kleuren, hoogtes, achtergrond (runtime gecompileerd) +├── js/theme.js # Thema JavaScript +└── theme.png # Voorbeeldafbeelding (tonen in admin) +``` #### Thema Configuratie (`themes//theme.json`) ```json { - "name": "Standaard", - "header_color": "#0a369d", - "header_font_color": "#ffffff", - "header_height": "56", - "navigation_color": "#2754b4", - "navigation_font_color": "#ffffff", - "nav_height": "42", - "sidebar_background": "#f8f9fa", - "sidebar_border": "#dee2e6", - "background_image": "", - "background_image_opacity": "100" + "title": "default", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig" + } } ``` +- **`config.default_template`**: de standaard sjabloon die gebruikt wordt wanneer een pagina een onbekende layout vraagt. +- **`template`**: de layout-sleutel → `.twig`-bestand koppeling. Zo kan een thema meerdere template-pagina's hebben. + +Kleuren, hoogtes en achtergrond worden **niet** in `theme.json` gezet, maar in `css/theme.scss`: + +```scss +$header-bg: #0a369d; +$header-font: #ffffff; +$header-height: 56px; +$nav-bg: #2754b4; +$nav-font: #ffffff; +$nav-height: 42px; +$sidebar-bg: #f8f9fa; +$sidebar-border: #dee2e6; +$header-bg-image: none; // optionele header-achtergrond +$header-bg-opacity: 1; +``` + +De SCSS wordt runtime gecompileerd naar `public/themes//theme.css`. + #### Een nieuw thema maken -1. Ga naar `/admin/theme` -2. Voer een naam in en klik "Aanmaken" -3. Pas kleuren, hoogtes en achtergrond aan -4. Activeer het thema +Thema's zijn handmatig aan te maken: kopieer de `themes/default/` map naar `themes//`, pas de SCSS-kleuren en sjablonen aan, en voeg een `theme.png` preview toe. Daarna is het thema beschikbaar op `/admin/theme` om te activeren. ### Beveiliging @@ -419,10 +465,23 @@ Landbepaling kan via drie bronnen: ### Logging -De admin console houdt twee logs bij, te bekijken via `/admin/logs`: +De admin console houdt logs bij, te bekijken via `/admin/logs`: - **Activiteiten log** (`admin/storage/logs/admin.log`) — admin acties zoals pagina's aanmaken, bewerken, verwijderen, plugin in/uitschakelen, configuratie wijzigen. - **Requests log** (`admin/storage/logs/requests.log`) — elke pageview op de website, met IP, pagina, domein, taal, user-agent en referrer. +- **Dynamisch log** — gestructureerde logregels via `LogManager`, met gebeurtenistype, niveau, IP en bericht. + +#### Dynamische logging configureren + +Via `/admin/config` → **Logging** kun je instellen hoe en wat er geregistreerd wordt: + +- **Opslag**: `SQLite` (standaard) of `Syslog`. +- **Syslog server**: als er een host is opgegeven, worden logregels via UDP naar die server gestuurd. Laat leeg om SQLite te gebruiken. +- **Facility**: de categorie van de logbron in syslog. `local0`–`local7` zijn bedoeld voor eigen applicaties; `daemon`, `user` en `auth` zijn standaard systeemcategorieën. +- **Syslog ident**: de naam die in het logbericht verschijnt (bijv. `codepress`). +- **Gebeurtenissen**: kies welke types geregistreerd worden — `admin`, `requests`, `errors`, `security`, `content`, `system`. + +Als er geen syslog-server is opgegeven, wordt altijd SQLite gebruikt (met een bestands-fallback als SQLite niet beschikbaar is). Het dashboard toont de laatste 20 entries van elk log. Klik "Bekijk alle →" voor de volledige lijst, waar je ook kunt downloaden of wissen. @@ -524,6 +583,8 @@ Deze handleiding is ook ingebouwd in het admin paneel via `/admin/guide`, met on ### Templates +Sjablonen zijn Twig-bestanden die per thema in `themes//` staan. `ThemeManager` rendert ze en compileert `css/theme.scss` runtime naar `public/themes//theme.css`. + #### Template Variabelen **Site Info** - `site_title`, `author_name`, `author_website`, `author_git` @@ -532,36 +593,39 @@ Deze handleiding is ook ingebouwd in het admin paneel via `/admin/guide`, met on **Navigation** - `menu`, `breadcrumb`, `homepage` -**Theme (uit theme.json)** - `header_color`, `header_font_color`, `header_height`, `navigation_color`, `navigation_font_color`, `nav_height`, `sidebar_background`, `sidebar_border`, `background_image_css`, `background_image_opacity` +**Theme** - `theme_title`, `theme_css_url`, `theme_js_url`, `theme_config` (config uit theme.json) **Language** - `current_lang`, `current_lang_upper`, `t_*` (vertaalde strings) #### Layout Opties -Gebruik YAML frontmatter om layout te selecteren: +Gebruik YAML frontmatter om de sjabloon te selecteren. De layout-sleutel verwijst naar een template in het actieve thema: ```yaml --- title: Mijn Pagina -layout: sidebar-content +layout: left_sidebar plugins: HTMLBlock --- ``` #### Beschikbare Layouts -- `sidebar-content` - Sidebar links, content rechts (standaard) -- `content` - Alleen content (volle breedte) -- `sidebar` - Alleen sidebar -- `content-sidebar` - Content links, sidebar rechts -- `content-sidebar-reverse` - Content rechts, sidebar links +De beschikbare layouts worden bepaald door de `template`-sectie van het actieve thema (`themes//theme.json`). Het standaard thema bevat: + +- `full_content` - Alleen content (volle breedte) +- `left_sidebar` - Sidebar links, content rechts +- `right_sidebar` - Content links, sidebar rechts +- `custom1` - Custom layout + +Vraag een pagina een onbekende layout aan, dan wordt de `default_template` uit `config` van het thema gebruikt. #### Meta Data ```yaml --- title: Pagina Titel -layout: content-sidebar +layout: left_sidebar description: Pagina beschrijving author: Auteur Naam date: 2025-11-26 diff --git a/plugins/test/README.md b/plugins/test/README.md deleted file mode 100644 index 152cb1e..0000000 --- a/plugins/test/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# test - -Dit is een test plugin diff --git a/plugins/test/config.json b/plugins/test/config.json deleted file mode 100644 index c26ec9a..0000000 --- a/plugins/test/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "enabled": true -} \ No newline at end of file diff --git a/plugins/test/test.php b/plugins/test/test.php deleted file mode 100644 index a42a5dd..0000000 --- a/plugins/test/test.php +++ /dev/null @@ -1,35 +0,0 @@ -config = [ - 'title' => 'Dit is een test plugin', - 'viewable' => true, - ]; - } - - public function setAPI(CMSAPI $api): void - { - $this->api = $api; - } - - public function getSidebarContent(): string - { - return 'Hallo'; - } - - public function getConfig(): array - { - return $this->config; - } - - public function setConfig(array $config): void - { - $this->config = array_merge($this->config, $config); - } -} \ No newline at end of file diff --git a/public/admin.php b/public/admin.php index f583c71..68c13c0 100644 --- a/public/admin.php +++ b/public/admin.php @@ -26,6 +26,13 @@ require_once __DIR__ . '/../cms/core/class/BotGuard.php'; require_once __DIR__ . '/../cms/core/class/Cache.php'; require_once __DIR__ . '/../cms/core/class/GeoIP.php'; require_once __DIR__ . '/../cms/core/class/Analytics.php'; +require_once __DIR__ . '/../cms/core/class/LogManager.php'; + +// Initialize dynamic logging from site config +$siteConfigForLogging = file_exists($appConfig['config_json']) + ? (json_decode(file_get_contents($appConfig['config_json']), true) ?? []) + : []; +LogManager::init($siteConfigForLogging['logging'] ?? []); $auth = new AdminAuth($appConfig); @@ -108,6 +115,14 @@ switch ($route) { handleTheme($auth, $appConfig); break; + case 'theme-new': + handleThemeNew($auth, $appConfig); + break; + + case 'theme-delete': + handleThemeDelete($auth, $appConfig); + break; + case 'plugins': handlePlugins($auth, $appConfig); break; @@ -328,6 +343,11 @@ function adminLog(array $config, string $level, string $message): void $timestamp = date('Y-m-d H:i:s'); $ip = RequestLogger::getClientIp(); @file_put_contents($logFile, "[{$timestamp}] [{$level}] [{$ip}] {$message}\n", FILE_APPEND); + + // Also record through the dynamic log manager (admin event) + if (class_exists('LogManager')) { + LogManager::log(LogManager::EVENT_ADMIN, $level, $message, ['ip' => $ip]); + } } function handleContentEdit(AdminAuth $auth, array $config): void @@ -410,6 +430,18 @@ function handleContentEdit(AdminAuth $auth, array $config): void $currentLayout = 'sidebar-content'; } + // Load available layouts from the active theme's theme.json + $themeLayouts = []; + $configJson = $config['config_json']; + $configData = file_exists($configJson) ? json_decode(file_get_contents($configJson), true) : []; + if (!is_array($configData)) $configData = []; + $activeThemeName = $configData['active_theme'] ?? 'default'; + $activeThemeFile = $config['codepress_root'] . '/themes/' . $activeThemeName . '/theme.json'; + if (file_exists($activeThemeFile)) { + $themeJson = json_decode(file_get_contents($activeThemeFile), true) ?? []; + $themeLayouts = $themeJson['template'] ?? []; + } + $fileName = basename($filePath); $route = 'content-edit'; @@ -522,6 +554,18 @@ function handleContentNew(AdminAuth $auth, array $config): void } } + // Load available layouts from the active theme's .twig files + $themeLayouts = []; + $configJson = $config['config_json']; + $configData = file_exists($configJson) ? json_decode(file_get_contents($configJson), true) : []; + if (!is_array($configData)) $configData = []; + $activeThemeName = $configData['active_theme'] ?? 'default'; + $activeThemeFile = $config['codepress_root'] . '/themes/' . $activeThemeName . '/theme.json'; + if (file_exists($activeThemeFile)) { + $themeJson = json_decode(file_get_contents($activeThemeFile), true) ?? []; + $themeLayouts = $themeJson['template'] ?? []; + } + $route = 'content-new'; require __DIR__ . '/../admin/templates/layout.php'; } @@ -748,7 +792,7 @@ function handleConfig(AdminAuth $auth, array $config): void $configData['seo']['description'] = trim($_POST['seo_description'] ?? ''); $configData['seo']['keywords'] = trim($_POST['seo_keywords'] ?? ''); $configData['author']['name'] = trim($_POST['author_name'] ?? ''); - $configData['author']['website'] = trim($_POST['author_website'] ?? ''); + $configData['author']['website'] = stripUrlScheme(trim($_POST['author_website'] ?? '')); $configData['show_version'] = !empty($_POST['show_version']); $configData['features']['auto_link_pages'] = !empty($_POST['feature_auto_link']); $configData['features']['search_enabled'] = !empty($_POST['feature_search']); @@ -767,6 +811,20 @@ function handleConfig(AdminAuth $auth, array $config): void }; $configData['analytics']['excluded_ips'] = $parseLines($_POST['excluded_ips'] ?? ''); + // Logging settings + $configData['logging']['enabled'] = !empty($_POST['logging_enabled']); + $configData['logging']['driver'] = ($_POST['logging_driver'] ?? 'sqlite') === 'syslog' ? 'syslog' : 'sqlite'; + $configData['logging']['syslog_host'] = trim($_POST['syslog_host'] ?? ''); + $configData['logging']['syslog_port'] = max(1, min(65535, (int)($_POST['syslog_port'] ?? 514))); + $configData['logging']['syslog_facility'] = preg_replace('/[^a-z0-9]/', '', $_POST['syslog_facility'] ?? 'local0'); + $configData['logging']['syslog_ident'] = trim($_POST['syslog_ident'] ?? 'codepress'); + $selectedEvents = $_POST['logging_events'] ?? []; + $allEvents = ['admin', 'requests', 'errors', 'security', 'content', 'system']; + $configData['logging']['events'] = []; + foreach ($allEvents as $ev) { + $configData['logging']['events'][$ev] = in_array($ev, $selectedEvents, true); + } + file_put_contents($configJson, json_encode($configData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); adminLog($config, 'info', $user['username'] . ' wijzigde site configuratie'); $message = 'Configuratie opgeslagen.'; @@ -993,115 +1051,19 @@ function handleTheme(AdminAuth $auth, array $config): void $csrf = $auth->getCsrfToken(); $configJson = $config['config_json']; $themesDir = $config['codepress_root'] . '/themes'; - $publicThemes = $config['codepress_root'] . '/public/themes'; $message = ''; $messageType = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { - if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) { - $message = 'Ongeldige CSRF token.'; - $messageType = 'danger'; - } else { - $action = $_POST['action'] ?? ''; - - if ($action === 'save') { - $themeName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['theme'] ?? ''); - $themeFile = $themesDir . '/' . $themeName . '/theme.json'; - if (file_exists($themeFile)) { - $themeData = json_decode(file_get_contents($themeFile), true) ?? []; - foreach (['header_color', 'header_font_color', 'navigation_color', 'navigation_font_color', 'sidebar_background', 'sidebar_border'] as $field) { - $value = trim($_POST[$field] ?? ''); - if (preg_match('/^#[0-9a-fA-F]{6}$/', $value)) { - $themeData[$field] = $value; - } - } - $themeData['name'] = trim($_POST['theme_name'] ?? $themeData['name'] ?? $themeName); - $themeData['header_height'] = preg_match('/^\d+$/', $_POST['header_height'] ?? '') ? trim($_POST['header_height']) : ($themeData['header_height'] ?? '56'); - $themeData['nav_height'] = preg_match('/^\d+$/', $_POST['nav_height'] ?? '') ? trim($_POST['nav_height']) : ($themeData['nav_height'] ?? '42'); - $themeData['background_image_opacity'] = preg_match('/^\d+$/', $_POST['background_image_opacity'] ?? '') ? max(0, min(100, intval($_POST['background_image_opacity']))) : ($themeData['background_image_opacity'] ?? '100'); - - // Handle background image upload - if (!empty($_FILES['bg_image']['name']) && $_FILES['bg_image']['error'] === UPLOAD_ERR_OK) { - $ext = strtolower(pathinfo($_FILES['bg_image']['name'], PATHINFO_EXTENSION)); - if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'])) { - $imgName = $themeName . '_bg.' . $ext; - if (!is_dir($publicThemes)) mkdir($publicThemes, 0755, true); - move_uploaded_file($_FILES['bg_image']['tmp_name'], $publicThemes . '/' . $imgName); - $themeData['background_image'] = $imgName; - } - } - // Handle background image URL - $bgUrl = trim($_POST['background_image_url'] ?? ''); - if (!empty($bgUrl)) { - $themeData['background_image'] = $bgUrl; - } - // Handle background image removal - if (!empty($_POST['bg_image_remove'])) { - if ($themeData['background_image'] ?? '') { - $oldFile = $publicThemes . '/' . $themeData['background_image']; - if (file_exists($oldFile)) unlink($oldFile); - } - $themeData['background_image'] = ''; - } - - file_put_contents($themeFile, json_encode($themeData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); - $message = 'Thema opgeslagen.'; - $messageType = 'success'; - } - } elseif ($action === 'activate') { - $themeName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['theme'] ?? ''); - if (file_exists($themesDir . '/' . $themeName . '/theme.json')) { - $cfg = json_decode(file_get_contents($configJson), true) ?? []; - $cfg['active_theme'] = $themeName; - file_put_contents($configJson, json_encode($cfg, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); - $message = 'Thema geactiveerd.'; - $messageType = 'success'; - } - } elseif ($action === 'create') { - $newName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['new_name'] ?? ''); - if (empty($newName)) { - $message = 'Geef een naam voor het nieuwe thema.'; - $messageType = 'danger'; - } elseif (file_exists($themesDir . '/' . $newName . '/theme.json')) { - $message = 'Thema bestaat al.'; - $messageType = 'danger'; - } else { - $defaults = [ - 'name' => $newName, - 'header_color' => '#0a369d', - 'header_font_color' => '#ffffff', - 'header_height' => '56', - 'navigation_color' => '#2754b4', - 'navigation_font_color' => '#ffffff', - 'nav_height' => '42', - 'sidebar_background' => '#f8f9fa', - 'sidebar_border' => '#dee2e6', - 'background_image' => '', - 'background_image_opacity' => '100', - ]; - $newThemeDir = $themesDir . '/' . $newName; - mkdir($newThemeDir, 0755, true); - file_put_contents($newThemeDir . '/theme.json', json_encode($defaults, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); - $message = 'Thema aangemaakt.'; - $messageType = 'success'; - } - } elseif ($action === 'delete') { - $themeName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['theme'] ?? ''); - $themeDir = $themesDir . '/' . $themeName; - if (is_dir($themeDir) && $themeName !== 'default') { - $themeFile = $themeDir . '/theme.json'; - if (file_exists($themeFile)) unlink($themeFile); - // Remove theme directory if empty - $remaining = array_diff(scandir($themeDir), ['.', '..']); - if (empty($remaining)) rmdir($themeDir); - $cfg = json_decode(file_get_contents($configJson), true) ?? []; - if (($cfg['active_theme'] ?? '') === $themeName) { - $cfg['active_theme'] = 'default'; - file_put_contents($configJson, json_encode($cfg, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); - } - $message = 'Thema verwijderd.'; - $messageType = 'success'; - } + if ($auth->verifyCsrf($_POST['csrf_token'] ?? '')) { + $themeName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['theme'] ?? ''); + if ($themeName !== '' && file_exists($themesDir . '/' . $themeName . '/theme.json')) { + $cfg = json_decode(file_get_contents($configJson), true) ?? []; + $cfg['active_theme'] = $themeName; + file_put_contents($configJson, json_encode($cfg, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); + adminLog($config, 'info', $user['username'] . ' activeerde thema ' . $themeName); + $message = 'Thema geactiveerd.'; + $messageType = 'success'; } } } @@ -1123,18 +1085,135 @@ function handleTheme(AdminAuth $auth, array $config): void } } - // Load theme being edited - $editThemeName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['edit'] ?? ''); - $editTheme = null; - if ($editThemeName && isset($themes[$editThemeName])) { - $editTheme = $themes[$editThemeName]; - $editTheme['name'] = $editThemeName; - } - $route = 'theme'; require __DIR__ . '/../admin/templates/layout.php'; } +function handleThemeNew(AdminAuth $auth, array $config): void +{ + $user = $auth->getCurrentUser(); + $csrf = $auth->getCsrfToken(); + $themesDir = $config['codepress_root'] . '/themes'; + $message = ''; + $messageType = ''; + + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + if (!$auth->verifyCsrf($_POST['csrf_token'] ?? '')) { + $message = 'Ongeldige CSRF token.'; + $messageType = 'danger'; + } else { + $newName = trim($_POST['theme_name'] ?? ''); + + if (empty($newName)) { + $message = 'Thema naam is verplicht.'; + $messageType = 'danger'; + } elseif (!preg_match('/^[a-zA-Z][a-zA-Z0-9_-]*$/', $newName)) { + $message = 'Ongeldige thema naam. Gebruik alleen letters, cijfers, streepjes en underscores. Begin met een letter.'; + $messageType = 'danger'; + } elseif (file_exists($themesDir . '/' . $newName . '/theme.json')) { + $message = 'Thema met deze naam bestaat al.'; + $messageType = 'danger'; + } else { + $newThemeDir = $themesDir . '/' . $newName; + mkdir($newThemeDir, 0755, true); + + $defaults = [ + 'title' => $newName, + 'config' => [ + 'default_template' => 'full_content', + ], + 'template' => [ + 'full_content' => 'full_content.twig', + 'left_sidebar' => 'left_sidebar.twig', + 'right_sidebar' => 'right_sidebar.twig', + 'custom1' => 'custom1.twig', + ], + ]; + file_put_contents($newThemeDir . '/theme.json', json_encode($defaults, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); + + // Scaffold a full theme folder from the default theme + $defaultThemeDir = $themesDir . '/default'; + if (is_dir($defaultThemeDir)) { + $copyDirs = ['partials', 'css', 'js']; + foreach ($copyDirs as $sub) { + $src = $defaultThemeDir . '/' . $sub; + if (is_dir($src)) { + $dst = $newThemeDir . '/' . $sub; + mkdir($dst, 0755, true); + foreach (scandir($src) as $f) { + if ($f[0] === '.') continue; + if (is_file($src . '/' . $f)) { + copy($src . '/' . $f, $dst . '/' . $f); + } + } + } + } + foreach (['base.twig', 'full_content.twig', 'left_sidebar.twig', 'right_sidebar.twig', 'custom1.twig'] as $tpl) { + if (is_file($defaultThemeDir . '/' . $tpl)) { + copy($defaultThemeDir . '/' . $tpl, $newThemeDir . '/' . $tpl); + } + } + // Copy the default theme's preview image if present + if (is_file($defaultThemeDir . '/theme.png')) { + copy($defaultThemeDir . '/theme.png', $newThemeDir . '/theme.png'); + } + } + + adminLog($config, 'info', $user['username'] . ' maakte thema ' . $newName . ' aan'); + header('Location: /admin/theme'); + exit; + } + } + } + + $route = 'theme-new'; + require __DIR__ . '/../admin/templates/layout.php'; +} + +function handleThemeDelete(AdminAuth $auth, array $config): void +{ + if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + header('Location: /admin/theme'); + exit; + } + + $configJson = $config['config_json']; + $themesDir = $config['codepress_root'] . '/themes'; + $themeName = preg_replace('/[^a-zA-Z0-9_-]/', '', $_GET['theme'] ?? ''); + $themeDir = $themesDir . '/' . $themeName; + + if ($themeName === '' || $themeName === 'default' || !is_dir($themeDir)) { + header('Location: /admin/theme'); + exit; + } + + if ($auth->verifyCsrf($_POST['csrf_token'] ?? '')) { + // Recursively remove the entire theme directory + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($themeDir, RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($iterator as $file) { + if ($file->isDir()) { + @rmdir($file->getRealPath()); + } else { + @unlink($file->getRealPath()); + } + } + @rmdir($themeDir); + + $cfg = json_decode(file_get_contents($configJson), true) ?? []; + if (($cfg['active_theme'] ?? '') === $themeName) { + $cfg['active_theme'] = 'default'; + file_put_contents($configJson, json_encode($cfg, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); + } + adminLog($config, 'info', ($_SESSION['admin_user'] ?? 'unknown') . ' verwijderde thema ' . $themeName); + } + + header('Location: /admin/theme'); + exit; +} + function handlePlugins(AdminAuth $auth, array $config): void { $user = $auth->getCurrentUser(); @@ -1707,55 +1786,39 @@ function handleLogs(AdminAuth $auth, array $config): void $user = $auth->getCurrentUser(); $csrf = $auth->getCsrfToken(); - $activeTab = $_GET['tab'] ?? 'admin'; - if (!in_array($activeTab, ['admin', 'requests'])) $activeTab = 'admin'; - - $adminLogFile = $config['log_file']; - $requestLogFile = $config['request_log']; + // Filters + $filterEvent = $_GET['event'] ?? ''; + $filterLevel = $_GET['level'] ?? ''; + $filterSearch = trim($_GET['search'] ?? ''); + $limit = max(10, min(1000, (int)($_GET['limit'] ?? 200))); // Clear if (isset($_GET['clear'])) { - $target = $activeTab === 'admin' ? $adminLogFile : $requestLogFile; - @file_put_contents($target, ''); - $message = $activeTab === 'admin' ? 'Activiteiten log gewist.' : 'Requestlog gewist.'; - header('Location: /admin/logs?tab=' . $activeTab); + LogManager::clear(); + $message = 'Log gewist.'; + header('Location: /admin/logs'); exit; } // Download if (isset($_GET['download'])) { - $target = $activeTab === 'admin' ? $adminLogFile : $requestLogFile; - $filename = $activeTab === 'admin' ? 'admin.log' : 'requests.log'; - if (file_exists($target)) { - header('Content-Type: text/plain'); - header('Content-Disposition: attachment; filename="' . $filename . '"'); - header('Content-Length: ' . filesize($target)); - readfile($target); + $entries = LogManager::getLogs(1000, $filterEvent ?: null, $filterLevel ?: null, $filterSearch ?: null); + $out = ''; + foreach ($entries as $e) { + $out .= '[' . $e['time'] . '] [' . $e['event'] . '] [' . $e['level'] . '] [' . $e['ip'] . '] ' . $e['message'] . "\n"; } + header('Content-Type: text/plain'); + header('Content-Disposition: attachment; filename="codepress.log"'); + echo $out; exit; } - // Read admin log - $adminLogs = []; - if (file_exists($adminLogFile)) { - $lines = file($adminLogFile); - $lines = array_slice($lines, -200); - foreach ($lines as $line) { - if (preg_match('/^\[([^\]]+)\] \[([^\]]+)\] \[([^\]]+)\] (.+)$/', trim($line), $m)) { - $adminLogs[] = [ - 'time' => $m[1], - 'level' => strtolower($m[2]), - 'ip' => $m[3], - 'message' => $m[4], - ]; - } - } - $adminLogs = array_reverse($adminLogs); - } + // Read log entries with filters + $logEntries = LogManager::getLogs($limit, $filterEvent ?: null, $filterLevel ?: null, $filterSearch ?: null); - // Read request log - $requestLogger = new RequestLogger($requestLogFile); - $requestLogs = $requestLogger->getLogs(200); + // Available event types for the filter dropdown + $eventTypes = ['admin', 'requests', 'errors', 'security', 'content', 'system']; + $levelTypes = ['info', 'warning', 'error', 'debug']; $route = 'logs'; require __DIR__ . '/../admin/templates/layout.php'; @@ -1826,6 +1889,22 @@ function handleUpdate(AdminAuth $auth, array $config): void // --- Frontmatter helpers --- +/** + * Remove the URL scheme (http://, https://) from a website value so it is + * stored as a bare hostname. The engine adds the scheme back when rendering. + * + * @param string $url Raw URL value + * @return string Hostname without scheme + */ +function stripUrlScheme(string $url): string +{ + $url = trim($url); + if (preg_match('#^[a-zA-Z][a-zA-Z0-9+.\-]*://#', $url)) { + $url = preg_replace('#^[a-zA-Z][a-zA-Z0-9+.\-]*://#', '', $url); + } + return rtrim($url, '/'); +} + /** * Keep a timestamped copy of a content file before it is overwritten. * @@ -1840,6 +1919,7 @@ function backupContentFile(string $filePath, int $keep = 5): void $contentRoot = realpath(dirname(__DIR__) . '/content'); $realFile = realpath($filePath); + if (!$contentRoot || !$realFile || strpos($realFile, $contentRoot) !== 0) { return; } diff --git a/public/index.php b/public/index.php index 562e3f3..1b5f543 100644 --- a/public/index.php +++ b/public/index.php @@ -4,6 +4,9 @@ require_once __DIR__ . '/../cms/core/index.php'; $config = include __DIR__ . '/../cms/core/config.php'; +// Initialize dynamic logging +LogManager::init($config['logging'] ?? []); + // Security headers header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: SAMEORIGIN'); @@ -114,8 +117,8 @@ $secSettings = $config['security'] ?? [ $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $analyticsSettings = $config['analytics'] ?? []; $excludedIps = $analyticsSettings['excluded_ips'] ?? []; -$isAllowedIp = in_array($clientIp, $secSettings['allowed_ips'] ?? [], true) - || in_array($clientIp, $excludedIps, true); +$isAllowedIp = RequestLogger::ipMatchesList($clientIp, $secSettings['allowed_ips'] ?? []) + || RequestLogger::ipMatchesList($clientIp, $excludedIps); $requestStatus = 'ok'; if (!$isAllowedIp) { @@ -184,6 +187,15 @@ if (!str_starts_with($path, '/-media/') && !str_starts_with($path, '/-assets/')) $geoCountry ); + // Also record through the dynamic log manager (requests event) + LogManager::log(LogManager::EVENT_REQUESTS, 'info', 'Request: ' . $currentPage, [ + 'ip' => $storedIp, + 'page' => $currentPage, + 'status' => $requestStatus, + 'country' => $geoCountry, + 'user' => $loggedInUser, + ]); + // Record aggregated statistics if (!empty($analyticsSettings['enabled']) && !in_array($clientIp, $excludedIps, true)) { $analytics = new Analytics($analyticsSettings); diff --git a/public/themes/test_bg.jpg b/public/themes/test_bg.jpg deleted file mode 100644 index 5e049ad..0000000 Binary files a/public/themes/test_bg.jpg and /dev/null differ diff --git a/themes/default/base.twig b/themes/default/base.twig new file mode 100644 index 0000000..98a5511 --- /dev/null +++ b/themes/default/base.twig @@ -0,0 +1,136 @@ + + + + + + {{ page_title }} - {{ site_title }} + + + + + + + + + + + + + + + {% if block_ai_bots %} + + + {% endif %} + {% if block_search_engines %} + + {% endif %} + + + + + + + + + + + + + + + + {% if theme_css_url %} + + {% endif %} + + + + + + + + + {% include 'partials/header.twig' %} + + + + + +
+ {% block content %}{% endblock %} +
+ +
+ {% include 'partials/footer.twig' %} +
+ + + + {% if theme_js_url %} + + {% endif %} + + diff --git a/themes/default/css/theme.scss b/themes/default/css/theme.scss new file mode 100644 index 0000000..62a1fb0 --- /dev/null +++ b/themes/default/css/theme.scss @@ -0,0 +1,367 @@ +// CodePress default theme styles +// Compiled at runtime by ThemeManager (scssphp) into public/themes/default/theme.css + +// Theme color variables (defined per theme; used by the CSS custom properties below) +$header-bg: #0a369d; +$header-font: #ffffff; +$header-height: 56px; +$nav-bg: #2754b4; +$nav-font: #ffffff; +$nav-height: 42px; +$sidebar-bg: #f8f9fa; +$sidebar-border: #dee2e6; + +// Optional header background image and overlay opacity +$header-bg-image: none; +$header-bg-opacity: 1; + +:root { + --header-bg: #{$header-bg}; + --header-font: #{$header-font}; + --header-height: #{$header-height}; + --nav-bg: #{$nav-bg}; + --nav-font: #{$nav-font}; + --nav-height: #{$nav-height}; + --sidebar-bg: #{$sidebar-bg}; + --sidebar-border: #{$sidebar-border}; +} + +// Header background (optional background image via $header-bg-image) +#site-header { + background-image: $header-bg-image; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + position: relative; +} + +@if $header-bg-image != 'none' { + #site-header::before { + content: ''; + position: absolute; + inset: 0; + background-color: var(--header-bg); + opacity: $header-bg-opacity; + pointer-events: none; + z-index: 0; + } +} + +// Header styles +.navbar { + background-color: var(--header-bg) !important; + min-height: var(--header-height); + + .navbar-brand, + .navbar-text, + .form-control, + .btn { + color: var(--header-font) !important; + } + + .form-control::placeholder { + color: rgba(255, 255, 255, 0.7) !important; + } + + .btn-outline-light { + border-color: var(--header-font) !important; + } +} + +// Language dropdown styling +.dropdown-menu { + background-color: var(--header-bg) !important; + border: 1px solid var(--header-font) !important; +} + +.dropdown-item { + color: var(--header-font) !important; + + &:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + color: var(--header-font) !important; + } +} + +// Hide Bootstrap dropdown arrow and use custom icon +.dropdown-toggle::after { + display: none !important; +} + +.btn-outline-light { + color: var(--header-font) !important; + border-color: var(--header-font) !important; + + &:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + color: var(--header-font) !important; + } + + &:focus, + &:active, + .show > &.dropdown-toggle { + background-color: rgba(255, 255, 255, 0.1) !important; + color: var(--header-font) !important; + border-color: var(--header-font) !important; + box-shadow: none !important; + } +} + +.bi-chevron-down { + font-size: 0.75em; + margin-left: 0.25rem; +} + +// Remove Bootstrap default breadcrumb separators +.breadcrumb-item + .breadcrumb-item::before { + content: "" !important; + padding: 0 !important; +} + +// Custom breadcrumb styling +.breadcrumb { + --bs-breadcrumb-divider: ""; + + .breadcrumb-item { + color: var(--nav-font) !important; + + a { + color: var(--nav-font) !important; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + } +} + +// Sidebar toggle button in breadcrumb +.sidebar-toggle-item { + display: flex; + align-items: center; + margin-right: 0.5rem; +} + +.sidebar-toggle-btn { + padding: 0; + line-height: 1; + font-size: 1.1rem; + color: var(--header-bg) !important; + border: none !important; + background: transparent !important; + box-shadow: none !important; + cursor: pointer; + + &:hover { + opacity: 0.7; + } +} + +// Sidebar hide/show transition +.sidebar-column { + transition: all 0.3s ease; +} + +.sidebar-hidden { + display: none !important; +} + +// Navigation section background +.navigation-section { + background-color: var(--nav-bg) !important; + color: var(--nav-font) !important; + min-height: var(--nav-height); +} + +// Enhanced accessibility styles +.focus-visible:focus, +.btn:focus, +.form-control:focus, +.nav-link:focus { + outline: 3px solid #0056b3 !important; + outline-offset: 2px !important; + box-shadow: 0 0 0 1px #ffffff, 0 0 0 4px #0056b3 !important; +} + +// High contrast mode support +@media (prefers-contrast: high) { + :root { + --text-color: #000000; + --bg-color: #ffffff; + --border-color: #000000; + --focus-color: #000000; + } + + .btn-primary { + background-color: #000000 !important; + border-color: #000000 !important; + color: #ffffff !important; + } + + .btn-outline-light { + color: #000000 !important; + border-color: #000000 !important; + } + + .text-muted { + color: #000000 !important; + } + + .navbar { + background-color: #ffffff !important; + border-bottom: 1px solid #000000 !important; + } +} + +// Reduced motion support +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} + +// Remove nav-tabs background so it inherits from parent +.nav-tabs { + background-color: transparent !important; + border: none !important; + + .nav-link { + background-color: transparent !important; + border: none !important; + color: var(--nav-font) !important; + + &:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + } + + &.active { + background-color: rgba(255, 255, 255, 0.2) !important; + border-bottom: 2px solid var(--nav-font) !important; + } + } +} + +// Sidebar styling +.sidebar-column { + background-color: var(--sidebar-bg) !important; + border-right: 1px solid var(--sidebar-border) !important; + position: sticky; + top: 0; + min-height: calc(100vh - var(--header-height) - var(--nav-height) - 42px); +} + +.sidebar { + padding: 1.5rem; + height: 100%; + overflow-y: auto; +} + +.content-column { + background-color: #ffffff; +} + +.content-wrapper { + padding: 2rem; + padding-bottom: 80px !important; +} + +// Ensure full height layout +.main-content { + flex: 1; +} + +// Mobile responsive +@media (max-width: 767.98px) { + .sidebar-column { + border-right: none !important; + border-top: 1px solid var(--sidebar-border) !important; + min-height: auto; + margin-top: 1rem; + } + + .content-column { + background-color: #ffffff; + } + + .content-wrapper { + min-height: auto; + padding-bottom: 2rem !important; + } +} + +// Tablet and mobile: sidebar below content +@media (max-width: 991.98px) { + .sidebar-column { + order: 2 !important; + } + + .content-column { + order: 1 !important; + } +} + +// Code block styling +pre { + background: #f8f9fa; + padding: 1rem; + border-radius: 6px; + overflow-x: auto; + border: 1px solid #dee2e6; + margin-bottom: 1rem; + + code { + background: none; + padding: 0; + color: #333; + font-size: 0.85rem; + line-height: 1.5; + } +} + +code { + background: #e8e8e8; + padding: 0.15rem 0.4rem; + border-radius: 3px; + font-size: 0.9em; + color: #d63384; +} + +// Footer icon hover effects +.footer-icon { + color: #6c757d; + text-decoration: none; + transition: all 0.2s ease-in-out; + display: inline-block; + padding: 2px; + + &:hover { + color: #0d6efd; + transform: translateY(-1px); + } + + &:active { + transform: translateY(0); + } + + &.guide:hover { + color: #198754; + } + + &.cms:hover { + color: #dc3545; + } + + &.git:hover { + color: #6f42c1; + } + + &.website:hover { + color: #fd7e14; + } +} diff --git a/themes/default/custom1.twig b/themes/default/custom1.twig new file mode 100644 index 0000000..4588091 --- /dev/null +++ b/themes/default/custom1.twig @@ -0,0 +1,18 @@ +{% extends 'base.twig' %} + +{% block content %} +
+
+ +
+
+ {{ content|raw }} +
+
+
+
+{% endblock %} diff --git a/themes/default/full_content.twig b/themes/default/full_content.twig new file mode 100644 index 0000000..05f4748 --- /dev/null +++ b/themes/default/full_content.twig @@ -0,0 +1,11 @@ +{% extends 'base.twig' %} + +{% block content %} +
+
+
+ {{ content|raw }} +
+
+
+{% endblock %} diff --git a/themes/default/js/theme.js b/themes/default/js/theme.js new file mode 100644 index 0000000..816a279 --- /dev/null +++ b/themes/default/js/theme.js @@ -0,0 +1,21 @@ +// CodePress default theme JavaScript +// Loaded after the global app.js on every page. + +(function () { + 'use strict'; + + // Sidebar toggle (used by the breadcrumb toggle button) + function toggleSidebar() { + var sidebar = document.getElementById('site-sidebar'); + if (!sidebar) return; + sidebar.classList.toggle('sidebar-hidden'); + var btn = document.querySelector('.sidebar-toggle-btn'); + if (btn) { + var hidden = sidebar.classList.contains('sidebar-hidden'); + btn.setAttribute('aria-expanded', hidden ? 'false' : 'true'); + } + } + + // Expose for inline onclick handlers + window.toggleSidebar = toggleSidebar; +})(); diff --git a/themes/default/left_sidebar.twig b/themes/default/left_sidebar.twig new file mode 100644 index 0000000..89e3197 --- /dev/null +++ b/themes/default/left_sidebar.twig @@ -0,0 +1,26 @@ +{% extends 'base.twig' %} + +{% block content %} +{% if sidebar_content %} +
+ +
+
+ {{ content|raw }} +
+
+
+{% else %} +
+
+
+ {{ content|raw }} +
+
+
+{% endif %} +{% endblock %} diff --git a/cms/templates/assets/footer.mustache b/themes/default/partials/footer.twig similarity index 61% rename from cms/templates/assets/footer.mustache rename to themes/default/partials/footer.twig index b9ffc14..78cd213 100644 --- a/cms/templates/assets/footer.mustache +++ b/themes/default/partials/footer.twig @@ -5,38 +5,38 @@
- - {{page_title}} - {{#file_info_block}} + + {{ page_title }} + {% if file_info_block %} - {{#show_created}} - - {{created}} - {{/show_created}} - - {{modified}} + {% if show_created %} + + {{ created }} + {% endif %} + + {{ modified }} - {{/file_info_block}} + {% endif %}
- + | - {{#cms_version}} - {{cms_version}} - {{/cms_version}} - + {% if cms_version %} + {{ cms_version }} + {% endif %} + | - + | - + @@ -45,4 +45,4 @@
- \ No newline at end of file + diff --git a/cms/templates/assets/header.mustache b/themes/default/partials/header.twig similarity index 63% rename from cms/templates/assets/header.mustache rename to themes/default/partials/header.twig index 6413fc4..a71f4da 100644 --- a/cms/templates/assets/header.mustache +++ b/themes/default/partials/header.twig @@ -1,75 +1,75 @@ \ No newline at end of file + diff --git a/cms/templates/assets/navigation.mustache b/themes/default/partials/navigation.twig similarity index 69% rename from cms/templates/assets/navigation.mustache rename to themes/default/partials/navigation.twig index 0b1495a..32e76e1 100644 --- a/cms/templates/assets/navigation.mustache +++ b/themes/default/partials/navigation.twig @@ -5,13 +5,13 @@
- \ No newline at end of file + diff --git a/themes/default/right_sidebar.twig b/themes/default/right_sidebar.twig new file mode 100644 index 0000000..630bcf1 --- /dev/null +++ b/themes/default/right_sidebar.twig @@ -0,0 +1,26 @@ +{% extends 'base.twig' %} + +{% block content %} +{% if sidebar_content %} +
+
+
+ {{ content|raw }} +
+
+ +
+{% else %} +
+
+
+ {{ content|raw }} +
+
+
+{% endif %} +{% endblock %} diff --git a/themes/default/theme.json b/themes/default/theme.json index e9cc83d..da748dd 100644 --- a/themes/default/theme.json +++ b/themes/default/theme.json @@ -1,13 +1,12 @@ { - "name": "Standaard", - "header_color": "#0a369d", - "header_font_color": "#ffffff", - "header_height": "56", - "navigation_color": "#2754b4", - "navigation_font_color": "#ffffff", - "nav_height": "42", - "sidebar_background": "#f8f9fa", - "sidebar_border": "#dee2e6", - "background_image": "", - "background_image_opacity": "100" + "title": "default", + "config": { + "default_template": "full_content" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig" + } } diff --git a/themes/default/theme.png b/themes/default/theme.png new file mode 100644 index 0000000..35ff861 Binary files /dev/null and b/themes/default/theme.png differ diff --git a/themes/demo/base.twig b/themes/demo/base.twig new file mode 100644 index 0000000..f84bfd9 --- /dev/null +++ b/themes/demo/base.twig @@ -0,0 +1,136 @@ + + + + + + {{ page_title }} - {{ site_title }} + + + + + + + + + + + + + + + {% if block_ai_bots %} + + + {% endif %} + {% if block_search_engines %} + + {% endif %} + + + + + + + + + + + + + + + + {% if theme_css_url %} + + {% endif %} + + + + + + + + + {% include 'partials/header.twig' %} + + + + + +
+ {% block content %}{% endblock %} +
+ +
+ {% include 'partials/footer.twig' %} +
+ + + + {% if theme_js_url %} + + {% endif %} + + diff --git a/themes/demo/css/theme.scss b/themes/demo/css/theme.scss new file mode 100644 index 0000000..7f87162 --- /dev/null +++ b/themes/demo/css/theme.scss @@ -0,0 +1,331 @@ +// CodePress demo theme styles +// A distinct look to demonstrate that themes are fully swappable. + +// Theme color variables (defined per theme; used by the CSS custom properties below) +$header-bg: #613583; +$header-font: #ffffff; +$header-height: 120px; +$nav-bg: #813d9c; +$nav-font: #ffffff; +$nav-height: 50px; +$sidebar-bg: #f3e8f7; +$sidebar-border: #d8b4e0; + +// Optional header background image and overlay opacity +$header-bg-image: none; +$header-bg-opacity: 1; + +:root { + --header-bg: #{$header-bg}; + --header-font: #{$header-font}; + --header-height: #{$header-height}; + --nav-bg: #{$nav-bg}; + --nav-font: #{$nav-font}; + --nav-height: #{$nav-height}; + --sidebar-bg: #{$sidebar-bg}; + --sidebar-border: #{$sidebar-border}; +} + +// Header background (optional background image via $header-bg-image) +#site-header { + background-image: $header-bg-image; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + position: relative; +} + +@if $header-bg-image != 'none' { + #site-header::before { + content: ''; + position: absolute; + inset: 0; + background-color: var(--header-bg); + opacity: $header-bg-opacity; + pointer-events: none; + z-index: 0; + } +} + +// Rounded, softer header +.navbar { + background-color: var(--header-bg) !important; + min-height: var(--header-height); + border-bottom: 4px solid var(--nav-bg) !important; + + .navbar-brand, + .navbar-text, + .form-control, + .btn { + color: var(--header-font) !important; + } + + .form-control::placeholder { + color: rgba(255, 255, 255, 0.7) !important; + } + + .btn-outline-light { + border-color: var(--header-font) !important; + } +} + +// Language dropdown styling +.dropdown-menu { + background-color: var(--header-bg) !important; + border: 1px solid var(--header-font) !important; +} + +.dropdown-item { + color: var(--header-font) !important; + + &:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + color: var(--header-font) !important; + } +} + +.dropdown-toggle::after { + display: none !important; +} + +.btn-outline-light { + color: var(--header-font) !important; + border-color: var(--header-font) !important; + + &:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + color: var(--header-font) !important; + } + + &:focus, + &:active, + .show > &.dropdown-toggle { + background-color: rgba(255, 255, 255, 0.1) !important; + color: var(--header-font) !important; + border-color: var(--header-font) !important; + box-shadow: none !important; + } +} + +.bi-chevron-down { + font-size: 0.75em; + margin-left: 0.25rem; +} + +// Breadcrumb +.breadcrumb-item + .breadcrumb-item::before { + content: "" !important; + padding: 0 !important; +} + +.breadcrumb { + --bs-breadcrumb-divider: ""; + + .breadcrumb-item { + color: var(--nav-font) !important; + + a { + color: var(--nav-font) !important; + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + } +} + +.sidebar-toggle-item { + display: flex; + align-items: center; + margin-right: 0.5rem; +} + +.sidebar-toggle-btn { + padding: 0; + line-height: 1; + font-size: 1.1rem; + color: var(--header-bg) !important; + border: none !important; + background: transparent !important; + box-shadow: none !important; + cursor: pointer; + + &:hover { + opacity: 0.7; + } +} + +.sidebar-column { + transition: all 0.3s ease; +} + +.sidebar-hidden { + display: none !important; +} + +// Navigation section background +.navigation-section { + background-color: var(--nav-bg) !important; + color: var(--nav-font) !important; + min-height: var(--nav-height); +} + +// Accessibility +.focus-visible:focus, +.btn:focus, +.form-control:focus, +.nav-link:focus { + outline: 3px solid #0056b3 !important; + outline-offset: 2px !important; + box-shadow: 0 0 0 1px #ffffff, 0 0 0 4px #0056b3 !important; +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +} + +.nav-tabs { + background-color: transparent !important; + border: none !important; + + .nav-link { + background-color: transparent !important; + border: none !important; + color: var(--nav-font) !important; + + &:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + } + + &.active { + background-color: rgba(255, 255, 255, 0.2) !important; + border-bottom: 2px solid var(--nav-font) !important; + } + } +} + +// Sidebar styling - rounded cards look +.sidebar-column { + background-color: var(--sidebar-bg) !important; + border-right: 1px solid var(--sidebar-border) !important; + position: sticky; + top: 0; + min-height: calc(100vh - var(--header-height) - var(--nav-height) - 42px); +} + +.sidebar { + padding: 1.5rem; + height: 100%; + overflow-y: auto; + + .card { + border-radius: 1rem; + border: 1px solid var(--sidebar-border); + } +} + +.content-column { + background-color: #ffffff; +} + +.content-wrapper { + padding: 2rem; + padding-bottom: 80px !important; +} + +.main-content { + flex: 1; +} + +// Mobile responsive +@media (max-width: 767.98px) { + .sidebar-column { + border-right: none !important; + border-top: 1px solid var(--sidebar-border) !important; + min-height: auto; + margin-top: 1rem; + } + + .content-wrapper { + min-height: auto; + padding-bottom: 2rem !important; + } +} + +@media (max-width: 991.98px) { + .sidebar-column { + order: 2 !important; + } + + .content-column { + order: 1 !important; + } +} + +// Code block styling +pre { + background: #f8f9fa; + padding: 1rem; + border-radius: 6px; + overflow-x: auto; + border: 1px solid #dee2e6; + margin-bottom: 1rem; + + code { + background: none; + padding: 0; + color: #333; + font-size: 0.85rem; + line-height: 1.5; + } +} + +code { + background: #e8e8e8; + padding: 0.15rem 0.4rem; + border-radius: 3px; + font-size: 0.9em; + color: #d63384; +} + +// Footer icon hover effects +.footer-icon { + color: #6c757d; + text-decoration: none; + transition: all 0.2s ease-in-out; + display: inline-block; + padding: 2px; + + &:hover { + color: #0d6efd; + transform: translateY(-1px); + } + + &:active { + transform: translateY(0); + } + + &.guide:hover { + color: #198754; + } + + &.cms:hover { + color: #dc3545; + } + + &.git:hover { + color: #6f42c1; + } + + &.website:hover { + color: #fd7e14; + } +} diff --git a/themes/demo/custom1.twig b/themes/demo/custom1.twig new file mode 100644 index 0000000..4588091 --- /dev/null +++ b/themes/demo/custom1.twig @@ -0,0 +1,18 @@ +{% extends 'base.twig' %} + +{% block content %} +
+
+ +
+
+ {{ content|raw }} +
+
+
+
+{% endblock %} diff --git a/themes/demo/full_content.twig b/themes/demo/full_content.twig new file mode 100644 index 0000000..05f4748 --- /dev/null +++ b/themes/demo/full_content.twig @@ -0,0 +1,11 @@ +{% extends 'base.twig' %} + +{% block content %} +
+
+
+ {{ content|raw }} +
+
+
+{% endblock %} diff --git a/themes/demo/js/theme.js b/themes/demo/js/theme.js new file mode 100644 index 0000000..816a279 --- /dev/null +++ b/themes/demo/js/theme.js @@ -0,0 +1,21 @@ +// CodePress default theme JavaScript +// Loaded after the global app.js on every page. + +(function () { + 'use strict'; + + // Sidebar toggle (used by the breadcrumb toggle button) + function toggleSidebar() { + var sidebar = document.getElementById('site-sidebar'); + if (!sidebar) return; + sidebar.classList.toggle('sidebar-hidden'); + var btn = document.querySelector('.sidebar-toggle-btn'); + if (btn) { + var hidden = sidebar.classList.contains('sidebar-hidden'); + btn.setAttribute('aria-expanded', hidden ? 'false' : 'true'); + } + } + + // Expose for inline onclick handlers + window.toggleSidebar = toggleSidebar; +})(); diff --git a/themes/demo/left_sidebar.twig b/themes/demo/left_sidebar.twig new file mode 100644 index 0000000..89e3197 --- /dev/null +++ b/themes/demo/left_sidebar.twig @@ -0,0 +1,26 @@ +{% extends 'base.twig' %} + +{% block content %} +{% if sidebar_content %} +
+ +
+
+ {{ content|raw }} +
+
+
+{% else %} +
+
+
+ {{ content|raw }} +
+
+
+{% endif %} +{% endblock %} diff --git a/themes/demo/partials/footer.twig b/themes/demo/partials/footer.twig new file mode 100644 index 0000000..78cd213 --- /dev/null +++ b/themes/demo/partials/footer.twig @@ -0,0 +1,48 @@ +
+
+
+
+
+
+ + + {{ page_title }} + {% if file_info_block %} + + {% if show_created %} + + {{ created }} + {% endif %} + + {{ modified }} + + {% endif %} + +
+
+ + + + + | + {% if cms_version %} + {{ cms_version }} + {% endif %} + + + + | + + + + | + + + + +
+
+
+
+
+
diff --git a/themes/demo/partials/header.twig b/themes/demo/partials/header.twig new file mode 100644 index 0000000..a71f4da --- /dev/null +++ b/themes/demo/partials/header.twig @@ -0,0 +1,75 @@ + diff --git a/themes/demo/partials/navigation.twig b/themes/demo/partials/navigation.twig new file mode 100644 index 0000000..32e76e1 --- /dev/null +++ b/themes/demo/partials/navigation.twig @@ -0,0 +1,17 @@ + diff --git a/themes/demo/right_sidebar.twig b/themes/demo/right_sidebar.twig new file mode 100644 index 0000000..630bcf1 --- /dev/null +++ b/themes/demo/right_sidebar.twig @@ -0,0 +1,26 @@ +{% extends 'base.twig' %} + +{% block content %} +{% if sidebar_content %} +
+
+
+ {{ content|raw }} +
+
+ +
+{% else %} +
+
+
+ {{ content|raw }} +
+
+
+{% endif %} +{% endblock %} diff --git a/themes/demo/theme.json b/themes/demo/theme.json new file mode 100644 index 0000000..a3adb20 --- /dev/null +++ b/themes/demo/theme.json @@ -0,0 +1,12 @@ +{ + "title": "demo", + "config": { + "default_template": "left_sidebar" + }, + "template": { + "full_content": "full_content.twig", + "left_sidebar": "left_sidebar.twig", + "right_sidebar": "right_sidebar.twig", + "custom1": "custom1.twig" + } +} diff --git a/themes/demo/theme.png b/themes/demo/theme.png new file mode 100644 index 0000000..f213bef Binary files /dev/null and b/themes/demo/theme.png differ diff --git a/themes/gen-preview.sh b/themes/gen-preview.sh new file mode 100755 index 0000000..dab12c6 --- /dev/null +++ b/themes/gen-preview.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Generate theme.png preview images for each theme using ImageMagick. +# Reads the theme's SCSS color variables and renders a simple page mockup. +set -euo pipefail + +cd "$(dirname "$0")/../themes" + +gen_preview() { + local dir="$1" + local scss="$dir/css/theme.scss" + if [[ ! -f "$scss" ]]; then + echo "Skip $dir (no theme.scss)" + return + fi + + local header_bg header_font nav_bg nav_font sidebar_bg sidebar_border + header_bg=$(grep -oE '^\$header-bg:\s*[^;]+;' "$scss" | grep -oE '#[0-9a-fA-F]{6}' || echo "#0a369d") + header_font=$(grep -oE '^\$header-font:\s*[^;]+;' "$scss" | grep -oE '#[0-9a-fA-F]{6}' || echo "#ffffff") + nav_bg=$(grep -oE '^\$nav-bg:\s*[^;]+;' "$scss" | grep -oE '#[0-9a-fA-F]{6}' || echo "#2754b4") + nav_font=$(grep -oE '^\$nav-font:\s*[^;]+;' "$scss" | grep -oE '#[0-9a-fA-F]{6}' || echo "#ffffff") + sidebar_bg=$(grep -oE '^\$sidebar-bg:\s*[^;]+;' "$scss" | grep -oE '#[0-9a-fA-F]{6}' || echo "#f8f9fa") + sidebar_border=$(grep -oE '^\$sidebar-border:\s*[^;]+;' "$scss" | grep -oE '#[0-9a-fA-F]{6}' || echo "#dee2e6") + + local size=640x400 + local body_bg="#ffffff" + + # Header bar + convert -size "$size" xc:"$body_bg" \ + -fill "$header_bg" -draw "rectangle 0,0 639,70" \ + -fill "$nav_bg" -draw "rectangle 0,70 639,95" \ + -fill "$sidebar_bg" -draw "rectangle 0,95 180,399" \ + -fill "$header_font" -font DejaVu-Sans-Bold -pointsize 20 -annotate +15+22 "$(basename "$dir")" \ + -fill "$header_font" -font DejaVu-Sans -pointsize 13 -annotate +15+45 "CodePress" \ + -fill "$nav_font" -font DejaVu-Sans -pointsize 12 -annotate +15+85 "Home | Over | Blog" \ + -fill "#666666" -font DejaVu-Sans -pointsize 14 -annotate +200+130 "Welkom bij $(basename "$dir")" \ + -fill "#999999" -font DejaVu-Sans -pointsize 11 -annotate +200+155 "Dit is een voorbeeld van het thema." \ + -fill "#cccccc" -draw "rectangle 200,400 639,399" \ + "$dir/theme.png" + + echo "Generated $dir/theme.png" +} + +for d in default demo test; do + if [[ -d "$d" ]]; then + gen_preview "$d" + fi +done diff --git a/themes/test/theme.json b/themes/test/theme.json deleted file mode 100644 index 2ceecbc..0000000 --- a/themes/test/theme.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "test", - "header_color": "#613583", - "header_font_color": "#ffffff", - "navigation_color": "#813d9c", - "navigation_font_color": "#ffffff", - "sidebar_background": "#f8f9fa", - "sidebar_border": "#dee2e6", - "header_height": "120", - "nav_height": "50", - "background_image": "test_bg.jpg", - "background_image_opacity": 10 -} \ No newline at end of file diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 414f45c..5da6d88 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -7,5 +7,11 @@ $baseDir = dirname($vendorDir); return array( '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', + '89efb1254ef2d1c5d80096acd12c4098' => $vendorDir . '/twig/twig/src/Resources/core.php', + 'ffecb95d45175fd40f75be8a23b34f90' => $vendorDir . '/twig/twig/src/Resources/debug.php', + 'c7baa00073ee9c61edf148c51917cfb4' => $vendorDir . '/twig/twig/src/Resources/escaper.php', + 'f844ccf1d25df8663951193c3fc307c8' => $vendorDir . '/twig/twig/src/Resources/string_loader.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index e6e3777..a9c8cf0 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -6,14 +6,27 @@ $vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( + 'Twig\\' => array($vendorDir . '/twig/twig/src'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), + 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'), + 'SourceSpan\\' => array($vendorDir . '/scssphp/source-span/src'), + 'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'), 'PhpMqtt\\Client\\' => array($vendorDir . '/php-mqtt/client/src'), 'Nette\\' => array($vendorDir . '/nette/schema/src', $vendorDir . '/nette/utils/src'), 'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'), 'Mustache\\' => array($vendorDir . '/mustache/mustache/src'), + 'MaxMind\\WebService\\' => array($vendorDir . '/maxmind/web-service-common/src/WebService'), + 'MaxMind\\Exception\\' => array($vendorDir . '/maxmind/web-service-common/src/Exception'), + 'MaxMind\\Db\\' => array($vendorDir . '/maxmind-db/reader/src/MaxMind/Db'), + 'League\\Uri\\' => array($vendorDir . '/league/uri', $vendorDir . '/league/uri-interfaces'), 'League\\Config\\' => array($vendorDir . '/league/config/src'), 'League\\CommonMark\\' => array($vendorDir . '/league/commonmark/src'), + 'GeoIp2\\' => array($vendorDir . '/geoip2/geoip2/src'), 'Dflydev\\DotAccessData\\' => array($vendorDir . '/dflydev/dot-access-data/src'), + 'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'), ); diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index e8aebd0..dbb30d2 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -8,17 +8,33 @@ class ComposerStaticInit071586d19f5409de22b3235d85d8476c { public static $files = array ( '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', + '89efb1254ef2d1c5d80096acd12c4098' => __DIR__ . '/..' . '/twig/twig/src/Resources/core.php', + 'ffecb95d45175fd40f75be8a23b34f90' => __DIR__ . '/..' . '/twig/twig/src/Resources/debug.php', + 'c7baa00073ee9c61edf148c51917cfb4' => __DIR__ . '/..' . '/twig/twig/src/Resources/escaper.php', + 'f844ccf1d25df8663951193c3fc307c8' => __DIR__ . '/..' . '/twig/twig/src/Resources/string_loader.php', ); public static $prefixLengthsPsr4 = array ( + 'T' => + array ( + 'Twig\\' => 5, + ), 'S' => array ( 'Symfony\\Polyfill\\Php80\\' => 23, + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Ctype\\' => 23, + 'Symfony\\Component\\Filesystem\\' => 29, + 'SourceSpan\\' => 11, + 'ScssPhp\\ScssPhp\\' => 16, ), 'P' => array ( 'Psr\\Log\\' => 8, + 'Psr\\Http\\Message\\' => 17, 'Psr\\EventDispatcher\\' => 20, 'PhpMqtt\\Client\\' => 15, ), @@ -30,27 +46,68 @@ class ComposerStaticInit071586d19f5409de22b3235d85d8476c array ( 'MyCLabs\\Enum\\' => 13, 'Mustache\\' => 9, + 'MaxMind\\WebService\\' => 19, + 'MaxMind\\Exception\\' => 18, + 'MaxMind\\Db\\' => 11, ), 'L' => array ( + 'League\\Uri\\' => 11, 'League\\Config\\' => 14, 'League\\CommonMark\\' => 18, ), + 'G' => + array ( + 'GeoIp2\\' => 7, + ), 'D' => array ( 'Dflydev\\DotAccessData\\' => 22, ), + 'C' => + array ( + 'Composer\\CaBundle\\' => 18, + ), ); public static $prefixDirsPsr4 = array ( + 'Twig\\' => + array ( + 0 => __DIR__ . '/..' . '/twig/twig/src', + ), 'Symfony\\Polyfill\\Php80\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', ), + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'Symfony\\Component\\Filesystem\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/filesystem', + ), + 'SourceSpan\\' => + array ( + 0 => __DIR__ . '/..' . '/scssphp/source-span/src', + ), + 'ScssPhp\\ScssPhp\\' => + array ( + 0 => __DIR__ . '/..' . '/scssphp/scssphp/src', + ), 'Psr\\Log\\' => array ( 0 => __DIR__ . '/..' . '/psr/log/src', ), + 'Psr\\Http\\Message\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/http-factory/src', + 1 => __DIR__ . '/..' . '/psr/http-message/src', + ), 'Psr\\EventDispatcher\\' => array ( 0 => __DIR__ . '/..' . '/psr/event-dispatcher/src', @@ -72,6 +129,23 @@ class ComposerStaticInit071586d19f5409de22b3235d85d8476c array ( 0 => __DIR__ . '/..' . '/mustache/mustache/src', ), + 'MaxMind\\WebService\\' => + array ( + 0 => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService', + ), + 'MaxMind\\Exception\\' => + array ( + 0 => __DIR__ . '/..' . '/maxmind/web-service-common/src/Exception', + ), + 'MaxMind\\Db\\' => + array ( + 0 => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db', + ), + 'League\\Uri\\' => + array ( + 0 => __DIR__ . '/..' . '/league/uri', + 1 => __DIR__ . '/..' . '/league/uri-interfaces', + ), 'League\\Config\\' => array ( 0 => __DIR__ . '/..' . '/league/config/src', @@ -80,10 +154,18 @@ class ComposerStaticInit071586d19f5409de22b3235d85d8476c array ( 0 => __DIR__ . '/..' . '/league/commonmark/src', ), + 'GeoIp2\\' => + array ( + 0 => __DIR__ . '/..' . '/geoip2/geoip2/src', + ), 'Dflydev\\DotAccessData\\' => array ( 0 => __DIR__ . '/..' . '/dflydev/dot-access-data/src', ), + 'Composer\\CaBundle\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/ca-bundle/src', + ), ); public static $classMap = array ( diff --git a/vendor/composer/ca-bundle/LICENSE b/vendor/composer/ca-bundle/LICENSE new file mode 100644 index 0000000..c5b5220 --- /dev/null +++ b/vendor/composer/ca-bundle/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2016 Composer + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/composer/ca-bundle/README.md b/vendor/composer/ca-bundle/README.md new file mode 100644 index 0000000..d8205ec --- /dev/null +++ b/vendor/composer/ca-bundle/README.md @@ -0,0 +1,85 @@ +composer/ca-bundle +================== + +Small utility library that lets you find a path to the system CA bundle, +and includes a fallback to the Mozilla CA bundle. + +Originally written as part of [composer/composer](https://github.com/composer/composer), +now extracted and made available as a stand-alone library. + + +Installation +------------ + +Install the latest version with: + +```bash +$ composer require composer/ca-bundle +``` + + +Requirements +------------ + +* PHP 5.3.2 is required but using the latest version of PHP is highly recommended. + + +Basic usage +----------- + +### `Composer\CaBundle\CaBundle` + +- `CaBundle::getSystemCaRootBundlePath()`: Returns the system CA bundle path, or a path to the bundled one as fallback +- `CaBundle::getBundledCaBundlePath()`: Returns the path to the bundled CA file +- `CaBundle::validateCaFile($filename)`: Validates a CA file using openssl_x509_parse only if it is safe to use +- `CaBundle::isOpensslParseSafe()`: Test if it is safe to use the PHP function openssl_x509_parse() +- `CaBundle::reset()`: Resets the static caches + + +#### To use with curl + +```php +$curl = curl_init("https://example.org/"); + +$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(); +if (is_dir($caPathOrFile)) { + curl_setopt($curl, CURLOPT_CAPATH, $caPathOrFile); +} else { + curl_setopt($curl, CURLOPT_CAINFO, $caPathOrFile); +} + +$result = curl_exec($curl); +``` + +#### To use with php streams + +```php +$opts = array( + 'http' => array( + 'method' => "GET" + ) +); + +$caPathOrFile = \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath(); +if (is_dir($caPathOrFile)) { + $opts['ssl']['capath'] = $caPathOrFile; +} else { + $opts['ssl']['cafile'] = $caPathOrFile; +} + +$context = stream_context_create($opts); +$result = file_get_contents('https://example.com', false, $context); +``` + +#### To use with Guzzle + +```php +$client = new \GuzzleHttp\Client([ + \GuzzleHttp\RequestOptions::VERIFY => \Composer\CaBundle\CaBundle::getSystemCaRootBundlePath() +]); +``` + +License +------- + +composer/ca-bundle is licensed under the MIT License, see the LICENSE file for details. diff --git a/vendor/composer/ca-bundle/composer.json b/vendor/composer/ca-bundle/composer.json new file mode 100644 index 0000000..c2ce2bb --- /dev/null +++ b/vendor/composer/ca-bundle/composer.json @@ -0,0 +1,54 @@ +{ + "name": "composer/ca-bundle", + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "type": "library", + "license": "MIT", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8 || ^9", + "phpstan/phpstan": "^1.10", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Composer\\CaBundle\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "scripts": { + "test": "@php phpunit", + "phpstan": "@php phpstan analyse" + } +} diff --git a/vendor/composer/ca-bundle/res/cacert.pem b/vendor/composer/ca-bundle/res/cacert.pem new file mode 100644 index 0000000..26ec7f7 --- /dev/null +++ b/vendor/composer/ca-bundle/res/cacert.pem @@ -0,0 +1,2910 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Thu Jul 16 03:12:01 2026 GMT +## +## Find updated versions here: https://curl.se/docs/caextract.html +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## https://raw.githubusercontent.com/mozilla-firefox/firefox/refs/heads/release/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.33. +## SHA256: e57912808daef7b2b0fa4df2ccf17e47aeaf26c839a38f85c76003ebafd866bd +## + + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +======================================== +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT +D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr +IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g +TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp +ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD +VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt +c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth +bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 +IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 +6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc +wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 +3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 +WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU +ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc +lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R +e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j +q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +GDCA TrustAUTH R5 ROOT +====================== +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw +BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD +DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow +YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs +AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p +OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr +pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ +9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ +xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM +R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ +D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4 +oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx +9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9 +H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35 +6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd ++PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ +HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD +F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ +8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv +/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT +aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +SSL.com Root Certification Authority RSA +======================================== +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM +BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x +MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw +MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx +EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM +LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C +Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8 +P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge +oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp +k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z +fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ +gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2 +UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8 +1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s +bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr +dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf +ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl +u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq +erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj +MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ +vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI +Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y +wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI +WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +SSL.com Root Certification Authority ECC +======================================== +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv +BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy +MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO +BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+ +8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR +hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT +jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW +e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z +5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +SSL.com EV Root Certification Authority RSA R2 +============================================== +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w +DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u +MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI +DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD +VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh +hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w +cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO +Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+ +B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh +CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim +9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto +RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm +JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48 ++qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp +qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1 +++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx +Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G +guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz +OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7 +CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq +lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR +rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1 +hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX +9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +SSL.com EV Root Certification Authority ECC +=========================================== +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy +BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw +MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx +EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM +LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy +3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O +BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe +5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ +N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm +m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +GlobalSign Root CA - R6 +======================= +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX +R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i +YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs +U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss +grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE +3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF +vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM +PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+ +azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O +WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy +CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP +0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN +b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE +AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV +HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0 +lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY +BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym +Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr +3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1 +0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T +uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK +oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t +JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GC CA +=============================== +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD +SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo +MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa +Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL +ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr +VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab +NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E +AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk +AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +UCA Global G2 Root +================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG +EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x +NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU +cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT +oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV +8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS +h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o +LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/ +R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe +KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa +4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc +OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97 +8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo +5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A +Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9 +yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX +c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo +jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk +bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x +ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn +RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A== +-----END CERTIFICATE----- + +UCA Extended Validation Root +============================ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG +EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u +IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G +A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs +iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF +Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu +eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR +59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH +0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR +el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv +B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth +WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS +NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS +3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL +BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM +aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4 +dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb ++7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW +F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi +GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc +GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi +djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr +dhh2n1ax +-----END CERTIFICATE----- + +Certigna Root CA +================ +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE +BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ +MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda +MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz +MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX +stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz +KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8 +JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16 +XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq +4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej +wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ +lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI +jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/ +/TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy +dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h +LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl +cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt +OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP +TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq +7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3 +4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd +8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS +6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY +tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS +aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde +E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +emSign Root CA - G1 +=================== +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET +MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl +ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx +ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk +aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN +LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 +cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW +DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ +6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH +hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 +vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q +NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q ++Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih +U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +emSign ECC Root CA - G3 +======================= +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG +A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg +MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 +MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 +ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc +58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr +MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D +CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 +jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +emSign Root CA - C1 +=================== +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx +EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp +Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD +ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up +ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ +Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX +OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V +I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms +lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ +XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp +/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 +NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 +wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ +BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +emSign ECC Root CA - C3 +======================= +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG +A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF +Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD +ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd +6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 +SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA +B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA +MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU +ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 3 +======================= +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG +A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK +Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2 +MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv +bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX +SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz +iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf +jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim +5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe +sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj +0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/ +JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u +y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h ++bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG +xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID +AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN +AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw +W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld +y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov ++BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc +eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw +9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7 +nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY +hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB +60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq +dBb9HxEGmpv0 +-----END CERTIFICATE----- + +Microsoft ECC Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND +IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4 +MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6 +thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB +eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM ++Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf +Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR +eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +Microsoft RSA Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg +UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw +NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u +MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml +7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e +S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7 +1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+ +dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F +yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS +MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr +lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ +0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ +ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og +6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80 +dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk ++ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex +/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy +AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW +ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE +7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT +c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D +5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +e-Szigno Root CA 2017 +===================== +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw +DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt +MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa +Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE +CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp +Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx +s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv +vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA +tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO +svxyqltZ+efcMQ== +-----END CERTIFICATE----- + +certSIGN Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw +EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy +MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH +TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05 +N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk +abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg +wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp +dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh +ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732 +jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf +95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc +z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL +iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud +DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB +ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB +/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5 +8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5 +BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW +atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU +Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M +NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N +0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +NAVER Global Root Certification Authority +========================================= +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG +A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD +DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4 +NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT +UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb +UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW ++j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7 +XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2 +aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4 +Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z +VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B +A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai +cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy +YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV +HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK +21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB +jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx +hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg +E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH +D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ +A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY +qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG +I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg +kpzNNIaRkPpkUZ3+/uul9XXeifdy +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM SERVIDORES SEGUROS +=================================== +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF +UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy +NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4 +MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt +UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB +QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2 +LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG +SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD +zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c= +-----END CERTIFICATE----- + +GlobalSign Root R46 +=================== +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv +b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX +BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es +CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/ +r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje +2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt +bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj +K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4 +12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on +ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls +eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9 +vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM +BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy +gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92 +CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm +OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq +JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye +qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz +nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7 +DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3 +QEUxeCp6 +-----END CERTIFICATE----- + +GlobalSign Root E46 +=================== +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT +AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg +RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV +BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB +jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj +QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL +gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk +vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ +CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +ANF Secure Server Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNVBAUTCUc2MzI4 +NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lv +bjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNVBAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3Qg +Q0EwHhcNMTkwOTA0MTAwMDM4WhcNMzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEw +MQswCQYDVQQGEwJFUzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQw +EgYDVQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9vdCBDQTCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCjcqQZAZ2cC4Ffc0m6p6zz +BE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9qyGFOtibBTI3/TO80sh9l2Ll49a2pcbnv +T1gdpd50IJeh7WhM3pIXS7yr/2WanvtH2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcv +B2VSAKduyK9o7PQUlrZXH1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXse +zx76W0OLzc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyRp1RM +VwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQzW7i1o0TJrH93PB0j +7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/SiOL9V8BY9KHcyi1Swr1+KuCLH5z +JTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJnLNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe +8TZBAQIvfXOn3kLMTOmJDVb3n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVO +Hj1tyRRM4y5Bu8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEATh65isagmD9uw2nAalxJ +UqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzx +j6ptBZNscsdW699QIyjlRRA96Gejrw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDt +dD+4E5UGUcjohybKpFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM +5gf0vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjqOknkJjCb +5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ/zo1PqVUSlJZS2Db7v54 +EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ92zg/LFis6ELhDtjTO0wugumDLmsx2d1H +hk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGy +g77FGr8H6lnco4g175x2MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3 +r5+qPeoott7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +Certum EC-384 CA +================ +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ +TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2 +MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh +dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq +vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn +iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo +ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0 +QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +Certum Trusted Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6MQswCQYDVQQG +EwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0g +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0Ew +HhcNMTgwMzE2MTIxMDEzWhcNNDMwMzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMY +QXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZn0EGze2jusDbCSzBfN8p +fktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/qp1x4EaTByIVcJdPTsuclzxFUl6s1wB52 +HO8AU5853BSlLCIls3Jy/I2z5T4IHhQqNwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2 +fJmItdUDmj0VDT06qKhF8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGt +g/BKEiJ3HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGamqi4 +NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi7VdNIuJGmj8PkTQk +fVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSFytKAQd8FqKPVhJBPC/PgP5sZ0jeJ +P/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0PqafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSY +njYJdmZm/Bo/6khUHL4wvYBQv3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHK +HRzQ+8S1h9E6Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQADggIBAEii1QAL +LtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4WxmB82M+w85bj/UvXgF2Ez8s +ALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvozMrnadyHncI013nR03e4qllY/p0m+jiGPp2K +h2RX5Rc64vmNueMzeMGQ2Ljdt4NR5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8 +CYyqOhNf6DR5UMEQGfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA +4kZf5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq0Uc9Nneo +WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj +6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTMqJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmT +OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck +bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +TunTrust Root CA +================ +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG +A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj +dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw +NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD +ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz +2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b +bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7 +NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd +gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW +VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f +Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ +juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas +DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS +VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI +04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl +0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd +Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY +YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp +adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x +xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP +jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM +MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z +ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r +AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +HARICA TLS RSA Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG +EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz +OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl +bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB +IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN +JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu +a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y +Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K +5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv +dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR +0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH +GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm +haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ +CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU +EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq +QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD +QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR +j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5 +vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0 +qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6 +Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/ +PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn +kf3/W9b3raYvAwtt41dU63ZTGI0RmLo= +-----END CERTIFICATE----- + +HARICA TLS ECC Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH +UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD +QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX +DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj +IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv +b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l +AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b +ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW +0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi +rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw +CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1Ud +DgQWBBRlzeurNR4APn7VdMActHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4w +gZswgZgGBFUdIAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABCAG8AbgBhAG4A +bwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAwADEANzAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9miWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL +4QjbEwj4KKE1soCzC1HA01aajTNFSa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDb +LIpgD7dvlAceHabJhfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1il +I45PVf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZEEAEeiGaP +cjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV1aUsIC+nmCjuRfzxuIgA +LI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2tCsvMo2ebKHTEm9caPARYpoKdrcd7b/+A +lun4jWq9GJAd/0kakFI3ky88Al2CdgtR5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH +9IBk9W6VULgRfhVwOEqwf9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpf +NIbnYrX9ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNKGbqE +ZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +vTrus ECC Root CA +================= +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMwRzELMAkGA1UE +BhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBS +b290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDczMTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAa +BgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+c +ToL0v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUde4BdS49n +TPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIwV53dVvHH4+m4SVBrm2nDb+zDfSXkV5UT +QJtS0zvzQBm8JsctBp61ezaf9SXUY2sAAjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQL +YgmRWAD5Tfs0aNoJrSEGGJTO +-----END CERTIFICATE----- + +vTrus Root CA +============= +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQELBQAwQzELMAkG +A1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xFjAUBgNVBAMTDXZUcnVzIFJv +b3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMxMDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoG +A1UEChMTaVRydXNDaGluYSBDby4sTHRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZots +SKYcIrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykUAyyNJJrI +ZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+GrPSbcKvdmaVayqwlHeF +XgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z98Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KA +YPxMvDVTAWqXcoKv8R1w6Jz1717CbMdHflqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70 +kLJrxLT5ZOrpGgrIDajtJ8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2 +AXPKBlim0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZNpGvu +/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQUqqzApVg+QxMaPnu +1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHWOXSuTEGC2/KmSNGzm/MzqvOmwMVO +9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMBAAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYg +scasGrz2iTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AgEAKbqSSaet8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1jbhd47F18iMjr +jld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvMKar5CKXiNxTKsbhm7xqC5PD4 +8acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIivTDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJn +xDHO2zTlJQNgJXtxmOTAGytfdELSS8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554Wg +icEFOwE30z9J4nfrI8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4 +sEb9b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNBUvupLnKW +nyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1PTi07NEPhmg4NpGaXutIc +SkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929vensBxXVsFy6K2ir40zSbofitzmdHxghm+H +l3s= +-----END CERTIFICATE----- + +ISRG Root X2 +============ +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQswCQYDVQQGEwJV +UzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElT +UkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVT +MSkwJwYDVQQKEyBJbnRlcm5ldCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNS +RyBSb290IFgyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H +ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9ItgKbppb +d9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZIzj0EAwMDaAAwZQIwe3lORlCEwkSHRhtF +cP9Ymd70/aTSVaYgLXTWNLxBo1BfASdWtL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5 +U6VR5CmD1/iQMVtCnwr1/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +HiPKI Root CA - G1 +================== +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xGzAZBgNVBAMMEkhpUEtJ +IFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRaFw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYT +AlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kg +Um9vdCBDQSAtIEcxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0 +o9QwqNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twvVcg3Px+k +wJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6lZgRZq2XNdZ1AYDgr/SE +YYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnzQs7ZngyzsHeXZJzA9KMuH5UHsBffMNsA +GJZMoYFL3QRtU6M9/Aes1MU3guvklQgZKILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfd +hSi8MEyr48KxRURHH+CKFgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj +1jOXTyFjHluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDry+K4 +9a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ/W3c1pzAtH2lsN0/ +Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgMa/aOEmem8rJY5AIJEzypuxC00jBF +8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQD +AgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqcSE5XCV0vrPSl +tJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6FzaZsT0pPBWGTMpWmWSBUdGSquE +wx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9TcXzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07Q +JNBAsNB1CI69aO4I1258EHBGG3zgiLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv +5wiZqAxeJoBF1PhoL5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+Gpz +jLrFNe85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wrkkVbbiVg +hUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+vhV4nYWBSipX3tUZQ9rb +yltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQUYDksswBVLuT1sw5XxJFBAJw/6KXf6vb/ +yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYDVQQLExtHbG9i +YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgwMTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9i +YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkW +ymOxuYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/+wpu+74zyTyjhNUwCgYI +KoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147bmF0774BxL4YSFlhgjICICadVGNA3jdg +UM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +GTS Root R1 +=========== +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7raKb0 +xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnWr4+w +B7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXW +nOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk +9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zq +kUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92wO1A +K/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om3xPX +V2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDW +cfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQAD +ggIBAJ+qQibbC5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuyh6f88/qBVRRi +ClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM47HLwEXWdyzRSjeZ2axfG34ar +J45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8JZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYci +NuaCp+0KueIHoI17eko8cdLiA6EfMgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5me +LMFrUKTX5hgUvYU/Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJF +fbdT6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ0E6yove+ +7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm2tIMPNuzjsmhDYAPexZ3 +FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bbbP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3 +gm3c +-----END CERTIFICATE----- + +GTS Root R3 +=========== +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi +MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMw +HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ +R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24CejQjBA +MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP0/Eq +Er24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azT +L818+FsuVbu/3ZL3pAzcMeGiAjEA/JdmZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV +11RZt+cRLInUue4X +-----END CERTIFICATE----- + +GTS Root R4 +=========== +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi +MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQw +HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ +R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqjQjBA +MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV2Py1 +PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/C +r8deVl5c1RxYIigL9zC2L7F8AjEA8GE8p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh +4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +Telia Root CA v2 +================ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNVBAYT +AkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2 +MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQK +DBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ7 +6zBqAMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9vVYiQJ3q +9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9lRdU2HhE8Qx3FZLgmEKn +pNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTODn3WhUidhOPFZPY5Q4L15POdslv5e2QJl +tI5c0BE0312/UqeBAMN/mUWZFdUXyApT7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW +5olWK8jjfN7j/4nlNW4o6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNr +RBH0pUPCTEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6WT0E +BXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63RDolUK5X6wK0dmBR4 +M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZIpEYslOqodmJHixBTB0hXbOKSTbau +BcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGjYzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7W +xy+G2CQ5MB0GA1UdDgQWBBRyrOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi0f6X+J8wfBj5 +tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMMA8iZGok1GTzTyVR8qPAs5m4H +eW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBSSRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+C +y748fdHif64W1lZYudogsYMVoe+KTTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygC +QMez2P2ccGrGKMOF6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15 +h2Er3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMtTy3EHD70 +sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pTVmBds9hCG1xLEooc6+t9 +xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAWysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQ +raVplI/owd8k+BsHMYeB2F326CjYSlKArBPuUBQemMc= +-----END CERTIFICATE----- + +D-TRUST BR Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7 +dPYSzuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0QVK5buXu +QqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/VbNafAkl1bK6CKBrqx9t +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2JyX3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFWwKrY7RjEsK70Pvom +AjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHVdWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +D-TRUST EV Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8 +ZRCC/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rDwpdhQntJ +raOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3OqQo5FD4pPfsazK2/umL +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2V2X3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR +AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +DigiCert TLS ECC P384 Root G5 +============================= +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4 +NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg +Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd +lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj +n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB +/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds +Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx +AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +DigiCert TLS RSA4096 Root G5 +============================ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG +EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0 +MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2 +IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8 +7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU +AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces +tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa +zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV +DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q +TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy +z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/ +MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk +wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E +FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN +lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN +MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/ +u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G +OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh +47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU +FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ +yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP +bEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +Certainly Root R1 +================= +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE +BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN +MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy +dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O +5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl +8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl +DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI +XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN +KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ +AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb +rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1 +VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS +p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz +HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v +MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB +GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+ +gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH +JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7 +fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw +x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S +X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +Certainly Root E1 +================= +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV +UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0 +MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu +bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4 +fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9 +YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E +AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 +rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +Security Communication ECC RootCA1 +================================== +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD +VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t +dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL +MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV +BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo +5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW +BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK +BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L +snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e +N9k= +-----END CERTIFICATE----- + +BJCA Global Root CA1 +==================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG +EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK +Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG +A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD +DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm +CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS +sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn +P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW +yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj +eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn +MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b +OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh +GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK +H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB +AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ +dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 +60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh +TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW +4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp +GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx +4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps +3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S +SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= +-----END CERTIFICATE----- + +BJCA Global Root CA2 +==================== +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD +TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg +R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE +BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC +SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl +SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK +/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI +1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 +W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g +UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root E46 +============================================= +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH +QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 +ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 +WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 +aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 +NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud +DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH +lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U +SAGKcw== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root R46 +============================================= +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 +OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k +1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf +GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP +FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu +ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz +Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A +wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF +plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ +EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW +6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI +IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp +E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 +exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M +0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI +84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m +pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd +Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b +E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm +J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +SSL.com TLS RSA Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG +EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg +Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC +VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u +9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y +7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac +oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M +R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG +D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW +TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk +8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq +g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk +7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu +N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN +j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by +iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU +o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo +ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib +MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi +vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 +P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 +9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +SSL.com TLS ECC Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v +dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx +GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy +JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 +5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 +81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG +MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w +7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 +Zn6g6g== +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA ECC TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB +dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD +VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg +VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT +AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K +DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS +b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX +NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ +uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY +a3cpetskz2VAv9LcjBHo9H1/IISpQuQo +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA RSA TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD +DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw +CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 +b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV +BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB +l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG +vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK +ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt +0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK +PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY +sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY +Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ +rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa +fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G +CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl +Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX +AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G +slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt +afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q +TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj +1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l +PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W +HYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +TrustAsia Global Root CA G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG +A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM +G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw +MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu +MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz +lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ +Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V +P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag +dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm +9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc +D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg +WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea +mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF +TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj +7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1 +D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T +G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj +duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl +cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys ++TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli +2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y +aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS +ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR +JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH +-----END CERTIFICATE----- + +TrustAsia Global Root CA G4 +=========================== +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE +BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry +dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa +MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw +IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8 +m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/ +pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA +bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk +dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +Telekom Security TLS ECC Root 2020 +================================== +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE +RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl +a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz +NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg +R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG +SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1 +2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC +MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ +Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU +ga/sf+Rn27iQ7t0l +-----END CERTIFICATE----- + +Telekom Security TLS RSA Root 2023 +================================== +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG +EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU +ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy +NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp +dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC +KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP +GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx +UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo +l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9 +FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v +zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg +rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML +KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S +WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+ +sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp +kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy +/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4 +mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz +aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa +oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8 +wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE +HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0 +o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +TWCA CYBER Root CA +================== +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG +EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB +IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s +Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh +V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT +o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT +Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK +/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH +IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM +fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF +2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR +wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83 +QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN +c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x +X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR +IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq +/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R +FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe +Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv +It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl +IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +SecureSign Root CA14 +==================== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG +A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT +ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ +BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU +U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh +1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn +bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb +1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa +/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE +kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx +jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz +ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0 +dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY +AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq +YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA +ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds +Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG +FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q +nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/ +OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa +OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO +pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN +eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S +-----END CERTIFICATE----- + +SecureSign Root CA15 +==================== +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE +BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1 +cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV +BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj +dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G +dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB +2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J +fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ +SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- + +D-TRUST BR Root CA 2 2023 +========================= +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBIMQswCQYDVQQG +EwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0Eg +MiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUwOTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTAT +BgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCT +cfKri3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNEgXtRr90z +sWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8k12b9py0i4a6Ibn08OhZ +WiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCTRphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6 +++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LUL +QyReS2tNZ9/WtT5PeB+UcSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIv +x9gvdhFP/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bSuREV +MweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+0bpwHJwh5Q8xaRfX +/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4NDfTisl01gLmB1IRpkQLLddCNxbU9 +CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUZ5Dw1t61GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRC +MEAwPqA8oDqGOGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tIFoE9c+CeJyrr +d6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67nriv6uvw8l5VAk1/DLQOj7aRv +U9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTRVFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4 +nj8+AybmTNudX0KEPUUDAxxZiMrcLmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdij +YQ6qgYF/6FKC0ULn4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff +/vtDhQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsGkoHU6XCP +pz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46ls/pdu4D58JDUjxqgejB +WoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aSEcr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/ +5usWDiJFAbzdNpQ0qTUmiteXue4Icr80knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jt +n/mtd+ArY0+ew+43u3gJhJ65bvspmZDogNOfJA== +-----END CERTIFICATE----- + +TrustAsia TLS ECC Root CA +========================= +-----BEGIN CERTIFICATE----- +MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMwWDELMAkGA1UE +BhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIjAgBgNVBAMTGVRy +dXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQwNTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBY +MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAG +A1UEAxMZVHJ1c3RBc2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/ +pVs/AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDpguMqWzJ8 +S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49 +BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15K +eAIxAKORh/IRM4PDwYqROkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== +-----END CERTIFICATE----- + +TrustAsia TLS RSA Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEMBQAwWDELMAkG +A1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIjAgBgNVBAMT +GVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcNMjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2 +WjBYMQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEi +MCAGA1UEAxMZVHJ1c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+NmDQDIPN +lOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJQ1DNDX3eRA5gEk9bNb2/ +mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fk +zv93uMltrOXVmPGZLmzjyUT5tUMnCE32ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYo +zza/+lcK7Fs/6TAWe8TbxNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyr +z2I8sMeXi9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQUNoy +IBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+jTnhMmCWr8n4uIF6C +FabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DTbE3txci3OE9kxJRMT6DNrqXGJyV1 +J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnT +q1mt1tve1CuBAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZ +ylomkadFK/hTMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 +Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4iqME3mmL5Dw8 +veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt7DlK9RME7I10nYEKqG/odv6L +TytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHx +tlotJnMnlvm5P1vQiJ3koP26TpUJg3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp +27RIGAAtvKLEiUUjpQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87q +qA8MpugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongPXvPKnbwb +PKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIweSsCI3zWQzj8C9GRh3sfI +B5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNz +FrwFuHnYWa8G5z9nODmxfKuU4CkUpijy323imttUQ/hHWKNddBWcwauwxzQ= +-----END CERTIFICATE----- + +D-TRUST EV Root CA 2 2023 +========================= +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBIMQswCQYDVQQG +EwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0Eg +MiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUwOTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTAT +BgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1 +sJkKF8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE7CUXFId/ +MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFeEMbsh2aJgWi6zCudR3Mf +vc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6lHPTGGkKSv/BAQP/eX+1SH977ugpbzZM +lWGG2Pmic4ruri+W7mjNPU0oQvlFKzIbRlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3 +YG14C8qKXO0elg6DpkiVjTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq910 +7PncjLgcjmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZxTnXo +nMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ARZZaBhDM7DS3LAa +QzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nkhbDhezGdpn9yo7nELC7MmVcOIQxF +AZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knFNXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUqvyREBuHkV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRC +MEAwPqA8oDqGOGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14QvBukEdHjqOS +Mo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4pZt+UPJ26oUFKidBK7GB0aL2 +QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xD +UmPBEcrCRbH0O1P1aa4846XerOhUt7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V +4U/M5d40VxDJI3IXcI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuo +dNv8ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT2vFp4LJi +TZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs7dpn1mKmS00PaaLJvOwi +S5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNPgofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/ +HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAstNl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L ++KIkBI3Y4WNeApI02phhXBxvWHZks/wCuPWdCg== +-----END CERTIFICATE----- + +SwissSign RSA TLS Root CA 2022 - 1 +================================== +-----BEGIN CERTIFICATE----- +MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UEAxMiU3dpc3NTaWduIFJTQSBU +TFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgxMTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJ +BgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0Eg +VExTIFJvb3QgQ0EgMjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmji +C8NXvDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7LCTLf5Im +gKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX5XH8irCRIFucdFJtrhUn +WXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyEEPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlf +GUEGjw5NBuBwQCMBauTLE5tzrE0USJIt/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36q +OTw7D59Ke4LKa2/KIj4x0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLO +EGrOyvi5KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM0ZPl +EuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shdOxtYk8EXlFXIC+OC +eYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrtaclXvyFu1cvh43zcgTFeRc5JzrBh3 +Q4IgaezprClG5QtO+DdziZaKHG29777YtvTKwP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow +4UD2p8P98Q+4DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL +BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO310aewCoSPY6W +lkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgzHqp41eZUBDqyggmNzhYzWUUo +8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQiJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zp +y1FVCypM9fJkT6lc/2cyjlUtMoIcgC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3Cjlvr +zG4ngRhZi0Rjn9UMZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6M +OuhFLhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJpzv1/THfQ +wUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/TdAo9QAwKxuDdollDruF/U +KIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0n +hzck5npgL7XTgwSqT0N1osGDsieYK7EOgLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rw +tnu64ZzZ +-----END CERTIFICATE----- + +OISTE Server Root ECC G1 +======================== +-----BEGIN CERTIFICATE----- +MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQswCQYDVQQGEwJD +SDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwYT0lTVEUgU2VydmVyIFJvb3Qg +RUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUyNDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAX +BgNVBAoMEE9JU1RFIEZvdW5kYXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBH +MTB2MBAGByqGSM49AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOuj +vqQycvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N2xml4z+c +KrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3TYhlz/w9itWj8UnATgwQ +b0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9CtJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqG +SM49BAMDA2kAMGYCMQCpKjAd0MKfkFFRQD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxg +ZzFDJe0CMQCSia7pXGKDYmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c= +-----END CERTIFICATE----- + +OISTE Server Root RSA G1 +======================== +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBLMQswCQYDVQQG +EwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwYT0lTVEUgU2VydmVyIFJv +b3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gx +GTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJT +QSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxV +YOPMvLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7brEi56rAU +jtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzkik/HEzxux9UTl7Ko2yRp +g1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4zO8vbUZeUapU8zhhabkvG/AePLhq5Svdk +NCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8RtOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY ++m0o/DjH40ytas7ZTpOSjswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+ +lKXHiHUhsd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+HomnqT +8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu+zrkL8Fl47l6QGzw +Brd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYRi3drVByjtdgQ8K4p92cIiBdcuJd5 +z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnTkCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAU8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC7 +7EUOSh+1sbM2zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33 +I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG5D1rd9QhEOP2 +8yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8qyiWXmFcuCIzGEgWUOrKL+ml +Sdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dPAGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l +8PjaV8GUgeV6Vg27Rn9vkf195hfkgSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+ +FKrDgHGdPY3ofRRsYWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNq +qYY19tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome/msVuduC +msuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3J8tRd/iWkx7P8nd9H0aT +olkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2wq1yVAb+axj5d9spLFKebXd7Yv0PTY6Y +MjAwcRLWJTXjn/hvnLXrahut6hDTlhZyBiElxky8j3C7DOReIoMt0r7+hVu05L0= +-----END CERTIFICATE----- + +e-Szigno TLS Root CA 2023 +========================= +-----BEGIN CERTIFICATE----- +MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xFzAVBgNVBGEMDlZBVEhV +LTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBUTFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0 +MDAwMFoXDTM4MDcxNzE0MDAwMFowdTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYw +FAYDVQQKDA1NaWNyb3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZ +ZS1Temlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAGgP36J8 +PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFSAL/fjO1ZrTJlqwlZULUZ +wmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/vSzUaQ49CE0y5LBqcvjC2xN7cS53kpDzL +Ltmt3999Cd8ukv+ho2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E +FgQUWYQCYlpGePVd3I8KECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0Uw +CgYIKoZIzj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpty7Ve +7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZlC9p2x1L/Cx6AcCIw +wzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6uWWL +-----END CERTIFICATE----- diff --git a/vendor/composer/ca-bundle/src/CaBundle.php b/vendor/composer/ca-bundle/src/CaBundle.php new file mode 100644 index 0000000..6cf3b84 --- /dev/null +++ b/vendor/composer/ca-bundle/src/CaBundle.php @@ -0,0 +1,322 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\CaBundle; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Process\PhpProcess; + +/** + * @author Chris Smith + * @author Jordi Boggiano + */ +class CaBundle +{ + /** @var string|null */ + private static $caPath; + /** @var array */ + private static $caFileValidity = array(); + + /** + * Returns the system CA bundle path, or a path to the bundled one + * + * This method was adapted from Sslurp. + * https://github.com/EvanDotPro/Sslurp + * + * (c) Evan Coury + * + * For the full copyright and license information, please see below: + * + * Copyright (c) 2013, Evan Coury + * All 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. + * + * 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. + * + * @param LoggerInterface $logger optional logger for information about which CA files were loaded + * @return string path to a CA bundle file or directory + */ + public static function getSystemCaRootBundlePath(?LoggerInterface $logger = null) + { + if (self::$caPath !== null) { + return self::$caPath; + } + $caBundlePaths = array(); + + // If SSL_CERT_FILE env variable points to a valid certificate/bundle, use that. + // This mimics how OpenSSL uses the SSL_CERT_FILE env variable. + $caBundlePaths[] = self::getEnvVariable('SSL_CERT_FILE'); + + // If SSL_CERT_DIR env variable points to a valid certificate/bundle, use that. + // This mimics how OpenSSL uses the SSL_CERT_FILE env variable. + $caBundlePaths[] = self::getEnvVariable('SSL_CERT_DIR'); + + $caBundlePaths[] = ini_get('openssl.cafile'); + $caBundlePaths[] = ini_get('openssl.capath'); + + $otherLocations = array( + '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem', // Fedora, RHEL, CentOS (ca-certificates package) - NEW + '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package) - Deprecated + '/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package) + '/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package) + '/usr/ssl/certs/ca-bundle.crt', // Cygwin + '/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package + '/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option) + '/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat? + '/etc/ssl/cert.pem', // OpenBSD + '/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package + '/usr/local/etc/openssl@1.1/cert.pem', // OS X homebrew, openssl@1.1 package + '/opt/homebrew/etc/openssl@3/cert.pem', // macOS silicon homebrew, openssl@3 package + '/opt/homebrew/etc/openssl@1.1/cert.pem', // macOS silicon homebrew, openssl@1.1 package + '/etc/pki/tls/certs', + '/etc/ssl/certs', // FreeBSD + ); + + $caBundlePaths = array_merge($caBundlePaths, $otherLocations); + + foreach ($caBundlePaths as $caBundle) { + if ($caBundle && self::caFileUsable($caBundle, $logger)) { + return self::$caPath = $caBundle; + } + + if ($caBundle && self::caDirUsable($caBundle, $logger)) { + return self::$caPath = $caBundle; + } + } + + return self::$caPath = static::getBundledCaBundlePath(); // Bundled CA file, last resort + } + + /** + * Returns the path to the bundled CA file + * + * In case you don't want to trust the user or the system, you can use this directly + * + * @return string path to a CA bundle file + */ + public static function getBundledCaBundlePath() + { + $caBundleFile = __DIR__.'/../res/cacert.pem'; + + // cURL does not understand 'phar://' paths + // see https://github.com/composer/ca-bundle/issues/10 + if (0 === strpos($caBundleFile, 'phar://')) { + $tempCaBundleFile = tempnam(sys_get_temp_dir(), 'openssl-ca-bundle-'); + if (false === $tempCaBundleFile) { + throw new \RuntimeException('Could not create a temporary file to store the bundled CA file'); + } + + file_put_contents( + $tempCaBundleFile, + file_get_contents($caBundleFile) + ); + + register_shutdown_function(function() use ($tempCaBundleFile) { + @unlink($tempCaBundleFile); + }); + + $caBundleFile = $tempCaBundleFile; + } + + return $caBundleFile; + } + + /** + * Validates a CA file using opensl_x509_parse only if it is safe to use + * + * @param string $filename + * @param LoggerInterface $logger optional logger for information about which CA files were loaded + * + * @return bool + */ + public static function validateCaFile($filename, ?LoggerInterface $logger = null) + { + static $warned = false; + + if (isset(self::$caFileValidity[$filename])) { + return self::$caFileValidity[$filename]; + } + + $contents = file_get_contents($filename); + + if (is_string($contents) && strlen($contents) > 0) { + $contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents); + if (null === $contents) { + // regex extraction failed + $isValid = false; + } else { + $isValid = (bool) openssl_x509_parse($contents); + } + } else { + $isValid = false; + } + + if ($logger) { + $logger->debug('Checked CA file '.realpath($filename).': '.($isValid ? 'valid' : 'invalid')); + } + + return self::$caFileValidity[$filename] = $isValid; + } + + /** + * Test if it is safe to use the PHP function openssl_x509_parse(). + * + * This checks if OpenSSL extensions is vulnerable to remote code execution + * via the exploit documented as CVE-2013-6420. + * + * @return bool + */ + public static function isOpensslParseSafe() + { + return true; + } + + /** + * Resets the static caches + * @return void + */ + public static function reset() + { + self::$caFileValidity = array(); + self::$caPath = null; + } + + /** + * @param string $name + * @return string|false + */ + private static function getEnvVariable($name) + { + if (isset($_SERVER[$name])) { + return (string) $_SERVER[$name]; + } + + if (PHP_SAPI === 'cli' && ($value = getenv($name)) !== false && $value !== null) { + return (string) $value; + } + + return false; + } + + /** + * @param string|false $certFile + * @param LoggerInterface|null $logger + * @return bool + */ + private static function caFileUsable($certFile, ?LoggerInterface $logger = null) + { + return $certFile + && self::isFile($certFile, $logger) + && self::isReadable($certFile, $logger) + && self::validateCaFile($certFile, $logger); + } + + /** + * @param string|false $certDir + * @param LoggerInterface|null $logger + * @return bool + */ + private static function caDirUsable($certDir, ?LoggerInterface $logger = null) + { + return $certDir + && self::isDir($certDir, $logger) + && self::isReadable($certDir, $logger) + && self::glob($certDir . '/*', $logger); + } + + /** + * @param string $certFile + * @param LoggerInterface|null $logger + * @return bool + */ + private static function isFile($certFile, ?LoggerInterface $logger = null) + { + $isFile = @is_file($certFile); + if (!$isFile && $logger) { + $logger->debug(sprintf('Checked CA file %s does not exist or it is not a file.', $certFile)); + } + + return $isFile; + } + + /** + * @param string $certDir + * @param LoggerInterface|null $logger + * @return bool + */ + private static function isDir($certDir, ?LoggerInterface $logger = null) + { + $isDir = @is_dir($certDir); + if (!$isDir && $logger) { + $logger->debug(sprintf('Checked directory %s does not exist or it is not a directory.', $certDir)); + } + + return $isDir; + } + + /** + * @param string $certFileOrDir + * @param LoggerInterface|null $logger + * @return bool + */ + private static function isReadable($certFileOrDir, ?LoggerInterface $logger = null) + { + $isReadable = @is_readable($certFileOrDir); + if (!$isReadable && $logger) { + $logger->debug(sprintf('Checked file or directory %s is not readable.', $certFileOrDir)); + } + + return $isReadable; + } + + /** + * @param string $pattern + * @param LoggerInterface|null $logger + * @return bool + */ + private static function glob($pattern, ?LoggerInterface $logger = null) + { + $certs = glob($pattern); + if ($certs === false) { + if ($logger) { + $logger->debug(sprintf("An error occurred while trying to find certificates for pattern: %s", $pattern)); + } + return false; + } + + if (count($certs) === 0) { + if ($logger) { + $logger->debug(sprintf("No CA files found for pattern: %s", $pattern)); + } + return false; + } + + return true; + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index f92df74..90cdeb5 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1,5 +1,80 @@ { "packages": [ + { + "name": "composer/ca-bundle", + "version": "1.5.13", + "version_normalized": "1.5.13.0", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "c008272789979f709f7fcb32c2ecf1d2db5e84e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/c008272789979f709f7fcb32c2ecf1d2db5e84e5", + "reference": "c008272789979f709f7fcb32c2ecf1d2db5e84e5", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "time": "2026-07-18T12:35:13+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.5.13" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "install-path": "./ca-bundle" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -78,6 +153,67 @@ }, "install-path": "../dflydev/dot-access-data" }, + { + "name": "geoip2/geoip2", + "version": "v2.13.0", + "version_normalized": "2.13.0.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/GeoIP2-php.git", + "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/6a41d8fbd6b90052bc34dff3b4252d0f88067b23", + "reference": "6a41d8fbd6b90052bc34dff3b4252d0f88067b23", + "shasum": "" + }, + "require": { + "ext-json": "*", + "maxmind-db/reader": "~1.8", + "maxmind/web-service-common": "~0.8", + "php": ">=7.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "3.*" + }, + "time": "2022-08-05T20:32:58+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "GeoIp2\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind GeoIP2 PHP API", + "homepage": "https://github.com/maxmind/GeoIP2-php", + "keywords": [ + "IP", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "support": { + "issues": "https://github.com/maxmind/GeoIP2-php/issues", + "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.13.0" + }, + "install-path": "../geoip2/geoip2" + }, { "name": "league/commonmark", "version": "2.8.0", @@ -273,6 +409,315 @@ ], "install-path": "../league/config" }, + { + "name": "league/uri", + "version": "7.8.1", + "version_normalized": "7.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.8.1", + "php": "^8.1", + "psr/http-factory": "^1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "time": "2026-03-15T20:22:25+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "URN", + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc2141", + "rfc3986", + "rfc3987", + "rfc6570", + "rfc8141", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "install-path": "../league/uri" + }, + { + "name": "league/uri-interfaces", + "version": "7.8.1", + "version_normalized": "7.8.1.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "time": "2026-03-08T20:05:35+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "install-path": "../league/uri-interfaces" + }, + { + "name": "maxmind-db/reader", + "version": "v1.13.1", + "version_normalized": "1.13.1.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git", + "reference": "2194f58d0f024ce923e685cdf92af3daf9951908" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/2194f58d0f024ce923e685cdf92af3daf9951908", + "reference": "2194f58d0f024ce923e685cdf92af3daf9951908", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "ext-maxminddb": "<1.11.1 || >=2.0.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": ">=8.0.0,<10.0.0", + "squizlabs/php_codesniffer": "4.*" + }, + "suggest": { + "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder", + "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups", + "maxmind-db/reader-ext": "C extension for significantly faster IP lookups (install via PIE: pie install maxmind-db/reader-ext)" + }, + "time": "2025-11-21T22:24:26+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MaxMind\\Db\\": "src/MaxMind/Db" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "description": "MaxMind DB Reader API", + "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php", + "keywords": [ + "database", + "geoip", + "geoip2", + "geolocation", + "maxmind" + ], + "support": { + "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues", + "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.13.1" + }, + "install-path": "../maxmind-db/reader" + }, + { + "name": "maxmind/web-service-common", + "version": "v0.11.1", + "version_normalized": "0.11.1.0", + "source": { + "type": "git", + "url": "https://github.com/maxmind/web-service-common-php.git", + "reference": "c309236b5a5555b96cf560089ec3cead12d845d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/c309236b5a5555b96cf560089ec3cead12d845d2", + "reference": "c309236b5a5555b96cf560089ec3cead12d845d2", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0.3", + "ext-curl": "*", + "ext-json": "*", + "php": ">=8.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpstan/phpstan": "*", + "phpunit/phpunit": "^10.0", + "squizlabs/php_codesniffer": "4.*" + }, + "time": "2026-01-13T17:56:03+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MaxMind\\Exception\\": "src/Exception", + "MaxMind\\WebService\\": "src/WebService" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Gregory Oschwald", + "email": "goschwald@maxmind.com" + } + ], + "description": "Internal MaxMind Web Service API", + "homepage": "https://github.com/maxmind/web-service-common-php", + "support": { + "issues": "https://github.com/maxmind/web-service-common-php/issues", + "source": "https://github.com/maxmind/web-service-common-php/tree/v0.11.1" + }, + "install-path": "../maxmind/web-service-common" + }, { "name": "mustache/mustache", "version": "v3.0.0", @@ -668,6 +1113,120 @@ }, "install-path": "../psr/event-dispatcher" }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2024-04-15T12:06:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "install-path": "../psr/http-factory" + }, + { + "name": "psr/http-message", + "version": "2.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:54:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "install-path": "../psr/http-message" + }, { "name": "psr/log", "version": "3.0.2", @@ -721,6 +1280,148 @@ }, "install-path": "../psr/log" }, + { + "name": "scssphp/scssphp", + "version": "v2.1.0", + "version_normalized": "2.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/scssphp/scssphp.git", + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/d8450c2baf5fb07d00374999d0ea51276974d1b6", + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", + "php": ">=8.1", + "scssphp/source-span": "^1.1", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0 || ^8.0" + }, + "require-dev": { + "jgthms/bulma": "~0.9.4", + "jiripudil/phpstan-sealed-classes": "^1.3", + "phpstan/phpstan": "^2.1.31", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpunit/phpunit": "^9.5.6", + "sass/sass-spec": "*", + "squizlabs/php_codesniffer": "^3.13", + "symfony/phpunit-bridge": "^7.3 || ^8.0", + "symfony/polyfill-php84": "^1.33", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0", + "thoughtbot/bourbon": "^7.0", + "twbs/bootstrap": "^5.3", + "twbs/bootstrap4": "4.6.1", + "zurb/foundation": "~6.7.0" + }, + "time": "2025-11-21T17:27:59+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ScssPhp\\ScssPhp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "homepage": "https://github.com/robocoder" + }, + { + "name": "Cédric Morin", + "email": "cedric@yterium.com", + "homepage": "https://github.com/Cerdic" + } + ], + "description": "scssphp is a compiler for SCSS written in PHP.", + "homepage": "https://scssphp.github.io/scssphp/", + "keywords": [ + "css", + "less", + "sass", + "scss", + "stylesheet" + ], + "support": { + "issues": "https://github.com/scssphp/scssphp/issues", + "source": "https://github.com/scssphp/scssphp/tree/v2.1.0" + }, + "install-path": "../scssphp/scssphp" + }, + { + "name": "scssphp/source-span", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/scssphp/source-span.git", + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scssphp/source-span/zipball/37d653206daf11da1ee60b333984101bc4c27ba2", + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", + "php": ">=8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpunit/phpunit": "^9.5.6", + "squizlabs/php_codesniffer": "~3.5", + "symfony/phpunit-bridge": "^6.4 || ^7.3 || ^8.0", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0" + }, + "time": "2025-11-21T16:28:19+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "SourceSpan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "homepage": "https://github.com/stof" + } + ], + "description": "Provides a representation for source code locations and spans.", + "keywords": [ + "parsing" + ], + "support": { + "issues": "https://github.com/scssphp/source-span/issues", + "source": "https://github.com/scssphp/source-span/tree/v1.1.0" + }, + "install-path": "../scssphp/source-span" + }, { "name": "symfony/deprecation-contracts", "version": "v3.6.0", @@ -791,6 +1492,249 @@ ], "install-path": "../symfony/deprecation-contracts" }, + { + "name": "symfony/filesystem", + "version": "v8.1.2", + "version_normalized": "8.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "17856b7a222664a26a5ea1cb06ee0721c2438217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/17856b7a222664a26a5ea1cb06ee0721c2438217", + "reference": "17856b7a222664a26a5ea1cb06ee0721c2438217", + "shasum": "" + }, + "require": { + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^7.4|^8.0" + }, + "time": "2026-07-22T15:42:13+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v8.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/filesystem" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", + "version_normalized": "1.37.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2026-04-10T16:19:22+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-ctype" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "version_normalized": "1.31.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2024-09-09T11:45:10+00:00", + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-mbstring" + }, { "name": "symfony/polyfill-php80", "version": "v1.33.0", @@ -877,6 +1821,89 @@ } ], "install-path": "../symfony/polyfill-php80" + }, + { + "name": "twig/twig", + "version": "v3.28.0", + "version_normalized": "3.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", + "reference": "597c12ed286fb9d1701a36684ce6e0cbe28ebc8b", + "shasum": "" + }, + "require": { + "php": ">=8.1.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "php-cs-fixer/shim": "^3.0@stable", + "phpstan/phpstan": "^2.0@stable", + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" + }, + "time": "2026-07-03T20:44:34+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.28.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "install-path": "../twig/twig" } ], "dev": true, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index d970740..572a232 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'f685c2490ab18e80afa64695135087eeeec57804', + 'reference' => 'd453b8073f07afc24f2a03f94a982977263aa107', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,12 +13,21 @@ '__root__' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => 'f685c2490ab18e80afa64695135087eeeec57804', + 'reference' => 'd453b8073f07afc24f2a03f94a982977263aa107', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), + 'composer/ca-bundle' => array( + 'pretty_version' => '1.5.13', + 'version' => '1.5.13.0', + 'reference' => 'c008272789979f709f7fcb32c2ecf1d2db5e84e5', + 'type' => 'library', + 'install_path' => __DIR__ . '/./ca-bundle', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'dflydev/dot-access-data' => array( 'pretty_version' => 'v3.0.3', 'version' => '3.0.3.0', @@ -28,6 +37,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'geoip2/geoip2' => array( + 'pretty_version' => 'v2.13.0', + 'version' => '2.13.0.0', + 'reference' => '6a41d8fbd6b90052bc34dff3b4252d0f88067b23', + 'type' => 'library', + 'install_path' => __DIR__ . '/../geoip2/geoip2', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'league/commonmark' => array( 'pretty_version' => '2.8.0', 'version' => '2.8.0.0', @@ -46,6 +64,42 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'league/uri' => array( + 'pretty_version' => '7.8.1', + 'version' => '7.8.1.0', + 'reference' => '08cf38e3924d4f56238125547b5720496fac8fd4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../league/uri', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'league/uri-interfaces' => array( + 'pretty_version' => '7.8.1', + 'version' => '7.8.1.0', + 'reference' => '85d5c77c5d6d3af6c54db4a78246364908f3c928', + 'type' => 'library', + 'install_path' => __DIR__ . '/../league/uri-interfaces', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'maxmind-db/reader' => array( + 'pretty_version' => 'v1.13.1', + 'version' => '1.13.1.0', + 'reference' => '2194f58d0f024ce923e685cdf92af3daf9951908', + 'type' => 'library', + 'install_path' => __DIR__ . '/../maxmind-db/reader', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'maxmind/web-service-common' => array( + 'pretty_version' => 'v0.11.1', + 'version' => '0.11.1.0', + 'reference' => 'c309236b5a5555b96cf560089ec3cead12d845d2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../maxmind/web-service-common', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'mustache/mustache' => array( 'pretty_version' => 'v3.0.0', 'version' => '3.0.0.0', @@ -100,6 +154,24 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'psr/http-factory' => array( + 'pretty_version' => '1.1.0', + 'version' => '1.1.0.0', + 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message' => array( + 'pretty_version' => '2.0', + 'version' => '2.0.0.0', + 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'psr/log' => array( 'pretty_version' => '3.0.2', 'version' => '3.0.2.0', @@ -109,6 +181,24 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'scssphp/scssphp' => array( + 'pretty_version' => 'v2.1.0', + 'version' => '2.1.0.0', + 'reference' => 'd8450c2baf5fb07d00374999d0ea51276974d1b6', + 'type' => 'library', + 'install_path' => __DIR__ . '/../scssphp/scssphp', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'scssphp/source-span' => array( + 'pretty_version' => 'v1.1.0', + 'version' => '1.1.0.0', + 'reference' => '37d653206daf11da1ee60b333984101bc4c27ba2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../scssphp/source-span', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'symfony/deprecation-contracts' => array( 'pretty_version' => 'v3.6.0', 'version' => '3.6.0.0', @@ -118,6 +208,33 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'symfony/filesystem' => array( + 'pretty_version' => 'v8.1.2', + 'version' => '8.1.2.0', + 'reference' => '17856b7a222664a26a5ea1cb06ee0721c2438217', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/filesystem', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-ctype' => array( + 'pretty_version' => 'v1.37.0', + 'version' => '1.37.0.0', + 'reference' => '141046a8f9477948ff284fa65be2095baafb94f2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-mbstring' => array( + 'pretty_version' => 'v1.31.0', + 'version' => '1.31.0.0', + 'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'symfony/polyfill-php80' => array( 'pretty_version' => 'v1.33.0', 'version' => '1.33.0.0', @@ -127,5 +244,14 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'twig/twig' => array( + 'pretty_version' => 'v3.28.0', + 'version' => '3.28.0.0', + 'reference' => '597c12ed286fb9d1701a36684ce6e0cbe28ebc8b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../twig/twig', + 'aliases' => array(), + 'dev_requirement' => false, + ), ), ); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 2beb149..4a0153c 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80100)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80401)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.4.1". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/geoip2/geoip2/CHANGELOG.md b/vendor/geoip2/geoip2/CHANGELOG.md new file mode 100644 index 0000000..6af744f --- /dev/null +++ b/vendor/geoip2/geoip2/CHANGELOG.md @@ -0,0 +1,323 @@ +CHANGELOG +========= + +2.13.0 (2022-08-05) +------------------- + +* The model class names are no longer constructed by concatenating strings. + This change was made to improve support for tools like PHP-Scoper. + Reported by Andrew Mead. GitHub #194. +* Box 4.0.1 is now used to generate the `geoip2.phar` file. + +2.12.2 (2021-11-30) +------------------- + +* The `geoip2.phar` now works when included from another directory. + Reported by Eduardo Ruiz. GitHub #179. + +2.12.1 (2021-11-23) +------------------- + +* The `geoip2.phar` included in 2.12.0 would only work in CLI applications. + This was due to a change in Box 3.x. The Phar should now work in all + applications. This release only affects users of the Phar file. + +2.12.0 (2021-11-18) +------------------- + +* Support for mobile country code (MCC) and mobile network codes (MNC) was + added for the GeoIP2 ISP and Enterprise databases as well as the GeoIP2 + City and Insights web services. `$mobileCountryCode` and + `$mobileNetworkCode` properties were added to `GeoIp2\Model\Isp` + for the GeoIP2 ISP database and `GeoIp2\Record\Traits` for the Enterprise + database and the GeoIP2 City and Insights web services. We expect this data + to be available by late January, 2022. +* `geoip2.phar` is now generated with Box 3.x. + +2.11.0 (2020-10-01) +------------------- + +* IMPORTANT: PHP 7.2 or greater is now required. +* Added the `isResidentialProxy` property to `GeoIp2\Model\AnonymousIP` and + `GeoIp2\Record\Traits`. +* Additional type hints have been added. + +2.10.0 (2019-12-12) +------------------- + +* PHP 5.6 or greater is now required. +* The `network` property was added to `GeoIp2\Record\Traits`, + `GeoIp2\Model\AnonymousIp`, `GeoIp2\Model\Asn`, + `GeoIp2\Model\ConnectionType`, `Geoip2\Model\Domain`, + and `GeoIp2\Model\Isp`. This is a string in CIDR format representing the + largest network where all of the properties besides `ipAddress` have the + same value. +* Updated documentation of anonymizer properties - `isAnonymousVpn` + and `isHostingProvider` - to be more descriptive. +* The `userCount` property was added to `GeoIp2\Record\Traits`. This is an + integer which indicates the estimated number of users sharing the + IP/network during the past 24 hours. This output is available from GeoIP2 + Precision Insights. +* The `staticIpScore` property was added to `GeoIp2\Record\Traits`. This is + a float which indicates how static or dynamic an IP address is. This + output is available from GeoIP2 Precision Insights. + +2.9.0 (2018-04-10) +------------------ + +* Refer to account IDs using the terminology "account" rather than "user". + +2.8.0 (2018-01-18) +------------------ + +* The `isInEuropeanUnion` property was added to `GeoIp2\Record\Country` + and `GeoIp2\Record\RepresentedCountry`. This property is `true` if the + country is a member state of the European Union. + +2.7.0 (2017-10-27) +------------------ + +* The following new anonymizer properties were added to `GeoIp2\Record\Traits` + for use with GeoIP2 Precision Insights: `isAnonymous`, `isAnonymousVpn`, + `isHostingProvider`, `isPublicProxy`, and `isTorExitNode`. + +2.6.0 (2017-07-10) +----------------- + +* Code clean-up and tidying. +* Set minimum required PHP version to 5.4 in `composer.json`. Previously, + 5.3 would work but was not tested. Now 5.4 is hard minimum version. + +2.5.0 (2017-05-08) +------------------ + +* Support for PHP 5.3 was dropped. +* Added support for GeoLite2 ASN database. + +2.4.5 (2017-01-31) +------------------ + +* Additional error checking on the data returned from `MaxMind\Db\Reader` + was added to help detect corrupt databases. GitHub #83. + +2.4.4 (2016-10-11) +------------------ + +* `isset()` on `mostSpecificSubdivision` attribute now returns the + correct value. Reported by Juan Francisco Giordana. GitHub #81. + +2.4.3 (2016-10-11) +------------------ + +* `isset()` on `name` attribute now returns the correct value. Reported by + Juan Francisco Giordana. GitHub #79. + +2.4.2 (2016-08-17) +------------------ + +* Updated documentation to clarify what the accuracy radius refers to. +* Upgraded `maxmind/web-service-common` to 0.3.0. This version uses + `composer/ca-bundle` rather than our own CA bundle. GitHub #75. +* Improved PHP documentation generation. + +2.4.1 (2016-06-10) +------------------ + +* Corrected type annotations in documentation. GitHub #66. +* Updated documentation to reflect that the accuracy radius is now included + in City. +* Upgraded web service client, which supports setting a proxy. GitHub #59. + +2.4.0 (2016-04-15) +------------------ + +* Added support for the GeoIP2 Enterprise database. + +2.3.3 (2015-09-24) +------------------ + +* Corrected case on `JsonSerializable` interface. Reported by Axel Etcheverry. + GitHub #56. + +2.3.2 (2015-09-23) +------------------ + +* `JsonSerializable` compatibility interface was moved to `GeoIp2\Compat` + rather than the global namespace to prevent autoloading issues. Reported by + Tomas Buteler. GitHub #54. +* Missing documentation for the `$postal` property was added to the + `GeoIp2\Model\City` class. Fix by Roy Sindre Norangshol. GitHub #51. +* In the Phar distribution, source files for this module no longer have their + documentation stripped, allowing IDE introspection to work properly. + Reported by Dominic Black. GitHub #52. + +2.3.1 (2015-06-30) +------------------ + +* Updated `maxmind/web-service-common` to version with fixes for PHP 5.3 and + 5.4. + +2.3.0 (2015-06-29) +------------------ + +* Support for demographics fields `averageIncome` and `populationDensity` in + the `Location` record, returned by the Insights endpoint. +* The `isAnonymousProxy` and `isSatelliteProvider` properties on + `GeoIP2\Record\Traits` have been deprecated. Please use our [GeoIP2 + Anonymous IP database](https://www.maxmind.com/en/geoip2-anonymous-ip-database) + to determine whether an IP address is used by an anonymizing service. + +2.2.0-beta1 (2015-06-09) +------------------------ + +* Typo fix in documentation. + +2.2.0-alpha2 (2015-06-01) +------------------------- + +* `maxmind-ws/web-service-common` was renamed to `maxmind/web-service-common`. + +2.2.0-alpha1 (2015-05-22) +------------------------- + +* The library no longer uses Guzzle and instead uses curl directly. +* Support for `timeout` and `connectTimout` were added to the `$options` array + passed to the `GeoIp2\WebService\Client` constructor. Pull request by Will + Bradley. GitHub #36. + +2.1.1 (2014-12-03) +------------------ + +* The 2.1.0 Phar builds included a shebang line, causing issues when loading + it as a library. This has been corrected. GitHub #33. + +2.1.0 (2014-10-29) +------------------ + +* Update ApiGen dependency to version that isn't broken on case sensitive + file systems. +* Added support for the GeoIP2 Anonymous IP database. The + `GeoIP2\Database\Reader` class now has an `anonymousIp` method which returns + a `GeoIP2\Model\AnonymousIp` object. +* Boolean attributes like those in the `GeoIP2\Record\Traits` class now return + `false` instead of `null` when they were not true. + +2.0.0 (2014-09-22) +------------------ + +* First production release. + +0.9.0 (2014-09-15) +------------------ + +* IMPORTANT: The deprecated `omni()` and `cityIspOrg()` methods have been + removed from `GeoIp2\WebService\Client`. + +0.8.1 (2014-09-12) +------------------ + +* The check added to the `GeoIP2\Database\Reader` lookup methods in 0.8.0 did + not work with the GeoIP2 City Database Subset by Continent with World + Countries. This has been fixed. Fixes GitHub issue #23. + +0.8.0 (2014-09-10) +------------------ + +* The `GeoIp2\Database\Reader` lookup methods (e.g., `city()`, `isp()`) now + throw a `BadMethodCallException` if they are used with a database that + does not match the method. In particular, doing a `city()` lookup on a + GeoIP2 Country database will result in an exception, and vice versa. +* A `metadata()` method has been added to the `GeoIP2\Database\Reader` class. + This returns a `MaxMind\Db\Reader\Metadata` class with information about the + database. +* The name attribute was missing from the RepresentedCountry class. + +0.7.0 (2014-07-22) +------------------ + +* The web service client API has been updated for the v2.1 release of the web + service. In particular, the `cityIspOrg` and `omni` methods on + `GeoIp2\WebService\Client` should be considered deprecated. The `city` + method now provides all of the data formerly provided by `cityIspOrg`, and + the `omni` method has been replaced by the `insights` method. +* Support was added for GeoIP2 Connection Type, Domain and ISP databases. + + +0.6.3 (2014-05-12) +------------------ + +* With the previous Phar builds, some users received `phar error: invalid url + or non-existent phar` errors. The correct alias is now used for the Phar, + and this should no longer be an issue. + +0.6.2 (2014-05-08) +------------------ + +* The Phar build was broken with Guzzle 3.9.0+. This has been fixed. + +0.6.1 (2014-05-01) +------------------ + +* This API now officially supports HHVM. +* The `maxmind-db/reader` dependency was updated to a version that does not + require BC Math. +* The Composer compatibility autoload rules are now targeted more narrowly. +* A `box.json` file is included to build a Phar package. + +0.6.0 (2014-02-19) +------------------ + +* This API is now licensed under the Apache License, Version 2.0. +* Model and record classes now implement `JsonSerializable`. +* `isset` now works with model and record classes. + +0.5.0 (2013-10-21) +------------------ + +* Renamed $languages constructor parameters to $locales for both the Client + and Reader classes. +* Documentation and code clean-up (Ben Morel). +* Added the interface `GeoIp2\ProviderInterface`, which is implemented by both + `\GeoIp2\Database\Reader` and `\GeoIp2\WebService\Client`. + +0.4.0 (2013-07-16) +------------------ + +* This is the first release with the GeoIP2 database reader. Please see the + `README.md` file and the `\GeoIp2\Database\Reader` class. +* The general exception classes were replaced with specific exception classes + representing particular types of errors, such as an authentication error. + +0.3.0 (2013-07-12) +------------------ + +* In namespaces and class names, "GeoIP2" was renamed to "GeoIp2" to improve + consistency. + +0.2.1 (2013-06-10) +------------------ + +* First official beta release. +* Documentation updates and corrections. + +0.2.0 (2013-05-29) +------------------ + +* `GenericException` was renamed to `GeoIP2Exception`. +* We now support more languages. The new languages are de, es, fr, and pt-BR. +* The REST API now returns a record with data about your account. There is + a new `GeoIP\Records\MaxMind` class for this data. +* The `continentCode` attribute on `Continent` was renamed to `code`. +* Documentation updates. + +0.1.1 (2013-05-14) +------------------ + +* Updated Guzzle version requirement. +* Fixed Composer example in README.md. + + +0.1.0 (2013-05-13) +------------------ + +* Initial release. diff --git a/vendor/geoip2/geoip2/LICENSE b/vendor/geoip2/geoip2/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/vendor/geoip2/geoip2/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/geoip2/geoip2/README.md b/vendor/geoip2/geoip2/README.md new file mode 100644 index 0000000..ea08e27 --- /dev/null +++ b/vendor/geoip2/geoip2/README.md @@ -0,0 +1,442 @@ +# GeoIP2 PHP API # + +## Description ## + +This package provides an API for the GeoIP2 and GeoLite2 +[web services](https://dev.maxmind.com/geoip/docs/web-services?lang=en) and +[databases](https://dev.maxmind.com/geoip/docs/databases?lang=en). + +## Install via Composer ## + +We recommend installing this package with [Composer](https://getcomposer.org/). + +### Download Composer ### + +To download Composer, run in the root directory of your project: + +```bash +curl -sS https://getcomposer.org/installer | php +``` + +You should now have the file `composer.phar` in your project directory. + +### Install Dependencies ### + +Run in your project root: + +```sh +php composer.phar require geoip2/geoip2:~2.0 +``` + +You should now have the files `composer.json` and `composer.lock` as well as +the directory `vendor` in your project directory. If you use a version control +system, `composer.json` should be added to it. + +### Require Autoloader ### + +After installing the dependencies, you need to require the Composer autoloader +from your code: + +```php +require 'vendor/autoload.php'; +``` + +## Install via Phar ## + +Although we strongly recommend using Composer, we also provide a +[phar archive](https://php.net/manual/en/book.phar.php) containing most of the +dependencies for GeoIP2. Our latest phar archive is available on +[our releases page](https://github.com/maxmind/GeoIP2-php/releases). + +### Install Dependencies ### + +In order to use the phar archive, you must have the PHP +[Phar extension](https://php.net/manual/en/book.phar.php) installed and +enabled. + +If you will be making web service requests, you must have the PHP +[cURL extension](https://php.net/manual/en/book.curl.php) +installed to use this archive. For Debian based distributions, this can +typically be found in the the `php-curl` package. For other operating +systems, please consult the relevant documentation. After installing the +extension you may need to restart your web server. + +If you are missing this extension, you will see errors like the following: + +``` +PHP Fatal error: Uncaught Error: Call to undefined function MaxMind\WebService\curl_version() +``` + +### Require Package ### + +To use the archive, just require it from your script: + +```php +require 'geoip2.phar'; +``` + +## Optional C Extension ## + +The [MaxMind DB API](https://github.com/maxmind/MaxMind-DB-Reader-php) +includes an optional C extension that you may install to dramatically increase +the performance of lookups in GeoIP2 or GeoLite2 databases. To install, please +follow the instructions included with that API. + +The extension has no effect on web-service lookups. + +## IP Geolocation Usage ## + +IP geolocation is inherently imprecise. Locations are often near the center of +the population. Any location provided by a GeoIP2 database or web service +should not be used to identify a particular address or household. + +## Database Reader ## + +### Usage ### + +To use this API, you must create a new `\GeoIp2\Database\Reader` object with +the path to the database file as the first argument to the constructor. You +may then call the method corresponding to the database you are using. + +If the lookup succeeds, the method call will return a model class for the +record in the database. This model in turn contains multiple container +classes for the different parts of the data such as the city in which the +IP address is located. + +If the record is not found, a `\GeoIp2\Exception\AddressNotFoundException` +is thrown. If the database is invalid or corrupt, a +`\MaxMind\Db\InvalidDatabaseException` will be thrown. + +See the API documentation for more details. + +### City Example ### + +```php +city('128.101.101.101'); + +print($record->country->isoCode . "\n"); // 'US' +print($record->country->name . "\n"); // 'United States' +print($record->country->names['zh-CN'] . "\n"); // '美国' + +print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' +print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' + +print($record->city->name . "\n"); // 'Minneapolis' + +print($record->postal->code . "\n"); // '55455' + +print($record->location->latitude . "\n"); // 44.9733 +print($record->location->longitude . "\n"); // -93.2323 + +print($record->traits->network . "\n"); // '128.101.101.101/32' + +``` + +### Anonymous IP Example ### + +```php +anonymousIp('128.101.101.101'); + +if ($record->isAnonymous) { print "anon\n"; } +print($record->ipAddress . "\n"); // '128.101.101.101' +print($record->network . "\n"); // '128.101.101.101/32' + +``` + +### Connection-Type Example ### + +```php +connectionType('128.101.101.101'); + +print($record->connectionType . "\n"); // 'Corporate' +print($record->ipAddress . "\n"); // '128.101.101.101' +print($record->network . "\n"); // '128.101.101.101/32' + +``` + +### Domain Example ### + +```php +domain('128.101.101.101'); + +print($record->domain . "\n"); // 'umn.edu' +print($record->ipAddress . "\n"); // '128.101.101.101' +print($record->network . "\n"); // '128.101.101.101/32' + +``` + +### Enterprise Example ### + +```php +enterprise method to do a lookup in the Enterprise database +$record = $reader->enterprise('128.101.101.101'); + +print($record->country->confidence . "\n"); // 99 +print($record->country->isoCode . "\n"); // 'US' +print($record->country->name . "\n"); // 'United States' +print($record->country->names['zh-CN'] . "\n"); // '美国' + +print($record->mostSpecificSubdivision->confidence . "\n"); // 77 +print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' +print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' + +print($record->city->confidence . "\n"); // 60 +print($record->city->name . "\n"); // 'Minneapolis' + +print($record->postal->code . "\n"); // '55455' + +print($record->location->accuracyRadius . "\n"); // 50 +print($record->location->latitude . "\n"); // 44.9733 +print($record->location->longitude . "\n"); // -93.2323 + +print($record->traits->network . "\n"); // '128.101.101.101/32' + +``` + +### ISP Example ### + +```php +isp('128.101.101.101'); + +print($record->autonomousSystemNumber . "\n"); // 217 +print($record->autonomousSystemOrganization . "\n"); // 'University of Minnesota' +print($record->isp . "\n"); // 'University of Minnesota' +print($record->organization . "\n"); // 'University of Minnesota' + +print($record->ipAddress . "\n"); // '128.101.101.101' +print($record->network . "\n"); // '128.101.101.101/32' + +``` + +## Database Updates ## + +You can keep your databases up to date with our +[GeoIP Update program](https://github.com/maxmind/geoipupdate/releases). +[Learn more about GeoIP Update on our developer +portal.](https://dev.maxmind.com/geoip/updating-databases?lang=en) + +There is also a third-party tool for updating databases using PHP and +Composer. MaxMind does not offer support for this tool or maintain it. +[Learn more about the Geoip2 Update tool for PHP and Composer on its +GitHub page.](https://github.com/tronovav/geoip2-update) + +## Web Service Client ## + +### Usage ### + +To use this API, you must create a new `\GeoIp2\WebService\Client` +object with your `$accountId` and `$licenseKey`: + +```php +$client = new Client(42, 'abcdef123456'); +``` + +You may also call the constructor with additional arguments. The third argument +specifies the language preferences when using the `->name` method on the model +classes that this client creates. The fourth argument is additional options +such as `host` and `timeout`. + +For instance, to call the GeoLite2 web service instead of the GeoIP2 web +service: + +```php +$client = new Client(42, 'abcdef123456', ['en'], ['host' => 'geolite.info']); +``` + +After creating the client, you may now call the method corresponding to a +specific endpoint with the IP address to look up, e.g.: + +```php +$record = $client->city('128.101.101.101'); +``` + +If the request succeeds, the method call will return a model class for the +endpoint you called. This model in turn contains multiple record classes, each +of which represents part of the data returned by the web service. + +If there is an error, a structured exception is thrown. + +See the API documentation for more details. + +### Example ### + +```php +city('128.101.101.101'); + +print($record->country->isoCode . "\n"); // 'US' +print($record->country->name . "\n"); // 'United States' +print($record->country->names['zh-CN'] . "\n"); // '美国' + +print($record->mostSpecificSubdivision->name . "\n"); // 'Minnesota' +print($record->mostSpecificSubdivision->isoCode . "\n"); // 'MN' + +print($record->city->name . "\n"); // 'Minneapolis' + +print($record->postal->code . "\n"); // '55455' + +print($record->location->latitude . "\n"); // 44.9733 +print($record->location->longitude . "\n"); // -93.2323 + +print($record->traits->network . "\n"); // '128.101.101.101/32' + +``` + +## Values to use for Database or Array Keys ## + +**We strongly discourage you from using a value from any `names` property as +a key in a database or array.** + +These names may change between releases. Instead we recommend using one of the +following: + +* `GeoIp2\Record\City` - `$city->geonameId` +* `GeoIp2\Record\Continent` - `$continent->code` or `$continent->geonameId` +* `GeoIp2\Record\Country` and `GeoIp2\Record\RepresentedCountry` - + `$country->isoCode` or `$country->geonameId` +* `GeoIp2\Record\Subdivision` - `$subdivision->isoCode` or `$subdivision->geonameId` + +### What data is returned? ### + +While many of the end points return the same basic records, the attributes +which can be populated vary between end points. In addition, while an end +point may offer a particular piece of data, MaxMind does not always have every +piece of data for any given IP address. + +Because of these factors, it is possible for any end point to return a record +where some or all of the attributes are unpopulated. + +See the +[GeoIP2 web service docs](https://dev.maxmind.com/geoip/docs/web-services?lang=en) +for details on what data each end point may return. + +The only piece of data which is always returned is the `ipAddress` +attribute in the `GeoIp2\Record\Traits` record. + +## Integration with GeoNames ## + +[GeoNames](https://www.geonames.org/) offers web services and downloadable +databases with data on geographical features around the world, including +populated places. They offer both free and paid premium data. Each +feature is unique identified by a `geonameId`, which is an integer. + +Many of the records returned by the GeoIP2 web services and databases +include a `geonameId` property. This is the ID of a geographical feature +(city, region, country, etc.) in the GeoNames database. + +Some of the data that MaxMind provides is also sourced from GeoNames. We +source things like place names, ISO codes, and other similar data from +the GeoNames premium data set. + +## Reporting data problems ## + +If the problem you find is that an IP address is incorrectly mapped, +please +[submit your correction to MaxMind](https://www.maxmind.com/en/correction). + +If you find some other sort of mistake, like an incorrect spelling, +please check the [GeoNames site](https://www.geonames.org/) first. Once +you've searched for a place and found it on the GeoNames map view, there +are a number of links you can use to correct data ("move", "edit", +"alternate names", etc.). Once the correction is part of the GeoNames +data set, it will be automatically incorporated into future MaxMind +releases. + +If you are a paying MaxMind customer and you're not sure where to submit +a correction, please +[contact MaxMind support](https://www.maxmind.com/en/support) for help. + +## Other Support ## + +Please report all issues with this code using the +[GitHub issue tracker](https://github.com/maxmind/GeoIP2-php/issues). + +If you are having an issue with a MaxMind service that is not specific +to the client API, please see +[our support page](https://www.maxmind.com/en/support). + +## Requirements ## + +This library requires PHP 7.2 or greater. + +This library also relies on the [MaxMind DB Reader](https://github.com/maxmind/MaxMind-DB-Reader-php). + +## Contributing ## + +Patches and pull requests are encouraged. All code should follow the PSR-2 +style guidelines. Please include unit tests whenever possible. You may obtain +the test data for the maxmind-db folder by running `git submodule update +--init --recursive` or adding `--recursive` to your initial clone, or from +https://github.com/maxmind/MaxMind-DB + +## Versioning ## + +The GeoIP2 PHP API uses [Semantic Versioning](https://semver.org/). + +## Copyright and License ## + +This software is Copyright (c) 2013-2020 by MaxMind, Inc. + +This is free software, licensed under the Apache License, Version 2.0. diff --git a/vendor/geoip2/geoip2/composer.json b/vendor/geoip2/geoip2/composer.json new file mode 100644 index 0000000..e29513b --- /dev/null +++ b/vendor/geoip2/geoip2/composer.json @@ -0,0 +1,32 @@ +{ + "name": "geoip2/geoip2", + "description": "MaxMind GeoIP2 PHP API", + "keywords": ["geoip", "geoip2", "geolocation", "ip", "maxmind"], + "homepage": "https://github.com/maxmind/GeoIP2-php", + "type": "library", + "license": "Apache-2.0", + "authors": [ + { + "name": "Gregory J. Oschwald", + "email": "goschwald@maxmind.com", + "homepage": "https://www.maxmind.com/" + } + ], + "require": { + "maxmind-db/reader": "~1.8", + "maxmind/web-service-common": "~0.8", + "php": ">=7.2", + "ext-json": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "3.*", + "phpunit/phpunit": "^8.0 || ^9.0", + "squizlabs/php_codesniffer": "3.*", + "phpstan/phpstan": "*" + }, + "autoload": { + "psr-4": { + "GeoIp2\\": "src" + } + } +} diff --git a/vendor/geoip2/geoip2/examples/benchmark.php b/vendor/geoip2/geoip2/examples/benchmark.php new file mode 100644 index 0000000..a735a78 --- /dev/null +++ b/vendor/geoip2/geoip2/examples/benchmark.php @@ -0,0 +1,26 @@ +city($ip); + } catch (\GeoIp2\Exception\AddressNotFoundException $e) { + } + if ($i % 10000 === 0) { + echo $i . ' ' . $ip . "\n"; + } +} +$endTime = microtime(true); + +$duration = $endTime - $startTime; +echo 'Requests per second: ' . $count / $duration . "\n"; diff --git a/vendor/geoip2/geoip2/src/Database/Reader.php b/vendor/geoip2/geoip2/src/Database/Reader.php new file mode 100644 index 0000000..4dabc5d --- /dev/null +++ b/vendor/geoip2/geoip2/src/Database/Reader.php @@ -0,0 +1,299 @@ + + */ + private $locales; + + /** + * Constructor. + * + * @param string $filename the path to the GeoIP2 database file + * @param array $locales list of locale codes to use in name property + * from most preferred to least preferred + * + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function __construct( + string $filename, + array $locales = ['en'] + ) { + $this->dbReader = new DbReader($filename); + $this->dbType = $this->dbReader->metadata()->databaseType; + $this->locales = $locales; + } + + /** + * This method returns a GeoIP2 City model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function city(string $ipAddress): City + { + // @phpstan-ignore-next-line + return $this->modelFor(City::class, 'City', $ipAddress); + } + + /** + * This method returns a GeoIP2 Country model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function country(string $ipAddress): Country + { + // @phpstan-ignore-next-line + return $this->modelFor(Country::class, 'Country', $ipAddress); + } + + /** + * This method returns a GeoIP2 Anonymous IP model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function anonymousIp(string $ipAddress): AnonymousIp + { + // @phpstan-ignore-next-line + return $this->flatModelFor( + AnonymousIp::class, + 'GeoIP2-Anonymous-IP', + $ipAddress + ); + } + + /** + * This method returns a GeoLite2 ASN model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function asn(string $ipAddress): Asn + { + // @phpstan-ignore-next-line + return $this->flatModelFor( + Asn::class, + 'GeoLite2-ASN', + $ipAddress + ); + } + + /** + * This method returns a GeoIP2 Connection Type model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function connectionType(string $ipAddress): ConnectionType + { + // @phpstan-ignore-next-line + return $this->flatModelFor( + ConnectionType::class, + 'GeoIP2-Connection-Type', + $ipAddress + ); + } + + /** + * This method returns a GeoIP2 Domain model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function domain(string $ipAddress): Domain + { + // @phpstan-ignore-next-line + return $this->flatModelFor( + Domain::class, + 'GeoIP2-Domain', + $ipAddress + ); + } + + /** + * This method returns a GeoIP2 Enterprise model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function enterprise(string $ipAddress): Enterprise + { + // @phpstan-ignore-next-line + return $this->modelFor(Enterprise::class, 'Enterprise', $ipAddress); + } + + /** + * This method returns a GeoIP2 ISP model. + * + * @param string $ipAddress an IPv4 or IPv6 address as a string + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address is + * not in the database + * @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database + * is corrupt or invalid + */ + public function isp(string $ipAddress): Isp + { + // @phpstan-ignore-next-line + return $this->flatModelFor( + Isp::class, + 'GeoIP2-ISP', + $ipAddress + ); + } + + private function modelFor(string $class, string $type, string $ipAddress): AbstractModel + { + [$record, $prefixLen] = $this->getRecord($class, $type, $ipAddress); + + $record['traits']['ip_address'] = $ipAddress; + $record['traits']['prefix_len'] = $prefixLen; + + return new $class($record, $this->locales); + } + + private function flatModelFor(string $class, string $type, string $ipAddress): AbstractModel + { + [$record, $prefixLen] = $this->getRecord($class, $type, $ipAddress); + + $record['ip_address'] = $ipAddress; + $record['prefix_len'] = $prefixLen; + + return new $class($record); + } + + private function getRecord(string $class, string $type, string $ipAddress): array + { + if (strpos($this->dbType, $type) === false) { + $method = lcfirst((new \ReflectionClass($class))->getShortName()); + + throw new \BadMethodCallException( + "The $method method cannot be used to open a {$this->dbType} database" + ); + } + [$record, $prefixLen] = $this->dbReader->getWithPrefixLen($ipAddress); + if ($record === null) { + throw new AddressNotFoundException( + "The address $ipAddress is not in the database." + ); + } + if (!\is_array($record)) { + // This can happen on corrupt databases. Generally, + // MaxMind\Db\Reader will throw a + // MaxMind\Db\Reader\InvalidDatabaseException, but occasionally + // the lookup may result in a record that looks valid but is not + // an array. This mostly happens when the user is ignoring all + // exceptions and the more frequent InvalidDatabaseException + // exceptions go unnoticed. + throw new InvalidDatabaseException( + "Expected an array when looking up $ipAddress but received: " + . \gettype($record) + ); + } + + return [$record, $prefixLen]; + } + + /** + * @throws \InvalidArgumentException if arguments are passed to the method + * @throws \BadMethodCallException if the database has been closed + * + * @return \MaxMind\Db\Reader\Metadata object for the database + */ + public function metadata(): DbReader\Metadata + { + return $this->dbReader->metadata(); + } + + /** + * Closes the GeoIP2 database and returns the resources to the system. + */ + public function close(): void + { + $this->dbReader->close(); + } +} diff --git a/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php b/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php new file mode 100644 index 0000000..628fb06 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php @@ -0,0 +1,12 @@ +uri = $uri; + parent::__construct($message, $httpStatus, $previous); + } +} diff --git a/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.php b/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.php new file mode 100644 index 0000000..925b68d --- /dev/null +++ b/vendor/geoip2/geoip2/src/Exception/InvalidRequestException.php @@ -0,0 +1,30 @@ +error = $error; + parent::__construct($message, $httpStatus, $uri, $previous); + } +} diff --git a/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.php b/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.php new file mode 100644 index 0000000..9734c8c --- /dev/null +++ b/vendor/geoip2/geoip2/src/Exception/OutOfQueriesException.php @@ -0,0 +1,12 @@ + + */ + protected $raw; + + /** + * @ignore + */ + public function __construct(array $raw) + { + $this->raw = $raw; + } + + /** + * @ignore + * + * @return mixed + */ + protected function get(string $field) + { + if (isset($this->raw[$field])) { + return $this->raw[$field]; + } + if (preg_match('/^is_/', $field)) { + return false; + } + + return null; + } + + /** + * @ignore + * + * @return mixed + */ + public function __get(string $attr) + { + if ($attr !== 'instance' && property_exists($this, $attr)) { + return $this->{$attr}; + } + + throw new \RuntimeException("Unknown attribute: $attr"); + } + + /** + * @ignore + */ + public function __isset(string $attr): bool + { + return $attr !== 'instance' && isset($this->{$attr}); + } + + public function jsonSerialize(): array + { + return $this->raw; + } +} diff --git a/vendor/geoip2/geoip2/src/Model/AnonymousIp.php b/vendor/geoip2/geoip2/src/Model/AnonymousIp.php new file mode 100644 index 0000000..5586bd0 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/AnonymousIp.php @@ -0,0 +1,91 @@ +isAnonymous = $this->get('is_anonymous'); + $this->isAnonymousVpn = $this->get('is_anonymous_vpn'); + $this->isHostingProvider = $this->get('is_hosting_provider'); + $this->isPublicProxy = $this->get('is_public_proxy'); + $this->isResidentialProxy = $this->get('is_residential_proxy'); + $this->isTorExitNode = $this->get('is_tor_exit_node'); + $ipAddress = $this->get('ip_address'); + $this->ipAddress = $ipAddress; + $this->network = Util::cidr($ipAddress, $this->get('prefix_len')); + } +} diff --git a/vendor/geoip2/geoip2/src/Model/Asn.php b/vendor/geoip2/geoip2/src/Model/Asn.php new file mode 100644 index 0000000..f05177e --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/Asn.php @@ -0,0 +1,58 @@ +autonomousSystemNumber = $this->get('autonomous_system_number'); + $this->autonomousSystemOrganization = + $this->get('autonomous_system_organization'); + $ipAddress = $this->get('ip_address'); + $this->ipAddress = $ipAddress; + $this->network = Util::cidr($ipAddress, $this->get('prefix_len')); + } +} diff --git a/vendor/geoip2/geoip2/src/Model/City.php b/vendor/geoip2/geoip2/src/Model/City.php new file mode 100644 index 0000000..b2e81dc --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/City.php @@ -0,0 +1,123 @@ + + */ + protected $subdivisions = []; + + /** + * @ignore + */ + public function __construct(array $raw, array $locales = ['en']) + { + parent::__construct($raw, $locales); + + $this->city = new \GeoIp2\Record\City($this->get('city'), $locales); + $this->location = new \GeoIp2\Record\Location($this->get('location')); + $this->postal = new \GeoIp2\Record\Postal($this->get('postal')); + + $this->createSubdivisions($raw, $locales); + } + + private function createSubdivisions(array $raw, array $locales): void + { + if (!isset($raw['subdivisions'])) { + return; + } + + foreach ($raw['subdivisions'] as $sub) { + $this->subdivisions[] = + new \GeoIp2\Record\Subdivision($sub, $locales) + ; + } + } + + /** + * @ignore + * + * @return mixed + */ + public function __get(string $attr) + { + if ($attr === 'mostSpecificSubdivision') { + return $this->{$attr}(); + } + + return parent::__get($attr); + } + + /** + * @ignore + */ + public function __isset(string $attr): bool + { + if ($attr === 'mostSpecificSubdivision') { + // We always return a mostSpecificSubdivision, even if it is the + // empty subdivision + return true; + } + + return parent::__isset($attr); + } + + private function mostSpecificSubdivision(): \GeoIp2\Record\Subdivision + { + return empty($this->subdivisions) ? + new \GeoIp2\Record\Subdivision([], $this->locales) : + end($this->subdivisions); + } +} diff --git a/vendor/geoip2/geoip2/src/Model/ConnectionType.php b/vendor/geoip2/geoip2/src/Model/ConnectionType.php new file mode 100644 index 0000000..36d4529 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/ConnectionType.php @@ -0,0 +1,50 @@ +connectionType = $this->get('connection_type'); + $ipAddress = $this->get('ip_address'); + $this->ipAddress = $ipAddress; + $this->network = Util::cidr($ipAddress, $this->get('prefix_len')); + } +} diff --git a/vendor/geoip2/geoip2/src/Model/Country.php b/vendor/geoip2/geoip2/src/Model/Country.php new file mode 100644 index 0000000..fdffc63 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/Country.php @@ -0,0 +1,96 @@ + + */ + protected $locales; + + /** + * @var \GeoIp2\Record\MaxMind + */ + protected $maxmind; + + /** + * @var \GeoIp2\Record\Country + */ + protected $registeredCountry; + + /** + * @var \GeoIp2\Record\RepresentedCountry + */ + protected $representedCountry; + + /** + * @var \GeoIp2\Record\Traits + */ + protected $traits; + + /** + * @ignore + */ + public function __construct(array $raw, array $locales = ['en']) + { + parent::__construct($raw); + + $this->continent = new \GeoIp2\Record\Continent( + $this->get('continent'), + $locales + ); + $this->country = new \GeoIp2\Record\Country( + $this->get('country'), + $locales + ); + $this->maxmind = new \GeoIp2\Record\MaxMind($this->get('maxmind')); + $this->registeredCountry = new \GeoIp2\Record\Country( + $this->get('registered_country'), + $locales + ); + $this->representedCountry = new \GeoIp2\Record\RepresentedCountry( + $this->get('represented_country'), + $locales + ); + $this->traits = new \GeoIp2\Record\Traits($this->get('traits')); + + $this->locales = $locales; + } +} diff --git a/vendor/geoip2/geoip2/src/Model/Domain.php b/vendor/geoip2/geoip2/src/Model/Domain.php new file mode 100644 index 0000000..067a507 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/Domain.php @@ -0,0 +1,50 @@ +domain = $this->get('domain'); + $ipAddress = $this->get('ip_address'); + $this->ipAddress = $ipAddress; + $this->network = Util::cidr($ipAddress, $this->get('prefix_len')); + } +} diff --git a/vendor/geoip2/geoip2/src/Model/Enterprise.php b/vendor/geoip2/geoip2/src/Model/Enterprise.php new file mode 100644 index 0000000..c63469b --- /dev/null +++ b/vendor/geoip2/geoip2/src/Model/Enterprise.php @@ -0,0 +1,15 @@ +autonomousSystemNumber = $this->get('autonomous_system_number'); + $this->autonomousSystemOrganization = + $this->get('autonomous_system_organization'); + $this->isp = $this->get('isp'); + $this->mobileCountryCode = $this->get('mobile_country_code'); + $this->mobileNetworkCode = $this->get('mobile_network_code'); + $this->organization = $this->get('organization'); + + $ipAddress = $this->get('ip_address'); + $this->ipAddress = $ipAddress; + $this->network = Util::cidr($ipAddress, $this->get('prefix_len')); + } +} diff --git a/vendor/geoip2/geoip2/src/ProviderInterface.php b/vendor/geoip2/geoip2/src/ProviderInterface.php new file mode 100644 index 0000000..7d14891 --- /dev/null +++ b/vendor/geoip2/geoip2/src/ProviderInterface.php @@ -0,0 +1,22 @@ + + */ + private $locales; + + /** + * @ignore + */ + public function __construct(?array $record, array $locales = ['en']) + { + $this->locales = $locales; + parent::__construct($record); + } + + /** + * @ignore + * + * @return mixed + */ + public function __get(string $attr) + { + if ($attr === 'name') { + return $this->name(); + } + + return parent::__get($attr); + } + + /** + * @ignore + */ + public function __isset(string $attr): bool + { + if ($attr === 'name') { + return $this->firstSetNameLocale() !== null; + } + + return parent::__isset($attr); + } + + private function name(): ?string + { + $locale = $this->firstSetNameLocale(); + + // @phpstan-ignore-next-line + return $locale === null ? null : $this->names[$locale]; + } + + private function firstSetNameLocale(): ?string + { + foreach ($this->locales as $locale) { + if (isset($this->names[$locale])) { + return $locale; + } + } + + return null; + } +} diff --git a/vendor/geoip2/geoip2/src/Record/AbstractRecord.php b/vendor/geoip2/geoip2/src/Record/AbstractRecord.php new file mode 100644 index 0000000..5ddb3c6 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/AbstractRecord.php @@ -0,0 +1,67 @@ + + */ + private $record; + + /** + * @ignore + */ + public function __construct(?array $record) + { + $this->record = isset($record) ? $record : []; + } + + /** + * @ignore + * + * @return mixed + */ + public function __get(string $attr) + { + // XXX - kind of ugly but greatly reduces boilerplate code + $key = $this->attributeToKey($attr); + + if ($this->__isset($attr)) { + return $this->record[$key]; + } + if ($this->validAttribute($attr)) { + if (preg_match('/^is_/', $key)) { + return false; + } + + return null; + } + + throw new \RuntimeException("Unknown attribute: $attr"); + } + + public function __isset(string $attr): bool + { + return $this->validAttribute($attr) + && isset($this->record[$this->attributeToKey($attr)]); + } + + private function attributeToKey(string $attr): string + { + return strtolower(preg_replace('/([A-Z])/', '_\1', $attr)); + } + + private function validAttribute(string $attr): bool + { + // @phpstan-ignore-next-line + return \in_array($attr, $this->validAttributes, true); + } + + public function jsonSerialize(): ?array + { + return $this->record; + } +} diff --git a/vendor/geoip2/geoip2/src/Record/City.php b/vendor/geoip2/geoip2/src/Record/City.php new file mode 100644 index 0000000..f25dcb3 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/City.php @@ -0,0 +1,33 @@ + + */ + protected $validAttributes = ['confidence', 'geonameId', 'names']; +} diff --git a/vendor/geoip2/geoip2/src/Record/Continent.php b/vendor/geoip2/geoip2/src/Record/Continent.php new file mode 100644 index 0000000..103e2e3 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/Continent.php @@ -0,0 +1,36 @@ + + */ + protected $validAttributes = [ + 'code', + 'geonameId', + 'names', + ]; +} diff --git a/vendor/geoip2/geoip2/src/Record/Country.php b/vendor/geoip2/geoip2/src/Record/Country.php new file mode 100644 index 0000000..3009ebc --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/Country.php @@ -0,0 +1,44 @@ + + */ + protected $validAttributes = [ + 'confidence', + 'geonameId', + 'isInEuropeanUnion', + 'isoCode', + 'names', + ]; +} diff --git a/vendor/geoip2/geoip2/src/Record/Location.php b/vendor/geoip2/geoip2/src/Record/Location.php new file mode 100644 index 0000000..cb6111c --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/Location.php @@ -0,0 +1,56 @@ + + */ + protected $validAttributes = [ + 'averageIncome', + 'accuracyRadius', + 'latitude', + 'longitude', + 'metroCode', + 'populationDensity', + 'postalCode', + 'postalConfidence', + 'timeZone', + ]; +} diff --git a/vendor/geoip2/geoip2/src/Record/MaxMind.php b/vendor/geoip2/geoip2/src/Record/MaxMind.php new file mode 100644 index 0000000..e972506 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/MaxMind.php @@ -0,0 +1,23 @@ + + */ + protected $validAttributes = ['queriesRemaining']; +} diff --git a/vendor/geoip2/geoip2/src/Record/Postal.php b/vendor/geoip2/geoip2/src/Record/Postal.php new file mode 100644 index 0000000..3e9c237 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/Postal.php @@ -0,0 +1,30 @@ + + */ + protected $validAttributes = ['code', 'confidence']; +} diff --git a/vendor/geoip2/geoip2/src/Record/RepresentedCountry.php b/vendor/geoip2/geoip2/src/Record/RepresentedCountry.php new file mode 100644 index 0000000..727c034 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/RepresentedCountry.php @@ -0,0 +1,33 @@ +military + * but this could expand to include other types in the future. + */ +class RepresentedCountry extends Country +{ + /** + * @ignore + * + * @var array + */ + protected $validAttributes = [ + 'confidence', + 'geonameId', + 'isInEuropeanUnion', + 'isoCode', + 'names', + 'type', + ]; +} diff --git a/vendor/geoip2/geoip2/src/Record/Subdivision.php b/vendor/geoip2/geoip2/src/Record/Subdivision.php new file mode 100644 index 0000000..0e83549 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/Subdivision.php @@ -0,0 +1,44 @@ + + */ + protected $validAttributes = [ + 'confidence', + 'geonameId', + 'isoCode', + 'names', + ]; +} diff --git a/vendor/geoip2/geoip2/src/Record/Traits.php b/vendor/geoip2/geoip2/src/Record/Traits.php new file mode 100644 index 0000000..8000d50 --- /dev/null +++ b/vendor/geoip2/geoip2/src/Record/Traits.php @@ -0,0 +1,158 @@ +The user type associated with the IP + * address. This can be one of the following values:

+ *
    + *
  • business + *
  • cafe + *
  • cellular + *
  • college + *
  • consumer_privacy_network + *
  • content_delivery_network + *
  • dialup + *
  • government + *
  • hosting + *
  • library + *
  • military + *
  • residential + *
  • router + *
  • school + *
  • search_engine_spider + *
  • traveler + *
+ *

+ * This attribute is only available from the Insights web service and the + * GeoIP2 Enterprise database. + *

+ */ +class Traits extends AbstractRecord +{ + /** + * @ignore + * + * @var array + */ + protected $validAttributes = [ + 'autonomousSystemNumber', + 'autonomousSystemOrganization', + 'connectionType', + 'domain', + 'ipAddress', + 'isAnonymous', + 'isAnonymousProxy', + 'isAnonymousVpn', + 'isHostingProvider', + 'isLegitimateProxy', + 'isp', + 'isPublicProxy', + 'isResidentialProxy', + 'isSatelliteProvider', + 'isTorExitNode', + 'mobileCountryCode', + 'mobileNetworkCode', + 'network', + 'organization', + 'staticIpScore', + 'userCount', + 'userType', + ]; + + public function __construct(?array $record) + { + if (!isset($record['network']) && isset($record['ip_address'], $record['prefix_len'])) { + $record['network'] = Util::cidr($record['ip_address'], $record['prefix_len']); + } + + parent::__construct($record); + } +} diff --git a/vendor/geoip2/geoip2/src/Util.php b/vendor/geoip2/geoip2/src/Util.php new file mode 100644 index 0000000..e0a03be --- /dev/null +++ b/vendor/geoip2/geoip2/src/Util.php @@ -0,0 +1,36 @@ + 0; $i++) { + $b = $ipBytes[$i]; + if ($curPrefix < 8) { + $shiftN = 8 - $curPrefix; + $b = \chr(0xFF & (\ord($b) >> $shiftN) << $shiftN); + } + $networkBytes[$i] = $b; + $curPrefix -= 8; + } + + $network = inet_ntop($networkBytes); + + return "$network/$prefixLen"; + } +} diff --git a/vendor/geoip2/geoip2/src/WebService/Client.php b/vendor/geoip2/geoip2/src/WebService/Client.php new file mode 100644 index 0000000..18d979d --- /dev/null +++ b/vendor/geoip2/geoip2/src/WebService/Client.php @@ -0,0 +1,255 @@ + + */ + private $locales; + + /** + * @var WsClient + */ + private $client; + + /** + * @var string + */ + private static $basePath = '/geoip/v2.1'; + + public const VERSION = 'v2.13.0'; + + /** + * Constructor. + * + * @param int $accountId your MaxMind account ID + * @param string $licenseKey your MaxMind license key + * @param array $locales list of locale codes to use in name property + * from most preferred to least preferred + * @param array $options array of options. Valid options include: + * * `host` - The host to use when querying the web + * service. To query the GeoLite2 web service + * instead of the GeoIP2 web service, set the + * host to `geolite.info`. + * * `timeout` - Timeout in seconds. + * * `connectTimeout` - Initial connection timeout in seconds. + * * `proxy` - The HTTP proxy to use. May include a schema, port, + * username, and password, e.g., + * `http://username:password@127.0.0.1:10`. + */ + public function __construct( + int $accountId, + string $licenseKey, + array $locales = ['en'], + array $options = [] + ) { + $this->locales = $locales; + + // This is for backwards compatibility. Do not remove except for a + // major version bump. + // @phpstan-ignore-next-line + if (\is_string($options)) { + $options = ['host' => $options]; + } + + if (!isset($options['host'])) { + $options['host'] = 'geoip.maxmind.com'; + } + + $options['userAgent'] = $this->userAgent(); + + $this->client = new WsClient($accountId, $licenseKey, $options); + } + + private function userAgent(): string + { + return 'GeoIP2-API/' . self::VERSION; + } + + /** + * This method calls the City Plus service. + * + * @param string $ipAddress IPv4 or IPv6 address as a string. If no + * address is provided, the address that the web service is called + * from will be used. + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address you + * provided is not in our database (e.g., a private address). + * @throws \GeoIp2\Exception\AuthenticationException if there is a problem + * with the account ID or license key that you provided + * @throws \GeoIp2\Exception\OutOfQueriesException if your account is out + * of queries + * @throws \GeoIp2\Exception\InvalidRequestException} if your request was received by the web service but is + * invalid for some other reason. This may indicate an issue + * with this API. Please report the error to MaxMind. + * @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error code or message was returned. + * This could indicate a problem with the connection between + * your server and the web service or that the web service + * returned an invalid document or 500 error code + * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent + * class to the above exceptions. It will be thrown directly + * if a 200 status code is returned but the body is invalid. + */ + public function city(string $ipAddress = 'me'): City + { + // @phpstan-ignore-next-line + return $this->responseFor('city', City::class, $ipAddress); + } + + /** + * This method calls the Country service. + * + * @param string $ipAddress IPv4 or IPv6 address as a string. If no + * address is provided, the address that the web service is called + * from will be used. + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address you provided is not in our database (e.g., + * a private address). + * @throws \GeoIp2\Exception\AuthenticationException if there is a problem + * with the account ID or license key that you provided + * @throws \GeoIp2\Exception\OutOfQueriesException if your account is out of queries + * @throws \GeoIp2\Exception\InvalidRequestException} if your request was received by the web service but is + * invalid for some other reason. This may indicate an + * issue with this API. Please report the error to MaxMind. + * @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error + * code or message was returned. This could indicate a problem + * with the connection between your server and the web service + * or that the web service returned an invalid document or 500 + * error code. + * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent class to the above exceptions. It + * will be thrown directly if a 200 status code is returned but + * the body is invalid. + */ + public function country(string $ipAddress = 'me'): Country + { + return $this->responseFor('country', Country::class, $ipAddress); + } + + /** + * This method calls the Insights service. Insights is only supported by + * the GeoIP2 web service. The GeoLite2 web service does not support it. + * + * @param string $ipAddress IPv4 or IPv6 address as a string. If no + * address is provided, the address that the web service is called + * from will be used. + * + * @throws \GeoIp2\Exception\AddressNotFoundException if the address you + * provided is not in our database (e.g., a private address). + * @throws \GeoIp2\Exception\AuthenticationException if there is a problem + * with the account ID or license key that you provided + * @throws \GeoIp2\Exception\OutOfQueriesException if your account is out + * of queries + * @throws \GeoIp2\Exception\InvalidRequestException} if your request was received by the web service but is + * invalid for some other reason. This may indicate an + * issue with this API. Please report the error to MaxMind. + * @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error code or message was returned. + * This could indicate a problem with the connection between + * your server and the web service or that the web service + * returned an invalid document or 500 error code + * @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent + * class to the above exceptions. It will be thrown directly + * if a 200 status code is returned but the body is invalid. + */ + public function insights(string $ipAddress = 'me'): Insights + { + // @phpstan-ignore-next-line + return $this->responseFor('insights', Insights::class, $ipAddress); + } + + private function responseFor(string $endpoint, string $class, string $ipAddress): Country + { + $path = implode('/', [self::$basePath, $endpoint, $ipAddress]); + + try { + $service = (new \ReflectionClass($class))->getShortName(); + $body = $this->client->get('GeoIP2 ' . $service, $path); + } catch (\MaxMind\Exception\IpAddressNotFoundException $ex) { + throw new AddressNotFoundException( + $ex->getMessage(), + $ex->getStatusCode(), + $ex + ); + } catch (\MaxMind\Exception\AuthenticationException $ex) { + throw new AuthenticationException( + $ex->getMessage(), + $ex->getStatusCode(), + $ex + ); + } catch (\MaxMind\Exception\InsufficientFundsException $ex) { + throw new OutOfQueriesException( + $ex->getMessage(), + $ex->getStatusCode(), + $ex + ); + } catch (\MaxMind\Exception\InvalidRequestException $ex) { + throw new InvalidRequestException( + $ex->getMessage(), + $ex->getErrorCode(), + $ex->getStatusCode(), + $ex->getUri(), + $ex + ); + } catch (\MaxMind\Exception\HttpException $ex) { + throw new HttpException( + $ex->getMessage(), + $ex->getStatusCode(), + $ex->getUri(), + $ex + ); + } catch (\MaxMind\Exception\WebServiceException $ex) { + throw new GeoIp2Exception( + $ex->getMessage(), + $ex->getCode(), + $ex + ); + } + + return new $class($body, $this->locales); + } +} diff --git a/vendor/league/uri-interfaces/Contracts/AuthorityInterface.php b/vendor/league/uri-interfaces/Contracts/AuthorityInterface.php new file mode 100644 index 0000000..9c364f3 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/AuthorityInterface.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use League\Uri\Exceptions\MissingFeature; +use League\Uri\Exceptions\SyntaxError; +use Stringable; + +interface AuthorityInterface extends UriComponentInterface +{ + /** + * Returns the host component of the authority. + */ + public function getHost(): ?string; + + /** + * Returns the port component of the authority. + */ + public function getPort(): ?int; + + /** + * Returns the user information component of the authority. + */ + public function getUserInfo(): ?string; + + /** + * Returns an associative array containing all the Authority components. + * + * The returned a hashmap similar to PHP's parse_url return value + * + * @link https://tools.ietf.org/html/rfc3986 + * + * @return array{user: ?string, pass : ?string, host: ?string, port: ?int} + */ + public function components(): array; + + /** + * Return an instance with the specified host. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified host. + * + * A null value provided for the host is equivalent to removing the host + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + * @throws MissingFeature for component or transformations + * requiring IDN support when IDN support is not present + * or misconfigured. + */ + public function withHost(Stringable|string|null $host): self; + + /** + * Return an instance with the specified port. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified port. + * + * A null value provided for the port is equivalent to removing the port + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withPort(?int $port): self; + + /** + * Return an instance with the specified user information. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified user information. + * + * Password is optional, but the user information MUST include the + * user; a null value for the user is equivalent to removing user + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withUserInfo(Stringable|string|null $user, Stringable|string|null $password = null): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/Conditionable.php b/vendor/league/uri-interfaces/Contracts/Conditionable.php new file mode 100644 index 0000000..385a78c --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/Conditionable.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +interface Conditionable +{ + /** + * Apply the callback if the given "condition" is (or resolves to) true. + * + * @param (callable(static): bool)|bool $condition + * @param callable(static): (static|null) $onSuccess + * @param ?callable(static): (static|null) $onFail + */ + public function when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null): static; +} diff --git a/vendor/league/uri-interfaces/Contracts/DataPathInterface.php b/vendor/league/uri-interfaces/Contracts/DataPathInterface.php new file mode 100644 index 0000000..01f9c40 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/DataPathInterface.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use SplFileObject; +use Stringable; + +interface DataPathInterface extends PathInterface +{ + /** + * Retrieve the data mime type associated to the URI. + * + * If no mimetype is present, this method MUST return the default mimetype 'text/plain'. + * + * @see http://tools.ietf.org/html/rfc2397#section-2 + */ + public function getMimeType(): string; + + /** + * Retrieve the parameters associated with the Mime Type of the URI. + * + * If no parameters is present, this method MUST return the default parameter 'charset=US-ASCII'. + * + * @see http://tools.ietf.org/html/rfc2397#section-2 + */ + public function getParameters(): string; + + /** + * Retrieve the mediatype associated with the URI. + * + * If no mediatype is present, this method MUST return the default parameter 'text/plain;charset=US-ASCII'. + * + * @see http://tools.ietf.org/html/rfc2397#section-3 + * + * @return string The URI scheme. + */ + public function getMediaType(): string; + + /** + * Retrieves the data string. + * + * Retrieves the data part of the path. If no data part is provided return + * an empty string + */ + public function getData(): string; + + /** + * Tells whether the data is binary safe encoded. + */ + public function isBinaryData(): bool; + + /** + * Save the data to a specific file. + */ + public function save(string $path, string $mode = 'w'): SplFileObject; + + /** + * Returns an instance where the data part is base64 encoded. + * + * This method MUST retain the state of the current instance, and return + * an instance where the data part is base64 encoded + */ + public function toBinary(): self; + + /** + * Returns an instance where the data part is url encoded following RFC3986 rules. + * + * This method MUST retain the state of the current instance, and return + * an instance where the data part is url encoded + */ + public function toAscii(): self; + + /** + * Return an instance with the specified mediatype parameters. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified mediatype parameters. + * + * Users must provide encoded characters. + * + * An empty parameters value is equivalent to removing the parameter. + */ + public function withParameters(Stringable|string $parameters): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php b/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php new file mode 100644 index 0000000..a2f1745 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php @@ -0,0 +1,125 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use BackedEnum; +use Countable; +use Iterator; +use IteratorAggregate; +use League\Uri\Exceptions\SyntaxError; +use Stringable; + +/** + * @extends IteratorAggregate + * + * @method bool isSubdomainOf(BackedEnum|Stringable|string|null $parentHost) Tells whether the current domain instance is a subdomain of the parent host. + * @method bool hasSubdomain(BackedEnum|Stringable|string|null $childHost) Tells whether the submitted host is a subdomain of the current instance. + * @method bool isSiblingOf(BackedEnum|Stringable|string|null $siblingHost) Tells whether the submitted host share the same parent domain as the current instance. + * @method static commonAncestorWith(BackedEnum|Stringable|string|null $other) Returns the common longest ancestor between 2 domain. The returned domain is empty if no ancestor is found + * @method static parentHost() Returns the current parent domain for the current instance. The returned domain is empty if no ancestor is found + * @method bool isEmpty() Tells whether the domain contains any label. + */ +interface DomainHostInterface extends Countable, HostInterface, IteratorAggregate +{ + /** + * Returns the labels total number. + */ + public function count(): int; + + /** + * Iterate over the Domain labels. + * + * @return Iterator + */ + public function getIterator(): Iterator; + + /** + * Retrieves a single host label. + * + * If the label offset has not been set, returns the null value. + */ + public function get(int $offset): ?string; + + /** + * Returns the associated key for a specific label or all the keys. + * + * @return int[] + */ + public function keys(?string $label = null): array; + + /** + * Tells whether the domain is absolute. + */ + public function isAbsolute(): bool; + + /** + * Prepends a label to the host. + */ + public function prepend(Stringable|string $label): self; + + /** + * Appends a label to the host. + */ + public function append(Stringable|string $label): self; + + /** + * Extracts a slice of $length elements starting at position $offset from the host. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the selected slice. + * + * If $length is null it returns all elements from $offset to the end of the Domain. + */ + public function slice(int $offset, ?int $length = null): self; + + /** + * Returns an instance with its Root label. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + */ + public function withRootLabel(): self; + + /** + * Returns an instance without its Root label. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + */ + public function withoutRootLabel(): self; + + /** + * Returns an instance with the modified label. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the new label + * + * If $key is non-negative, the added label will be the label at $key position from the start. + * If $key is negative, the added label will be the label at $key position from the end. + * + * @throws SyntaxError If the key is invalid + */ + public function withLabel(int $key, Stringable|string $label): self; + + /** + * Returns an instance without the specified label. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified component + * + * If $key is non-negative, the removed label will be the label at $key position from the start. + * If $key is negative, the removed label will be the label at $key position from the end. + * + * @throws SyntaxError If the key is invalid + */ + public function withoutLabel(int ...$keys): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/FragmentDirective.php b/vendor/league/uri-interfaces/Contracts/FragmentDirective.php new file mode 100644 index 0000000..e85471c --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/FragmentDirective.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use Stringable; + +/** + * @see https://wicg.github.io/scroll-to-text-fragment/#the-fragment-directive + * + * @method string toFragmentValue() returns the encoded string representation of the directive as a fragment string + */ +interface FragmentDirective extends Stringable +{ + /** + * The decoded Directive name. + * + * @return non-empty-string + */ + public function name(): string; + + /** + * The decoded Directive value. + */ + public function value(): ?string; + + /** + * The encoded string representation of the directive. + */ + public function toString(): string; + + /** + * The encoded string representation of the fragment using + * the Stringable interface. + * + * @see FragmentDirective::toString() + */ + public function __toString(): string; + + /** + * Tells whether the submitted value is equals to the string + * representation of the given directive. + */ + public function equals(mixed $directive): bool; +} diff --git a/vendor/league/uri-interfaces/Contracts/FragmentInterface.php b/vendor/league/uri-interfaces/Contracts/FragmentInterface.php new file mode 100644 index 0000000..440a087 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/FragmentInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +/** + * @method self normalize() returns the normalized string representation of the component + */ +interface FragmentInterface extends UriComponentInterface +{ + /** + * Returns the decoded fragment. + */ + public function decoded(): ?string; +} diff --git a/vendor/league/uri-interfaces/Contracts/HostInterface.php b/vendor/league/uri-interfaces/Contracts/HostInterface.php new file mode 100644 index 0000000..48d8abe --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/HostInterface.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +/** + * @method string|null encoded() returns RFC3986 encoded host + */ +interface HostInterface extends UriComponentInterface +{ + /** + * Returns the ascii representation. + */ + public function toAscii(): ?string; + + /** + * Returns the unicode representation. + */ + public function toUnicode(): ?string; + + /** + * Returns the IP version. + * + * If the host is a not an IP this method will return null + */ + public function getIpVersion(): ?string; + + /** + * Returns the IP component If the Host is an IP address. + * + * If the host is a not an IP this method will return null + */ + public function getIp(): ?string; + + /** + * Tells whether the host is a domain name. + */ + public function isDomain(): bool; + + /** + * Tells whether the host is an IP Address. + */ + public function isIp(): bool; + + /** + * Tells whether the host is a registered name. + */ + public function isRegisteredName(): bool; +} diff --git a/vendor/league/uri-interfaces/Contracts/IpHostInterface.php b/vendor/league/uri-interfaces/Contracts/IpHostInterface.php new file mode 100644 index 0000000..7daac22 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/IpHostInterface.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +interface IpHostInterface extends HostInterface +{ + /** + * Tells whether the host is an IPv4 address. + */ + public function isIpv4(): bool; + + /** + * Tells whether the host is an IPv6 address. + */ + public function isIpv6(): bool; + + /** + * Tells whether the host is an IPv6 address. + */ + public function isIpFuture(): bool; + + /** + * Tells whether the host has a ZoneIdentifier. + * + * @see http://tools.ietf.org/html/rfc6874#section-4 + */ + public function hasZoneIdentifier(): bool; + + /** + * Returns a host without its zone identifier according to RFC6874. + * + * This method MUST retain the state of the current instance, and return + * an instance without the host zone identifier according to RFC6874 + * + * @see http://tools.ietf.org/html/rfc6874#section-4 + */ + public function withoutZoneIdentifier(): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/PathInterface.php b/vendor/league/uri-interfaces/Contracts/PathInterface.php new file mode 100644 index 0000000..1408eec --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/PathInterface.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use League\Uri\Exceptions\SyntaxError; + +/** + * @method static normalize() returns the normalized string representation of the component + */ +interface PathInterface extends UriComponentInterface +{ + /** + * Returns the decoded path. + */ + public function decoded(): string; + + /** + * Tells whether the path is absolute or relative. + */ + public function isAbsolute(): bool; + + /** + * Tells whether the path has a trailing slash. + */ + public function hasTrailingSlash(): bool; + + /** + * Returns an instance without dot segments. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the path component normalized by removing + * the dot segment. + * + * @throws SyntaxError for invalid component or transformations + * that would result in a object in invalid state. + */ + public function withoutDotSegments(): self; + + /** + * Returns an instance with a leading slash. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the path component with a leading slash + * + * @throws SyntaxError for invalid component or transformations + * that would result in a object in invalid state. + */ + public function withLeadingSlash(): self; + + /** + * Returns an instance without a leading slash. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the path component without a leading slash + * + * @throws SyntaxError for invalid component or transformations + * that would result in a object in invalid state. + */ + public function withoutLeadingSlash(): self; + + /** + * Returns an instance with a trailing slash. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the path component with a trailing slash + * + * @throws SyntaxError for invalid component or transformations + * that would result in a object in invalid state. + */ + public function withTrailingSlash(): self; + + /** + * Returns an instance without a trailing slash. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the path component without a trailing slash + * + * @throws SyntaxError for invalid component or transformations + * that would result in a object in invalid state. + */ + public function withoutTrailingSlash(): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/PortInterface.php b/vendor/league/uri-interfaces/Contracts/PortInterface.php new file mode 100644 index 0000000..7230c4a --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/PortInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +interface PortInterface extends UriComponentInterface +{ + /** + * Returns the integer representation of the Port. + */ + public function toInt(): ?int; +} diff --git a/vendor/league/uri-interfaces/Contracts/QueryInterface.php b/vendor/league/uri-interfaces/Contracts/QueryInterface.php new file mode 100644 index 0000000..1b2ac33 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/QueryInterface.php @@ -0,0 +1,272 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use BackedEnum; +use Countable; +use Deprecated; +use Iterator; +use IteratorAggregate; +use League\Uri\QueryComposeMode; +use League\Uri\StringCoercionMode; +use Stringable; + +/** + * @extends IteratorAggregate + * + * @method string|null toFormData() Returns the string representation using the application/www-form-urlencoded rules + * @method string|null toRFC3986() Returns the string representation using RFC3986 rules + * @method string|null first(string $key) Returns the first value associated with the given name + * @method string|null last(string $key) Returns the first value associated with the given name + * @method int|null indexOf(string $key, int $nth = 0) Returns the offset of the pair based on its key and its nth occurrence; negative occurrences are supported + * @method int|null indexOfValue(?string $value, int $nth = 0) Returns the offset of the pair based on its value and its nth occurrence; negative occurrences are supported + * @method array pair(int $offset) Returns the key/value pair at the given numeric offset; negative occurrences are supported + * @method int countDistinctKeys() Returns the total number of distinct keys + * @method string|null valueAt(int $offset): Returns the value at the given numeric offset; negative occurrences are supported + * @method string keyAt(int $offset): Returns the key at the given numeric offset; negative occurrences are supported + * @method self normalize() returns the normalized string representation of the component + * @method self withoutPairByKey(string ...$keys) Returns an instance without pairs with the specified keys. + * @method self withoutPairByValue(array|BackedEnum|Stringable|string|int|bool|null $values, StringCoercionMode $coercionMode = StringCoercionMode::Native) Returns an instance without pairs with the specified values. + * @method self withoutPairByKeyValue(string $key, BackedEnum|Stringable|string|int|bool|null $value, StringCoercionMode $coercionMode = StringCoercionMode::Native) Returns an instance without pairs with the specified key/value pair + * @method bool hasPair(string $key, ?string $value) Tells whether the pair exists in the query. + * @method array getList(string $name) Returns the list associated with the given name or an empty array if it does not exist. + * @method bool hasList(string ...$names) Tells whether the parameter list exists in the query. + * @method self appendList(string $name, array $values, QueryComposeMode $composeMode = QueryComposeMode::Native) Appends a parameter to the query string + * @method self withList(string $name, array $values, QueryComposeMode $composeMode = QueryComposeMode::Native) Adds a new parameter to the query string and remove any previously set values + * @method self withoutList(string ...$names) Removes any given list associated with the given names + * @method self withoutLists() Removes all lists from the query string + * @method self onlyLists() Removes all pairs without a valid PHP's bracket notation + */ +interface QueryInterface extends Countable, IteratorAggregate, UriComponentInterface +{ + /** + * Returns the query separator. + * + * @return non-empty-string + */ + public function getSeparator(): string; + + /** + * Returns the number of key/value pairs present in the object. + */ + public function count(): int; + + /** + * Returns an iterator allowing to go through all key/value pairs contained in this object. + * + * The pair is represented as an array where the first value is the pair key + * and the second value the pair value. + * + * The key of each pair is a string + * The value of each pair is a scalar or the null value + * + * @return Iterator + */ + public function getIterator(): Iterator; + + /** + * Returns an iterator allowing to go through all key/value pairs contained in this object. + * + * The return type is as an Iterator where its offset is the pair key and its value the pair value. + * + * The key of each pair is a string + * The value of each pair is a scalar or the null value + * + * @return iterable + */ + public function pairs(): iterable; + + /** + * Tells whether a list of pair with a specific key exists. + * + * @see https://url.spec.whatwg.org/#dom-urlsearchparams-has + */ + public function has(string ...$keys): bool; + + /** + * Returns the first value associated to the given pair name. + * + * If no value is found null is returned + * + * @see https://url.spec.whatwg.org/#dom-urlsearchparams-get + */ + public function get(string $key): ?string; + + /** + * Returns all the values associated to the given pair name as an array or all + * the instance pairs. + * + * If no value is found an empty array is returned + * + * @see https://url.spec.whatwg.org/#dom-urlsearchparams-getall + * + * @return array + */ + public function getAll(string $key): array; + + /** + * Returns the store PHP variables as elements of an array. + * + * The result is similar as PHP parse_str when used with its + * second argument with the difference that variable names are + * not mangled. + * + * @see http://php.net/parse_str + * @see https://wiki.php.net/rfc/on_demand_name_mangling + * + * @return array the collection of stored PHP variables or the empty array if no input is given, + */ + public function parameters(): array; + + /** + * Returns the value attached to the specific key. + * + * The result is similar to PHP parse_str with the difference that variable + * names are not mangled. + * + * If a key is submitted it will return the value attached to it or null + * + * @see http://php.net/parse_str + * @see https://wiki.php.net/rfc/on_demand_name_mangling + * + * @return mixed the collection of stored PHP variables or the empty array if no input is given, + * the single value of a stored PHP variable or null if the variable is not present in the collection + */ + public function parameter(string $name): mixed; + + /** + * Tells whether a list of variable with specific names exists. + * + * @see https://url.spec.whatwg.org/#dom-urlsearchparams-has + */ + public function hasParameter(string ...$names): bool; + + /** + * Returns the RFC1738 encoded query. + */ + public function toRFC1738(): ?string; + + /** + * Returns an instance with a different separator. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the query component with a different separator + */ + public function withSeparator(string $separator): self; + + /** + * Returns an instance with the new pairs set to it. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified query + * + * @see ::withPair + */ + public function merge(Stringable|string $query): self; + + /** + * Returns an instance with the new pairs appended to it. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified query + * + * If the pair already exists the value will be added to it. + */ + public function append(Stringable|string $query): self; + + /** + * Returns a new instance with a specified key/value pair appended as a new pair. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified query + */ + public function appendTo(string $key, Stringable|string|int|bool|null $value): self; + + /** + * Sorts the query string by offset, maintaining offset to data correlations. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified query + * + * @see https://url.spec.whatwg.org/#dom-urlsearchparams-sort + */ + public function sort(): self; + + /** + * Returns an instance without duplicate key/value pair. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the query component normalized by removing + * duplicate pairs whose key/value are the same. + */ + public function withoutDuplicates(): self; + + /** + * Returns an instance without empty key/value where the value is the null value. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the query component normalized by removing + * empty pairs. + * + * A pair is considered empty if its value is equal to the null value + */ + public function withoutEmptyPairs(): self; + + /** + * Returns an instance where numeric indices associated to PHP's array like key are removed. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the query component normalized so that numeric indexes + * are removed from the pair key value. + * + * i.e.: toto[3]=bar[3]&foo=bar becomes toto[]=bar[3]&foo=bar + */ + public function withoutNumericIndices(): self; + + /** + * Returns an instance with a new key/value pair added to it. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified query + * + * If the pair already exists the value will replace the existing value. + * + * @see https://url.spec.whatwg.org/#dom-urlsearchparams-set + */ + public function withPair(string $key, Stringable|string|int|float|bool|null $value): self; + + /** + * DEPRECATION WARNING! This method will be removed in the next major point release. + * + * @deprecated Since version 7.3.0 + * @codeCoverageIgnore + * @see QueryInterface::withoutPairByKey() + * + * Returns an instance without the specified keys. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified component + */ + #[Deprecated(message:'use League\Uri\Contracts\QueryInterface::withoutPairByKey() instead', since:'league/uri-interfaces:7.3.0')] + public function withoutPair(string ...$keys): self; + + /** + * Returns an instance without the specified params. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified component without PHP's value. + * PHP's mangled is not taken into account. + */ + public function withoutParameters(string ...$names): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php b/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php new file mode 100644 index 0000000..87355f4 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use Countable; +use Iterator; +use IteratorAggregate; +use League\Uri\Exceptions\SyntaxError; +use Stringable; + +/** + * @extends IteratorAggregate + */ +interface SegmentedPathInterface extends Countable, IteratorAggregate, PathInterface +{ + /** + * Returns the total number of segments in the path. + */ + public function count(): int; + + /** + * Iterate over the path segment. + * + * @return Iterator + */ + public function getIterator(): Iterator; + + /** + * Returns parent directory's path. + */ + public function getDirname(): string; + + /** + * Returns the path basename. + */ + public function getBasename(): string; + + /** + * Returns the basename extension. + */ + public function getExtension(): string; + + /** + * Retrieves a single path segment. + * + * If the segment offset has not been set, returns null. + */ + public function get(int $offset): ?string; + + /** + * Returns the associated key for a specific segment. + * + * If a value is specified only the keys associated with + * the given value will be returned + * + * @return array + */ + public function keys(Stringable|string|null $segment = null): array; + + /** + * Appends a segment to the path. + */ + public function append(Stringable|string $path): self; + + /** + * Extracts a slice of $length elements starting at position $offset from the host. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the selected slice. + * + * If $length is null it returns all elements from $offset to the end of the Path. + */ + public function slice(int $offset, ?int $length = null): self; + + /** + * Prepends a segment to the path. + */ + public function prepend(Stringable|string $path): self; + + /** + * Returns an instance with the modified segment. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the new segment + * + * If $key is non-negative, the added segment will be the segment at $key position from the start. + * If $key is negative, the added segment will be the segment at $key position from the end. + * + * @throws SyntaxError If the key is invalid + */ + public function withSegment(int $key, Stringable|string $segment): self; + + /** + * Returns an instance without the specified segment. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the modified component + * + * If $key is non-negative, the removed segment will be the segment at $key position from the start. + * If $key is negative, the removed segment will be the segment at $key position from the end. + * + * @throws SyntaxError If the key is invalid + */ + public function withoutSegment(int ...$keys): self; + + /** + * Returns an instance without duplicate delimiters. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the path component normalized by removing + * multiple consecutive empty segment + */ + public function withoutEmptySegments(): self; + + /** + * Returns an instance with the specified parent directory's path. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the extension basename modified. + */ + public function withDirname(Stringable|string $path): self; + + /** + * Returns an instance with the specified basename. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the extension basename modified. + */ + public function withBasename(Stringable|string $basename): self; + + /** + * Returns an instance with the specified basename extension. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the extension basename modified. + */ + public function withExtension(Stringable|string $extension): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/Transformable.php b/vendor/league/uri-interfaces/Contracts/Transformable.php new file mode 100644 index 0000000..957fa50 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/Transformable.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +interface Transformable +{ + /** + * Apply a transformation to this instance and return a new instance. + * + * This method MUST retain the state of the current instance, and return + * a new instance of the same type. + * + * @param callable(static): static $callback + */ + public function transform(callable $callback): static; +} diff --git a/vendor/league/uri-interfaces/Contracts/UriAccess.php b/vendor/league/uri-interfaces/Contracts/UriAccess.php new file mode 100644 index 0000000..a74da57 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/UriAccess.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use Psr\Http\Message\UriInterface as Psr7UriInterface; + +/** + * @deprecated since version 7.6.0 + */ +interface UriAccess +{ + public function getUri(): UriInterface|Psr7UriInterface; + + /** + * Returns the RFC3986 string representation of the complete URI. + */ + public function getUriString(): string; +} diff --git a/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php b/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php new file mode 100644 index 0000000..fa550aa --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use JsonSerializable; +use Stringable; + +/** + * @method static when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null) conditionally return a new instance + * @method bool equals(mixed $value) tells whether the submitted value is equal to the current instance value + */ +interface UriComponentInterface extends JsonSerializable, Stringable +{ + /** + * Returns the instance string representation. + * + * If the instance is defined, the value returned MUST be percent-encoded, + * but MUST NOT double-encode any characters. To determine what characters + * to encode, please refer to RFC 3986, Sections 2 and 3. + * + * If the instance is not defined null is returned + */ + public function value(): ?string; + + /** + * Returns the instance string representation. + * + * If the instance is defined, the value returned MUST be percent-encoded, + * but MUST NOT double-encode any characters. To determine what characters + * to encode, please refer to RFC 3986, Sections 2 and 3. + * + * If the instance is not defined, an empty string is returned + */ + public function toString(): string; + + /** + * Returns the instance string representation. + * + * If the instance is defined, the value returned MUST be percent-encoded, + * but MUST NOT double-encode any characters. To determine what characters + * to encode, please refer to RFC 3986, Sections 2 and 3. + * + * If the instance is not defined, an empty string is returned + */ + public function __toString(): string; + + /** + * Returns the instance json representation. + * + * If the instance is defined, the value returned MUST be percent-encoded, + * but MUST NOT double-encode any characters. To determine what characters + * to encode, please refer to RFC 3986 or RFC 1738. + * + * If the instance is not defined, null is returned + */ + public function jsonSerialize(): ?string; + + /** + * Returns the instance string representation with its optional URI delimiters. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode any + * characters. To determine what characters to encode, please refer to RFC 3986, + * Sections 2 and 3. + * + * If the instance is not defined, an empty string is returned + */ + public function getUriComponent(): string; +} diff --git a/vendor/league/uri-interfaces/Contracts/UriException.php b/vendor/league/uri-interfaces/Contracts/UriException.php new file mode 100644 index 0000000..c0fec2a --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/UriException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use Throwable; + +interface UriException extends Throwable +{ +} diff --git a/vendor/league/uri-interfaces/Contracts/UriInterface.php b/vendor/league/uri-interfaces/Contracts/UriInterface.php new file mode 100644 index 0000000..60e6c8e --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/UriInterface.php @@ -0,0 +1,321 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use JsonSerializable; +use League\Uri\Exceptions\MissingFeature; +use League\Uri\Exceptions\SyntaxError; +use League\Uri\UriString; +use Stringable; + +/** + * @phpstan-import-type ComponentMap from UriString + * + * @method string|null getUsername() returns the user component of the URI. + * @method self withUsername(?string $user) returns a new URI instance with the user component updated. + * @method string|null getPassword() returns the scheme-specific information about how to gain authorization to access the resource. + * @method self withPassword(?string $password) returns a new URI instance with the password component updated. + * @method string toAsciiString() returns the string representation of the URI in its RFC3986 form + * @method string toUnicodeString() returns the string representation of the URI in its RFC3987 form (the host is in its IDN form) + * @method array toComponents() returns an associative array containing all the URI components. + * @method self normalize() returns a new URI instance with normalized components + * @method self resolve(UriInterface $uri) resolves a URI against a base URI using RFC3986 rules + * @method self relativize(UriInterface $uri) relativize a URI against a base URI using RFC3986 rules + */ +interface UriInterface extends JsonSerializable, Stringable +{ + /** + * Returns the string representation as a URI reference. + * + * @see http://tools.ietf.org/html/rfc3986#section-4.1 + */ + public function __toString(): string; + + /** + * Returns the string representation as a URI reference. + * + * @see http://tools.ietf.org/html/rfc3986#section-4.1 + */ + public function toString(): string; + + /** + * Returns the string representation as a URI reference. + * + * @see http://tools.ietf.org/html/rfc3986#section-4.1 + * @see ::__toString + */ + public function jsonSerialize(): string; + + /** + * Retrieve the scheme component of the URI. + * + * If no scheme is present, this method MUST return a null value. + * + * The value returned MUST be normalized to lowercase, per RFC 3986 + * Section 3.1. + * + * The trailing ":" character is not part of the scheme and MUST NOT be + * added. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.1 + */ + public function getScheme(): ?string; + + /** + * Retrieve the authority component of the URI. + * + * If no scheme is present, this method MUST return a null value. + * + * If the port component is not set or is the standard port for the current + * scheme, it SHOULD NOT be included. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2 + */ + public function getAuthority(): ?string; + + /** + * Retrieve the user information component of the URI. + * + * If no scheme is present, this method MUST return a null value. + * + * If a user is present in the URI, this will return that value; + * additionally, if the password is also present, it will be appended to the + * user value, with a colon (":") separating the values. + * + * The trailing "@" character is not part of the user information and MUST + * NOT be added. + */ + public function getUserInfo(): ?string; + + /** + * Retrieve the host component of the URI. + * + * If no host is present this method MUST return a null value. + * + * The value returned MUST be normalized to lowercase, per RFC 3986 + * Section 3.2.2. + * + * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 + */ + public function getHost(): ?string; + + /** + * Retrieve the port component of the URI. + * + * If a port is present, and it is non-standard for the current scheme, + * this method MUST return it as an integer. If the port is the standard port + * used with the current scheme, this method SHOULD return null. + * + * If no port is present, and no scheme is present, this method MUST return + * a null value. + * + * If no port is present, but a scheme is present, this method MAY return + * the standard port for that scheme, but SHOULD return null. + */ + public function getPort(): ?int; + + /** + * Retrieve the path component of the URI. + * + * The path can either be empty or absolute (starting with a slash) or + * rootless (not starting with a slash). Implementations MUST support all + * three syntaxes. + * + * Normally, the empty path "" and absolute path "/" are considered equal as + * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically + * do this normalization because in contexts with a trimmed base path, e.g. + * the front controller, this difference becomes significant. It's the task + * of the user to handle both "" and "/". + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986, Sections 2 and 3.3. + * + * As an example, if the value should include a slash ("/") not intended as + * delimiter between path segments, that value MUST be passed in encoded + * form (e.g., "%2F") to the instance. + * + * @see https://tools.ietf.org/html/rfc3986#section-2 + * @see https://tools.ietf.org/html/rfc3986#section-3.3 + */ + public function getPath(): string; + + /** + * Retrieve the query string of the URI. + * + * If no host is present this method MUST return a null value. + * + * The leading "?" character is not part of the query and MUST NOT be + * added. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986, Sections 2 and 3.4. + * + * As an example, if a value in a key/value pair of the query string should + * include an ampersand ("&") not intended as a delimiter between values, + * that value MUST be passed in encoded form (e.g., "%26") to the instance. + * + * @see https://tools.ietf.org/html/rfc3986#section-2 + * @see https://tools.ietf.org/html/rfc3986#section-3.4 + */ + public function getQuery(): ?string; + + /** + * Retrieve the fragment component of the URI. + * + * If no host is present this method MUST return a null value. + * + * The leading "#" character is not part of the fragment and MUST NOT be + * added. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986, Sections 2 and 3.5. + * + * @see https://tools.ietf.org/html/rfc3986#section-2 + * @see https://tools.ietf.org/html/rfc3986#section-3.5 + */ + public function getFragment(): ?string; + + /** + * Returns an associative array containing all the URI components. + * + * The returned array is similar to PHP's parse_url return value with the following + * differences: + * + *
    + *
  • All components are present in the returned array
  • + *
  • Empty and undefined component are treated differently. And empty component is + * set to the empty string while an undefined component is set to the `null` value.
  • + *
+ * + * @link https://tools.ietf.org/html/rfc3986 + * + * @return ComponentMap + */ + public function getComponents(): array; + + /** + * Return an instance with the specified scheme. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified scheme. + * + * A null value provided for the scheme is equivalent to removing the scheme + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withScheme(Stringable|string|null $scheme): self; + + /** + * Return an instance with the specified user information. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified user information. + * + * Password is optional, but the user information MUST include the + * user; a null value for the user is equivalent to removing user + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withUserInfo(Stringable|string|null $user, Stringable|string|null $password = null): self; + + /** + * Return an instance with the specified host. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified host. + * + * A null value provided for the host is equivalent to removing the host + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + * @throws MissingFeature for component or transformations + * requiring IDN support when IDN support is not present + * or misconfigured. + */ + public function withHost(Stringable|string|null $host): self; + + /** + * Return an instance with the specified port. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified port. + * + * A null value provided for the port is equivalent to removing the port + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withPort(?int $port): self; + + /** + * Return an instance with the specified path. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified path. + * + * The path can either be empty or absolute (starting with a slash) or + * rootless (not starting with a slash). Implementations MUST support all + * three syntaxes. + * + * Users can provide both encoded and decoded path characters. + * Implementations ensure the correct encoding as outlined in getPath(). + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withPath(Stringable|string $path): self; + + /** + * Return an instance with the specified query string. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified query string. + * + * Users can provide both encoded and decoded query characters. + * Implementations ensure the correct encoding as outlined in getQuery(). + * + * A null value provided for the query is equivalent to removing the query + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withQuery(Stringable|string|null $query): self; + + /** + * Return an instance with the specified URI fragment. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified URI fragment. + * + * Users can provide both encoded and decoded fragment characters. + * Implementations ensure the correct encoding as outlined in getFragment(). + * + * A null value provided for the fragment is equivalent to removing the fragment + * information. + * + * @throws SyntaxError for invalid component or transformations + * that would result in an object in invalid state. + */ + public function withFragment(Stringable|string|null $fragment): self; +} diff --git a/vendor/league/uri-interfaces/Contracts/UserInfoInterface.php b/vendor/league/uri-interfaces/Contracts/UserInfoInterface.php new file mode 100644 index 0000000..bd36b86 --- /dev/null +++ b/vendor/league/uri-interfaces/Contracts/UserInfoInterface.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use Stringable; + +interface UserInfoInterface extends UriComponentInterface +{ + /** + * Returns the user component part. + */ + public function getUser(): ?string; + + /** + * Returns the pass component part. + */ + public function getPass(): ?string; + + /** + * Returns an associative array containing all the User Info components. + * + * The returned a hashmap similar to PHP's parse_url return value + * + * @link https://tools.ietf.org/html/rfc3986 + * + * @return array{user: ?string, pass : ?string} + */ + public function components(): array; + + /** + * Returns an instance with the specified user and/or pass. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified new username + * otherwise it returns the same instance unchanged. + * + * A variable equal to null is equivalent to removing the complete user information. + */ + public function withUser(Stringable|string|null $username): self; + + /** + * Returns an instance with the specified user and/or pass. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified password if the user is specified + * otherwise it returns the same instance unchanged. + * + * An empty user is equivalent to removing the user information. + */ + public function withPass(Stringable|string|null $password): self; +} diff --git a/vendor/league/uri-interfaces/Encoder.php b/vendor/league/uri-interfaces/Encoder.php new file mode 100644 index 0000000..cbd3f2e --- /dev/null +++ b/vendor/league/uri-interfaces/Encoder.php @@ -0,0 +1,506 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri; + +use BackedEnum; +use Closure; +use Deprecated; +use League\Uri\Exceptions\SyntaxError; +use League\Uri\IPv6\Converter as IPv6Converter; +use SensitiveParameter; +use Stringable; +use Throwable; + +use function explode; +use function filter_var; +use function gettype; +use function in_array; +use function preg_match; +use function preg_replace_callback; +use function rawurldecode; +use function rawurlencode; +use function sprintf; +use function str_starts_with; +use function strtolower; +use function strtoupper; + +use const FILTER_FLAG_IPV4; +use const FILTER_VALIDATE_IP; + +final class Encoder +{ + private const REGEXP_CHARS_INVALID = '/[\x00-\x1f\x7f]/'; + private const REGEXP_CHARS_ENCODED = ',%[A-Fa-f0-9]{2},'; + private const REGEXP_CHARS_PREVENTS_DECODING = ',% + 2[A-F|1-2|4-9]| + 3[0-9|B|D]| + 4[1-9|A-F]| + 5[0-9|A|F]| + 6[1-9|A-F]| + 7[0-9|E] + ,ix'; + private const REGEXP_PART_SUBDELIM = "\!\$&'\(\)\*\+,;\=%"; + private const REGEXP_PART_UNRESERVED = 'A-Za-z\d_\-.~'; + private const REGEXP_PART_ENCODED = '%(?![A-Fa-f\d]{2})'; + + /** + * Unreserved characters. + * + * @see https://www.rfc-editor.org/rfc/rfc3986.html#section-2.3 + */ + private const REGEXP_UNRESERVED_CHARACTERS = ',%(2[DdEe]|3[0-9]|4[1-9A-Fa-f]|5[AaFf]|6[1-9A-Fa-f]|7[0-9A-Ea-e]),'; + + /** + * Tell whether the user component is correctly encoded. + */ + public static function isUserEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.']+|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + + /** + * Encode User. + * + * All generic delimiters MUST be encoded + */ + public static function encodeUser(BackedEnum|Stringable|string|null $user): ?string + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.']+|'.self::REGEXP_PART_ENCODED.'/'; + + return self::encode($user, $pattern); + } + + /** + * Normalize user component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeUser(BackedEnum|Stringable|string|null $user): ?string + { + return self::normalize(self::encodeUser(self::decodeUnreservedCharacters($user))); + } + + private static function normalize(?string $component): ?string + { + if (null === $component) { + return null; + } + + return (string) preg_replace_callback( + '/%[0-9a-f]{2}/i', + static fn (array $found) => strtoupper($found[0]), + $component + ); + } + + /** + * Tell whether the password component is correctly encoded. + */ + public static function isPasswordEncoded(#[SensitiveParameter] BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':]+|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + + /** + * Encode Password. + * + * Generic delimiters ":" MUST NOT be encoded + */ + public static function encodePassword(#[SensitiveParameter] BackedEnum|Stringable|string|null $component): ?string + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':]+|'.self::REGEXP_PART_ENCODED.'/'; + + return self::encode($component, $pattern); + } + + /** + * Normalize password component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizePassword(#[SensitiveParameter] BackedEnum|Stringable|string|null $password): ?string + { + return self::normalize(self::encodePassword(self::decodeUnreservedCharacters($password))); + } + + /** + * Tell whether the userInfo component is correctly encoded. + */ + public static function isUserInfoEncoded(#[SensitiveParameter] BackedEnum|Stringable|string|null $userInfo): bool + { + if (null === $userInfo) { + return true; + } + + if ($userInfo instanceof BackedEnum) { + $userInfo = $userInfo->value; + } + + [$user, $password] = explode(':', (string) $userInfo, 2) + [1 => null]; + + return self::isUserEncoded($user) + && self::isPasswordEncoded($password); + } + + public static function encodeUserInfo(#[SensitiveParameter] BackedEnum|Stringable|string|null $userInfo): ?string + { + if (null === $userInfo) { + return null; + } + + if ($userInfo instanceof BackedEnum) { + $userInfo = $userInfo->value; + } + + [$user, $password] = explode(':', (string) $userInfo, 2) + [1 => null]; + $userInfo = self::encodeUser($user); + if (null === $password) { + return $userInfo; + } + + return $userInfo.':'.self::encodePassword($password); + } + + public static function normalizeUserInfo(#[SensitiveParameter] BackedEnum|Stringable|string|null $userInfo): ?string + { + if (null === $userInfo) { + return null; + } + + if ($userInfo instanceof BackedEnum) { + $userInfo = $userInfo->value; + } + + [$user, $password] = explode(':', (string) $userInfo, 2) + [1 => null]; + $userInfo = self::normalizeUser($user); + if (null === $password) { + return $userInfo; + } + + return $userInfo.':'.self::normalizePassword($password); + } + + /** + * Decodes all the URI component characters. + */ + public static function decodeAll(BackedEnum|Stringable|string|null $component): ?string + { + return self::decode($component, static fn (array $matches): string => rawurldecode($matches[0])); + } + + /** + * Decodes the URI component without decoding the unreserved characters which are already encoded. + */ + public static function decodeNecessary(BackedEnum|Stringable|string|int|null $component): ?string + { + $decoder = static function (array $matches): string { + if (1 === preg_match(self::REGEXP_CHARS_PREVENTS_DECODING, $matches[0])) { + return strtoupper($matches[0]); + } + + return rawurldecode($matches[0]); + }; + + return self::decode($component, $decoder); + } + + /** + * Decodes the component unreserved characters. + */ + public static function decodeUnreservedCharacters(BackedEnum|Stringable|string|null $str): ?string + { + if ($str instanceof BackedEnum) { + $str = $str->value; + } + + if (null === $str) { + return null; + } + + return preg_replace_callback( + self::REGEXP_UNRESERVED_CHARACTERS, + static fn (array $matches): string => rawurldecode($matches[0]), + (string) $str + ); + } + + /** + * Tell whether the path component is correctly encoded. + */ + public static function isPathEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/]+|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + + /** + * Encode Path. + * + * Generic delimiters ":", "@", and "/" MUST NOT be encoded + */ + public static function encodePath(BackedEnum|Stringable|string|null $component): string + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/]+|'.self::REGEXP_PART_ENCODED.'/'; + + return (string) self::encode($component, $pattern); + } + + /** + * Decodes the path component while preserving characters that should not be decoded in the context of a full valid URI. + */ + public static function decodePath(BackedEnum|Stringable|string|null $path): ?string + { + $decoder = static function (array $matches): string { + $encodedChar = strtoupper($matches[0]); + + return in_array($encodedChar, ['%2F', '%20', '%3F', '%23'], true) ? $encodedChar : rawurldecode($encodedChar); + }; + + return self::decode($path, $decoder); + } + + /** + * Normalize path component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizePath(BackedEnum|Stringable|string|null $component): ?string + { + return self::normalize(self::encodePath(self::decodePath($component))); + } + + /** + * Tell whether the query component is correctly encoded. + */ + public static function isQueryEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.'\/?%]+|'.self::REGEXP_PART_ENCODED.'/'; + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + + /** + * Decodes the query component while preserving characters that should not be decoded in the context of a full valid URI. + */ + public static function decodeQuery(BackedEnum|Stringable|string|null $path): ?string + { + $decoder = static function (array $matches): string { + $encodedChar = strtoupper($matches[0]); + + return in_array($encodedChar, ['%26', '%3D', '%20', '%23', '%3F'], true) ? $encodedChar : rawurldecode($encodedChar); + }; + + return self::decode($path, $decoder); + } + + /** + * Normalize the query component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeQuery(BackedEnum|Stringable|string|null $query): ?string + { + return self::normalize(self::encodeQueryOrFragment(self::decodeQuery($query))); + } + + /** + * Tell whether the query component is correctly encoded. + */ + public static function isFragmentEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/?%]|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + + /** + * Decodes the fragment component while preserving characters that should not be decoded in the context of a full valid URI. + */ + public static function decodeFragment(BackedEnum|Stringable|string|null $path): ?string + { + return self::decode($path, static fn (array $matches): string => '%20' === $matches[0] ? $matches[0] : rawurldecode($matches[0])); + } + + /** + * Normalize the fragment component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeFragment(BackedEnum|Stringable|string|null $fragment): ?string + { + return self::normalize(self::encodeQueryOrFragment(self::decodeFragment($fragment))); + } + + /** + * Normalize the host component. + * + * @see https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2 + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeHost(BackedEnum|Stringable|string|null $host): ?string + { + if ($host instanceof BackedEnum) { + $host = (string) $host->value; + } + + if ($host instanceof Stringable) { + $host = (string) $host; + } + + if (null === $host || '' === $host || false !== filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + return $host; + } + + if (str_starts_with($host, '[')) { + return IPv6Converter::normalize($host); + } + + $host = strtolower($host); + + return (!str_contains($host, '%')) ? $host : preg_replace_callback( + '/%[a-f0-9]{2}/', + fn (array $matches) => 1 === preg_match('/%([0-7][0-9a-f])/', $matches[0]) ? rawurldecode($matches[0]) : strtoupper($matches[0]), + $host + ); + } + + /** + * Encode Query or Fragment. + * + * Generic delimiters ":", "@", "?", and "/" MUST NOT be encoded + */ + public static function encodeQueryOrFragment(BackedEnum|Stringable|string|null $component): ?string + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/?]+|'.self::REGEXP_PART_ENCODED.'/'; + + return self::encode($component, $pattern); + } + + public static function encodeQueryKeyValue(mixed $component): ?string + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.']+|'.self::REGEXP_PART_ENCODED.'/'; + $encoder = static fn (array $found): string => 1 === preg_match('/[^'.self::REGEXP_PART_UNRESERVED.']/', rawurldecode($found[0])) ? rawurlencode($found[0]) : $found[0]; + $filteredComponent = self::filterComponent($component); + + return match (true) { + null === $filteredComponent => throw new SyntaxError(sprintf('A pair key/value must be a scalar value `%s` given.', gettype($component))), + 1 === preg_match(self::REGEXP_CHARS_INVALID, $filteredComponent) => rawurlencode($filteredComponent), + default => (string) preg_replace_callback($pattern, $encoder, $filteredComponent), + }; + } + + private static function filterComponent(mixed $component): ?string + { + try { + return StringCoercionMode::Native->coerce($component); + } catch (Throwable $exception) { + throw new SyntaxError( + sprintf('The component must be a scalar value `%s` given.', gettype($component)), + previous: $exception + ); + } + } + + /** + * Encodes the URI component characters using a regular expression to find which characters need encoding. + */ + private static function encode(BackedEnum|Stringable|string|int|bool|null $component, string $pattern): ?string + { + $component = self::filterComponent($component); + if (null === $component || '' === $component) { + return $component; + } + + return (string) preg_replace_callback( + $pattern, + static fn (array $found): string => 1 === preg_match('/[^'.self::REGEXP_PART_UNRESERVED.']/', rawurldecode($found[0])) ? rawurlencode($found[0]) : $found[0], + $component + ); + } + + /** + * Decodes the URI component characters using a closure. + */ + private static function decode(BackedEnum|Stringable|string|int|null $component, Closure $decoder): ?string + { + $component = self::filterComponent($component); + if (null === $component || '' === $component) { + return $component; + } + + if (1 === preg_match(self::REGEXP_CHARS_INVALID, $component)) { + throw new SyntaxError('Invalid component string: '.$component.'.'); + } + + if (1 === preg_match(self::REGEXP_CHARS_ENCODED, $component)) { + return (string) preg_replace_callback(self::REGEXP_CHARS_ENCODED, $decoder, $component); + } + + return $component; + } + + /** + * Decodes the URI component without decoding the unreserved characters which are already encoded. + * + * DEPRECATION WARNING! This method will be removed in the next major point release. + * + * @deprecated Since version 7.6.0 + * @codeCoverageIgnore + * @see Encoder::decodeNecessary() + * + * Create a new instance from the environment. + */ + #[Deprecated(message:'use League\Uri\Encoder::decodeNecessary() instead', since:'league/uri:7.6.0')] + public static function decodePartial(BackedEnum|Stringable|string|int|null $component): ?string + { + return self::decodeNecessary($component); + } +} diff --git a/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php b/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php new file mode 100644 index 0000000..9063ceb --- /dev/null +++ b/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Exceptions; + +use BackedEnum; +use League\Uri\Idna\Error; +use League\Uri\Idna\Result; +use Stringable; + +final class ConversionFailed extends SyntaxError +{ + private function __construct( + string $message, + private readonly string $host, + private readonly Result $result + ) { + parent::__construct($message); + } + + public static function dueToIdnError(BackedEnum|Stringable|string $host, Result $result): self + { + $reasons = array_map(fn (Error $error): string => $error->description(), $result->errors()); + + if ($host instanceof BackedEnum) { + $host = (string) $host->value; + } + + return new self('Host `'.$host.'` is invalid: '.implode('; ', $reasons).'.', (string) $host, $result); + } + + public function getHost(): string + { + return $this->host; + } + + public function getResult(): Result + { + return $this->result; + } +} diff --git a/vendor/league/uri-interfaces/Exceptions/MissingFeature.php b/vendor/league/uri-interfaces/Exceptions/MissingFeature.php new file mode 100644 index 0000000..034e969 --- /dev/null +++ b/vendor/league/uri-interfaces/Exceptions/MissingFeature.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Exceptions; + +use League\Uri\Contracts\UriException; +use RuntimeException; + +class MissingFeature extends RuntimeException implements UriException +{ +} diff --git a/vendor/league/uri-interfaces/Exceptions/OffsetOutOfBounds.php b/vendor/league/uri-interfaces/Exceptions/OffsetOutOfBounds.php new file mode 100644 index 0000000..737a5cc --- /dev/null +++ b/vendor/league/uri-interfaces/Exceptions/OffsetOutOfBounds.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Exceptions; + +class OffsetOutOfBounds extends SyntaxError +{ +} diff --git a/vendor/league/uri-interfaces/Exceptions/SyntaxError.php b/vendor/league/uri-interfaces/Exceptions/SyntaxError.php new file mode 100644 index 0000000..f44cca6 --- /dev/null +++ b/vendor/league/uri-interfaces/Exceptions/SyntaxError.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Exceptions; + +use InvalidArgumentException; +use League\Uri\Contracts\UriException; + +class SyntaxError extends InvalidArgumentException implements UriException +{ +} diff --git a/vendor/league/uri-interfaces/FeatureDetection.php b/vendor/league/uri-interfaces/FeatureDetection.php new file mode 100644 index 0000000..be0c4d6 --- /dev/null +++ b/vendor/league/uri-interfaces/FeatureDetection.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri; + +use finfo; +use League\Uri\Exceptions\MissingFeature; +use League\Uri\IPv4\Calculator; + +use function class_exists; +use function defined; +use function extension_loaded; +use function function_exists; + +use const PHP_INT_SIZE; + +/** + * Allow detecting features needed to make the packages work. + */ +final class FeatureDetection +{ + public static function supportsFileDetection(): void + { + static $isSupported = null; + $isSupported = $isSupported ?? class_exists(finfo::class); + + $isSupported || throw new MissingFeature('Support for file type detection requires the `fileinfo` extension.'); + + } + + public static function supportsIdn(): void + { + static $isSupported = null; + $isSupported = $isSupported ?? (function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46')); + + $isSupported || throw new MissingFeature('Support for IDN host requires the `intl` extension for best performance or run "composer require symfony/polyfill-intl-idn" to install a polyfill.'); + } + + public static function supportsIPv4Conversion(): void + { + static $isSupported = null; + $isSupported = $isSupported ?? (extension_loaded('gmp') || extension_loaded('bcmath') || (4 < PHP_INT_SIZE)); + + $isSupported || throw new MissingFeature('A '.Calculator::class.' implementation could not be automatically loaded. To perform IPv4 conversion use a x.64 PHP build or install one of the following extension GMP or BCMath. You can also ship your own implementation.'); + } + + public static function supportsDom(): void + { + static $isSupported = null; + $isSupported = $isSupported ?? extension_loaded('dom'); + + $isSupported || throw new MissingFeature('To use a DOM related feature, the DOM extension must be installed in your system.'); + } +} diff --git a/vendor/league/uri-interfaces/HostFormat.php b/vendor/league/uri-interfaces/HostFormat.php new file mode 100644 index 0000000..baf7375 --- /dev/null +++ b/vendor/league/uri-interfaces/HostFormat.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri; + +enum HostFormat +{ + case Ascii; + case Unicode; +} diff --git a/vendor/league/uri-interfaces/HostRecord.php b/vendor/league/uri-interfaces/HostRecord.php new file mode 100644 index 0000000..e379568 --- /dev/null +++ b/vendor/league/uri-interfaces/HostRecord.php @@ -0,0 +1,448 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri; + +use BackedEnum; +use Exception; +use JsonSerializable; +use League\Uri\Contracts\UriComponentInterface; +use League\Uri\Exceptions\SyntaxError; +use League\Uri\Idna\Converter as IdnConverter; +use Stringable; +use Throwable; + +use function array_key_first; +use function count; +use function explode; +use function filter_var; +use function get_object_vars; +use function in_array; +use function inet_pton; +use function is_object; +use function preg_match; +use function rawurldecode; +use function strpos; +use function strtolower; +use function substr; + +use const FILTER_FLAG_IPV4; +use const FILTER_FLAG_IPV6; +use const FILTER_VALIDATE_IP; + +/** + * @phpstan-type HostRecordSerializedShape array{0: array{host: ?string}, 1: array{}} + */ +final class HostRecord implements JsonSerializable +{ + /** + * Maximum number of host cached. + * + * @var int + */ + private const MAXIMUM_HOST_CACHED = 100; + + private const REGEXP_NON_ASCII_PATTERN = '/[^\x20-\x7f]/'; + + /** + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + * + * invalid characters in host regular expression + */ + private const REGEXP_INVALID_HOST_CHARS = '/ + [:\/?#\[\]@ ] # gen-delims characters as well as the space character + /ix'; + + /** + * General registered name regular expression. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + * @see https://regex101.com/r/fptU8V/1 + */ + private const REGEXP_REGISTERED_NAME = '/ + (?(DEFINE) + (?[a-z0-9_~\-]) # . is missing as it is used to separate labels + (?[!$&\'()*+,;=]) + (?%[A-F0-9]{2}) + (?(?:(?&unreserved)|(?&sub_delims)|(?&encoded))*) + ) + ^(?:(?®_name)\.)*(?®_name)\.?$ + /ix'; + + /** + * Domain name regular expression. + * + * Everything but the domain name length is validated + * + * @see https://tools.ietf.org/html/rfc1034#section-3.5 + * @see https://tools.ietf.org/html/rfc1123#section-2.1 + * @see https://regex101.com/r/71j6rt/1 + */ + private const REGEXP_DOMAIN_NAME = '/ + (?(DEFINE) + (? [a-z0-9]) # alpha digit + (? [a-z0-9-]) # alpha digit and hyphen + (? (?&let_dig_hyp){0,61}(?&let_dig)) # domain label end + (?