diff --git a/_import.html b/_import.html
index 3b7f2ae..2903a19 100644
--- a/_import.html
+++ b/_import.html
@@ -75,8 +75,17 @@
 				{{vtSet: PagePath="{vtGet:PagePath}/{vtName}"}}
 			{{vtEndUse}}	
 
-			{{vtIf: {vtGetValue:dirlist} .neq.}}
-				{{vtSet: Directories="{vtGetValue:dirlist}"}}
+			{{vtIf: {vtGetValue:root} .neq. }}
+				{{vtCalc: getDirectoryTree('{vtGet:BasePath}/{vtGetValue:root,escaped}') }}
+				{{vtRepeat: {vtResult} }}
+					{{vtIf: {vtItem} .eq. / }}
+						{{vtSet: Directories = "/{vtGetValue:root} }}
+					{{vtElse}}
+						{{vtSet: Directories = "{vtGet:Directories}, /{vtGetValue:root,escaped}{vtItem} }}
+					{{vtEndIf}}
+				{{vtEndRepeat}}
+			{{vtElseIf: {vtGetValue:dirlist} .neq.}}
+				{{vtSet: Directories="{vtGetValue:dirlist,escaped}"}}
 			{{vtElse}}
 				{{vtCalc: getDirectoryTree('{vtGet:BasePath}') }}
 				{{vtSet: Directories}}
@@ -94,7 +103,7 @@
 					{{vtSet: pfad="{vtGet:BasePath}/"}}
 					{{vtSet: Seite="{vtGet:PagePath}"}}
 				{{vtElse}}
-					{{vtSet: pfad="{vtGet:BasePath}/{vtItem}/"}}
+					{{vtSet: pfad="{vtGet:BasePath}{vtItem}/"}}
 					{{vtSet: Seite="{vtGet:PagePath}{vtItem}"}}
 				{{vtEndIf}}
 				
@@ -122,6 +131,9 @@
 									InheritProducts="{vtGet:InheritProducts}", 
 									UserSetting="{vtGet:UserSetting}", 
 									DownloadAllowed="{vtGet:DownloadAllowed}", 
+									ViewType="{vtGlobal:pxtcCategoryListType}", 
+									SortField="{vtGlobal:pxtcImportSortfield}", 
+									SortOrderDesc="{vtGlobal:pxtcDefaultSortDesc}", 
 									Assortment="{vtGet:Assortment}", 
 									Products="{vtGet:Products}"
 					}}
diff --git a/ajax/order_dialog.html b/ajax/order_dialog.html
index 3319790..bb40ab9 100644
--- a/ajax/order_dialog.html
+++ b/ajax/order_dialog.html
@@ -68,7 +68,13 @@
 						<tr class="pxtc-product" data-id="{{vtItem:id}}" data-quantity="{{vtItem:cartQuantity}}" data-type="{{vtItem:type}}">
 							<!--{{vtIf: {vtItem:id} .eq. 0 }}-->
 								<td colspan="1" class="row table-secondary">
-									<h6 class="col-12">{{vtItem:name}}</h6>
+									<!--
+										{{vtCalc: strtok( '{vtItem:name}', '||' ) }}
+										{{vtIf: {vtGet:Language} .neq. de .and. {vtItem:name} .cn. || }}
+											{{vtCalc: strtok( '||' ) }}
+										{{vtEndIf}}
+									-->
+									<h6 class="col-12">{{vtResult}}</h6>
 								</td>
 							<!--{{vtElseIf: {vtItem:type} .neq. Gruppe .or. {vtItem:options} .neq. [] }}-->
 								<td class="row {{vtGet:CellClass}}">
diff --git a/assortment.vtedit.html b/assortment.vtedit.html
index 4a5aa8a..ef9f565 100644
--- a/assortment.vtedit.html
+++ b/assortment.vtedit.html
@@ -233,7 +233,7 @@
 		});
 
 		$('#btnAddText').click( function(){
-			var theText = prompt('Text für den neuen Eintrag:');
+			var theText = prompt('Text für den neuen Eintrag (deutsch || englisch):');
 			if ( theText )
 			{
 				$('#prodlist').append( '<div class="text"><button type="button">&times;</button><span>&#9776;</span><p>' + theText + '</p></div>' );
@@ -253,6 +253,13 @@
 			});
 			$('#product_chooser').dialog('open');
 		});
