aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Wurst <ChristophWurst@users.noreply.github.com>2023-11-16 19:48:06 +0100
committerGitHub <noreply@github.com>2023-11-16 19:48:06 +0100
commitc9dc377ebcdda91d2e471a3c26c72ed94fecb9aa (patch)
treed36483514f248638c9e61d8ccd5da034985810d9
parent23605d60dd7f1f4fca8609885f00036281f49ec6 (diff)
parent475dd6035435e326b0ffab6e74f961757896b97d (diff)
downloadnextcloud-server-c9dc377ebcdda91d2e471a3c26c72ed94fecb9aa.tar.gz
nextcloud-server-c9dc377ebcdda91d2e471a3c26c72ed94fecb9aa.zip
Merge pull request #41395 from nextcloud/hello-emf
feat: add preview provider for emf files based on office
-rw-r--r--config/config.sample.php11
-rw-r--r--core/js/mimetypelist.js3
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Preview/EMF.php33
-rw-r--r--lib/private/Preview/Office.php60
-rw-r--r--lib/private/PreviewManager.php60
-rw-r--r--lib/private/Repair/RepairMimeTypes.php11
-rw-r--r--resources/config/mimetypealiases.dist.json3
-rw-r--r--resources/config/mimetypemapping.dist.json1
-rw-r--r--tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js1
-rw-r--r--tests/data/integritycheck/mimetypeListModified/core/signature.json4
12 files changed, 131 insertions, 58 deletions
diff --git a/config/config.sample.php b/config/config.sample.php
index ab86feedb85..27b99636a22 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -1237,14 +1237,6 @@ $CONFIG = [
* Defaults to ``''`` (empty string)
*/
'preview_libreoffice_path' => '/usr/bin/libreoffice',
-/**
- * Use this if LibreOffice/OpenOffice requires additional arguments.
- *
- * Defaults to ``''`` (empty string)
- */
-'preview_office_cl_parameters' =>
- ' --headless --nologo --nofirststartwizard --invisible --norestore '.
- '--convert-to png --outdir ',
/**
* custom path for ffmpeg binary
@@ -1285,6 +1277,7 @@ $CONFIG = [
* - ``OC\Preview\StarOffice``
* - ``OC\Preview\SVG``
* - ``OC\Preview\TIFF``
+ * - ``OC\Preview\EMF``
*
*
* Defaults to the following providers:
@@ -1945,7 +1938,7 @@ $CONFIG = [
*
* Example for windows systems: ``array('?', '<', '>', ':', '*', '|', '"', chr(0), "\n", "\r")``
* see https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits
- *
+ *
* Defaults to ``array()``
*/
'forbidden_chars' => [],
diff --git a/core/js/mimetypelist.js b/core/js/mimetypelist.js
index a2ca2c23d07..2e87ce756ba 100644
--- a/core/js/mimetypelist.js
+++ b/core/js/mimetypelist.js
@@ -113,7 +113,8 @@ OC.MimeTypeList={
"application/vnd.xmind.workbook": "mindmap",
"image/targa": "image/tga",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form",
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template"
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template",
+ "image/x-emf": "image/emf"
},
files: [
"application",
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 39085325067..39a3f2638f4 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1540,6 +1540,7 @@ return array(
'OC\\Preview\\BackgroundCleanupJob' => $baseDir . '/lib/private/Preview/BackgroundCleanupJob.php',
'OC\\Preview\\Bitmap' => $baseDir . '/lib/private/Preview/Bitmap.php',
'OC\\Preview\\Bundled' => $baseDir . '/lib/private/Preview/Bundled.php',
+ 'OC\\Preview\\EMF' => $baseDir . '/lib/private/Preview/EMF.php',
'OC\\Preview\\Font' => $baseDir . '/lib/private/Preview/Font.php',
'OC\\Preview\\GIF' => $baseDir . '/lib/private/Preview/GIF.php',
'OC\\Preview\\Generator' => $baseDir . '/lib/private/Preview/Generator.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 498f4d8c0b1..4a09a5db6da 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1573,6 +1573,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Preview\\BackgroundCleanupJob' => __DIR__ . '/../../..' . '/lib/private/Preview/BackgroundCleanupJob.php',
'OC\\Preview\\Bitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/Bitmap.php',
'OC\\Preview\\Bundled' => __DIR__ . '/../../..' . '/lib/private/Preview/Bundled.php',
+ 'OC\\Preview\\EMF' => __DIR__ . '/../../..' . '/lib/private/Preview/EMF.php',
'OC\\Preview\\Font' => __DIR__ . '/../../..' . '/lib/private/Preview/Font.php',
'OC\\Preview\\GIF' => __DIR__ . '/../../..' . '/lib/private/Preview/GIF.php',
'OC\\Preview\\Generator' => __DIR__ . '/../../..' . '/lib/private/Preview/Generator.php',
diff --git a/lib/private/Preview/EMF.php b/lib/private/Preview/EMF.php
new file mode 100644
index 00000000000..2b5f40e66af
--- /dev/null
+++ b/lib/private/Preview/EMF.php
@@ -0,0 +1,33 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2023 Daniel Kesselberg <mail@danielkesselberg.de>
+ *
+ * @author Daniel Kesselberg <mail@danielkesselberg.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Preview;
+
+class EMF extends Office {
+ public function getMimeType(): string {
+ return '/image\/emf/';
+ }
+}
diff --git a/lib/private/Preview/Office.php b/lib/private/Preview/Office.php
index 3ba7c5a21a0..68499a6fea6 100644
--- a/lib/private/Preview/Office.php
+++ b/lib/private/Preview/Office.php
@@ -31,7 +31,8 @@ namespace OC\Preview;
use OCP\Files\File;
use OCP\Files\FileInfo;
use OCP\IImage;
-use Psr\Log\LoggerInterface;
+use OCP\ITempManager;
+use OCP\Server;
abstract class Office extends ProviderV2 {
/**
@@ -49,51 +50,60 @@ abstract class Office extends ProviderV2 {
return null;
}
- $absPath = $this->getLocalFile($file);
-
- $tmpDir = \OC::$server->getTempManager()->getTempBaseDir();
+ $tempManager = Server::get(ITempManager::class);
- $defaultParameters = ' -env:UserInstallation=file://' . escapeshellarg($tmpDir . '/owncloud-' . \OC_Util::getInstanceId() . '/') . ' --headless --nologo --nofirststartwizard --invisible --norestore --convert-to png --outdir ';
- $clParameters = \OC::$server->getConfig()->getSystemValue('preview_office_cl_parameters', $defaultParameters);
+ // The file to generate the preview for.
+ $absPath = $this->getLocalFile($file);
- $cmd = $this->options['officeBinary'] . $clParameters . escapeshellarg($tmpDir) . ' ' . escapeshellarg($absPath);
+ // The destination for the LibreOffice user profile.
+ // LibreOffice can rune once per user profile and therefore instance id and file id are included.
+ $profile = $tempManager->getTemporaryFolder(
+ 'nextcloud-office-profile-' . \OC_Util::getInstanceId() . '-' . $file->getId()
+ );
- exec($cmd, $output, $returnCode);
+ // The destination for the LibreOffice convert result.
+ $outdir = $tempManager->getTemporaryFolder(
+ 'nextcloud-office-preview-' . \OC_Util::getInstanceId() . '-' . $file->getId()
+ );
- if ($returnCode !== 0) {
+ if ($profile === false || $outdir === false) {
$this->cleanTmpFiles();
return null;
}
- //create imagick object from png
- $pngPreview = null;
- try {
- [$dirname, , , $filename] = array_values(pathinfo($absPath));
- $pngPreview = $tmpDir . '/' . $filename . '.png';
+ $parameters = [
+ $this->options['officeBinary'],
+ '-env:UserInstallation=file://' . escapeshellarg($profile),
+ '--headless',
+ '--nologo',
+ '--nofirststartwizard',
+ '--invisible',
+ '--norestore',
+ '--convert-to png',
+ '--outdir ' . escapeshellarg($outdir),
+ escapeshellarg($absPath),
+ ];
- $png = new \Imagick($pngPreview . '[0]');
- $png->setImageFormat('jpg');
- } catch (\Exception $e) {
+ $cmd = implode(' ', $parameters);
+ exec($cmd, $output, $returnCode);
+
+ if ($returnCode !== 0) {
$this->cleanTmpFiles();
- unlink($pngPreview);
- \OC::$server->get(LoggerInterface::class)->error($e->getMessage(), [
- 'exception' => $e,
- 'app' => 'core',
- ]);
return null;
}
+ $preview = $outdir . pathinfo($absPath, PATHINFO_FILENAME) . '.png';
+
$image = new \OCP\Image();
- $image->loadFromData((string) $png);
+ $image->loadFromFile($preview);
$this->cleanTmpFiles();
- unlink($pngPreview);
if ($image->valid()) {
$image->scaleDownToFit($maxX, $maxY);
-
return $image;
}
+
return null;
}
}
diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php
index 3af6848686e..aedcbbce335 100644
--- a/lib/private/PreviewManager.php
+++ b/lib/private/PreviewManager.php
@@ -366,7 +366,7 @@ class PreviewManager implements IPreview {
$this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/');
$this->registerCoreProvider(Preview\Imaginary::class, Preview\Imaginary::supportedMimeTypes());
- // SVG, Office and Bitmap require imagick
+ // SVG and Bitmap require imagick
if ($this->imagickSupport->hasExtension()) {
$imagickProviders = [
'SVG' => ['mimetype' => '/image\/svg\+xml/', 'class' => Preview\SVG::class],
@@ -391,27 +391,10 @@ class PreviewManager implements IPreview {
$this->registerCoreProvider($class, $provider['mimetype']);
}
}
-
- if ($this->imagickSupport->supportsFormat('PDF')) {
- // Office requires openoffice or libreoffice
- $officeBinary = $this->config->getSystemValue('preview_libreoffice_path', null);
- if (!is_string($officeBinary)) {
- $officeBinary = $this->binaryFinder->findBinaryPath('libreoffice');
- }
- if (!is_string($officeBinary)) {
- $officeBinary = $this->binaryFinder->findBinaryPath('openoffice');
- }
-
- if (is_string($officeBinary)) {
- $this->registerCoreProvider(Preview\MSOfficeDoc::class, '/application\/msword/', ["officeBinary" => $officeBinary]);
- $this->registerCoreProvider(Preview\MSOffice2003::class, '/application\/vnd.ms-.*/', ["officeBinary" => $officeBinary]);
- $this->registerCoreProvider(Preview\MSOffice2007::class, '/application\/vnd.openxmlformats-officedocument.*/', ["officeBinary" => $officeBinary]);
- $this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/', ["officeBinary" => $officeBinary]);
- $this->registerCoreProvider(Preview\StarOffice::class, '/application\/vnd.sun.xml.*/', ["officeBinary" => $officeBinary]);
- }
- }
}
+ $this->registerCoreProvidersOffice();
+
// Video requires avconv or ffmpeg
if (in_array(Preview\Movie::class, $this->getEnabledDefaultProvider())) {
$movieBinary = $this->config->getSystemValue('preview_ffmpeg_path', null);
@@ -429,6 +412,43 @@ class PreviewManager implements IPreview {
}
}
+ private function registerCoreProvidersOffice(): void {
+ $officeProviders = [
+ ['mimetype' => '/application\/msword/', 'class' => Preview\MSOfficeDoc::class],
+ ['mimetype' => '/application\/vnd.ms-.*/', 'class' => Preview\MSOffice2003::class],
+ ['mimetype' => '/application\/vnd.openxmlformats-officedocument.*/', 'class' => Preview\MSOffice2007::class],
+ ['mimetype' => '/application\/vnd.oasis.opendocument.*/', 'class' => Preview\OpenDocument::class],
+ ['mimetype' => '/application\/vnd.sun.xml.*/', 'class' => Preview\StarOffice::class],
+ ['mimetype' => '/image\/emf/', 'class' => Preview\EMF::class],
+ ];
+
+ $findBinary = true;
+ $officeBinary = false;
+
+ foreach ($officeProviders as $provider) {
+ $class = $provider['class'];
+ if (!in_array(trim($class, '\\'), $this->getEnabledDefaultProvider())) {
+ continue;
+ }
+
+ if ($findBinary) {
+ // Office requires openoffice or libreoffice
+ $officeBinary = $this->config->getSystemValue('preview_libreoffice_path', false);
+ if ($officeBinary === false) {
+ $officeBinary = $this->binaryFinder->findBinaryPath('libreoffice');
+ }
+ if ($officeBinary === false) {
+ $officeBinary = $this->binaryFinder->findBinaryPath('openoffice');
+ }
+ $findBinary = false;
+ }
+
+ if ($officeBinary) {
+ $this->registerCoreProvider($class, $provider['mimetype'], ['officeBinary' => $officeBinary]);
+ }
+ }
+ }
+
private function registerBootstrapProviders(): void {
$context = $this->bootstrapCoordinator->getRegistrationContext();
diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php
index ee5a84ad65c..cab8d8ca02a 100644
--- a/lib/private/Repair/RepairMimeTypes.php
+++ b/lib/private/Repair/RepairMimeTypes.php
@@ -229,6 +229,13 @@ class RepairMimeTypes implements IRepairStep {
return $this->updateMimetypes($updatedMimetypes);
}
+ private function introduceEnhancedMetafileFormatType() {
+ $updatedMimetypes = [
+ 'emf' => 'image/emf',
+ ];
+
+ return $this->updateMimetypes($updatedMimetypes);
+ }
/**
* Fix mime types
@@ -286,5 +293,9 @@ class RepairMimeTypes implements IRepairStep {
if (version_compare($ocVersionFromBeforeUpdate, '26.0.0.1', '<') && $this->introduceAsciidocType()) {
$out->info('Fixed AsciiDoc mime types');
}
+
+ if (version_compare($ocVersionFromBeforeUpdate, '28.0.0.5', '<') && $this->introduceEnhancedMetafileFormatType()) {
+ $out->info('Fixed Enhanced Metafile Format mime types');
+ }
}
}
diff --git a/resources/config/mimetypealiases.dist.json b/resources/config/mimetypealiases.dist.json
index 67e79a52283..6b0bcf3e59a 100644
--- a/resources/config/mimetypealiases.dist.json
+++ b/resources/config/mimetypealiases.dist.json
@@ -114,5 +114,6 @@
"application/vnd.xmind.workbook": "mindmap",
"image/targa": "image/tga",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form",
- "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template"
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template",
+ "image/x-emf": "image/emf"
}
diff --git a/resources/config/mimetypemapping.dist.json b/resources/config/mimetypemapping.dist.json
index 7b631466972..88a09d0b928 100644
--- a/resources/config/mimetypemapping.dist.json
+++ b/resources/config/mimetypemapping.dist.json
@@ -51,6 +51,7 @@
"dot": ["application/msword"],
"dotx": ["application/vnd.openxmlformats-officedocument.wordprocessingml.template"],
"dv": ["video/dv"],
+ "emf": ["image/emf"],
"eot": ["application/vnd.ms-fontobject"],
"eps": ["application/postscript"],
"epub": ["application/epub+zip"],
diff --git a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js
index a8e98e786f5..ffcf5e1fb1c 100644
--- a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js
+++ b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js
@@ -115,6 +115,7 @@ OC.MimeTypeList={
"image/targa": "image/tga",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template",
+ "image/x-emf": "image/emf",
"my-custom/mimetype": "custom"
},
files: [
diff --git a/tests/data/integritycheck/mimetypeListModified/core/signature.json b/tests/data/integritycheck/mimetypeListModified/core/signature.json
index 43f489f6d3f..4ee844b87f8 100644
--- a/tests/data/integritycheck/mimetypeListModified/core/signature.json
+++ b/tests/data/integritycheck/mimetypeListModified/core/signature.json
@@ -1,7 +1,7 @@
{
"hashes": {
- "core\/js\/mimetypelist.js": "2a6ab9af5353d464c0dd3bd651cfc13ba35009463949bc45bd8f7073828fa34fbdac7a81ba2b188e7e0c97fc63c2167825b069f61341e507ca33213b1e6e4593"
+ "core\/js\/mimetypelist.js": "e9e515c5eeb08b02971e5943640bef89b6d1c2d746d5883bf974c6ac753f810685c7a20bf0ed4d32d8c046cd2cef6c045682c7d89c6a3b7b6c33122f5fd2088f"
},
- "signature": "A5JmjvGiWC9iDaDL0\/wzIBx1ovV6xW5pL134ZtzcFh6dCRoYVZFZvInb98zz4Js3Y4R+uAv4XYKFgclG9BXjoa+q7SmN4qV95o870OsX3MEAaPRHEJv7V6P19hinwC0\/c6XUtMUlTn2IqdoacmELV3v+vmXiU0bYpNfqkYDjt1mCfl3EWB+uMCn+W849k1hoRc\/nI3JuDzl3VtP4G6zzJ3NexsXJOHOb6\/GyGVnkOltN3Ep5wBqXtr28LLLWWYbgxUEQ5ZNBd98PCpRm3r\/3eGreREccUzh+Kfo1XK+Rbnf8U6z3DXOwZK4cP\/CJBAhtlUDyw+TY58jcOSLxF2I61jqYoa8En2ukcQdXUvyTcsN+RzAKo+yhAPw0CJvDzb9zuS7gJUpev6nZnJKQ6dNQApQQILtwgz9dDlVKToxgyyhV1giTqEEZDvH1t2MSjz8fbGlm1YY60YJSs2SA\/cAff+sQVmoGCpRtdHriCDAET+5gTuz0wEXnvn6Jvxqxta9IZ0fisKCjfRH5FFdjfBM8Cgk6HOhSAfHoSH+ZFUGy8+NICZXe7CGr40iIjFLSIS0RgclQZSjYK8bfjA43XFpXeJNGjIvxHTr4tzm8gJ3YbVqCyN45HBcxS3q7yJCie3brqCZvXfXyhoGY6WhPAkBLQ+8nNP\/qeWlV8DMX+ZUYxso=",
+ "signature": "iKEOaoY+lowIZrDjozpCqDFtag8qtANZ4AqnwZG1HrzuP3Yv7uaCUZbpsyr4FklKyyZFbh4w5K3x5bacKq\/h7tFVu5A56sunSZIMDjO\/ToGFYtZC59hTi0mKlmR+rIbAwmlm2Qad0uSD+\/4bkihL\/haPAtV8IbHXqxwjcYjkPmyi0W3rN1sOycgbH8Hmu7UlkdZORGTVVHdMpQuIljaBGBonQUTnqUb2BVsZ7YKW3Ls1AKMBam\/OGrB8rAJOht5b86qIE1jzzU\/BI7Qs+r8C+sh84LpLgz\/33njaBNANwfnvbrcb4f\/95BZCL4DcMGfwJ\/VNRVJrBjQSweYb+ypq5WMMOUvHHEg4CovoH\/XbdCAbRVet34vRZnZe5F4bXQOZXp0eqbqoY+STwQ5Ku2O7YUWwfppjxWMMfs1hDUrvvMBFRCd5mla\/aktV7ugishcZdKUFyDsyOEtT292Cb5f\/62RqnMniD9a+TOBE1qWH5DXYQqRO9TUdVtGQ3ITbLxEAzlfUmwYoXp+wgKbzOXC4KFzpxJnxHM+vuURkO5lUza68gqiG8\/uhNcPQufDT5CjasQVBTK5tdoL64UnXqATgU3rrD\/MByOXWlZvMsAS+NjPkF30UnvqgApEwytOlTZ27+ntZjfwhM3DlXNKE3mzUx+tvVfwBDmhEpBK\/Qpk6HLc=",
"certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
} \ No newline at end of file