+
+		$('#prodlist div.text p').on( 'click', function(){
+			var theText = prompt( 'Text bearbeiten (deutsch || englisch)', $(this).text() );
+			if ( theText ){
+				$(this).text( theText );
+			}
+		});
 		
 		function serialize_prod_List( theElement )
 		{
diff --git a/cart.html b/cart.html
index 710ce41..81f6a87 100644
--- a/cart.html
+++ b/cart.html
@@ -73,6 +73,9 @@
 							<button type="button" class="btn btn-outline-secondary btn-plus"><i class="fas fa-plus"></i></button>
 						<!--{{vtEndIf}}-->
 					</div>
+					<!--{{vtIf: {vtUser:admin} .eq. 1 }}-->
+						<div class="float-right small text-muted pr-2" style="color:#bbb !important">{{vtItem:filename}}</div>
+					<!--{{vtEndIf}}-->
 					{{vtItem:title}}<br>
 					<small class="text-muted d-block">
 						<span class="quantity">{{vtItem:quantity}}</span> &times;
diff --git a/checkout.html b/checkout.html
index 65c27fb..c112a50 100644
--- a/checkout.html
+++ b/checkout.html
@@ -197,7 +197,7 @@
 
 	<link rel="stylesheet" type="text/css" href="{{vtResource:jquery/jquery-ui.custom.min.css}}">
 
-	{{vtInclude: includes/countrylist_{vtGet:Language}.html}}
+	{{vtInclude: /config/includes/countrylist_{vtGet:Language}.html, includes/countrylist_{vtGet:Language}.html}}
 
 <!--{{vtEndCapture}}-->
 
diff --git a/checkout.summary.html b/checkout.summary.html
index 212fdb9..7821420 100644
--- a/checkout.summary.html
+++ b/checkout.summary.html
@@ -51,9 +51,9 @@
 		{{vtEndIf}}
 	{{vtEndRepeat}}
 
-	{{vtIf: {vtGlobal:pxtcVatCountry} .eq. .or. {vtSession:Land} .eq. {vtGlobal:pxtcVatCountry} .or. {vtGlobal:pxtcVatHandling} .eq.
+	{{vtIf: {vtGlobal:pxtcVatIgnoreCountry} .eq. 1 .or. {vtGlobal:pxtcVatCountry} .eq. .or. {vtSession:Land} .eq. {vtGlobal:pxtcVatCountry} .or. {vtGlobal:pxtcVatHandling} .eq.
 		.or. {vtSession:Land} .eq. LI .and. {vtGlobal:pxtcVatCountry} .eq. CH .or. {vtSession:Land} .eq. CH .and. {vtGlobal:pxtcVatCountry} .eq. LI }}
-	{{vtElseIf: {vtGlobal:pxtcVatCountry} .nin. {vtGet:EU_Countries} .or. {vtSession:USt_ID} .neq.}}
+	{{vtElseIf: {vtGlobal:pxtcVatCountry} .in. {vtGet:EU_Countries} .and. {vtSession:Land} .nin. {vtGet:EU_Countries} .or. {vtSession:USt_ID} .neq.}}
 		{{vtSet: nicht_steuerbar="1"}}
 	{{vtEndIf}}
 
diff --git a/checkout.vtedit.html b/checkout.vtedit.html
index 296ff59..bf8acbb 100644
--- a/checkout.vtedit.html
+++ b/checkout.vtedit.html
@@ -6,7 +6,7 @@
 	<title>Pixtacy-Kontaktformular bearbeiten</title>
 	<meta http-equiv="content-type" content="text/html;charset=utf-8">
 	{{vtInclude: includes/html_headers_internal.html }}
-	<!--{{vtInclude: includes/countrylist_{vtGet:Language}.html}}-->
+	<!--{{vtInclude: /config/includes/countrylist_{vtGet:Language}.html, includes/countrylist_{vtGet:Language}.html}}-->
 	<script type="text/javascript" src="resources/validations.js"></script>
 	<script type="text/javascript" src="{{vtConfig:baseURLResources}}tiny_mce/tinymce.min.js"></script>
 	<script type="text/javascript">
diff --git a/download.html b/download.html
index 08d3bb4..13017fe 100644
--- a/download.html
+++ b/download.html
@@ -155,6 +155,7 @@
 							<!--{{vtEndIf}}-->
 						</td>
 						<td>
+							<strong>{{vtItem:filename}}</strong><br>
 							{{vtItem:title}}<br>
 							<a href="{{vtLink:-met='single',o='{vtGetValue:o}',t='{vtGetValue:t}',i='{vtItem:id}'}}">{{vtGet:s_btn_download_file}}</a>
 						</td>
diff --git a/image.download.html b/image.download.html
index 89f0c07..cb131af 100644
--- a/image.download.html
+++ b/image.download.html
@@ -72,6 +72,9 @@
 			{{vtIf: {vtGet:File} .bw. - }}
 				{{vtCode: die( 'Could not generate image [' . v::vtget('File:escaped') . ']' ); }}
 			{{vtEndIf}}
+		{{vtElseIf: {vtGetValue:v} .eq. .and. {vtGlobal:pxtcImagingLoresSuffix} .neq. }}
+			{{vtCalc: basename( '{vtGet:File,escaped}', '.jpg' ) . '{vtGlobal:pxtcImagingLoresSuffix,escaped}.jpg' }}
+			{{vtSet: FileName }}
 		{{vtEndIf}}
 
 		{{vtDeliver: {vtGet:File}, {vtGet:FileName} }}
diff --git a/imagelist.download.html b/imagelist.download.html
index 95ee5a7..771508a 100644
--- a/imagelist.download.html
+++ b/imagelist.download.html
@@ -93,6 +93,7 @@
 	{{vtEndIf}}
 	{{vtSet: Directory="{vtGlobal:pxtcPathLores}"}}
 	{{vtSet: Zipname="bilder_lores.zip"}}
+	{{vtSet: Suffix = "{vtGlobal:pxtcImagingLoresSuffix}" }}
 	{{vtIf: {vtGlobal:pxtcDownloadLogLores} .eq. 1 }}
 		{{vtSet: LogType="lores"}}
 	{{vtEndIf}}
@@ -171,10 +172,10 @@
 	{{vtSet: ZipMethod }}
 
 	{{vtIf: {vtGet:ZipMethod} .eq. external }}
-		{{vtCalc: create_zip_file( '{vtGet:Zipname}', '{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}' ) }}
+		{{vtCalc: create_zip_file( '{vtGet:Zipname}', '{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}', '{vtGet:Suffix,escaped}' ) }}
 		{{vtSet: ZipFile}}
 	{{vtElse}}
-		{{vtCalc: deliver_zip_file( '{vtGet:Zipname}', '{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}' ) }}
+		{{vtCalc: deliver_zip_file( '{vtGet:Zipname}', '{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}', '{vtGet:Suffix,escaped}' ) }}
 		{{vtSet: SuccessfulDelivery }}
 	{{vtEndIf}}
 	
diff --git a/includes/functions.html b/includes/functions.html
index 1f12f91..416e673 100644
--- a/includes/functions.html
+++ b/includes/functions.html
@@ -278,7 +278,6 @@
 			{{vtEndDBSelect}}
 		{{vtEndIf}}
 
-		{{vtSet: istKategorie="{istKategorie}"}}
 		{{vtSet: Source="{vtArg:Source}"}}
 		
 		{{vtIf: {vtGet:Source} .eq. hires }}
@@ -294,8 +293,6 @@
 			{{vtRepeat: {vtResult} }}
 				{{vtIf: {vtItem} .nin. {vtGet:ExistingImages} }}
 
-					{{vtSet: istKategorie=""}}
-
 					{{vtIf: {vtGet:Source} .eq. hires }}
 						{{vtCalc: update_lores_image( utf8_encode('{Verzeichnis}/{vtItem}'), TRUE ) }}
 					{{vtEndIf}}
@@ -313,7 +310,7 @@
 			{{vtEndRepeat}}
 	
 			{{vtCalc: getFileInfo('{vtGet:pfad}', 'mtime') }}
-			{{vtDo: -act="update", -obj="{vtID}", Timestamp="{vtResult}", istKategorie="{vtGet:istKategorie}"}}
+			{{vtDo: -act="update", -obj="{vtID}", Timestamp="{vtResult}" }}
 			
 		{{vtEndIf}}
 	
diff --git a/includes/get_products_lb.html b/includes/get_products_lb.html
index bb2c663..36724ef 100644
--- a/includes/get_products_lb.html
+++ b/includes/get_products_lb.html
@@ -21,7 +21,7 @@
 	{{vtLoad: templates/pixtacy/lib/pxtc_products.class.php }}
 	{{vtCalc: Pixtacy_Products::set_options( array ( 
 		'paymentsPossible' => v::vtget('PaymentPossible'),
-		'deliveryPossible' => v::vtget('DeliveryPayment'),
+		'deliveryPossible' => v::vtget('DeliveryPossible'),
 		'vatRate1' => v::vtglobal('pxtcVatRate'),
 		'vatRate2' => v::vtglobal('pxtcVatRate2'),
 		'preferEnglish' => v::vtget('Language') != 'de' ? '1' : '' 
diff --git a/lib/image_processor.class.php b/lib/image_processor.class.php
index 349714e..d1d5e39 100644
--- a/lib/image_processor.class.php
+++ b/lib/image_processor.class.php
@@ -41,15 +41,15 @@ class Image_Processor {
 			$this->xmpData = $image->getXmp();
 		}
 
-		$memoryNeed = $width * $height * 3;
+		// 8 Bytes/Pixel (4 Byte RGBA × 2 für Quelle + Ziel bei imagecopyresampled)
+		// + 20 % Puffer für PHP-Overhead
+		$memoryNeed = (int) ceil( $width * $height * 8 * 1.2 );
 
 		if ( $memoryNeed > $this->_get_available_memory() / 3 )
 		{
 			ini_set( 'memory_limit', $memoryNeed );
-			ini_set( 'se_memory_limit', $memoryNeed );
 			
-			if ( ini_get( 'memory_limit' ) != $memoryNeed 
-					&& ini_get( 'se_memory_limit' ) != $memoryNeed )
+			if ( ini_get( 'memory_limit' ) != $memoryNeed )
 			{
 				return FALSE;
 			}
@@ -152,7 +152,7 @@ class Image_Processor {
 		$font = $font ? $font : 'Vera.ttf';
 		$rotation = $rotation ? $rotation : 0;
 		
-		if ( $size <= 0 || $size > 1 )
+		if ( $size <= 0 || $size > 1.5 )
 		{
 			$size = 0.7;
 		}
@@ -242,7 +242,7 @@ class Image_Processor {
 
 		$imageWidth = imagesx( $this->image );
 		$imageHeight = imagesy( $this->image );
-		$scaling = max( 0, min( 1, $scaling ) );
+		$scaling = max( 0, min( 1.5, $scaling ) );
 
 		$watermark = imagecreatefrompng( $watermarkFile );
 		$watermarkWidth = imagesx( $watermark );
@@ -339,13 +339,18 @@ class Image_Processor {
 	}
 
 
-	function write( $file, $quality = 90 )
+	function write( $file, $quality = 90, $dpi = NULL )
 	{
 		if ( empty( $file ) )
 		{
 			return FALSE;
 		}
 
+		if ( $dpi )
+		{
+			imageresolution( $this->image, (int) $dpi, (int) $dpi );
+		}
+
 		$parts = explode( '/', dirname( $file ) );
 		$dir = '';
 
@@ -461,17 +466,7 @@ class Image_Processor {
 		}
 
 		$unit = strtolower( substr( $value, -1 ) );
-		$value1 = $value ? substr( $value, 0, -1 ) * pow( 1024, strpos( '*kmgt', $unit ) ) : 0;
-		$value = trim( ini_get( 'se_memory_limit' ) );
-
-		if ( $value == '-1' )
-		{
-			$value = '1T';
-		}
-
-		$unit = strtolower( substr( $value, -1 ) );
-		$value2 = $value ? substr( $value, 0, -1 ) * pow( 1024, strpos( '*kmgt', $unit ) ) : 0;
-		return max( $value1, $value2 );
+		return substr( $value, 0, -1 ) * pow( 1024, strpos( '*kmgt', $unit ) );
 	}
 
 }
diff --git a/lib/tbszip.php b/lib/tbszip.php
index 370ed5a..c93ad0e 100644
--- a/lib/tbszip.php
+++ b/lib/tbszip.php
@@ -1,8 +1,8 @@
 <?php
 
 /*
-TbsZip version 2.14 (modified by Martin Wandelt [-mw] [+mw])
-Date    : 2013-06-11
+TbsZip version 2.18
+Date    : 2025-11-01
 Author  : Skrol29 (email: http://www.tinybutstrong.com/onlyyou.html)
 Licence : LGPL
 This class is independent from any other classes and has been originally created for the OpenTbs plug-in
@@ -17,6 +17,31 @@ define('TBSZIP_STRING',32);    // output to string, or add from string
 
 class clsTbsZip {
 
+	public $Meth8Ok;
+	public $DisplayError;
+	public $ArchFile;
+	public $Error;
+	
+	// Compatibility PHP 8.2
+	public $ArchHnd;
+	public $ArchIsNew;
+	public $CdEndPos;
+	public $CdPos;
+	public $CdInfo;
+	public $ArchIsStream;
+	public $CdFileLst;
+	public $CdFileNbr;
+	public $CdFileByName;
+	public $VisFileLst;
+	public $LastReadComp;
+	public $LastReadIdx;
+	public $ReplInfo;
+	public $ReplByPos;
+	public $AddInfo;
+	public $OutputMode;
+	public $OutputHandle;
+	public $OutputSrc;
+
 	function __construct() {
 		$this->Meth8Ok = extension_loaded('zlib'); // check if Zlib extension is available. This is need for compress and uncompress with method 8.
 		$this->DisplayError = true;
@@ -24,8 +49,10 @@ class clsTbsZip {
 		$this->Error = false;
 	}
 
+	/**
+	 * Create a new virtual empty archive, the name will be the default name when the archive is flushed.
+	 */
 	function CreateNew($ArchName='new.zip') {
-	// Create a new virtual empty archive, the name will be the default name when the archive is flushed.
 		if (!isset($this->Meth8Ok)) $this->__construct();  // for PHP 4 compatibility
 		$this->Close(); // note that $this->ArchHnd is set to false here
 		$this->Error = false;
@@ -37,15 +64,23 @@ class clsTbsZip {
 		$this->CdPos = $this->CdInfo['p_cd'];
 	}
 
+	/**
+	 * Open the zip archive
+	 */
 	function Open($ArchFile, $UseIncludePath=false) {
-	// Open the zip archive
+
 		if (!isset($this->Meth8Ok)) $this->__construct();  // for PHP 4 compatibility
 		$this->Close(); // close handle and init info
 		$this->Error = false;
 		$this->ArchIsNew = false;
 		$this->ArchIsStream = (is_resource($ArchFile) && (get_resource_type($ArchFile)=='stream'));
 		if ($this->ArchIsStream) {
-			$this->ArchFile = 'from_stream.zip';
+			$info = stream_get_meta_data($ArchFile);
+			if (isset($info['uri'])) {
+				$this->ArchFile = $info['uri'];
+			} else {
+				$this->ArchFile = 'from_stream.zip';
+			}
 			$this->ArchHnd = $ArchFile;
 		} else {
 			// open the file
@@ -96,9 +131,18 @@ class clsTbsZip {
 		$cd_pos = -22;
 		$this->_MoveTo($cd_pos, SEEK_END);
 		$b = $this->_ReadData(4);
-		if ($b!==$cd_info) return $this->RaiseError('The End of Central Rirectory Record is not found.');
-
-		$this->CdEndPos = ftell($this->ArchHnd) - 4;
+		if ($b===$cd_info) {
+			$this->CdEndPos = ftell($this->ArchHnd) - 4;
+		} else {
+			$p = $this->_FindCDEnd($cd_info);
+			//echo 'p='.var_export($p,true); exit;
+			if ($p===false) {
+				return $this->RaiseError('The End of Central Directory Record is not found.');
+			} else {
+				$this->CdEndPos = $p;
+				$this->_MoveTo($p+4);
+			}
+		}
 		$this->CdInfo = $this->CentralDirRead_End($cd_info);
 		$this->CdFileLst = array();
 		$this->CdFileNbr = $this->CdInfo['file_nbr_curr'];
@@ -167,7 +211,13 @@ class clsTbsZip {
 	}
 
 	function RaiseError($Msg) {
-		if ($this->DisplayError) echo '<strong>'.get_class($this).' ERROR :</strong> '.$Msg.'<br>'."\r\n";
+		if ($this->DisplayError) {
+			if (PHP_SAPI==='cli') {
+				echo get_class($this).' ERROR with the zip archive: '.$Msg."\r\n";
+			} else {
+				echo '<strong>'.get_class($this).' ERROR with the zip archive:</strong> '.$Msg.'<br>'."\r\n";
+			}
+		}
 		$this->Error = $Msg;
 		return false;
 	}
@@ -230,8 +280,10 @@ class clsTbsZip {
 		return ($this->FileGetIdx($NameOrIdx)!==false);
 	}
 
-	function FileGetIdx($NameOrIdx) {
-	// Check if a file name, or a file index exists in the Central Directory, and return its index
+	/**
+	 * Check if a file name, or a file index exists in the Central Directory, and return its index
+	 */
+	 function FileGetIdx($NameOrIdx) {
 		if (is_string($NameOrIdx)) {
 			if (isset($this->CdFileByName[$NameOrIdx])) {
 				return $this->CdFileByName[$NameOrIdx];
@@ -247,8 +299,10 @@ class clsTbsZip {
 		}
 	}
 
+	/**
+	 * Check if a file name exists in the list of file to add, and return its index
+	 */
 	function FileGetIdxAdd($Name) {
-	// Check if a file name exists in the list of file to add, and return its index
 		if (!is_string($Name)) return false;
 		$idx_lst = array_keys($this->AddInfo);
 		foreach ($idx_lst as $idx) {
@@ -263,7 +317,7 @@ class clsTbsZip {
 		$this->LastReadIdx = false;
 
 		$idx = $this->FileGetIdx($NameOrIdx);
-		if ($idx===false) return $this->RaiseError('File "'.$NameOrIdx.'" is not found in the Central Directory.');
+		if ($idx===false) return $this->RaiseError('File "' . htmlspecialchars($NameOrIdx) . '" is not found in the Central Directory.');
 
 		$pos = $this->CdFileLst[$idx]['p_loc'];
 		$this->_MoveTo($pos);
@@ -281,13 +335,13 @@ class clsTbsZip {
 					$Data = gzinflate($Data);
 					$Comp = -1; // means uncompressed
 				} else {
-					$this->RaiseError('Unable to uncompress file "'.$NameOrIdx.'" because extension Zlib is not installed.');
+					$this->RaiseError('Unable to uncompress file "' . htmlspecialchars($NameOrIdx) . '" because extension Zlib is not installed.');
 				}
 			}
 		} elseif($meth==0) {
 			$Comp = 0; // means stored without compression
 		} else {
-			if ($Uncompress) $this->RaiseError('Unable to uncompress file "'.$NameOrIdx.'" because it is compressed with method '.$meth.'.');
+			if ($Uncompress) $this->RaiseError('Unable to uncompress file "' . htmlspecialchars($NameOrIdx) . '" because it is compressed with method ' . $meth . '.');
 		}
 		$this->LastReadComp = $Comp;
 
@@ -295,8 +349,10 @@ class clsTbsZip {
 
 	}
 
+	/**
+	 * Read the file header (and maybe the data ) in the archive, assuming the cursor in at a new file position
+	 */
 	function _ReadFile($idx, $ReadData) {
-	// read the file header (and maybe the data ) in the archive, assuming the cursor in at a new file position
 
 		$b = $this->_ReadData(30);
 
@@ -374,11 +430,13 @@ class clsTbsZip {
 
 	}
 
+	/**
+	 * Store replacement information.
+	 */
 	function FileReplace($NameOrIdx, $Data, $DataType=TBSZIP_STRING, $Compress=true) {
-	// Store replacement information.
 
 		$idx = $this->FileGetIdx($NameOrIdx);
-		if ($idx===false) return $this->RaiseError('File "'.$NameOrIdx.'" is not found in the Central Directory.');
+		if ($idx===false) return $this->RaiseError('File "' . htmlspecialchars($NameOrIdx) . '" is not found in the Central Directory.');
 
 		$pos = $this->CdFileLst[$idx]['p_loc'];
 
@@ -427,9 +485,11 @@ class clsTbsZip {
 
 	}
 
+	/**
+	 * Cancel added, modified or deleted modifications on a file in the archive.
+	 * @return integer The number of cancellations.
+	 */
 	function FileCancelModif($NameOrIdx, $ReplacedAndDeleted=true) {
-	// cancel added, modified or deleted modifications on a file in the archive
-	// return the number of cancels
 
 		$nbr = 0;
 
@@ -459,8 +519,8 @@ class clsTbsZip {
 
 	function Flush($Render=TBSZIP_DOWNLOAD, $File='', $ContentType='') {
 
-		if ( ($File!=='') && ($this->ArchFile===$File)) {
-			$this->RaiseError('Method Flush() cannot overwrite the current opened archive: \''.$File.'\''); // this makes corrupted zip archives without PHP error.
+		if ( ($File!=='') && ($this->ArchFile===$File) && ($Render==TBSZIP_FILE) ) {
+			$this->RaiseError('Method Flush() cannot overwrite the current opened archive: \'' . htmlspecialchars($File) . '\''); // this makes corrupted zip archives without PHP error.
 			return false;
 		}
 
@@ -514,8 +574,7 @@ class clsTbsZip {
 					$this->_PutDec($b2, $ReplInfo['len_u'], $d+8, 4); // l_data_u
 				}
 				// output data
-				// $this->OutputFromString($b1.$ReplInfo['data'].$b2); // [-mw]
-				readfile( $ReplInfo['path'] ); // [+mw]
+				$this->OutputFromString($b1.$ReplInfo['data'].$b2);
 				unset($ReplInfo['data']); // save PHP memory
 				$Delta = $Delta + $ReplInfo['diff'] + $ReplInfo['len_c'];
 			}
@@ -568,8 +627,8 @@ class clsTbsZip {
 		}
 		$this->OutputFromString($b2);
 		$ArchPos += $old_cd_len;
- 		$DeltaCdLen =  $DeltaCdLen + strlen($b2) - $old_cd_len;
- 
+		$DeltaCdLen =  $DeltaCdLen + strlen($b2) - $old_cd_len;
+
 		// Output until "end of central directory record"
 		if ($this->ArchHnd!==false) $this->OutputFromArch($ArchPos, $this->CdEndPos); // ArchHnd is false if CreateNew() has been called
 
@@ -586,7 +645,7 @@ class clsTbsZip {
 		// Output "end of central directory record"
 		$b2 = $this->CdInfo['bin'];
 		$DelNbr = count($DelLst);
-		if ( ($AddNbr>0) or ($DelNbr>0) ) {
+		if ( ($AddNbr>0) || ($DelNbr>0) ) {
 			// total number of entries in the central directory on this disk
 			$n = $this->_GetDec($b2, 8, 2);
 			$this->_PutDec($b2, $n + $AddNbr - $DelNbr,  8, 2);
@@ -618,8 +677,7 @@ class clsTbsZip {
 			if (''.$File=='') $File = basename($this->ArchFile).'.zip';
 			$this->OutputHandle = @fopen($File, 'w');
 			if ($this->OutputHandle===false) {
-				$this->RaiseError('Method Flush() cannot overwrite the target file \''.$File.'\'. This may not be a valid file path or the file may be locked by another process or because of a denied permission.');
-				return false;
+				return $this->RaiseError('Method Flush() cannot overwrite the target file \'' . htmlspecialchars($File) . '\'. This may not be a valid file path or the file may be locked by another process or because of a denied permission.');
 			}
 		} elseif (($Render & TBSZIP_STRING)==TBSZIP_STRING) {
 			$this->OutputMode = TBSZIP_STRING;
@@ -641,6 +699,8 @@ class clsTbsZip {
 				$Len = $this->_EstimateNewArchSize();
 				if ($Len!==false) header('Content-Length: '.$Len); 
 			}
+		} else {
+			return $this->RaiseError('Method Flush is called with a unsupported render option.');
 		}
 
 		return true;
@@ -782,6 +842,34 @@ class clsTbsZip {
 		return $pos." (h:".dechex($pos).")";
 	}
 
+	/**
+	 * Search the record of end of the Central Directory.
+	 * Return the position of the record in the file.
+	 * Return false if the record is not found. The comment cannot exceed 65335 bytes (=FFFF).
+	 * The method is read backwards a block of 256 bytes and search the key in this block.
+	 */
+	function _FindCDEnd($cd_info) {
+		$nbr = 1;
+		$p = false;
+		$pos = ftell($this->ArchHnd) - 4 - 256;
+		while ( ($p===false) && ($nbr<256) ) {
+			if ($pos<=0) {
+				$pos = 0;
+				$nbr = 256; // in order to make this a last check
+			}
+			$this->_MoveTo($pos);
+			$x = $this->_ReadData(256);
+			$p = strpos($x, $cd_info);
+			if ($p===false) {
+				$nbr++;
+				$pos = $pos - 256 - 256;
+			} else {
+				return $pos + $p;
+			}
+		}
+		return false;
+	}
+	
 	function _DataOuputAddedFile($Idx, $PosLoc) {
 
 		$Ref =& $this->AddInfo[$Idx];
@@ -810,9 +898,7 @@ class clsTbsZip {
 		$b .= ''; // fields
 
 		// Output the data
-		// $this->OutputFromString($b.$Ref['data']); // [-mw]
-		echo $b; // [+mw]
-		readfile( $Ref['path'] ); // [+mw]
+		$this->OutputFromString($b.$Ref['data']);
 		$OutputLen = strlen($b) + $Ref['len_c']; // new position of the cursor
 		unset($Ref['data']); // save PHP memory
 
@@ -888,7 +974,7 @@ class clsTbsZip {
 				if ($len_u===false) $len_u = $fz;
 				$len_c = ($Compress) ? false : $fz;
 			} else {
-				return $this->RaiseError("Cannot add the file '".$path."' because it is not found.");
+				return $this->RaiseError("Cannot add the file '" . htmlspecialchars($path) . "' because it is not found.");
 			}
 		}
 
@@ -897,13 +983,13 @@ class clsTbsZip {
 
 	}
 
+	/**
+	 * Returns the real size of data
+	 */
 	function _DataPrepare(&$Ref) {
-	// returns the real size of data
 		if ($Ref['path']!==false) {
-			// $Ref['data'] = file_get_contents($Ref['path']); // [-mw]
-			$Ref['data'] = ''; // [+mw]
-			// if ($Ref['crc32']===false) $Ref['crc32'] = crc32($Ref['data']); // [-mw]
-			if ($Ref['crc32']===false) { $array = unpack('N', pack('H*', hash_file( 'crc32b', $Ref['path'] ))); $Ref['crc32'] = $array[1]; } // [+mw]
+			$Ref['data'] = file_get_contents($Ref['path']);
+			if ($Ref['crc32']===false) $Ref['crc32'] = crc32($Ref['data']);
 			if ($Ref['len_c']===false) {
 				// means the data must be compressed
 				$Ref['data'] = gzdeflate($Ref['data']);
@@ -912,8 +998,10 @@ class clsTbsZip {
 		}
 	}
 
-	function _EstimateNewArchSize($Optim=true) {
-	// Return the size of the new archive, or false if it cannot be calculated (because of external file that must be compressed before to be insered)
+	/**
+	 * Return the size of the new archive, or false if it cannot be calculated (because of external file that must be compressed before to be insered)
+	 */
+	 function _EstimateNewArchSize($Optim=true) {
 
 		if ($this->ArchIsNew) {
 			$Len = strlen($this->CdInfo['bin']);
@@ -961,4 +1049,4 @@ class clsTbsZip {
 
 	}
 
-}
\ No newline at end of file
+}
diff --git a/lightbox.download.html b/lightbox.download.html
index fce6622..10ba4ed 100644
--- a/lightbox.download.html
+++ b/lightbox.download.html
@@ -31,6 +31,7 @@
 	{{vtSet: Allowed="{vtGet:LoresDownloadAllowed}"}}
 	{{vtSet: Directory="{vtGlobal:pxtcPathLores}"}}
 	{{vtSet: Zipname="bilder_lores.zip"}}
+	{{vtSet: Suffix = "{vtGlobal:pxtcImagingLoresSuffix}" }}
 	{{vtIf: {vtGlobal:pxtcDownloadLogLores} .eq. 1 }}
 		{{vtSet: LogType="lores"}}
 	{{vtEndIf}}
@@ -118,10 +119,10 @@
 	{{vtSet: ZipMethod }}
 
 	{{vtIf: {vtGet:ZipMethod} .eq. external }}
-		{{vtCalc: create_zip_file( '{vtGet:Zipname}', '{vtConfig:pathToVirthos}{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}' ) }}
+		{{vtCalc: create_zip_file( '{vtGet:Zipname}', '{vtConfig:pathToVirthos}{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}', '{vtGet:Suffix,escaped}' ) }}
 		{{vtSet: ZipFile}}
 	{{vtElse}}
-		{{vtCalc: deliver_zip_file( '{vtGet:Zipname}', '{vtConfig:pathToVirthos}{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}' ) }}
+		{{vtCalc: deliver_zip_file( '{vtGet:Zipname}', '{vtConfig:pathToVirthos}{vtGet:Directory,escaped}', '{vtGet:FinalList,escaped}', '{vtGet:Suffix,escaped}' ) }}
 		{{vtSet: SuccessfulDelivery }}
 	{{vtEndIf}}
 
diff --git a/order.html b/order.html
index b202a51..f7e6632 100644
--- a/order.html
+++ b/order.html
@@ -4,7 +4,7 @@
 <html>
 <head>
 	<!--{{vtInclude: includes/initialize.html}}-->
-	<!--{{vtScript}} {{Nummer:short}} {{Rechnungsnummer:short}} {{Token:short}} {{abgeschlossen:checkbox,[{"value":"1","text":"ja"}] }} {{bezahlt:checkbox,[{"value":"1","text":"ja"}] }} {{erledigt:checkbox,[{"value":"1","text":"ja"}] }} {{Datum:short}} {{Uhrzeit:short}} {{Kommentar:styled}} {{Anrede:short}} {{Vorname:short}} {{Name:short}} {{Firma:short}} {{USt_ID:short}} {{Strasse:short}} {{PLZ:short}} {{Ort:short}} {{Land:short}} {{Landesname:short}} {{Bundesland:short}} {{Telefon:short}} {{Email:short}} {{Registrierung:select,["ja","nein"] }} {{Bemerkungen}} {{Lieferanschrift:checkbox,[{"value":"1","text":"ja"}] }} {{Vorname2:short}} {{Name2:short}} {{Firma2:short}} {{Strasse2:short}} {{Plz2:short}} {{Ort2:short}} {{Land2:short}} {{Landesname2:short}} {{Bundesland2:short}} {{Datenlieferung:checkbox,[{"value":"1","text":"ja"}] }} {{Liefermethode:short}} {{Liefermethode_en:short}} {{Bezahlmethode:select,["vorkasse","rechnung","lastschrift","sepa","paypal","payrexx","mollie","sofortueberweisung","barzahlung"] }} {{SEPA_IBAN:short}} {{SEPA_BIC:short}} {{SEPA_Inhaber:short}} {{SEPA_Email:short}} {{SEPA_Ref:short}} {{Payment_TAN:short}} {{Payment_Date:short}} {{Payment_Value:short}} {{Payment_Comment:short}} {{Warenkorb}} {{Anzahl_Files:short}} {{Anzahl_Prints:short}} {{Warenwert_netto:short}} {{Warenwert:short}} {{Rabatt_netto:short}} {{Rabatt:short}} {{CD_Versand_netto:short}} {{CD_Versand:short}} {{Auftragspauschale_netto:short}} {{Auftragspauschale:short}} {{Versandkosten_netto:short}} {{Versandkosten:short}} {{Mehrwertsteuer:short}} {{nicht_steuerbar:checkbox,[{"value":"1","text":"ja"}] }} {{Rechnungsbetrag:short}} {{Waehrung:short}} {{pxprint_Order_ID:short}} {{pxprint_Order_TS:short}} {{pxprint_Error:short}} {{Easybill_Number:short}} {{Easybill_ID:short}} {{Easybill_TS:short}} {{Easybill_Error:short}} {{Gutscheincode:short}} {{GutscheinID:short}} {{Language:short}} {{Session:non_editable}} {{Userid:non_editable}} {{Zwischensumme:non_editable}} {{DeliveryNotificationSent:non_editable}} {{vtEndScript}}-->
+	<!--{{vtScript}} {{Nummer:short}} {{Rechnungsnummer:short}} {{Rechnungsdatum:short}} {{Token:short}} {{abgeschlossen:checkbox,[{"value":"1","text":"ja"}] }} {{bezahlt:checkbox,[{"value":"1","text":"ja"}] }} {{erledigt:checkbox,[{"value":"1","text":"ja"}] }} {{Datum:short}} {{Uhrzeit:short}} {{Kommentar:styled}} {{Anrede:short}} {{Vorname:short}} {{Name:short}} {{Firma:short}} {{USt_ID:short}} {{Strasse:short}} {{PLZ:short}} {{Ort:short}} {{Land:short}} {{Landesname:short}} {{Bundesland:short}} {{Telefon:short}} {{Email:short}} {{Registrierung:select,["ja","nein"] }} {{Bemerkungen}} {{Lieferanschrift:checkbox,[{"value":"1","text":"ja"}] }} {{Vorname2:short}} {{Name2:short}} {{Firma2:short}} {{Strasse2:short}} {{Plz2:short}} {{Ort2:short}} {{Land2:short}} {{Landesname2:short}} {{Bundesland2:short}} {{Datenlieferung:checkbox,[{"value":"1","text":"ja"}] }} {{Liefermethode:short}} {{Liefermethode_en:short}} {{Bezahlmethode:select,["vorkasse","rechnung","lastschrift","sepa","paypal","payrexx","mollie","sofortueberweisung","barzahlung"] }} {{SEPA_IBAN:short}} {{SEPA_BIC:short}} {{SEPA_Inhaber:short}} {{SEPA_Email:short}} {{SEPA_Ref:short}} {{Payment_TAN:short}} {{Payment_Date:short}} {{Payment_Value:short}} {{Payment_Comment:short}} {{Warenkorb}} {{Anzahl_Files:short}} {{Anzahl_Prints:short}} {{Warenwert_netto:short}} {{Warenwert:short}} {{Rabatt_netto:short}} {{Rabatt:short}} {{CD_Versand_netto:short}} {{CD_Versand:short}} {{Auftragspauschale_netto:short}} {{Auftragspauschale:short}} {{Versandkosten_netto:short}} {{Versandkosten:short}} {{Mehrwertsteuer:short}} {{nicht_steuerbar:checkbox,[{"value":"1","text":"ja"}] }} {{Rechnungsbetrag:short}} {{Waehrung:short}} {{pxprint_Order_ID:short}} {{pxprint_Order_TS:short}} {{pxprint_Error:short}} {{Easybill_Number:short}} {{Easybill_ID:short}} {{Easybill_TS:short}} {{Easybill_Error:short}} {{Gutscheincode:short}} {{GutscheinID:short}} {{Language:short}} {{Session:non_editable}} {{Userid:non_editable}} {{Zwischensumme:non_editable}} {{DeliveryNotificationSent:non_editable}} {{vtEndScript}}-->
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<title>Bestellung {{Nummer}} | {{vtGlobal:siteName}}</title>
 	{{vtInclude: includes/html_headers_internal.html }}
diff --git a/order.invoice.html b/order.invoice.html
index 37239d0..d60e518 100644
--- a/order.invoice.html
+++ b/order.invoice.html
@@ -13,7 +13,11 @@
 		{{vtDo: -act="update", -obj="{vtId}", Rechnungsnummer="{vtGet:NeueRechnungsnummer}", Rechnungsdatum="{vtDate|d.m.Y}" }}
       {{vtRedirect}}
       {{vtReturn}}
-	{{vtEndIf}}
+	{{vtElseIf: {Rechnungsdatum} .eq. }}
+		{{vtDo: -act="update", -obj="{vtId}", Rechnungsdatum="{vtDate|d.m.Y}" }}
+		{{vtRedirect}}
+		{{vtReturn}}
+ 	{{vtEndIf}}
 
 	{{vtCalc: {Anzahl_Files} + {Anzahl_Prints} }}
 	{{vtSet: Artikelanzahl }}
diff --git a/order.pxprint.html b/order.pxprint.html
index 6b4cf34..20a9587 100644
--- a/order.pxprint.html
+++ b/order.pxprint.html
@@ -73,16 +73,18 @@ function getPreferredProduct( $pxprintIds ){
 					## daher bleibt die Variable vorerst leer
 			
 					{{vtSet: Contact=""}}
-					{{_vtSet: Contact[firstname]="{Vorname}"}}
-					{{_vtSet: Contact[lastname]="{Name}"}}
-					{{_vtSet: Contact[organization]="{Firma}"}}
-					{{_vtSet: Contact[address]="{Strasse}"}}
-					{{_vtSet: Contact[zipcode]="{PLZ}"}}
-					{{_vtSet: Contact[city]="{Ort}"}}
-					{{_vtSet: Contact[country]="{Land}"}}
-					{{_vtSet: Contact[state]="{Bundesland}"}}
-					{{_vtSet: Contact[phone]="{Telefon}"}}
-					{{_vtSet: Contact[email]="{Email}"}}
+					{{vtIf: {vtGlobal:pxtcPxprintInvoice} .eq. customer }}
+						{{vtSet: Contact[firstname]="{Vorname}"}}
+						{{vtSet: Contact[lastname]="{Name}"}}
+						{{vtSet: Contact[organization]="{Firma}"}}
+						{{vtSet: Contact[address]="{Strasse}"}}
+						{{vtSet: Contact[zipcode]="{PLZ}"}}
+						{{vtSet: Contact[city]="{Ort}"}}
+						{{vtSet: Contact[country]="{Land}"}}
+						{{vtSet: Contact[state]="{Bundesland}"}}
+						{{vtSet: Contact[phone]="{Telefon}"}}
+						{{vtSet: Contact[email]="{Email}"}}
+					{{vtEndIf}}
 
 					{{vtIf: {vtGlobal:pxtcPxprintDelivery} .eq. customer}}
 						{{vtIf: {Lieferanschrift} .eq. 1}}
diff --git a/resources/functions.php b/resources/functions.php
index 6612f2c..2d0a19e 100644
--- a/resources/functions.php
+++ b/resources/functions.php
@@ -1591,9 +1591,9 @@ function saveLightbox()
 }
 
 
-function create_zip_file( $name, $basedir, $files )
+function create_zip_file( $name, $basedir, $files, $suffix = '' )
 {
-	$files = array_map( 'escapeshellarg', array_map( 'trim', explode( '|', $files ) ) );
+	$raw_files = array_map( 'trim', explode( '|', $files ) );
 	$pxtc_dir = v::vtconfig('pathToVirthos');
 	$cmd = v::vtconfig('pathToZipCommand') == '' ? '/usr/bin/zip' : v::vtconfig('pathToZipCommand');
 
@@ -1664,10 +1664,55 @@ function create_zip_file( $name, $basedir, $files )
 		return -2; // could not create temp subdirectory
 	}
 
+	/*** Optional: Dateien mit Suffix in Staging-Verzeichnis verlinken ***/
+
+	if ( $suffix !== '' )
+	{
+		$srcdir = "$zipdir/src";
+		mkdir( $srcdir, 0777 );
+
+		$files = array ();
+
+		foreach ( $raw_files as $raw_file )
+		{
+			if ( $raw_file === '' )
+			{
+				continue;
+			}
+
+			$source_path = $basedir . '/' . $raw_file;
+
+			if ( ! file_exists( $source_path ) )
+			{
+				continue; // Datei existiert nicht, überspringen
+			}
+
+			$new_relative = pxtc_insert_suffix( $raw_file, $suffix );
+			$target_path = $srcdir . '/' . $new_relative;
+			$target_dir = dirname( $target_path );
+
+			if ( ! file_exists( $target_dir ) )
+			{
+				mkdir( $target_dir, 0777, true );
+			}
+
+			symlink( realpath( $source_path ), $target_path );
+
+			$files[] = escapeshellarg( $new_relative );
+		}
+
+		$zip_source_dir = $srcdir;
+	}
+	else
+	{
+		$files = array_map( 'escapeshellarg', $raw_files );
+		$zip_source_dir = $basedir;
+	}
+
 	/*** Create zip file ***/
 
-	chdir( $basedir );
-	$cmd .= " -0 $zipdir/$name " . implode( ' ', $files );
+	chdir( $zip_source_dir );
+	$cmd .= " -0 -y $zipdir/$name " . implode( ' ', $files );
 	exec( $cmd );
 
 	if ( $handle = @opendir( $pxtc_dir . '/config/zip' ) )
@@ -1693,7 +1738,7 @@ function create_zip_file( $name, $basedir, $files )
 }
 
 
-function deliver_zip_file( $name, $basedir, $files )
+function deliver_zip_file( $name, $basedir, $files, $suffix = '' )
 {
 	if ( ! ini_get('safe_mode') )
 	{
@@ -1716,11 +1761,13 @@ function deliver_zip_file( $name, $basedir, $files )
 		if ( strpos( $file, '|' ) )
 		{
 			list ( $virtualPath, $file ) = explode( '|', $file );
+			$virtualPath = pxtc_insert_suffix( $virtualPath, $suffix );
 			$zip->FileAdd( $virtualPath, $file, TBSZIP_FILE, FALSE );
 		}
 		else
 		{
-			$zip->FileAdd( $file, "{$basedir}/{$file}", TBSZIP_FILE, FALSE );
+			$virtualPath = pxtc_insert_suffix( $file, $suffix );
+			$zip->FileAdd( $virtualPath, "{$basedir}/{$file}", TBSZIP_FILE, FALSE );
 		}
 	}
 
@@ -1764,6 +1811,25 @@ function deliver_zip_file( $name, $basedir, $files )
 	return ! connection_aborted();
 }
 
+/**
+ * Fügt ein Suffix vor der Dateiendung eines (ggf. relativen) Pfades ein.
+ * z. B. "images/bild.jpg" + "_lay" -> "images/bild_lay.jpg"
+ */
+function pxtc_insert_suffix( $filename, $suffix )
+{
+	if ( $suffix === '' )
+	{
+		return $filename;
+	}
+
+	$pathinfo = pathinfo( $filename );
+	$dir  = ( ! isset( $pathinfo['dirname'] ) || $pathinfo['dirname'] === '.' ) ? '' : $pathinfo['dirname'] . '/';
+	$ext  = isset( $pathinfo['extension'] ) && $pathinfo['extension'] !== '' ? '.' . $pathinfo['extension'] : '';
+	$base = $pathinfo['filename'];
+
+	return $dir . $base . $suffix . $ext;
+}
+
 
 function discountCart( $couponProduct = NULL, $couponAmount = NULL )
 {
@@ -1977,7 +2043,7 @@ function update_lores_image( $image_path, $force = FALSE )
 		}
 	}
 
-	if ( file_exists( $path ) && filemtime( $image_path ) >= filemtime( $path ) && ! $force )
+	if ( file_exists( $path ) && filemtime( $image_path ) <= filemtime( $path ) && ! $force )
 	{
 		return 0; // Low-res file is newer than High-res file
 	}
@@ -2191,7 +2257,7 @@ function generate_image_file( $filePath, $imagingRule, $pageId = NULL )
 
 	$tempfile = v::vtconfig('pathToCache') . 'images/' . sha1( $filePath . '-' . $rule['name'] ) . '.jpg' ;
 	
-	if ( ! $imager->write( $tempfile, $rule['quality'] ) )
+	if ( ! $imager->write( $tempfile, $rule['quality'], $rule['dpi'] ?? NULL ) )
 	{
 		return -5; // Could not write temporary file
 	}
diff --git a/resources/lg-cart.js b/resources/lg-cart.js
index cf04540..48e40b7 100644
--- a/resources/lg-cart.js
+++ b/resources/lg-cart.js
@@ -75,7 +75,7 @@
 			var sheet = document.createElement('style')
 			sheet.innerHTML = 
 				'.lg-cart-box { padding:20px; z-index:9999; position:absolute; cursor:pointer; } ' +
-				'.lg-cart-box i { color:white; opacity:0.9; text-shadow: 1px 1px 2px black, 0 0 1em grey, 0 0 0.2em grey; font-size: 1.75rem } ' +
+				'.lg-cart-box i { color:white; opacity:0.6; text-shadow: 1px 1px 2px black, 0 0 1em grey, 0 0 0.2em grey; font-size: 1.75rem } ' +
 				'.in-cart.lg-cart-box i { color:orange; } ' +
 				'.lg-cart-box:hover i { opacity:1; text-shadow: 1px 1px 2px black, 0 0 1em black, 0 0 0.2em black; } ' +
 				'.lg-cart-dialog { position:fixed; top:0; right:0; width:300px; height:100%; background:white; z-index:99999; }';
diff --git a/setup_imaging.html b/setup_imaging.html
index f8973f4..16303bc 100644
--- a/setup_imaging.html
+++ b/setup_imaging.html
@@ -76,6 +76,16 @@
 								<!--{{vtEndIf}}-->
 							</td>
 						</tr>
+						<tr>
+							<td style="width:10em">Suffix:</td>
+							<td>
+								<!--{{vtIf: {pxtcImagingLoresSuffix} .eq. }}-->
+									&mdash;
+								<!--{{vtElse}}-->
+									{{pxtcImagingLoresSuffix}}
+								<!--{{vtEndIf}}-->
+							</td>
+						</tr>
 						<tr>
 							<td style="width:10em">JPEG-Qualität:</td>
 							<td>
@@ -156,6 +166,10 @@
    							<td style="width:10em">JPEG-Qualität:</td>
    							<td>{{vtItem:quality}}%</td>
    						</tr>
+   						<tr>
+   							<td style="width:10em">Auflösung</td>
+								<td><!--{{vtIf: {vtItem:dpi} .gt. 0 }}-->{{vtItem:dpi}}<!--{{vtElse}}-->96<!--{{vtEndIf}}--> dpi</td>
+   						</tr>
    						<tr>
    							<td style="width:10em">Wasserzeichen:</td>
    							<td>
diff --git a/setup_imaging.vtedit.html b/setup_imaging.vtedit.html
index cae4b13..9954aec 100644
--- a/setup_imaging.vtedit.html
+++ b/setup_imaging.vtedit.html
@@ -126,6 +126,7 @@
 						size: $(this).find('input[name=ruleSize]').val(), 
 						minimum: $(this).find('input[name=ruleMinimum]').val(), 
 						quality: $(this).find('select[name=ruleQuality]').val(),
+						dpi: $(this).find('input[name=ruleDpi]').val().match(/\d+/)[0],
 						watermark: $(this).find('select[name=ruleWatermark]').val(),
 						wmtext: $(this).find('input[name=ruleWmText]').val(),
 						wmurl: $(this).find('input[name=ruleWmUrl]').val(),
@@ -212,6 +213,13 @@
 								<td style="width:10em">Minimum:</td>
 								<td><input type="text" id="pxtcImagingLoresSizeMin" name="pxtcImagingLoresSizeMin" value="{{pxtcImagingLoresSizeMin}}" size="5"> Pixel</td>
 							</tr>
+							<tr>
+								<td style="width:10em">Suffix:</td>
+								<td>
+									<input type="text" id="pxtcImagingLoresSuffix" name="pxtcImagingLoresSuffix" value="{{pxtcImagingLoresSuffix}}" size="8">
+									&nbsp; <span style="color:#aaa">Namenszusatz beim Download</span>
+								</td>
+							</tr>
 							<tr>
 								<td style="width:10em">JPEG-Qualität:</td>
 								<td>
@@ -259,6 +267,11 @@
 										<option value="0.9" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 0.9}}selected{{vtEndIf}}>80%</option>
 										<option value="0.8" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 0.8}}selected{{vtEndIf}}>90%</option>
 										<option value="1.0" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 1.0}}selected{{vtEndIf}}>100%</option>
+										<option value="1.1" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 1.1}}selected{{vtEndIf}}>110%</option>
+										<option value="1.2" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 1.2}}selected{{vtEndIf}}>120%</option>
+										<option value="1.3" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 1.3}}selected{{vtEndIf}}>130%</option>
+										<option value="1.4" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 1.4}}selected{{vtEndIf}}>140%</option>
+										<option value="1.5" {{vtIf: {pxtcImagingLoresWatermarkSize} .eq. 1.5}}selected{{vtEndIf}}>150%</option>
 									</select>
 									&nbsp;&nbsp;
 									<span style="color:#aaa">bezogen auf die Schmalseite des Bildes</span>
@@ -333,6 +346,13 @@
 										</select>
 									</td>
 								</tr>
+								<tr>
+									<td style="width:10em">Auflösung:</td>
+									<td>
+										<input type="text" name="ruleDpi" value="{{vtItem:dpi}}" size="5"> dpi
+										&nbsp; <span style="color:#aaa">(leer = 96)</span>
+									</td>
+								</tr>
 								<tr>
 									<td>Wasserzeichen:</td>
 									<td>
@@ -370,6 +390,11 @@
 											<option value="0.9" {{vtIf: {vtItem:wmsize} .eq. 0.9}}selected{{vtEndIf}}>80%</option>
 											<option value="0.8" {{vtIf: {vtItem:wmsize} .eq. 0.8}}selected{{vtEndIf}}>90%</option>
 											<option value="1.0" {{vtIf: {vtItem:wmsize} .eq. 1.0}}selected{{vtEndIf}}>100%</option>
+											<option value="1.1" {{vtIf: {vtItem:wmsize} .eq. 1.1}}selected{{vtEndIf}}>110%</option>
+											<option value="1.2" {{vtIf: {vtItem:wmsize} .eq. 1.2}}selected{{vtEndIf}}>120%</option>
+											<option value="1.3" {{vtIf: {vtItem:wmsize} .eq. 1.3}}selected{{vtEndIf}}>130%</option>
+											<option value="1.4" {{vtIf: {vtItem:wmsize} .eq. 1.4}}selected{{vtEndIf}}>140%</option>
+											<option value="1.5" {{vtIf: {vtItem:wmsize} .eq. 1.5}}selected{{vtEndIf}}>150%</option>
 										</select>
 										&nbsp;&nbsp;
 										<span style="color:#aaa">bezogen auf die Schmalseite des Bildes</span>
@@ -439,6 +464,13 @@
 									</select>
 								</td>
 							</tr>
+							<tr>
+								<td style="width:10em">Auflösung:</td>
+								<td>
+									<input type="text" name="ruleDpi" size="5"> dpi
+									&nbsp; <span style="color:#aaa">(leer = 96)</span>
+								</td>
+							</tr>
 							<tr>
 								<td>Wasserzeichen:</td>
 								<td>
@@ -476,6 +508,11 @@
 										<option value="0.9">80%</option>
 										<option value="0.8">90%</option>
 										<option value="1.0">100%</option>
+										<option value="1.1">110%</option>
+										<option value="1.2">120%</option>
+										<option value="1.3">130%</option>
+										<option value="1.4">140%</option>
+										<option value="1.5">150%</option>
 									</select>
 									&nbsp;&nbsp;
 									<span style="color:#aaa">bezogen auf die Schmalseite des Bildes</span>
diff --git a/setup_vat.html b/setup_vat.html
index 0ee0950..ac448e6 100644
--- a/setup_vat.html
+++ b/setup_vat.html
@@ -7,7 +7,7 @@
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<title>Einstellungen Mehrwertsteuer</title>
 	{{vtInclude: includes/html_headers_internal.html }}
-	<!--{{vtInclude: includes/countrylist_{vtConfig:systemLanguage}.html}}-->
+	<!--{{vtInclude: /config/includes/countrylist_{vtConfig:systemLanguage}.html, includes/countrylist_{vtConfig:systemLanguage}.html}}-->
 </head>
 <body>
 	<div class="content">
diff --git a/setup_vat.vtedit.html b/setup_vat.vtedit.html
index 19f39f8..d743eb2 100644
--- a/setup_vat.vtedit.html
+++ b/setup_vat.vtedit.html
@@ -16,7 +16,7 @@
 			{{vtEndLoop}}
 		{{vtEndSelect}}
 	-->
-	<!--{{vtInclude: includes/countrylist_{vtConfig:systemLanguage}.html}}-->
+	<!--{{vtInclude: /config/includes/countrylist_{vtConfig:systemLanguage}.html, includes/countrylist_{vtConfig:systemLanguage}.html}}-->
 	<script type="text/javascript">
 		$( function(){
 			buildMenuCountries( '{{pxtcVatCountry}}' );
diff --git a/views/gallery_r.html b/views/gallery_r.html
index fe870c7..0f30970 100644
--- a/views/gallery_r.html
+++ b/views/gallery_r.html
@@ -209,7 +209,7 @@
 							</div>
 							<!--{{vtIf: {vtGet:ShowCaption} .eq. 1 }}-->
 								<div class="caption text-muted small">
-									{{vtItem:title}}
+									{{vtItem:title,raw}}
 								</div>
 							<!--{{vtEndIf}}-->
 						</div>
diff --git a/views/namelist_r.html b/views/namelist_r.html
index 5b8a394..82effb1 100644
--- a/views/namelist_r.html
+++ b/views/namelist_r.html
@@ -83,7 +83,7 @@
 						<!--{{vtElse}}-->
 							<i class="far fa-image"></i>
 						<!--{{vtEndIf}}-->
-						{{vtItem:title}}
+						{{vtItem:title,raw}}
 					</a>
 					<!--{{vtIf: {vtItem:caption} .neq. }}-->
 						<small class="ml-3 text-muted">{{vtItem:caption,raw}}</small>
