diff --git a/_repair.html b/_repair.html
index 28b0b34..a1ef84d 100644
--- a/_repair.html
+++ b/_repair.html
@@ -31,7 +31,7 @@
 
 			<!--{{vtIf: {vtResult} .eq. 1}}-->
 				<p>Der Löschvorgang wurde erfolgreich ausgeführt.</p>
-				<p><a href="{{vtLink:/}}" class="text_link">weiter</a></p>
+				<p><a href="{{vtLink: {vtGet:ID_Home} }}" class="text_link">weiter</a></p>
 			<!--{{vtElse}}-->
 				<p>Beim Löschen ist ein Fehler aufgetreten. Bitte versuchen Sie, den oder die Bilderorder manuell zu entfernen.</p>
 				<ul>
diff --git a/_serp.html b/_serp.html
index b4d48c9..883429d 100644
--- a/_serp.html
+++ b/_serp.html
@@ -48,7 +48,7 @@
 
 	{{vtIf: {vtGlobal:pxtcSearchSortfield} .eq.}}
 		{{vtSet: SortField="name"}}
-	{{vtElseIf: {vtGlobal:pxtcSearchSortfield} .cn. .}}
+	{{vtElseIf: {vtGlobal:pxtcSearchSortfield} .cn. . .or. {vtGlobal:pxtcSearchSortfield} .cn. + }}
 		{{vtSet: SortField="{vtGlobal:pxtcSearchSortfield}"}}
 	{{vtElse}}
 		{{vtSet: SortField="vt{vtGlobal:pxtcSearchSortfield}"}}
@@ -70,6 +70,11 @@
 				-sortfield[]="image.creationdate", -sortfield[]="image.creationtime", 
 				-sortorder[]="{vtGlobal:pxtcSearchSortorder}", -sortorder[]="{vtGlobal:pxtcSearchSortorder}"
 			}}
+		{{vtElseIf: {vtGet:SortField} .eq. day+rating }}
+			{{vtDo: -act="updateSelection", -name="mainsearch", 
+				-sortfield[]="image.creationdate", -sortfield[]="image.rating", 
+				-sortorder[]="{vtGlobal:pxtcSearchSortorder}", -sortorder[]="{vtGlobal:pxtcSearchSortorder}"
+			}}
 		{{vtEndIf}}
 		{{vtDo: -act="updateSession", -portions[]=""}}
 	
@@ -96,7 +101,8 @@
 			Category="{vtGet:Search[category]}", 
 			Name="{vtGet:Search[title]}", 
 			Dateiname="{vtGet:Search[file]}", 
-			Remarks="{vtGet:Search[caption]}"
+			Remarks="{vtGet:Search[caption]}",
+			Rating="{vtGet:Search[rating]}"
 		}}
 
 		{{vtIf: userhasadminprivileges}}
@@ -110,6 +116,11 @@
 				-sortfield[]="image.creationdate", -sortfield[]="image.creationtime", 
 				-sortorder[]="{vtGlobal:pxtcSearchSortorder}", -sortorder[]="{vtGlobal:pxtcSearchSortorder}"
 			}}
+		{{vtElseIf: {vtGet:SortField} .eq. day+rating }}
+			{{vtDo: -act="updateSelection", -name="mainsearch", 
+				-sortfield[]="image.creationdate", -sortfield[]="image.rating", 
+				-sortorder[]="{vtGlobal:pxtcSearchSortorder}", -sortorder[]="{vtGlobal:pxtcSearchSortorder}"
+			}}
 		{{vtEndIf}}
 
 		{{vtDo: -act="updateSession", -portions[]=""}}
diff --git a/actions/update.html b/actions/update.html
index 927c01d..985c990 100644
--- a/actions/update.html
+++ b/actions/update.html
@@ -63,6 +63,18 @@ folder"
 		{{vtDo: -act="delete", -obj="{vtResult}" }}
 	{{vtEndIf}}
 
+	{{vtIf: {vtGlobal:pxtc_version_number} .lt. 52 }}
+		{{vtDo: -act="create", -target="8", -template="image", Name="Temp", Rating="3" }}
+		{{vtSelect: -origin="1", -type="image", -filter="{Rating} .gt. 1" }}
+		{{vtEndSelect}}
+		{{vtDo: -act="delete", -obj="{vtResult}" }}
+	{{vtEndIf}}
+
+	{{vtIf: {vtGlobal:pxtc_version_number} .lt. 53 }}
+		{{vtDo: -act="create", -target="8", -template="product", Bezeichnung="x", Bezeichnung_en="x", Beschreibung_en="x" }}
+		{{vtDo: -act="delete", -obj="{vtResult}" }}
+	{{vtEndIf}}
+
 	{{vtEndAsAdmin}}
 
 {{vtEndScript}}
diff --git a/ajax/order_dialog.html b/ajax/order_dialog.html
index f515049..602ce0b 100644
--- a/ajax/order_dialog.html
+++ b/ajax/order_dialog.html
@@ -25,23 +25,17 @@
 				<tbody>
 					<!--{{vtRepeat: {vtGet:ProductList} }}-->
 						<!--
-							{{vtIf: {vtItem:quantity} .gt. 0 }}
+							{{vtIf: {vtItem:cartQuantity} .gt. 0 }}
 								{{vtSet: CellClass = "table-warning" }}
 							{{vtElse}}
 								{{vtSet: CellClass = "" }}
 							{{vtEndIf}}
 						-->
-						<tr class="pxtc-product" data-id="{{vtItem:id}}" data-quantity="{{vtItem:quantity}}" data-type="{{vtItem:type}}">
-							<!--
-								{{vtIf: {vtGet:Language} .neq. de .and. {vtItem:name_en} .neq.}}
-									{{vtSet: Name = "{vtItem:name_en}" }}
-								{{vtElse}}
-									{{vtSet: Name = "{vtItem:name}" }}
-								{{vtEndIf}}
-							-->
+						<!--{{vtSet: ProductsExist = "1" }}-->
+						<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="table-secondary">
-									<h6>{{vtGet:Name}}</h6>
+									<h6>{{vtItem:name}}</h6>
 								</td>
 							<!--{{vtElse}}-->
 								<td class="{{vtGet:CellClass}}">
@@ -49,12 +43,12 @@
 										<input type="hidden" name="item" value="{{vtItem:id}}">
 										<input type="hidden" name="q" value="">
 										<div class="btn-group" role="group">
-											<button type="button" class="btn btn-outline-secondary btn-minus" {{vtIf: {vtItem:quantity} .eq. 0}}disabled{{vtEndIf}}><i class="fas fa-minus"></i></button>
-											<button type="button" class="btn btn-outline-secondary quantity" disabled>{{vtItem:quantity}}</button>
-											<button type="button" class="btn btn-outline-secondary btn-plus" {{vtIf: {vtItem:type} .eq. datei .and. {vtItem:quantity} .gt. 0}}disabled{{vtEndIf}}><i class="fas fa-plus"></i></button>
+											<button type="button" class="btn btn-outline-secondary btn-minus" {{vtIf: {vtItem:cartQuantity} .eq. 0}}disabled{{vtEndIf}}><i class="fas fa-minus"></i></button>
+											<button type="button" class="btn btn-outline-secondary quantity" disabled>{{vtItem:cartQuantity}}</button>
+											<button type="button" class="btn btn-outline-secondary btn-plus" {{vtIf: {vtItem:type} .eq. datei .and. {vtItem:cartQuantity} .gt. 0}}disabled{{vtEndIf}}><i class="fas fa-plus"></i></button>
 										</div>
 									</form>
-									<span class="btn-toggle">{{vtGet:Name}}</span>
+									<span class="btn-toggle">{{vtItem:name}}</span>
 									<!--{{vtIf: {vtItem:description} .neq. }}-->
 										<i class="fa fa-info-circle text-info btn-prod-info" style="cursor:pointer"></i>
 									<!--{{vtEndIf}}-->
@@ -79,7 +73,7 @@
 						</tr>
 					<!--{{vtEndRepeat}}-->
 
-					<!--{{vtIf: {vtGet:Name} .eq.}}-->
+					<!--{{vtIf: {vtGet:ProductsExist} .eq.}}-->
 						<tr>
 							<td>{{vtGet:s_txt_0063}}</td>
 						</tr>
diff --git a/ajax/update_next_image.html b/ajax/update_next_image.html
index 3846234..36a10fa 100644
--- a/ajax/update_next_image.html
+++ b/ajax/update_next_image.html
@@ -83,7 +83,7 @@
 					{{vtEndIf}}
 				{{vtEndIf}}
 
-				{{vtRepeat: Category, Keywords, ReferenceNumber, CreationDate, CreationTime, Photographer, City, State, CountryCode, Country, Title, Credit, Copyright, Description, Instructions }}
+				{{vtRepeat: Category, Keywords, ReferenceNumber, CreationDate, CreationTime, Photographer, City, State, CountryCode, Country, Title, Credit, Copyright, Description, Instructions, Rating }}
 					{{vtCalc: getIPTCHeader('{vtGet:ImagePath,escaped}', '{vtItem}', '{vtGet:charset}' ) }}
 					{{vtSet: {vtItem}="{vtResult}"}}
 				{{vtEndRepeat}}
@@ -105,7 +105,8 @@
 					Country="{vtGet:Country}",
 					Credit="{vtGet:Credit}",
 					Copyright="{vtGet:Copyright}",
-					Instructions="{vtGet:Instructions}"
+					Instructions="{vtGet:Instructions}",
+					Rating="{vtGet:Rating}"
 				}}
 			
 				{{vtSet: Result[status_iptc]="1"}}
diff --git a/ajax/upload.html b/ajax/upload.html
index 01c2688..44f1c01 100644
--- a/ajax/upload.html
+++ b/ajax/upload.html
@@ -2,12 +2,10 @@
 
 function storeUploadedFile( $path )
 {
-	global $vtConfig;
-	
 	$file = $_FILES['datei'];
 	$path = rtrim( $path, '/' );
 	$allowedFileTypes = explode( ',', '.jpg,.jpeg,.tif,.tiff,.eps,.raw,.crw,.pdf,.psd' 
-		. ( isset( $vtConfig['pxtcHiresFileTypes'] ) ? ',' . $vtConfig['pxtcHiresFileTypes'] : '' ) );
+		. ',' . v::vtconfig('pxtcHiresFileTypes') );
 	
 	if ( empty( $file['name'] ) || empty( $file['tmp_name'] ) || $file['tmp_name'] == 'none' )
 	{
@@ -68,4 +66,4 @@ function storeUploadedFile( $path )
 	{{vtIf: {vtGet:Ergebnis} .bw. 4 }}
 		{{vtHeader: HTTP/1.1 {vtGet:Ergebnis} }}
 	{{vtEndIf}}
---><!--{{vtEndScript}}-->{{vtGet:Ergebnis}}
\ No newline at end of file
+--><!--{{vtEndScript}}-->{{vtGet:Ergebnis}}
diff --git a/checkout.finish.html b/checkout.finish.html
index 5e75256..f559e5c 100644
--- a/checkout.finish.html
+++ b/checkout.finish.html
@@ -18,8 +18,10 @@
 		{{vtIf: {Order_Confirmation_Salutation} .eq. 1 }}
 			{{vtIf: {vtSession:Anrede} .eq. Frau }}
 				{{vtCalc: sprintf( '{vtGet:s_txt_0055,escaped}', '{vtSession:Vorname,escaped}', '{vtSession:Name,escaped}' ) }}
-			{{vtElse}}
+			{{vtElseIf: {vtSession:Anrede} .eq. Herr }}
 				{{vtCalc: sprintf( '{vtGet:s_txt_0054,escaped}', '{vtSession:Vorname,escaped}', '{vtSession:Name,escaped}' ) }}
+			{{vtElse}}
+				{{vtCalc: sprintf( '{vtGet:s_txt_0073,escaped}', '{vtSession:Vorname,escaped}', '{vtSession:Name,escaped}' ) }}
 			{{vtEndIf}}
 			{{vtSet: Anredezeile }}
 		{{vtEndIf}}
diff --git a/checkout.finish_pp.html b/checkout.finish_pp.html
index 2f58db9..e9dd96a 100644
--- a/checkout.finish_pp.html
+++ b/checkout.finish_pp.html
@@ -18,8 +18,10 @@
 		{{vtIf: {Order_Confirmation_Salutation} .eq. 1 }}
 			{{vtIf: {vtSession:Anrede} .eq. Frau }}
 				{{vtCalc: sprintf( '{vtGet:s_txt_0055,escaped}', '{vtSession:Vorname,escaped}', '{vtSession:Name,escaped}' ) }}
-			{{vtElse}}
+			{{vtElseIf: {vtSession:Anrede} .eq. Herr }}
 				{{vtCalc: sprintf( '{vtGet:s_txt_0054,escaped}', '{vtSession:Vorname,escaped}', '{vtSession:Name,escaped}' ) }}
+			{{vtElse}}
+				{{vtCalc: sprintf( '{vtGet:s_txt_0073,escaped}', '{vtSession:Vorname,escaped}', '{vtSession:Name,escaped}' ) }}
 			{{vtEndIf}}
 			{{vtSet: Anredezeile }}
 		{{vtEndIf}}
diff --git a/checkout.html b/checkout.html
index 5d8fd09..ec48f42 100644
--- a/checkout.html
+++ b/checkout.html
@@ -146,9 +146,7 @@
 
 		{{vtDo: -act="updateSession", -postvalues="AGB, Bemerkungen, Bezahlmethode, Bundesland, Bundesland2, couponcode, Datenlieferung, Email, Firma, Firma2, Gutscheincode, SEPA_IBAN, SEPA_BIC, SEPA_Inhaber, SEPA_Email, Land, Land2, Landesname, Landesname2, Lieferanschrift, Liefermethode, Name, Name2, Ort, Ort2, PLZ, PLZ2, Registrierung, Strasse, Strasse2, Telefon, USt_ID, Anrede, Vorname, Vorname2, Datenschutz, Widerrufsverzicht" }}
 
-		{{vtIf: {vtPostValue:Anrede} .eq.}}
-			{{vtSet: Error="1"}}
-		{{vtElseIf: {vtPostValue:Vorname} .eq.}}
+		{{vtIf: {vtPostValue:Vorname} .eq.}}
 			{{vtSet: Error="1"}}
 		{{vtElseIf: {vtPostValue:Name} .eq.}}
 			{{vtSet: Error="1"}}
@@ -235,11 +233,9 @@
    		<div class="card-body">
 				<div class="form-row">
 					<div class="form-group col-sm-2">
-						<label for="fldAnrede">{{vtGet:s_fld_salutation}}:*</label>
-						<select name="Anrede" class="form-control" id="fldAnrede" required>
-							<!--{{vtIf: {vtSession:Anrede} .eq. }}-->
-								<option value="">...</option>
-							<!--{{vtEndIf}}-->
+						<label for="fldAnrede">{{vtGet:s_fld_salutation}}:</label>
+						<select name="Anrede" class="form-control" id="fldAnrede">
+							<option value=""></option>
 							<!--{{vtRepeat: {vtGet:Salutations} }}-->
 								<option value="{{vtItem:value}}" {{vtIf: {vtItem:value} .eq. {vtSession:Anrede} }}selected{{vtEndIf}}>{{vtItem:text}}</option>
 							<!--{{vtEndRepeat}}-->
@@ -575,12 +571,10 @@
 	<!--{{vtEndIf}}-->
 	<table>
 		<tr>
-			<td>{{vtGet:s_fld_salutation}}:*</td>
+			<td>{{vtGet:s_fld_salutation}}:</td>
 			<td>
 				<select name="Anrede" id="Anrede">
-					<!--{{vtIf: {vtSession:Anrede} .eq. }}-->
-						<option value=""></option>
-					<!--{{vtEndIf}}-->
+					<option value=""></option>
 					<!--{{vtRepeat: {vtGet:Salutations} }}-->
 						<option value="{{vtItem:value}}" {{vtIf: {vtItem:value} .eq. {vtSession:Anrede} }}selected{{vtEndIf}}>{{vtItem:text}}</option>
 					<!--{{vtEndRepeat}}-->
@@ -1004,7 +998,7 @@
 
 		function handleSubmit( f )
 		{
-			if ( f.Anrede.options[ f.Anrede.selectedIndex ].value == '' || f.Vorname.value == '' || f.Name.value == '' || f.Strasse.value == '' || f.PLZ.value == '' || f.Ort.value == '' || f.Email.value == '' )
+			if ( f.Vorname.value == '' || f.Name.value == '' || f.Strasse.value == '' || f.PLZ.value == '' || f.Ort.value == '' || f.Email.value == '' )
 			{
 				my_dialog('{{vtGet:s_msg_0015,escaped}}');
 				return false;
diff --git a/checkout.summary.html b/checkout.summary.html
index ece1a78..9848324 100644
--- a/checkout.summary.html
+++ b/checkout.summary.html
@@ -295,10 +295,12 @@
 			</div>
 			<div class="card-body">
 				<table class="table table-sm table-borderless">
+					<!--{{vtIf: {vtSession:Anrede} .neq. }}-->
 					<tr>
 						<td>{{vtGet:s_fld_salutation}}:</td>
 						<td class="text-monospace">{{vtSession:Anrede|list:Salutations}}</td>
 					</tr>
+					<!--{{vtEndIf}}-->
 					<tr>
 						<td>{{vtGet:s_fld_fullname}}:</td>
 						<td class="text-monospace">{{vtSession:Vorname}} {{vtSession:Name}}</td>
@@ -420,9 +422,11 @@
 						<td class="text-monospace">
 							{{vtSession:Gutscheincode}}
 							<!--{{vtIf: {vtGet:GutscheinID} .eq. }}-->
+								<br>
 								<span style="color:red">{{vtGet:s_txt_0049}}!</span>
 							<!--{{vtElseIf: {vtGet:MindestbestellwertErreicht} .neq. 1 }}-->
-								<span style="color:red">{{vtEcho: sprintf( '{vtGet:s_txt_0060,escaped}', '{vtGet:GutscheinMindestbestellwert|num:2} {vtGlobal:pxtcCurrency}' ) }}</span>
+								<br>
+								<span style="color:red">{{vtEcho: sprintf( '{vtGet:s_txt_0060,escaped}', '{vtGet:GutscheinMindestbestellwert|num-en:2} {vtGlobal:pxtcCurrency}' ) }}</span>
 							<!--{{vtEndIf}}-->
 						</td>
 					</tr>
@@ -634,6 +638,15 @@
 					<input type="hidden" name="hash" value="{{vtCode: echo getInputHashSU();}}">
 					<button type="submit" class="btn btn-primary btn-lg btn-block">{{vtGet:s_btn_pay_now}}</button>
 				</form>
+			<!--{{vtElseIf: {vtSession:Bezahlmethode} .eq. payrexx .and. {vtGet:Gesamtpreis} .gt. 0 }}-->
+				<script type="text/javascript" src="https://media.payrexx.com/modal/v1/gateway.min.js"></script>
+				<script type="text/javascript">
+					$('.payrexx-modal-window').payrexxModal();
+					$('.payrexx-modal-window').payrexxModal();
+				</script>
+				<form action="{{vtLink: -met='payrexx'}}" method="POST">
+					<button type="submit" class="btn btn-primary btn-lg btn-block payrexx-modal-window" data-href="">{{vtGet:s_btn_pay_now}}</button>
+				</form>
 			<!--{{vtElse}}-->
 				<form action="{{vtLink: -met='finish'}}" method="POST">
 					<button type="submit" class="btn btn-primary btn-lg btn-block">{{vtGet:s_btn_send_order}}</button>
@@ -922,6 +935,10 @@
 				<input type="hidden" name="hash" value="{{vtCode: echo getInputHashSU();}}">
 				<input type="submit" name="" value="{{vtGet:s_btn_pay_now}}">
 			</form>
+		<!--{{vtElseIf: {vtSession:Bezahlmethode} .eq. payrexx .and. {vtGet:Gesamtpreis} .gt. 0 }}-->
+			<form action="{{vtLink:-met='payrexx'}}" method="post" style="float:right; text-align:right">
+				<input type="submit" name="" value="{{vtGet:s_btn_pay_now}}">
+			</form>
 		<!--{{vtElse}}-->
 			<form action="{{vtLink: -met='finish'}}" method="post" style="float:right; text-align:right">
 				<input type="submit" name="" value="{{vtGet:s_btn_send_order}}">
diff --git a/download.zip.html b/download.zip.html
index 9a0df7a..bd0c3ae 100644
--- a/download.zip.html
+++ b/download.zip.html
@@ -37,7 +37,7 @@
 					{{vtIf: {vtGet:TempFile} .bw. - }}
 						{{vtLogError: Error generating image for file {vtGet:File,raw} with rule '{vtItem:rule}' ({vtGet:TempFile}) }}
 					{{vtElse}}
-						{{vtCalc: substr( '{vtGet:File,escaped}', 0, -4 ) . '_' . strtolower('{vtItem:rule}') . '.jpg' }}
+						{{vtCalc: substr( '{vtGet:File,escaped}', 0, strrpos( '{vtGet:File,raw}', '.' ) ) . '_' . strtolower('{vtItem:rule}') . '.jpg' }}
 						{{vtSet: FinalList[] = "{vtResult}|{vtGet:TempFile}" }}
 						{{vtSet: DeleteList[] = "{vtGet:TempFile}" }}
 					{{vtEndIf}}
@@ -90,4 +90,4 @@
 
 {{vtEndIf}}
 
-{{vtEndScript}}{{vtInclude:download.html}}
\ No newline at end of file
+{{vtEndScript}}{{vtInclude:download.html}}
diff --git a/image.delete.html b/image.delete.html
index 5f16846..ce93ef6 100644
--- a/image.delete.html
+++ b/image.delete.html
@@ -65,12 +65,15 @@
 					
 					<!--
 						{{vtSet: PageId = "{vtId}"}}
+						{{vtUse: {vtGet:ID_Home} }}
+							{{vtSet: Pfad = "//{vtName}" }}
+						{{vtEndUse}}
 						{{vtUse: {vtGet:ID_Bilder} }}
-							{{vtSet: Name = "{vtName}" }}
+							{{vtSet: Pfad = "{vtGet:Pfad}/{vtName}" }}
 						{{vtEndUse}}
 					-->
 
-					<!--{{vtUse: /{vtGet:Name}{Verzeichnis}/{vtName} }}-->
+					<!--{{vtUse: {vtGet:Pfad}{Verzeichnis}/{vtName} }}-->
 					<!--{{vtIf: {vtPageType} .eq. image .and. {vtId} .neq. {vtGet:PageId} }}-->
 
 						<p>Wenn Sie alle zugehörigen Dateien mit entfernen möchten, rufen Sie zuerst das <a href="{{vtLink}}" class="text_link">Originalbild</a> 
diff --git a/image.download.html b/image.download.html
index 91fb684..92708fb 100644
--- a/image.download.html
+++ b/image.download.html
@@ -13,7 +13,7 @@
 	{{vtIf: {vtGetValue:rule} .neq. }}
 		{{vtRepeat: {vtGlobal:pxtcImagingRules} }}
 			{{vtIf: {vtItem:name} .eq. {vtGetValue:rule} }}
-				{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 
+				{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 .or. {vtGet:HiresDownloadAllowed} .eq. 1 
 						.or. {vtItem:privilege} .eq. 1 .and. {vtUser:name} .gt. 0 
 						.or. {vtItem:privilege} .eq. 3 .and. {vtItem:groups} .cn1of. {vtUser:groups} 
 				}}
diff --git a/image.html b/image.html
index b9b0bce..2d4657b 100644
--- a/image.html
+++ b/image.html
@@ -67,6 +67,26 @@
 
 	{{vtIf: {vtGlobal:pxtcDetailCaption} .neq. 9 }}
 		{{vtSet: ImageCaption = "{Remarks:html}"}}
+		{{vtIf: {vtGet:ImageCaption} .neq. .and. {vtGlobal:pxtcCaptionRules} .neq. }}
+			{{vtRepeat: {vtGlobal:pxtcCaptionRules} }}
+				{{vtIf: {vtItem:case_insensitive} .in. 1|true|TRUE }}
+					{{vtSet: Flag = "i" }}
+				{{vtEndIf}}
+				{{vtIf: {vtItem:link} .bw. vt: }}
+					{{vtCalc: substr( '{vtItem:link,escaped}', 3 ) }}
+					{{vtCapture: Link }}{{vtLink: {vtResult} }}{{vtEndCapture}}
+					{{vtSet: Target = "" }}
+				{{vtElseIf: {vtItem:link} .cn. : }}
+					{{vtSet: Link = "{vtItem:link}" }}
+					{{vtSet: Target = "_blank" }}
+				{{vtElse}}
+					{{vtSet: Link = "{vtItem:link}" }}
+					{{vtSet: Target = "" }}
+				{{vtEndIf}}
+				{{vtCalc: preg_replace( '/\\b({vtItem:word,escaped})\\b/{vtGet:Flag}', '<a href="{vtGet:Link}" title="{vtItem:title,escaped}" target="{vtGet:Target}">\1</a>', '{vtGet:ImageCaption,escaped}' ) }}
+				{{vtSet: ImageCaption }}
+			{{vtEndRepeat}}
+		{{vtEndIf}}
 	{{vtEndIf}}
 	
 	{{vtCapture:ImageNameOrTitle}}{{vtIf: {Name} .neq. }}{{Name}}{{vtElse}}{{Dateiname}}{{vtEndIf}}{{vtEndCapture}}
@@ -124,6 +144,10 @@
 		{{vtSet: MetaInstructions = "{Instructions}" }}
 	{{vtEndIf}}
 
+	{{vtIf: {vtGlobal:pxtcDetailMetadata} .cn. rating }}
+		{{vtSet: MetaRating = "{Rating}" }}
+	{{vtEndIf}}
+
 	### Lightbox setzen
 
 	{{vtIf: {vtGlobal:pxtcNaviLightboxBehaviour} .neq. -1 }}
@@ -266,8 +290,8 @@
 	{{vtCalc: file_exists( '{vtGlobal:pxtcPathHires}{Verzeichnis:escaped}/{vtName:escaped}' ) ? 1 : 0 }}
 	{{vtIf: {vtResult} .eq. 1 }}
 		{{vtRepeat: {vtGlobal:pxtcImagingRules} }}
-			{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 
-					.or. {vtItem:privilege} .eq. 1 .and. {vtUser:name} .gt. 0 
+			{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 .or. {vtGet:HiresDownloadAllowed} .eq. 1
+					.or. {vtItem:privilege} .eq. 2 .and. {vtUser:name} .gt. 0 
 					.or. {vtItem:privilege} .eq. 3 .and. {vtItem:groups} .cn1of. {vtUser:groups} 
 			}}
 				{{vtCapture}}{{vtLink:-met='download',rule='{vtItem:name}'}}{{vtEndCapture}}
diff --git a/image.update_thumbnail.html b/image.update_thumbnail.html
index 27b107f..7309bb9 100644
--- a/image.update_thumbnail.html
+++ b/image.update_thumbnail.html
@@ -1,8 +1,8 @@
 {{vtScript}}
 {{vtInclude: includes/initialize.html}}
-{{vtCalc: makeThumbnail( utf8_encode('{Verzeichnis:escaped}/{Dateiname:escaped}'), TRUE ) }}
+{{vtCalc: makeThumbnail( '{Verzeichnis:escaped}/{Dateiname:escaped}', TRUE ) }}
 {{vtSet: Result}}
 {{vtIf: {vtResult} .eq. 1 }}
 	{{vtDo: -act="update", -obj="{vtID}", thumb_timestamp="{vtDate}" }}
 {{vtEndIf}}
-{{vtEndScript}}{{vtGet:Result}}
\ No newline at end of file
+{{vtEndScript}}{{vtGet:Result}}
diff --git a/image.vtedit.html b/image.vtedit.html
index a9551b0..3b331e9 100644
--- a/image.vtedit.html
+++ b/image.vtedit.html
@@ -52,7 +52,7 @@
 
 		function updateThumbnail_proceed(){
 			if(http.readyState == 4){
-				if( http.responseText[0] == '-' )
+				if( http.responseText.trim()[0] == '-' )
 				{
 					document.getElementById('update_thumb').innerHTML = '<a class="text_link" href="#" onclick="updateThumbnail(); return false;">Thumbnail aktualisieren</a>';
 					alert( "Beim Erstellen des Thumbnails ist folgender Fehler aufgetreten:\n\n" + http.responseText );
@@ -153,7 +153,7 @@
 				<td class="normal" style="padding-bottom:15px">
 					<input type="text" name="Photographer" size="50" value="{{Photographer:rawhtml}}">
 				</td>
-				<td class="normal" rowspan="9">
+				<td class="normal" rowspan="10">
 					<!--
 						{{vtSet: Produkte="{Produkte}"}}
 						{{vtUse:..}}
@@ -234,6 +234,19 @@
 					<input type="text" name="Instructions" size="50" value="{{Instructions:rawhtml}}">
 				</td>
 			</tr>
+			<tr>
+				<td align="right" class="normal">Bewertung</td>
+				<td class="normal" style="padding-bottom:15px">
+					<select name="Rating">
+						<option value="">ohne</option>
+						<option value="5" {{vtIf: {Rating} .eq. 5}}selected{{vtEndIf}}>5 - sehr gut</option>
+						<option value="4" {{vtIf: {Rating} .eq. 4}}selected{{vtEndIf}}>4</option>
+						<option value="3" {{vtIf: {Rating} .eq. 3}}selected{{vtEndIf}}>3 - durchschnittlich</option>
+						<option value="2" {{vtIf: {Rating} .eq. 2}}selected{{vtEndIf}}>2</option>
+						<option value="1" {{vtIf: {Rating} .eq. 1}}selected{{vtEndIf}}>1 - schlecht</option>
+					</select>
+				</td>
+			</tr>
 			<tr id="buttontd">
 				<td align="right" class="normal" valign="top">&nbsp;</td>
 				<td class="normal" colspan="2">
diff --git a/imagelist._onchange.html b/imagelist._onchange.html
index eee9576..3b06cf7 100644
--- a/imagelist._onchange.html
+++ b/imagelist._onchange.html
@@ -77,12 +77,14 @@
 {{vtIf: {Sortierfeld} .eq. random}}
 	{{vtSet: sortField=""}}
 	{{vtSet: sortOrder="random"}}
-{{vtElseIf: {Sortierfeld} .in. title|name|modificationTime|creationTime|creationDate}}
+{{vtElseIf: {Sortierfeld} .in. title|name|modificationTime|creationTime|creationDate|rating}}
 	{{vtSet: sortField="{Sortierfeld}"}}
 	{{vtIf: {Sortierfeld} .eq. title}}
 		{{vtSet: sortField="image.name"}}
 	{{vtElseIf: {Sortierfeld} .eq. creationDate}}
 		{{vtSet: sortField="image.creationdate"}}
+	{{vtElseIf: {Sortierfeld} .eq. rating}}
+		{{vtSet: sortField="image.rating"}}
 	{{vtEndIf}}
 	{{vtIf: {Sortierung_absteigend} .eq. 1}}
 		{{vtSet: sortOrder="descending"}}
diff --git a/imagelist.download.html b/imagelist.download.html
index 5390efe..abe63e4 100644
--- a/imagelist.download.html
+++ b/imagelist.download.html
@@ -12,10 +12,30 @@
 	{{vtEndIf}}
 {{vtEndIf}}
 
+{{vtIf: {vtPageUserID} .eq. 52 }}
+{{vtElseIf: OthersViewAccess}}
+	{{vtSet: Public="1"}}
+{{vtEndIf}} 
+
+{{vtIf: {vtUser:admin} .eq. 1 .or. {vtGlobal:pxtcPrivilegeHiresDownload} .eq. 1 }}
+	{{vtSet: HiresDownloadAllowed="1"}}
+{{vtElseIf: {DownloadAllowed} .eq. 1 .and. {vtGet:Public} .neq. 1 }}
+	{{vtSet: HiresDownloadAllowed="1"}}
+{{vtElseIf: {vtGlobal:pxtcPrivilegeHiresDownload} .eq. 2 .and. {vtUser:id} .gt. 0 }}
+	{{vtSet: HiresDownloadAllowed="1"}}
+{{vtElseIf: {vtGlobal:pxtcPrivilegeHiresDownload} .eq. 3}}
+	{{vtRepeat: {vtGlobal:pxtcGroupsHiresDownload} }}
+		{{vtIf: {vtItem} .in. {vtUser:groups} }}
+			{{vtSet: HiresDownloadAllowed="1"}}
+			{{vtExit}}
+		{{vtEndIf}}
+	{{vtEndRepeat}}
+{{vtEndIf}}
+
 {{vtIf: {vtGetValue:rule} .neq. }}
 	{{vtRepeat: {vtGlobal:pxtcImagingRules} }}
 		{{vtIf: {vtItem:name} .eq. {vtGetValue:rule} }}
-			{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 
+			{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 .or. {vtGet:HiresDownloadAllowed} .eq. 1 
 					.or. {vtItem:privilege} .eq. 1 .and. {vtUser:name} .gt. 0 
 					.or. {vtItem:privilege} .eq. 3 .and. {vtItem:groups} .cn1of. {vtUser:groups} 
 			}}
@@ -121,7 +141,7 @@
 		{{vtEndIf}}
 		
 		{{vtIf: {vtGet:File} .neq. .and. {vtGetValue:rule} .eq. }}
-			{{vtCalc: substr( '{vtGet:File,raw}', 0, -3 ) }}
+			{{vtCalc: substr( '{vtGet:File,raw}', 0, strrpos( '{vtGet:File,raw}', '.' ) ) . '.' }}
 			{{vtSet: BaseName }}
 			{{vtIf: {vtGetValue:v} .eq. }}
 				{{vtSet: Suffixes = "jpg,JPG,jpeg,JPEG" }}
diff --git a/imagelist.html b/imagelist.html
index a1ddb59..24f2c54 100644
--- a/imagelist.html
+++ b/imagelist.html
@@ -203,6 +203,12 @@
 	### Bilderliste zusammenstellen
 
 	{{vtDo: -act="setSelection", -name="search", -origin="{vtID}", -depth="1",	-sortfield="{vtSortfield}", -sortorder="{vtSortorder}" }}
+	{{vtIf: {vtSortfield} .eq. day+rating }}
+		{{vtDo: -act="updateSelection", -name="search", 
+			-sortfield[]="image.creationdate", -sortfield[]="image.rating", 
+			-sortorder[]="{vtSortorder}", -sortorder[]="{vtSortorder}"
+		}}
+	{{vtEndIf}}
 
 	{{vtIf: {vtUser:admin} .neq. 1 .and. {vtPageUserID} .neq. 52}}
 		{{vtDo: -act="updateSelection", -name="search", -filter="{vtPageUserID} .neq. 52"}}
@@ -249,6 +255,7 @@
 			{{vtElse}}
 				{{vtSet: Image[type] = "image" }}
 				{{vtSet: Image[keywords] = "{Keywords}" }}
+				{{vtSet: Image[rating] = "{Rating}" }}
 
 				{{vtIf: {Name} .neq. }}
 					{{vtSet: Image[title] = "{Name}" }}
@@ -308,6 +315,7 @@
 				{{vtSet: Image[height] = "{vtGet:Info[height]}" }}
 				{{vtSet: Image[orientation] = "{vtGet:Info[orientation]}" }}
 				{{vtSet: Image[keywords] = "{Keywords}" }}
+				{{vtSet: Image[rating] = "{Rating}" }}
 		
 				{{vtCapture}}{{vtLink:-met='{vtGet:ImageMethod}'}}{{vtEndCapture}}
 				{{vtSet: Image[link] }}
@@ -492,7 +500,7 @@
 				{{vtCalc: file_exists( '{vtGlobal:pxtcPathHires}{Verzeichnis:escaped}' ) ? 1 : 0 }}
 				{{vtIf: {vtResult} .eq. 1 }}
 					{{vtRepeat: {vtGlobal:pxtcImagingRules} }}
-						{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 
+						{{vtIf: {vtUser:admin} .eq. 1 .or. {vtItem:privilege} .eq. 1 .or. {vtGet:HiresDownloadAllowed} .eq. 1 
 								.or. {vtItem:privilege} .eq. 1 .and. {vtUser:name} .gt. 0 
 								.or. {vtItem:privilege} .eq. 3 .and. {vtItem:groups} .cn1of. {vtUser:groups} 
 						}}
diff --git a/imagelist.upload2.html b/imagelist.upload2.html
index 64a4091..eb46756 100644
--- a/imagelist.upload2.html
+++ b/imagelist.upload2.html
@@ -138,7 +138,7 @@
 				paramName: 'datei',
 				maxFilesize: {{vtEcho: get_upload_limit() }},
 				forceFallback: false,
-				acceptedFiles: acceptedFiles,
+				acceptedFiles: {{vtIf: {vtGlobal:pxtcImportSource} .eq. lores }}acceptedFiles{{vtElse}}acceptedSpecialFiles{{vtEndIf}},
 				uploadMultiple: false,
 				parallelUploads: 1,
 				autoProcessQueue: false,
@@ -305,7 +305,7 @@
 			else if ( value == '*' )
 			{
 				$('#targetDir').text( baseUrlHires );
-				myDropzone.options.acceptedFiles = acceptedFiles;
+				myDropzone.options.acceptedFiles = acceptedSpecialFiles;
 			}
 			else if ( value == '?' )
 			{
diff --git a/imagelist.vtedit.html b/imagelist.vtedit.html
index 25218c2..45a8e47 100644
--- a/imagelist.vtedit.html
+++ b/imagelist.vtedit.html
@@ -155,6 +155,8 @@
 							<option value="name" {{vtIf:{vtGet:Sortierfeld}.eq.name}}selected{{vtEndIf}}>Dateiname</option>
 							<option value="title" {{vtIf: {vtGet:Sortierfeld} .eq. image.name}}selected{{vtEndIf}}>Titel</option>
 							<option value="creationDate" {{vtIf: {vtGet:Sortierfeld} .eq. image.creationdate}}selected{{vtEndIf}}>Aufnahmedatum</option>
+							<option value="rating" {{vtIf:{vtGet:Sortierfeld} .eq. image.rating}}selected{{vtEndIf}}>Bewertung</option>
+							<option value="day+rating" {{vtIf: {vtGet:Sortierfeld} .eq. day+rating}}selected{{vtEndIf}}>Aufnahmetag + Bewertung</option>
 						</optgroup>
 						<optgroup label="nach Datensatzmerkmal">
 							<option value="creationTime" {{vtIf:{vtGet:Sortierfeld}.eq.creationTime}}selected{{vtEndIf}}>Erstellungsdatum</option>
diff --git a/imagelist.vtnew.html b/imagelist.vtnew.html
index 69955b0..00f7b2a 100644
--- a/imagelist.vtnew.html
+++ b/imagelist.vtnew.html
@@ -140,6 +140,7 @@
 							<option value="name" {{vtIf:{vtGet:Sortierfeld}.eq.name}}selected{{vtEndIf}}>Dateiname</option>
 							<option value="title" {{vtIf: {vtGet:Sortierfeld} .eq. image.name}}selected{{vtEndIf}}>Titel</option>
 							<option value="creationDate" {{vtIf: {vtGet:Sortierfeld} .eq. image.creationdate}}selected{{vtEndIf}}>Aufnahmedatum</option>
+							<option value="rating" {{vtIf:{vtGet:Sortierfeld} .eq. image.rating}}selected{{vtEndIf}}>Bewertung</option>
 						</optgroup>
 						<optgroup label="nach Datensatzmerkmal">
 							<option value="creationTime" {{vtIf:{vtGet:Sortierfeld}.eq.creationTime}}selected{{vtEndIf}}>Erstellungsdatum</option>
diff --git a/includes/func_add_to_cart.html b/includes/func_add_to_cart.html
index ef2e11e..82fc9ae 100644
--- a/includes/func_add_to_cart.html
+++ b/includes/func_add_to_cart.html
@@ -113,7 +113,7 @@
 			{{vtElse}}
 				{{vtSet: subfolder="{vtGet:Kennung}/"}}
 			{{vtEndIf}}
-			{{vtCalc: getFileList( '{vtGlobal:pxtcPathHires}/{vtGet:Verzeichnis}/{vtGet:subfolder}', '^' . preg_quote( substr( '{vtGet:Dateiname}', 0, strpos( '{vtGet:Dateiname}', '.' ) ) ) . '\..+' ) }}
+			{{vtCalc: getFileList( '{vtGlobal:pxtcPathHires}/{vtGet:Verzeichnis}/{vtGet:subfolder}', '^' . preg_quote( substr( '{vtGet:Dateiname}', 0, strrpos( '{vtGet:Dateiname}', '.' ) ) ) . '\..+' ) }}
 			{{vtRepeat:{vtResult} }}
 				{{vtSet: hires_path="{vtGet:subfolder}{vtItem}"}}
 				{{vtExit}}
@@ -175,4 +175,4 @@
 
 {{vtEndFunction}}
 
-{{vtEndScript}}
\ No newline at end of file
+{{vtEndScript}}
diff --git a/includes/functions.html b/includes/functions.html
index 863b51a..1f12f91 100644
--- a/includes/functions.html
+++ b/includes/functions.html
@@ -187,7 +187,7 @@
 	{{vtCalc: getImageOrientation( '{vtGet:ImagePath,escaped}', 0.01 ) }}
 	{{vtSet: Format}}
 	
-	{{vtCalc: makeThumbnail( utf8_encode('{vtArg:Path,escaped}') ) }}
+	{{vtCalc: makeThumbnail( '{vtArg:Path,escaped}' ) }}
 
 	{{vtIf: {vtArg:Charset} .eq. latin1}}
 		{{vtSet:Charset=""}}
@@ -197,7 +197,7 @@
 		{{vtSet:Charset="{vtArg:Charset}"}}
 	{{vtEndIf}}
 
-	{{vtRepeat: Category, Keywords, ReferenceNumber, CreationDate, CreationTime, Photographer, City, State, CountryCode, Country, Title, Credit, Copyright, Description, Instructions }}
+	{{vtRepeat: Category, Keywords, ReferenceNumber, CreationDate, CreationTime, Photographer, City, State, CountryCode, Country, Title, Credit, Copyright, Description, Instructions, Rating }}
 		{{vtSet: {vtItem}=""}}
 		{{vtCalc: getIPTCHeader('{vtGet:ImagePath,escaped}', '{vtItem}', '{vtGet:Charset}' ) }}
 		{{vtSet: {vtItem}="{vtResult}"}}
@@ -233,6 +233,7 @@
 		ReferenceNumber="{vtGet:ReferenceNumber}",
 		CreationTime="{vtGet:CreationTime}",
 		Instructions="{vtGet:Instructions}",
+		Rating="{vtGet:Rating}",
 		-properties[name]="{vtGet:FileName}",
 		-properties[protected]="1"
 	}}
@@ -488,7 +489,7 @@
 	
 		{{vtCalc: mkdir( '{vtGet:thumbnailPath}{vtArg:Target_Path}', 0777, TRUE ) }}
 		{{vtCalc: chmod( '{vtGet:thumbnailPath}{vtArg:Target_Path}', 0777 ) }}
-		{{vtCalc: rename( '{vtGet:thumbnailPath}{vtArg:Object_Path}', '{vtGet:thumbnailPath}{vtArg:Target_Path}/{vtGet:Object_Name}' ) ? 1 : 0 }}
+		{{vtCalc: rename( '{vtGet:thumbnailPath}{vtArg:Object_Path}', '{vtGet:thumbnailPath}{vtArg:Target_Path}/{vtGet:Object_Name}' ) }}
 	
 	{{vtElse}}
 
diff --git a/includes/get_payment_methods.html b/includes/get_payment_methods.html
index d783b7c..b040807 100644
--- a/includes/get_payment_methods.html
+++ b/includes/get_payment_methods.html
@@ -37,6 +37,12 @@
 			{{vtSet: Methode[label]="{vtGet:s_payment_sofortueberweisung}"}}
 			{{vtSet: Bezahlmethoden[]="{vtGet:Methode}"}}
 		{{vtEndIf}}
+		{{vtIf: {vtGlobal:pxtcPaymentPayrexx} .in. 1|2 .or. {vtGlobal:pxtcPaymentPayrexx} .in. {vtUser:groups} .and. {vtGet:AdvancedOptions} .eq. 1 }}
+			{{vtSet: Methode[id]="7"}}
+			{{vtSet: Methode[name]="payrexx"}}
+			{{vtSet: Methode[label]="{vtGet:s_payment_payrexx}"}}
+			{{vtSet: Bezahlmethoden[]="{vtGet:Methode}"}}
+		{{vtEndIf}}
 
 	{{vtElse}}
 
@@ -70,7 +76,13 @@
 			{{vtSet: Methode[label]="{vtGet:s_payment_sofortueberweisung}"}}
 			{{vtSet: Bezahlmethoden[]="{vtGet:Methode}"}}
 		{{vtEndIf}}
+		{{vtIf: {vtGet:PayrexxInitialized} .eq. 1 .and. {vtGlobal:pxtcPaymentPayrexx} .eq. 2 }}
+			{{vtSet: Methode[id]="7"}}
+			{{vtSet: Methode[name]="payrexx"}}
+			{{vtSet: Methode[label]="{vtGet:s_payment_payrexx}"}}
+			{{vtSet: Bezahlmethoden[]="{vtGet:Methode}"}}
+		{{vtEndIf}}
 
 	{{vtEndIf}}
 
-{{vtEndScript}}
\ No newline at end of file
+{{vtEndScript}}
diff --git a/includes/get_products.html b/includes/get_products.html
index b30280c..266a035 100644
--- a/includes/get_products.html
+++ b/includes/get_products.html
@@ -6,161 +6,36 @@
 	{{vtInclude: includes/get_payment_methods.html}}
 	{{vtInclude: includes/deliverymethods.html }}
 
-
-	{{vtFunction: getProduct }}
-
-		### liefert (falls verfügbar) Produktdatensatz im Kontext eines bestimmten Bildes zurück
-		### Argumente:
-		### ProductFolderId = ID der Produkt-Containerseite
-		### ImageId = ID des Bildes
-		### ImageFolder = relatives Verzeichnis der Galerie
-		### ImageFilename = Name des Bildes
-	
-		{{vtIf: {vtPageType} .neq. product .or. {vtContainerId} .neq. {vtArg:ProductFolderId} }}
-			{{vtReturn}}
-		{{vtEndIf}}
-
-		{{vtIf: {Preis|num} .gt. 0 .and. {vtGet:Bezahlmethoden} .eq. .and. {vtGet:DeliveryPayment} .neq. 1 }}
-			{{vtReturn}}
-		{{vtEndIf}}
-
-		{{vtIf: {Typ} .eq. Print .and. {vtGet:DeliveryMethods} .eq. }}
-			{{vtReturn}}
-		{{vtEndIf}}
-
-		{{vtIf: {Benutzer} .neq. .and. {Benutzer} .neq. guest .and. {vtUser:groups} .ncn. {Benutzer} .and. {vtUser:admin} .neq. 1 }}
-			{{vtReturn}}
-		{{vtEndIf}}
-
-		{{vtIf: {Benutzer} .eq. guest .and. {vtUser:name} .neq. .and. {vtUser:admin} .neq. 1 }}
-			{{vtReturn}}
-		{{vtEndIf}}
-
-		{{vtSet: isAvailable = "1" }}
-
-		{{vtIf: {Kennung} .neq. }}
-			{{vtSet: isAvailable = "" }}
-			{{vtIf: {Kennung} .eq. * }}
-				{{vtSet: Kennung = "" }}
-			{{vtElse}}
-				{{vtSet: Kennung = "{Kennung:raw}" }}
-			{{vtEndIf}}
-			{{vtCalc: getFileList( '{vtGlobal:pxtcPathHires}/{vtArg:ImageFolder,escaped}/{vtGet:Kennung}', '^' . preg_quote( substr( '{vtArg:ImageFilename,escaped}', 0, strpos( '{vtArg:ImageFilename,escaped}', '.' ) ) ) . '\..+' ) }}
-			{{vtIf: {vtResult} .neq. -1 }}
-				{{vtRepeat: {vtResult} }}
-					{{vtSet: isAvailable = "1" }}
-					{{vtExit}}
-				{{vtEndRepeat}}
-			{{vtEndIf}}
-		{{vtEndIf}}
-
-		{{vtIf: {vtGet:isAvailable} .neq. 1 }}
-			{{vtReturn}}
-		{{vtEndIf}}
-
-		{{vtSet: Prod = "" }}
-		{{vtSet: Prod[id] = "{vtID}" }}
-		{{vtSet: Prod[name] = "{Bezeichnung:raw}" }}
-		{{vtSet: Prod[name_en] = "{Bezeichnung_en:raw}" }}
-		{{vtSet: Prod[type] = "{Typ}" }}
-		{{vtSet: Prod[description] = "{Beschreibung:raw}" }}
-
-		{{vtIf: {Preisanpassung} .eq. 1 .and. {vtUser:Preisfaktor} .gt. 0}}
-			{{vtCalc: {Preis} * {vtUser:Preisfaktor|num:2.} }}
-			{{vtSet: Prod[price] = "{vtResult}" }}
-		{{vtElse}}
-			{{vtSet: Prod[price] = "{Preis}" }}
-		{{vtEndIf}}
-
-		{{vtIf: {Steuersatz} .eq. 2 }}
-			{{vtSet: Prod[vatRate] = "{vtGlobal:pxtcVatRate2}" }}
-		{{vtElse}}
-			{{vtSet: Prod[vatRate] = "{vtGlobal:pxtcVatRate}" }}
-		{{vtEndIf}}
-		
-		{{vtCalc: get_cart_price( {vtId} ) }}
-		{{vtIf: {vtResult} .neq. }}
-			{{vtSet: Prod[price] = "{vtResult}" }}
-		{{vtEndIf}}
-
-		{{vtCalc: get_cart_quantity( {vtArg:ImageId}, {vtID} ) }}
-		{{vtSet: Prod[quantity] = "{vtResult}" }}
-
-		{{vtReturn: {vtGet:Prod} }}
-
-	{{vtEndFunction}}
-
-	###############################################
-
-	{{vtSet: Produkte = "{Produkte}"}}
-	{{vtSet: Folder = "{Verzeichnis}" }}
-	{{vtSet: Filename = "{Dateiname}" }}
-	{{vtSet: ProductList = "" }}
-	{{vtSet: ProductCount = "0" }}
-	{{vtSet: ImageId = "{vtId}" }}
-
-
-	{{vtIf: {Sortiment} .gt. 0 }}
-		{{vtSet: Sortiment = "{Sortiment}" }}
-	{{vtElseIf: {Sortiment} .neq. -1 }}
-		{{vtUse: .. }}
-			{{vtSet: Sortiment = "{Sortiment}" }}
-			{{vtIf: {Sortiment} .eq. 0 .or. {Sortiment} .eq.}}
-				{{vtSet: Produkte = "{vtGet:Produkte}
-{Produkte}" }}
-			{{vtEndIf}}
-		{{vtEndUse}}
+	{{vtIf: {vtGet:Bezahlmethoden} .eq. .and. {vtGet:DeliveryPayment} .neq. 1 }}
+		{{vtSet: PaymentPossible = "0" }}
+	{{vtElse}}
+		{{vtSet: PaymentPossible = "1" }}
 	{{vtEndIf}}
 
-	{{vtIf: {vtGet:Sortiment} .gt. 0 }}
-		{{vtUse: {vtGet:Sortiment} }}
-			{{vtRepeat: {Liste} }}
-				{{vtIf: {vtItem:text} .neq. }}
-					{{vtSet: Prod = "" }}
-					{{vtSet: Prod[id] = "0" }}
-					{{vtSet: Prod[name] = "{vtItem:text}" }}
-					{{vtSet: Prod[name_en] = "{vtItem:text_en}" }}
-					{{vtSet: Assortment[] = "{vtGet:Prod}" }}
-				{{vtElseIf: {vtItem:product_id} .gt. 0 }}
-					{{vtUse: {vtItem:product_id} }}
-						{{vtCall: -name="getProduct", ImageId = "{vtGet:ImageId}", ProductFolderId = "{vtGet:ID_Produkte}", ImageFolder = "{vtGet:Folder}", ImageFilename = "{vtGet:Filename}" }}
-						{{vtIf: {vtResult} .neq. }}
-							{{vtSet: ProductIds = "{vtGet:ProductIds}|{vtId}" }}
-							{{vtSet: Assortment[] = "{vtResult}" }}
-						{{vtEndIf}}
-					{{vtEndUse}}
-				{{vtEndIf}}
-			{{vtEndRepeat}}
-		{{vtEndUse}}
+	{{vtIf: {vtGet:DeliveryMethods} .eq. }}
+		{{vtSet: DeliveryPossible = "0" }}
+	{{vtElse}}
+		{{vtSet: DeliveryPossible = "1" }}
 	{{vtEndIf}}
 
-	{{vtAsAdmin}}
-		{{vtSelect: -origin="{vtGet:ID_Produkte}", -type="product", -filter="{Zuordnung} .eq. 1", -sortfield="vtSortValue" }}
-			{{vtLoop}}
-				{{vtSet: Produkte = "{vtGet:Produkte}
-	{vtId}" }}
-			{{vtEndLoop}}
-		{{vtEndSelect}}
-	{{vtEndAsAdmin}}
-
-	{{vtRepeat: {vtGet:Produkte} }}
-		{{vtIf: {vtItem} .gt. 0 .and. {vtItem} .nin. {vtGet:ProductIds} }}
-			{{vtUse: {vtItem} }}
-				{{vtCall: -name="getProduct", ImageId = "{vtGet:ImageId}", ProductFolderId = "{vtGet:ID_Produkte}", ImageFolder = "{vtGet:Folder}", ImageFilename = "{vtGet:Filename}" }}
-				{{vtIf: {vtResult} .neq. }}
-					{{vtSet: ProductIds = "{vtGet:ProductIds}|{vtId}" }}
-					{{vtSet: ProductList[] = "{vtResult}" }}
-					{{vtCalc: {vtGet:ProductCount} + 1 }}
-					{{vtSet: ProductCount }}
-				{{vtEndIf}}
-			{{vtEndUse}}
-		{{vtEndIf}}
-	{{vtEndRepeat}}
+	{{vtLoad: templates/pixtacy/lib/pxtc_products.class.php }}
+	{{vtCalc: Pixtacy_Products::set_options( array ( 
+		'paymentsPossible' => v::vtget('PaymentPossible'),
+		'deliveryPossible' => v::vtget('DeliveryPossible'),
+		'vatRate1' => v::vtglobal('pxtcVatRate'),
+		'vatRate2' => v::vtglobal('pxtcVatRate2'),
+		'preferEnglish' => v::vtget('Language') != 'de' ? '1' : '' 
+	) ) }}
+	{{vtCalc: Pixtacy_Products::initialize( v::get_db(), v::vtget('ID_Produkte'), v::vtget('ID_Sortimente'), v::vtget('Cart') ) }}
+
+	{{vtUse: ..}}
+		{{vtSet: Produkte = "{Produkte}" }}
+		{{vtSet: Sortiment = "{Sortiment}" }}
+	{{vtEndUse}}
 	
-	{{vtRepeat: {vtGet:Assortment} }}
-		{{vtSet: ProductList[] = "{vtItem}" }}
-		{{vtCalc: {vtGet:ProductCount} + 1 }}
-		{{vtSet: ProductCount }}
-	{{vtEndRepeat}}
+	{{vtCalc: Pixtacy_Products::get_products( '{vtId}', '{Verzeichnis}/{Dateiname}', '{Sortiment}', '{Produkte}', '{vtGet:Sortiment}', '{vtGet:Produkte}' ) }}
+	{{vtSet: ProductList }}
+	{{vtCalc: Pixtacy_Products::$lastProductsCount }}
+	{{vtSet: ProductCount }}
 
 {{vtEndScript}}
diff --git a/includes/header_r.html b/includes/header_r.html
index a3b04e8..2198be0 100644
--- a/includes/header_r.html
+++ b/includes/header_r.html
@@ -69,7 +69,7 @@
 				<!--{{vtIf: {vtGlobal:pxtcNaviBrand} .neq. -1 }}-->
 					<!--{{vtIf: {vtGlobal:pxtcNaviBrandTarget} .neq. -1 }}-->
 						<a class="navbar-brand mr-2" 
-							href="{{vtIf: {vtGlobal:pxtcNaviBrandTarget} .eq. 1}}{{vtGlobal:pxtcLogoLink}}{{vtElse}}{{vtLink:/}}{{vtEndIf}}" 
+							href="{{vtIf: {vtGlobal:pxtcNaviBrandTarget} .eq. 1}}{{vtGlobal:pxtcLogoLink}}{{vtElse}}{{vtLink: {vtGet:ID_Home} }}{{vtEndIf}}" 
 							target="{{vtIf: {vtGlobal:pxtcNaviBrandTarget} .eq. 1}}{{vtGlobal:pxtcLogoTarget}}{{vtEndIf}}">
 					<!--{{vtElse}}-->
 						<span class="navbar-brand mr-2">
diff --git a/includes/imagelist_update.html b/includes/imagelist_update.html
index 2f68a31..75833f9 100644
--- a/includes/imagelist_update.html
+++ b/includes/imagelist_update.html
@@ -32,7 +32,7 @@
 
 		<li>{{vtItem}}</li>
 
-		{{vtCalc: makeThumbnail( utf8_encode('{vtGet:Verzeichnis}/{vtItem}') ) }}
+		{{vtCalc: makeThumbnail( '{vtGet:Verzeichnis}/{vtItem}' ) }}
 
 		{{vtSet: Title="", Keywords="", Description="" }}
 			
@@ -73,4 +73,4 @@
 {{vtCalc: getFileInfo('{vtGet:pfad}', 'mtime') }}
 {{vtDo: -act="update", -obj="{vtID}", Timestamp="{vtResult}", istKategorie="{vtGet:istKategorie}"}}
 
-</ul>
\ No newline at end of file
+</ul>
diff --git a/includes/initialize.html b/includes/initialize.html
index 891cae7..420dc24 100644
--- a/includes/initialize.html
+++ b/includes/initialize.html
@@ -3,14 +3,26 @@
 
 	{{vtLoad: templates/pixtacy/resources/functions.php}}
 	
-	{{vtSet: CurrentVersionNumber="51"}}
+	{{vtSet: CurrentVersionNumber="53"}}
 	{{vtSet: ID_Current="{vtID}"}}
 	{{vtSet: thumbnailUrl="{vtConfig:baseURLData}pixtacy_thumbnails"}}
 	{{vtSet: thumbnailPath="{vtConfig:pathToData}pixtacy_thumbnails"}}
 
-	{{vtUse:/}}
+	{{vtIf: {vtGlobal:pxtcHomePageId} .gt. 0 }}
+		{{vtSet: ID_Home = "{vtGlobal:pxtcHomePageId}" }}
+	{{vtElse}}
+		{{vtUse: //}}
+			{{vtLoop}}
+				{{vtIf: {vtPackage} .eq. pixtacy }}
+					{{vtSet: ID_Home = "{vtId}" }}
+					{{vtDo: -act="update", -obj="70", pxtcHomePageId="{vtId}" }}
+					{{vtExit}}
+				{{vtEndIf}}
+			{{vtEndLoop}}
+		{{vtEndUse}}
+	{{vtEndIf}}
 
-		{{vtSet: ID_Home="{vtID}"}}
+	{{vtUse: {vtGet:ID_Home} }}
 
 		{{vtIf: userhasadminprivileges .or. {vtGlobal:pxtc_version_number} .neq. {vtGet:CurrentVersionNumber} }}
 
diff --git a/languages/de.txt b/languages/de.txt
index adc2ecd..9d0f21e 100644
--- a/languages/de.txt
+++ b/languages/de.txt
@@ -302,12 +302,14 @@ Viele Grüße
 {{vtSet: s_txt_0070 = "inkl."}}
 {{vtSet: s_txt_0071 = "zzgl."}}
 {{vtSet: s_txt_0072 = "MwSt."}}
+{{vtSet: s_txt_0073 = "Hallo %1$s %2$s,"}}
 
 {{vtSet: s_payment_vorkasse           = "Vorkasse"}}
 {{vtSet: s_payment_sepa               = "SEPA-Lastschrift"}}
 {{vtSet: s_payment_rechnung           = "Rechnung"}}
 {{vtSet: s_payment_sofortueberweisung = "sofortüberweisung.de"}}
 {{vtSet: s_payment_paypal             = "PayPal"}}
+{{vtSet: s_payment_payrexx            = "Payrexx"}}
 
 {{vtSet: s_invoice_text_vorkasse            = "Bitte überweisen Sie den Rechnungsbetrag auf unser unten angegebenes Konto." }}
 {{vtSet: s_invoice_text_sepa                = "Der Rechnungsbetrag wird wie vereinbart von Ihrem Konto eingezogen." }}
diff --git a/languages/en.txt b/languages/en.txt
index 97cff76..7505253 100644
--- a/languages/en.txt
+++ b/languages/en.txt
@@ -302,12 +302,14 @@ Regards,
 {{vtSet: s_txt_0070 = "incl."}}
 {{vtSet: s_txt_0071 = "plus"}}
 {{vtSet: s_txt_0072 = "VAT"}}
+{{vtSet: s_txt_0073 = "Hello %1$s %2$s,"}}
 
 {{vtSet: s_payment_vorkasse           = "Prepayment"}}
 {{vtSet: s_payment_sepa               = "SEPA Direct Debit"}}
 {{vtSet: s_payment_rechnung           = "Invoice"}}
 {{vtSet: s_payment_sofortueberweisung = "sofortüberweisung.de"}}
 {{vtSet: s_payment_paypal             = "PayPal"}}
+{{vtSet: s_payment_payrexx            = "Payrexx"}}
 
 {{vtSet: s_invoice_text_vorkasse            = "Please transfer the invoiced amount to our bank account (see below)." }}
 {{vtSet: s_invoice_text_sepa                = "The invoiced amount will be debited from your bank account." }}
diff --git a/lib/image_processor.class.php b/lib/image_processor.class.php
index 9f2a67b..0c59ed1 100644
--- a/lib/image_processor.class.php
+++ b/lib/image_processor.class.php
@@ -131,12 +131,13 @@ class Image_Processor {
 			
 			if ( $exif && isset( $exif['Orientation'] ) && isset( $angles[ $exif['Orientation'] ] ) )
 			{
-				$imageNew = imagerotate( $imageNew, $angles[ $exif['Orientation'] ], 0 );
+				$imageRotated = imagerotate( $imageNew, $angles[ $exif['Orientation'] ], 0 );
 			}
 		}
 
 		imagedestroy( $this->image );
-		$this->image = $imageNew;
+		unset( $this->image );
+		$this->image = isset( $imageRotated ) ? $imageRotated : $imageNew;
 	}
 
 
diff --git a/lib/pxtc_products.class.php b/lib/pxtc_products.class.php
new file mode 100644
index 0000000..2dedd27
--- /dev/null
+++ b/lib/pxtc_products.class.php
@@ -0,0 +1,270 @@
+<?php
+
+class Pixtacy_Products {
+
+	private static $allImagesBuyable = FALSE;
+	private static $noImageBuyable = FALSE;
+	private static $globalProducts; // Gesamtliste der theoretisch kaufbaren Produkte
+	private static $autoProducts; // Liste der automatisch zugeordneten theoretisch kaufbaren Produkte
+	private static $assortments = array (); // Gesamtliste der Sortimente mit ihren Produkten (Sortiment-ID = Schlüssel)
+	private static $assortmentsAlwaysBuyable = array (); // Liste der Sortimente, die stets kaufbare Produkte enthalten
+	private static $productAssortments; // Liste mit Produkt-IDs (= Schlüssel) und Sortimenten, zu denen das Produkt gehört
+	private static $options; // Datensatz mit globalen Optionen
+	private static $productQuantities; // Liste der Warenkorbprodukte mit ihren (aufsummierten) Mengen
+	private static $imageQuantities; // Liste der Warenkorbbilder mit ihren Mengen je Produkt
+	public static $cart = [];
+	public static $lastProductsCount;
+
+
+	public function __set( $name, $value ){
+		self::$options[ $name ] = $value;
+	}
+
+
+	public static function set_options( $options ){
+		self::$options = $options;
+	}
+
+	// initialize() has to be called prior to other methods
+	public static function initialize( $db, $pageIdProducts, $pageIdAssortments, $cart = NULL ){
+		if ( empty( $db ) || empty( $pageIdProducts ) || empty( $pageIdAssortments ) ){
+			return FALSE;
+		}
+		$pageIdProducts = (int) $pageIdProducts;
+		$pageIdAssortments = (int) $pageIdAssortments;
+		if ( $cart ){
+			self::$cart = is_array( $cart ) ? $cart : json_decode( $cart, TRUE );
+		}
+
+		// build product assortment mapping table
+		$sql = "SELECT c.`id`, a.`liste` 
+			FROM `%data_assortment` a LEFT JOIN `%content` c ON c.id = a.vtid 
+			WHERE c.containerID = {$pageIdAssortments}";
+		$result = $db->query( $sql );
+		while ( $assortment = $result->fetch_assoc() ) {
+			$elements = json_decode( $assortment['liste'], TRUE );
+			self::$assortments[ $assortment['id'] ] = $elements;
+			foreach ( $elements as $element ) {
+				if ( ! empty( $element['product_id'] ) ) {
+					self::$productAssortments[ $element['product_id'] ][] = $assortment['id'];
+				}
+			}
+		}
+
+		// build lists of buyable products and assortments
+		$groups = empty( self::$options['userGroups'] ) ? array () : explode( ',', self::$options['userGroups'] );
+		$sql = "SELECT c.id, p.`benutzer`, p.`kennung`, p.`preis:num`, p.`zuordnung:num`, p.`typ`,
+			p.`bezeichnung`, p.`bezeichnung_en`, p.`beschreibung`, p.`beschreibung_en`, p.`preisanpassung`, p.`steuersatz`
+			FROM `%data_product` p LEFT JOIN `%content` c ON c.id = p.vtid 
+			WHERE c.containerID = {$pageIdProducts}
+			ORDER BY IF( c.sortValue > 0, 0, 1 ), c.sortValue, p.bezeichnung";
+		$result = $db->query( $sql );
+		//if ( ! $result ){
+		//	die( $db->error );
+		//}
+
+		while ( $product = $result->fetch_assoc() ) {
+			if ( ( empty( self::$options['paymentsPossible'] ) && $product['preis:num'] )
+				|| ( empty( self::$options['deliveryPossible'] ) && strtolower( $product['typ'] ) == 'print' )
+				|| ( ! empty( $product['benutzer'] ) && ! in_array( $product['benutzer'], $groups ) 
+				&& ! ( $product['benutzer'] == 'guest' && empty( self::$options['userName'] ) )
+				&& ! ( $product['benutzer'] == 'Alle' && ! empty( self::$options['userName'] ) ) ) 
+			) {
+				continue; // Produkt ist generell nicht kaufbar
+			}
+			$prodId = (int) $product['id'];
+			self::$globalProducts[ $prodId ] = $product;
+			if ( $product['zuordnung:num'] ) {
+				// es ist ein automatisch zugeordnetes Produkt
+				self::$autoProducts[] = $prodId;
+				if ( empty( $product['kennung'] ) ) {
+					// es ist nicht von High-res-Datei abhängig
+					self::$allImagesBuyable = TRUE;
+				}
+			}
+			elseif ( ! isset( self::$productAssortments[ $prodId ] ) ) { 
+				// Produkt ist keinem Sortiment zugeordnet
+				continue;
+			}
+			elseif ( empty( $product['kennung'] ) ) { 
+				// Produkt ist nicht von High-res-Datei abhängig
+				// setze alle Sortimente, denen das Produkt zugeordnet ist, auf "generell kaufbar"
+				foreach ( self::$productAssortments[ $prodId ] as $assortmentId ) {
+					self::$assortmentsAlwaysBuyable[] = $assortmentId;
+				}
+			}
+		}
+		return array ( 'assortments' => self::$assortments, 'assortmentsAlwaysBuyable' => self::$assortmentsAlwaysBuyable,
+			'globalProducts' => self::$globalProducts, 'autoProducts' => self::$autoProducts );
+	}
+
+	public static function get_offerings( $imageAssortment, $imageProducts, $galleryAssortment, $galleryProducts ){
+		$assortment = $imageAssortment == -1 ? NULL : (int) $imageAssortment;
+		$products = $imageProducts ? explode( "\n", $imageProducts ) : array ();
+		// Automatisch zugeordnete Produkte
+		if ( ! empty( self::$autoProducts ) ){
+			$products = array_merge( $products, self::$autoProducts );
+		}
+		// Galeriesortiment
+		if ( $imageAssortment == 0 ){
+			if ( $galleryAssortment == 0 ){
+				// Galerie hat kein Sortiment, sondern eigene Produktauswahl
+				$products = array_merge( $products, explode( "\n", $galleryProducts ) );
+			}
+			else {
+				$assortment = $galleryAssortment == -1 ? NULL : (int) $galleryAssortment;
+			}
+		}
+		return compact( 'assortment', 'products' );
+	}
+
+	public static function is_image_buyable( $imagePath, $imageAssortment, $imageProducts, 
+		$galleryAssortment, $galleryProducts )
+	{
+		if ( self::$allImagesBuyable ) {
+			return TRUE;
+		}
+		if ( self::$noImageBuyable ) {
+			return FALSE;
+		}
+		$offerings = self::get_offerings( $imageAssortment, $imageProducts, $galleryAssortment, $galleryProducts );
+		$products = array ();
+		if ( isset( self::$assortments[ $offerings['assortment'] ] ) ){
+			if ( in_array( $offerings['assortment'], self::$assortmentsAlwaysBuyable ) ){
+				return TRUE;
+			}
+			foreach ( self::$assortments[ $offerings['assortment'] ] as $item ){
+				if ( ! empty( $item['product_id'] ) ){
+					$products[] = $item['product_id'];
+				}
+			}
+		}
+		$products = array_merge( $products, $offerings['products'] );
+		foreach ( $products as $product ) {
+			if ( isset( self::$globalProducts[ $product ] ) 
+				&& ( self::$globalProducts[ $product ]['kennung'] == '' 
+				|| hires_file_exists( $imagePath, self::$globalProducts[ $product ]['kennung'] ) )
+			) {
+				return TRUE;
+			}
+		}
+		return FALSE;
+	}
+
+
+	public static function get_products( $imageId, $imagePath, $imageAssortment, $imageProducts, $galleryAssortment, $galleryProducts ){
+		$products = array ();
+		$productIds = array ();
+		$offerings = self::get_offerings( $imageAssortment, $imageProducts, $galleryAssortment, $galleryProducts );
+		// prüfe Produkte des zugeordneten Sortiments
+		if ( isset( self::$assortments[ $offerings['assortment'] ] ) ) {
+			foreach ( self::$assortments[ $offerings['assortment'] ] as $item ){
+				if ( empty( $item['product_id'] ) && ! empty( $item['text'] ) ){
+					$products[] = array ( 'id' => 0, 'name' => $item['text'], 'name_en' => $item['text_en'] );
+				}
+				elseif ( empty( self::$globalProducts[ $item['product_id'] ]['kennung'] ) 
+					|| hires_file_exists( $imagePath, self::$globalProducts[ $item['product_id'] ]['kennung'] ) 
+				){
+					$products[] = self::get_product_record( $item['product_id'], $imageId );
+					$productIds[] = $item['product_id'];
+				}
+			}
+		}
+		// prüfe individuell zugeordnete Produkte
+		foreach ( $offerings['products'] as $productId ) {
+			if ( isset( self::$globalProducts[ $productId ] ) 
+				&& ! in_array( $productId, $productIds )
+				&& ( empty( self::$globalProducts[ $productId ]['kennung'] )
+				|| hires_file_exists( $imagePath, self::$globalProducts[ $productId ]['kennung'] ) )
+			) {
+				$products[] = self::get_product_record( $productId, $imageId );
+				$productIds[] = $productId;
+			}
+		}
+		// liefere Produktliste zurück
+		self::$lastProductsCount = count( $products );
+		return $products;
+	}
+
+
+	public static function get_cart_price( $prodId ){
+		if ( empty( self::$globalProducts[ $prodId ] ) ){
+			return FALSE;
+		}
+		if ( empty( self::$cart ) ){
+			return 0;
+		}
+		if ( is_null( self::$productQuantities ) ){
+			self::$productQuantities = array ();
+			foreach ( self::$cart as $item ){
+				self::$productQuantities[ $item['product'] ] = 
+				isset( self::$productQuantities[ $item['product'] ] ) 
+					? self::$productQuantities[ $item['product'] ] + $item['quantity'] 
+				: $item['quantity'];
+			}
+		}
+		$quantity = isset( self::$productQuantities[ $prodId ] ) 
+			? self::$productQuantities[ $prodId ] 
+			: 1;
+		$product = self::$globalProducts[ $prodId ];
+		$price = (float) $product['price'];
+		$factor = empty( self::$options['userPriceFactor'] ) 
+			? 1 
+			: (float) str_replace( ',', '.', self::$options['userPriceFactor'] );
+		if ( ! empty( $product['applyDiscount'] ) && ! empty( $product['discountScale'] ) ){
+			foreach ( $product['discountScale'] as $level ){
+				if ( $quantity >= $level['quantity'] ){
+					$price = (float) $level['price'];
+				}
+			}
+		}
+		if ( $product['applyUserPriceFactor'] && $factor != 1 ){
+			$price = $price * $factor;
+		}
+		if ( empty( self::$options['vatHandling'] ) || self::$options['vatHandling'] == 'excluded' ){
+			return $price;
+		}
+		$vatrate = self::$options[ $product['vatRate1'] == 2 ? 'vatRate2' : 'vatRate1' ];
+		return round( $price / ( 1 + $vatrate / 100 ), 2 );
+	}
+
+
+	public static function get_cart_quantity( $imageId, $prodId ){
+		if ( ! isset( self::$imageQuantities ) && ! empty( self::$cart ) ){
+			self::$imageQuantities = array ();
+			foreach ( self::$cart as $item ){
+				self::$imageQuantities[ $item['image'] ][ $item['product'] ] = $item['quantity'];
+			}
+		}
+		if ( isset( self::$imageQuantities[ $imageId ][ $prodId ] ) ){
+			return self::$imageQuantities[ $imageId ][ $prodId ];
+		}
+		return 0;
+	}
+
+
+	private static function get_product_record( $prodId, $imageId ){
+		if ( ! isset( self::$globalProducts[ $prodId ] ) ){
+			return FALSE;
+		}
+		$p = self::$globalProducts[ $prodId ];
+		return array (
+			'id' => (int) $prodId,
+			'name' => ! empty( self::$options['preferEnglish'] ) && ! empty( $p['bezeichnung_en'] ) ? $p['bezeichnung_en'] : $p['bezeichnung'],
+			'type' => $p['typ'],
+			'description' => ! empty( self::$options['preferEnglish'] ) && ! empty( $p['beschreibung_en'] ) ? $p['beschreibung_en'] : $p['beschreibung'],
+			'price' => $p['preis:num'],
+			'applyUserPriceFactor' => ! empty( $p['preisanpassung'] ),
+			'vatRate' => (int) $p['steuersatz'],
+			'applyDiscount' => ! empty( $p['rabatt_anwenden'] ),
+			'discountScale' => empty( $p['rabattstaffel'] ) 
+				? NULL 
+				: json_decode( $p['rabattstaffel'] ),
+			'cartVatRate' => self::$options[ $p['steuersatz'] == 2 ? 'vatrate2' : 'vatrate1' ],
+			'cartQuantity' => self::get_cart_quantity( $imageId, $prodId ),
+		);
+	}
+}
+
+// end of file pxtc_products.class.php
+
diff --git a/lightbox.download.html b/lightbox.download.html
index 65fb3b4..324a4ba 100644
--- a/lightbox.download.html
+++ b/lightbox.download.html
@@ -88,7 +88,7 @@
 			{{vtEndIf}}
 	
 			{{vtIf: {vtGet:File} .neq. .and. {vtGetValue:rule} .eq. }}
-				{{vtCalc: substr( '{vtGet:File,raw}', 0, -3 ) }}
+				{{vtCalc: substr( '{vtGet:File,raw}', 0, strrpos( '{vtGet:File,raw}', '.' ) ) . '.' }}
 				{{vtSet: BaseName }}
 				{{vtIf: {vtConfig:pxtcHiresSuffixes} .neq. }}
 					{{vtSet: Suffixes = "{vtConfig:pxtcHiresSuffixes}" }}
diff --git a/modules/PmConnector.class.php b/modules/PmConnector.class.php
index b4493e3..03e2868 100644
--- a/modules/PmConnector.class.php
+++ b/modules/PmConnector.class.php
@@ -609,7 +609,14 @@ class PmConnector {
 				$value = str_replace( array( 'oe', 'ö' ), '(oe|ö)', $value );
 				$value = str_replace( array( 'ue', 'ü' ), '(ue|ü)', $value );
 				$value = str_replace( array( 'ss', 'ß' ), '(ss|ß)', $value );
-				$str .= " REGEXP '[[:<:]]{$value}[[:>:]]' ";
+				if ( $this->db->server_version < 80000 )
+				{
+					$str .= " REGEXP '[[:<:]]{$value}[[:>:]]' ";
+				}
+				else
+				{
+					$str .= " REGEXP '\\\\b{$value}\\\\b' ";
+				}
 				break;
 			case 'equal':
 				$str = " = '$value' ";
@@ -731,7 +738,7 @@ class PmConnector {
 		}
 
 		$row = $result->fetch_assoc();
-		$data = unserialize( $row['data'] );
+		$data = $row['data'][0] == '{' ? json_decode( $row['data'], TRUE ) : unserialize( $row['data'] );
 		$this->globals = $data['globals'];
 		return TRUE;
 	}
diff --git a/modules/PmConnector_xml3.class.php b/modules/PmConnector_xml3.class.php
index a555b8b..b83a722 100644
--- a/modules/PmConnector_xml3.class.php
+++ b/modules/PmConnector_xml3.class.php
@@ -72,6 +72,8 @@ class PmConnector {
 	
 	function connect( $request )
 	{
+		$this->request = $request;
+
 		if ( is_object( $this->db ) && get_class( $this->db ) == 'mysqli' )
 		{
 			return TRUE;
@@ -97,7 +99,6 @@ class PmConnector {
 			return FALSE;
 		}
 
-		$this->request = $request;
 		return TRUE;
 	}
 	
@@ -340,16 +341,12 @@ class PmConnector {
 		$result->free();
 		$resArray = array( '1' => 'thumb', '2' => 'preview', '3' => 'highres' );
 		
-		if ( ! in_array( $resolution, $resArray ) )
+		if ( ! isset( $resArray[ $resolution ] ) )
 		{
-			if ( ! isset( $resArray[ $resolution ] ) )
-			{
-				return -3;
-			}
-			
-			$resolution = $resArray[ $resolution ];
+			return -3;
 		}
 		
+		$resolution = $resArray[ $resolution ];
 		$type = $download ? 'download' : 'view';
 		
 		if ( ! $this->get_permission( $ref, $resolution, $type ) )
@@ -653,7 +650,14 @@ class PmConnector {
 				$value = str_replace( array( 'oe', 'ö' ), '(oe|ö)', $value );
 				$value = str_replace( array( 'ue', 'ü' ), '(ue|ü)', $value );
 				$value = str_replace( array( 'ss', 'ß' ), '(ss|ß)', $value );
-				$str .= " REGEXP '[[:<:]]{$value}[[:>:]]' ";
+				if ( $this->db->server_version < 80000 )
+				{
+					$str .= " REGEXP '[[:<:]]{$value}[[:>:]]' ";
+				}
+				else
+				{
+					$str .= " REGEXP '\\\\b{$value}\\\\b' ";
+				}
 				break;
 			case 'equal':
 				$str = " = '$value' ";
@@ -775,7 +779,7 @@ class PmConnector {
 		}
 
 		$row = $result->fetch_assoc();
-		$data = unserialize( $row['data'] );
+		$data = $row['data'][0] == '{' ? json_decode( $row['data'], TRUE ) : unserialize( $row['data'] );
 		$this->globals = $data['globals'];
 		return TRUE;
 	}
diff --git a/order._onchange.html b/order._onchange.html
index cb1124c..2df7672 100644
--- a/order._onchange.html
+++ b/order._onchange.html
@@ -48,8 +48,10 @@
 	{{vtInclude: includes/initialize.html }}
 	{{vtIf: {Anrede} .eq. Frau }}
 		{{vtCalc: sprintf( '{vtGet:s_txt_0055,escaped}', '{Vorname:escaped}', '{Name:escaped}' ) }}
-	{{vtElse}}
+	{{vtElseIf: {Anrede} .eq. Herr }}
 		{{vtCalc: sprintf( '{vtGet:s_txt_0054,escaped}', '{Vorname:escaped}', '{Name:escaped}' ) }}
+	{{vtElse}}
+		{{vtCalc: sprintf( '{vtGet:s_txt_0073,escaped}', '{Vorname:escaped}', '{Name:escaped}' ) }}
 	{{vtEndIf}}
 	{{vtSet: Anredezeile }}
 	{{vtIf: {vtGet:Language} .eq. en}}
diff --git a/order.html b/order.html
index 1de736f..1931ad0 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}} {{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","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}} {{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}} {{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","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 }}
@@ -35,7 +35,7 @@
 <body>
 	<!--
 		{{vtRepeat:{Warenkorb:raw} }}
-			{{vtIf: {vtItem:pxprint_id} .gt. 0 }}
+			{{vtIf: {vtItem:pxprint_id} .neq. }}
 				{{vtSet: ContainsPxprintItems = "1" }}
 			{{vtEndIf}}
 			{{vtIf: {vtItem:hires_path} .neq. }}
@@ -44,8 +44,11 @@
 			{{vtExit: {vtGet:ContainsPxprintItems} .eq. 1 .and. {vtGet:ContainsHiresFiles} .eq. 1 }}
 		{{vtEndRepeat}}
 
+		{{vtUse: {vtGet:ID_Home} }}
+			{{vtSet: BaseName = "//{vtName}" }}
+		{{vtEndUse}}
 		{{vtUse: {vtGet:ID_Bilder} }}
-			{{vtSet: BaseName = "{vtName}" }}
+			{{vtSet: BaseName = "{vtGet:BaseName}/{vtName}" }}
 		{{vtEndUse}}
 
 		{{vtSet: Cart = "{Warenkorb:raw}"}}
@@ -66,7 +69,7 @@
 				<!--{{vtIf: {erledigt} .eq. 1 .or. {pxprint_order_id} .gt. 0 .or. {easybill_id} .gt. 0 .or. {abgeschlossen} .neq. 1 }}-->
 				<!--{{vtElseIf: {vtSession:OrderEditMode} .eq. 1 .and. {vtSession:OrderPageID} .eq. {vtID} }}-->
 					<span style="background:yellow; padding:5px">
-						<a class="text_link" href="{{vtLink:/Warenkorb}}">Bearbeitung fortsetzen</a> |
+						<a class="text_link" href="{{vtLink: {vtGet:ID_Warenkorb} }}">Bearbeitung fortsetzen</a> |
 						<a class="text_link" href="{{vtLink:-met='tosession',cancel='1'}}">Bearbeitung beenden</a>
 					</span>
 					&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -303,7 +306,7 @@
 			<tr>
 				<td width="130" class="fieldHeading">Anschrift</td>
 				<td class="fieldContent">
-					{{Anrede}} {{Vorname}} {{Name}}<br>
+					<!--{{vtIf: {Anrede} .neq. }}-->{{Anrede}} <!--{{vtEndIf}}-->{{Vorname}} {{Name}}<br>
 					<!--{{vtIf: {Firma} .neq.}}-->
 					{{Firma}}<br>
 					<!--{{vtEndIf}}-->
@@ -366,7 +369,7 @@
 								</td>
 								<td>
 									<strong>{{vtItem:filename}}</strong><br>
-									<a href="{{vtLink:/{vtGet:BaseName}{vtItem:folder} }}">{{vtItem:folder}}</a><br>
+									<a href="{{vtLink: {vtGet:BaseName}{vtItem:folder} }}">{{vtItem:folder}}</a><br>
 									<a href="{{vtLink: -pg='{vtItem:product}', -met='vtedit' }}">{{vtItem:title}}</a><br>
 									{{vtItem:quantity}} Stck. à {{vtItem:price|num-en:2}} {{Waehrung}}
 								</td>
@@ -406,7 +409,7 @@
 								</td>
 								<td>
 									<strong>{{vtItem:filename}}</strong><br>
-									<a href="{{vtLink:/{vtGet:BaseName}{vtItem:folder} }}">{{vtItem:folder}}</a><br>
+									<a href="{{vtLink: {vtGet:BaseName}{vtItem:folder} }}">{{vtItem:folder}}</a><br>
 									<a href="{{vtLink: -pg='{vtItem:product}', -met='vtedit' }}">{{vtItem:title}}</a>
 								</td>
 								<td style="text-align:right" width="80">
diff --git a/order.invoice_pdf.html b/order.invoice_pdf.html
index ebd1da7..f517b67 100644
--- a/order.invoice_pdf.html
+++ b/order.invoice_pdf.html
@@ -6,6 +6,7 @@
    $dompdf = new Dompdf\Dompdf();
    $dompdf->loadHtml( v::vtget('HTML,raw') );
    $dompdf->setPaper('A4');
+   $dompdf->getOptions()->setChroot( v::vtconfig('pathToVirthos') );
    $dompdf->render();
    $dompdf->stream( 'Rechnung-' . v::vtpage('Rechnungsnummer') . '.pdf', array( 'Attachment' => 0 ) );
 ?>
diff --git a/order.pxprint.html b/order.pxprint.html
index 7d9d2bf..a3a05c9 100644
--- a/order.pxprint.html
+++ b/order.pxprint.html
@@ -1,3 +1,23 @@
+<?php
+function getPreferredProduct( $pxprintIds ){
+	static $priorites;
+	if ( is_null( $priorities ) ){
+		$priorities = array_flip( explode( ' ', v::vtglobal('pxtcPxprintProviderPreference') ) );
+	}
+	$pxprintIds = explode( '|', $pxprintIds );
+	if ( empty( $priorities ) ){
+		return $pxprintIds[0];
+	}
+	$selection = [];
+	foreach ( $pxprintIds as $pxprintId ){
+		$providerId = substr( $pxprintId, 0, strpos( $pxprintId, '-' ) );
+		$priority = $priorities[ $providerId ] ?? count( $selection ) + 1;
+		$selection[ $priority ] = $pxprintId;
+	}
+	ksort( $selection );
+	return reset( $selection );
+}
+?>
 {{vtScript}}
 
 	## Bestelldaten an pxprint.net übertragen, falls noch nicht geschehen
@@ -16,10 +36,10 @@
 
 				## stelle Liste der Produkte zusammen, die über pxprint.net produziert werden sollen
 
-				{{vtSet: Items = "" }}
+				{{vtSet: Items = "", Item = "" }}
 
 				{{vtRepeat:{Warenkorb:raw} }}
-					{{vtIf: {vtItem:pxprint_id} .gt. 0 }}
+					{{vtIf: {vtItem:pxprint_id} .neq. }}
 					
 						{{vtSet: Item[copies]="{vtItem:quantity}"}}
 						{{vtSet: Item[filename]="{vtItem:filename}"}}
@@ -34,7 +54,12 @@
 						{{vtEndIf}}
 						
 						{{vtRepeat: ,{vtItem:pxprint_id} }}
-							{{vtSet: Item[product_id]="{vtItem}"}}
+							{{vtIf: {vtItem} .cn. | }}
+								{{vtCalc: getPreferredProduct( '{vtItem:escaped}' ) }}
+								{{vtSet: Item[product_id]="{vtResult}"}}
+							{{vtElse}}
+								{{vtSet: Item[product_id]="{vtItem}"}}
+							{{vtEndIf}}
 							{{vtSet: Items[]="{vtGet:Item}"}}
 						{{vtEndRepeat}}
 
diff --git a/order.send_confirmation.html b/order.send_confirmation.html
index d3a386d..fed9302 100644
--- a/order.send_confirmation.html
+++ b/order.send_confirmation.html
@@ -13,8 +13,10 @@
 		{{vtIf: {Order_Confirmation_Salutation} .eq. 1 }}
 			{{vtIf: {vtGet:Anrede} .eq. Frau }}
 				{{vtCalc: sprintf( '{vtGet:s_txt_0055,escaped}', '{vtGet:Vorname,escaped}', '{vtGet:Name,escaped}' ) }}
-			{{vtElse}}
+			{{vtElseIf: {vtGet:Anrede} .eq. Herr }}
 				{{vtCalc: sprintf( '{vtGet:s_txt_0054,escaped}', '{vtGet:Vorname,escaped}', '{vtGet:Name,escaped}' ) }}
+			{{vtElse}}
+				{{vtCalc: sprintf( '{vtGet:s_txt_0073,escaped}', '{vtGet:Vorname,escaped}', '{vtGet:Name,escaped}' ) }}
 			{{vtEndIf}}
 			{{vtSet: Anredezeile }}
 		{{vtEndIf}}
diff --git a/orderlist.html b/orderlist.html
index 32668c2..9593e4f 100644
--- a/orderlist.html
+++ b/orderlist.html
@@ -4,8 +4,10 @@
 <html>
 <head>
 	<!--{{vtInclude: includes/initialize.html}}-->
+	<!-- {{vtIf: {Titel} .eq. }}{{vtDo: -act="update", -obj="{vtId}", Titel="Bestellungen" }}{{vtRedirect}}{{vtEndIf}} -->
+	<!-- {{vtLoop: orderlist}}{{vtExit}}{{vtEndLoop}} -->
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-	<title>Liste der Bestellungen | {{vtGlobal:siteName}}</title>
+	<title>{{Titel:short}} | {{vtGlobal:siteName}}</title>
 	{{vtInclude: includes/html_headers_internal.html }}
 	<script type="text/javascript">
 		$( function(){
@@ -74,11 +76,11 @@
 <body>
 	<div class="content" style="width:800px">
 		<!--
-			{{vtSelect: -type="order", -filter="{Nummer} .gt. 0, {Datum} .gte. {vtDate|d.m.Y}, {Rechnungsbetrag} .gt. 0", -max="1" }}{{vtEndSelect}}
+			{{vtSelect: -type="order", -filter="{Nummer} .gt. 0, {Datum} .gte. {vtDate|d.m.Y}, {Rechnungsbetrag} .gt. 0", -max="1", -depth="1" }}{{vtEndSelect}}
 
 			{{vtIf: {vtSelection:orderlist,-type} .eq.}}
 				# Selektion neu aufbauen
-				{{vtDo: -act="setSelection", -name="orderlist", -type="order", -sortfield="Nummer", -sortorder="desc" }}
+				{{vtDo: -act="setSelection", -name="orderlist", -type="order", -sortfield="Nummer", -sortorder="desc", -depth="1" }}
 				{{vtDo: -act="updateSession", OrderlistSortfield="nummer" }}
 			{{vtEndIf}}
 		
@@ -118,7 +120,7 @@
 
 				{{vtDo: -act="updateSession", OrderlistFilter="{vtPostValue:filter}" }}
 
-				{{vtIf: {vtPostValue:filter} .eq. 0  }}
+				{{vtIf: {vtPostValue:filter} .eq. alle  }}
 					{{vtDo: -act="updateSelection", -name="orderlist", -filter="" }}
 				{{vtElseIf: {vtPostValue:filter} .eq. abgebrochen  }}
 					{{vtDo: -act="updateSelection", -name="orderlist", -filter="{abgeschlossen} .neq. 1" }}
@@ -138,7 +140,7 @@
 				&nbsp;&nbsp;
 				Filter:&nbsp;&nbsp;
 				<select name="filter" onchange="document.getElementById('status_indicator').innerHTML='bitte warten ...';this.form.submit()">
-					<option value="0">&lt;alle&gt;</option>
+					<option value="alle">&lt;alle&gt;</option>
 					<option value="abgebrochen" {{vtIf: {vtSession:OrderlistFilter} .eq. abgebrochen }}selected{{vtEndIf}}>nicht abgeschlossen</option>
 					<option value="abgeschlossen" {{vtIf: {vtSession:OrderlistFilter} .eq. abgeschlossen }}selected{{vtEndIf}}>abgeschlossen/unbezahlt</option>
 					<option value="bezahlt" {{vtIf: {vtSession:OrderlistFilter} .eq. bezahlt }}selected{{vtEndIf}}>bezahlt/unerledigt</option>
@@ -146,7 +148,7 @@
 				</select>
 			</form>
 		<!--{{vtEndIf}}-->
-		<h1>Bestellungen</h1>
+		<h1>{{Titel:short}}</h1>
 		<!--{{vtSelect: -name="orderlist" }}-->
 		<!--{{vtIf: {vtCountSelection} .gt. 0}}-->
 		<form id="table_form" name="table_form" action="{{vtLink:-act='itemaction'}}" method="post" onsubmit="return confirm('Sind Sie sicher, dass die ausgewählten Bestellungen gelöscht werden sollen?')">
@@ -175,7 +177,7 @@
 					<a href="{{vtLink:sort='status'}}">Status</a>
 				</th>
 			</tr>
-			<!--{{vtLoop:-size="20"}}-->
+			<!--{{vtLoop:-size="20", -type="order"}}-->
 			<tr class="{{vtIf: {abgeschlossen} .neq. 1}}inactive{{vtElseIf: {erledigt} .neq. 1}}marked{{vtEndIf}}" onclick="location.href='{{vtLink}}'" style="cursor:pointer">
 				<td class="fieldContent" style="text-align:center; vertical-align:middle">
 					<input type="checkbox" class="object_selector" name="-obj[]" value="{{vtID}}">
diff --git a/register.html b/register.html
index ee092b3..b81dc0a 100644
--- a/register.html
+++ b/register.html
@@ -294,7 +294,7 @@
 <!--{{vtCapture:PageContentLeft}}-->
 
 	<!--{{vtIf: {vtGlobal:locked} .eq. 1 }}-->
-		<p style="float:right"><a href="{{vtLink:/}}">zurück</a></p>
+		<p style="float:right"><a href="{{vtLink: {vtGet:ID_Home} }}">zurück</a></p>
 	<!--{{vtEndIf}}-->
 	<!--{{vtIf: {vtGet:Language} .neq. de .and. {Text_en} .neq.}}-->
 		{{Text_en:html}}
diff --git a/resources/easybill-rest.class.php b/resources/easybill-rest.class.php
index 40c0820..27fbe2a 100644
--- a/resources/easybill-rest.class.php
+++ b/resources/easybill-rest.class.php
@@ -174,6 +174,7 @@ class Easybill {
 			'description' => 'itemDescription',
 			'quantity' => 'count',
 			'single_price_net' => 'singlePriceNetto',
+			'single_price_gross' => 'singlePriceBrutto',
 			'vat_percent' => 'ustPercent'
 		);
 			
@@ -183,6 +184,7 @@ class Easybill {
 			'itemDescription' => 'description',
 			'count' => 'quantity',
 			'singlePriceNetto' => 'single_price_net',
+			'singlePriceBrutto' => 'single_price_gross',
 			'ustPercent' => 'vat_percent'
 		);
 		
@@ -224,7 +226,8 @@ class Easybill {
 
 			if ( $rule == 'customer_from_rest' && $key == 'salutation' )
 			{
-				$newArray['salutation'] = $value == 2 ? 'Frau' : ( $value == 3 ? 'Firma' : 'Herr' );
+				$keys = [ 1 => 'Herr', 2 => 'Frau', 3 => 'Firma' ];
+				$newArray['salutation'] = $keys[ $value ] ?? '';
 				continue;
 			}
 
@@ -236,7 +239,8 @@ class Easybill {
 
 			if ( $rule == 'customer_to_rest' && $key == 'salutation' )
 			{
-				$newArray['salutation'] = $value == 'Frau' ? 2 : ( $value == 'Firma' ? 3 : 1 );
+				$keys = [ 'Herr' => 1, 'Frau' => 2, 'Firma' => 3 ];
+				$newArray['salutation'] = $keys[ $value ] ?? 0;
 				continue;
 			}
 
diff --git a/resources/functions.php b/resources/functions.php
index 432ef0e..305be0f 100644
--- a/resources/functions.php
+++ b/resources/functions.php
@@ -77,14 +77,14 @@ function makeThumbnail( $image, $force = FALSE )
 	$size = v::vtglobal('pxtcImagingThumbnailSize');
 	$sizeMin = v::vtglobal('pxtcImagingThumbnailSizeMin');
 	$quality = v::vtglobal('pxtcImagingThumbnailQuality');
-	$imager->resize( $size ? $size : 120, $sizeMin ? $sizeMin : 0 );
+	$result = $imager->resize( $size ? $size : 120, $sizeMin ? $sizeMin : 0 );
 
 	if ( ! $imager->write( $path, $quality ? $quality : 80 ) )
 	{
 		return -12;
 	}
 
-	return 1;
+	return $result;
 }
 
 
@@ -111,7 +111,8 @@ function getIPTCHeader( $image, $header, $charset = '' )
 		'Copyright' => '116',
 		'Description' => '120',
 		'Instructions' => '040',
-		'Writer' => '122'
+		'Writer' => '122',
+		'Rating' => 'xmp'
 	);
 
 	if ( !isset( $fieldNames[ $header ] ) )
@@ -119,6 +120,28 @@ function getIPTCHeader( $image, $header, $charset = '' )
 		return '';
 	}
 
+	if ( $fieldNames[ $header ] == 'xmp' )
+	{
+		if ( ! isset( $GLOBALS['pxtc']['xmp_data'][ $image ] ) )
+		{
+			error_reporting( E_ALL );
+			require_once 'templates/pixtacy/lib/image/ImageInterface.php';
+			require_once 'templates/pixtacy/lib/image/Image.php';
+			require_once 'templates/pixtacy/lib/image/Metadata/Xmp.php';
+			require_once 'templates/pixtacy/lib/image/Format/JPEG.php';
+			require_once 'templates/pixtacy/lib/image/Format/JPEG/Segment.php';
+			$imageObj = CSD\Image\Image::fromFile( $image );
+			$GLOBALS['pxtc']['xmp_data'][ $image ] = $imageObj->getXmp();
+		}
+
+		if ( is_callable( array( $GLOBALS['pxtc']['xmp_data'][ $image ], "get{$header}" ) ) )
+		{
+			return call_user_func( array( $GLOBALS['pxtc']['xmp_data'][ $image ], "get{$header}" ) );
+		}
+
+		return '';
+	}
+
 	if ( isset( $GLOBALS['pxtc']['iptc_data'][ $image ] ) )
 	{
 		$iptc = $GLOBALS['pxtc']['iptc_data'][ $image ];
@@ -165,7 +188,7 @@ function getIPTCHeader( $image, $header, $charset = '' )
 	}
 	else
 	{
-		$result = $iptc[ $code ];
+		$result = isset( $iptc[ $code ] ) ? $iptc[ $code ] : '';
 	}
 
 	if ( $charset == 'utf-8' && function_exists('mb_convert_encoding') && defined('ENT_HTML401') ){
@@ -614,22 +637,9 @@ function verifyPaypalIPNMessage()
 {
 	$req = 'cmd=_notify-validate';
 
-	if ( function_exists( 'get_magic_quotes_gpc' ) )
-	{
-		$get_magic_quotes_exists = TRUE;
-	}
-
 	foreach ( $_POST as $key => $value )
 	{
-		// Handle escape characters, which depends on setting of magic quotes
-		if ( $get_magic_quotes_exists == TRUE && get_magic_quotes_gpc() == 1 )
-		{
-			$value = urlencode( stripslashes( $value ) );
-		}
-		else
-		{
-			$value = urlencode( $value );
-		}
+		$value = urlencode( $value );
 		$req .= "&$key=$value";
 	}
 
@@ -694,11 +704,6 @@ function analyzeSearchString()
 		$_REQUEST['-search'] = implode( ' ', $_REQUEST['-search'] );
 	}
 
-	if ( get_magic_quotes_gpc() )
-	{
-		$_REQUEST['-search'] = stripslashes( $_REQUEST['-search'] );
-	}
-
 	$matches = array ();
 	$result['all'] = '';
 	preg_match_all( '/-?([a-zA-Z0-9_]+:)?(("[^"]+")|([\S]+))/', $_REQUEST['-search'], $matches );
@@ -751,12 +756,16 @@ function analyzeSearchString()
 function isZipAvailable()
 {
 	$result = 0;
-	$cmd = v::vtconfig('pathToZipCommand') ? v::vtconfig('pathToZipCommand') : '/usr/bin/zip';
-	exec( $cmd . ' -L', $output );
 
-	if ( strpos( implode( $output ), 'Copyright' ) !== FALSE )
+	if ( function_exists('exec') )
 	{
-		$result += 1;
+		$cmd = v::vtconfig('pathToZipCommand') ? v::vtconfig('pathToZipCommand') : '/usr/bin/zip';
+		exec( $cmd . ' -L', $output );
+
+		if ( strpos( implode( $output ), 'Copyright' ) !== FALSE )
+		{
+			$result += 1;
+		}
 	}
 
 	if ( function_exists( 'hash_file' ) )
@@ -1330,6 +1339,16 @@ function createEasybillInvoice( $customer_id,  $customer_number )
 	$items = json_decode( v::vtpage( 'Warenkorb' ), TRUE );
 	$products = array ();
 	$max_vat_rate = 0;
+	if ( v::vtglobal('pxtcVatHandling') == 'excluded' )
+	{
+		$priceLabel = 'singlePriceNetto';
+		$priceField = 'netprice';
+	}
+	else
+	{
+		$priceLabel = 'singlePriceBrutto';
+		$priceField = 'price';
+	}
 	foreach ( $items as $item )
 	{
 		if ( isset( $products[ $item['product'] ] ) )
@@ -1345,7 +1364,7 @@ function createEasybillInvoice( $customer_id,  $customer_number )
 					'itemDescription' => $item['title'],
 					'count' => $item['quantity'],
 					'unit' => '',
-					'singlePriceNetto' => 100 * $item['netprice'],
+					$priceLabel => 100 * $item[ $priceField ],
 					'ustPercent' => $item['vatrate']
 				);
 		}
@@ -2283,18 +2302,19 @@ function hires_file_exists( $imagePath, $code )
 }
 
 
-function image_is_buyable( $imagePath, $imageAssortment, $imageProducts )
+function image_is_buyable( $imagePath, $imageAssortment, $imageProducts, $returnProductList = FALSE )
 {
 	static $allImagesBuyable = FALSE;
 	static $noImageBuyable = FALSE;
 	static $globalProducts; // Gesamtliste der theoretisch kaufbaren Produkte
-	static $assortments; // Gesamtliste der Sortimente ( Seiten-ID = Schlüssel, Kennungen = Wert )
+	static $assortmentCodes; // Gesamtliste der Sortimente ( Seiten-ID = Schlüssel, Kennungen = Wert )
 	static $productAssortments; // Liste der Sortimente, denen ein Produkt (ID = Schlüssel) zugeordnet ist
 
-	if ( $allImagesBuyable ) {
+	if ( $allImagesBuyable && ! $returnProductList ) {
 		return TRUE;
 	}
-	elseif ( $noImageBuyable ) {
+
+	if ( $noImageBuyable ) {
 		return FALSE;
 	}
 
@@ -2334,17 +2354,19 @@ function image_is_buyable( $imagePath, $imageAssortment, $imageProducts )
 				continue;
 			}
 			$prodId = (int) $product['id'];
-			$globalProducts[ $prodId ] = $product['kennung'];
+			$globalProducts[ $prodId ] = $product;
 			if ( $product['zuordnung'] ) {
 				// es ist ein automatisch zugeordnetes Produkt
 				if ( empty( $product['kennung'] ) ) {
 					// es ist nicht von High-res-Datei abhängig
 					$allImagesBuyable = TRUE;
-					return TRUE;
+					if ( ! $returnProductList ){
+						return TRUE;
+					}
 				}
 				// von High-res-Datei abhängig - Kennung in automatisches Sortiment aufnehmen
-				if ( empty( $assortments[0] ) || ! in_array( $product['kennung'], $assortments[0] ) ){
-					$assortments[0][] = $product['kennung'];
+				if ( empty( $assortmentCodes[0] ) || ! in_array( $product['kennung'], $assortmentCodes[0] ) ){
+					$assortmentCodes[0][] = $product['kennung'];
 				}
 			}
 			elseif ( ! isset( $productAssortments[ $prodId ] ) ) { 
@@ -2355,17 +2377,17 @@ function image_is_buyable( $imagePath, $imageAssortment, $imageProducts )
 				// Produkt ist nicht von High-res-Datei abhängig
 				// setze alle Sortimente, denen das Produkt zugeordnet ist, auf "generell kaufbar"
 				foreach ( $productAssortments[ $prodId ] as $assortmentId ) {
-					$assortments[ $assortmentId ] = '~';
+					$assortmentCodes[ $assortmentId ] = '~';
 				}
 			}
 			else {
 				// Produkt ist von High-res-Datei abhängig
 				// nimm Kennung in Kennungsliste der Sortimente auf, denen das Produkt zugeordnet ist
 				foreach ( $productAssortments[ $prodId ] as $assortmentId ) {
-					if ( empty( $assortments[ $assortmentId ] ) || ( $assortments[ $assortmentId ] != '~' 
-						&& ! in_array( $product['kennung'], $assortments[ $assortmentId ] ) ) 
+					if ( empty( $assortmentCodes[ $assortmentId ] ) || ( $assortmentCodes[ $assortmentId ] != '~' 
+						&& ! in_array( $product['kennung'], $assortmentCodes[ $assortmentId ] ) ) 
 					) {
-						$assortments[ $assortmentId ][] = $product['kennung'];
+						$assortmentCodes[ $assortmentId ][] = $product['kennung'];
 					}
 				}
 			}
@@ -2378,43 +2400,53 @@ function image_is_buyable( $imagePath, $imageAssortment, $imageProducts )
 
 	// Prüfe Bild individuell
 
-	if ( $imageAssortment == -1 || ! isset( $assortments[ $imageAssortment ] ) ) {
+	$imageProducts = array ();
+
+	if ( $imageAssortment == -1 || ! isset( $assortmentCodes[ $imageAssortment ] ) ) {
 		// kein Sortiment zugeordnet
 		// prüfe automat. zugeordnete Produkte
-		if ( ! empty( $assortments[0] ) ){
-			foreach ( $assortments[0] as $code ){
+		if ( ! empty( $assortmentCodes[0] ) ){
+			foreach ( $assortmentCodes[0] as $code ){
 				if ( hires_file_exists( $imagePath, $code ) ){
-					return TRUE;
+					if ( ! $returnProductList ){
+						return TRUE;
+					}
 				}
 			}
 		}
 		// prüfe individuell zugeordnete Produkte
-		if ( empty( $imageProducts ) ) {
+		if ( empty( $imageProducts ) && ! $returnProductList ) {
 			return FALSE;
 		}
 		foreach ( explode( "\n", $imageProducts ) as $product ) {
 			if ( isset( $globalProducts[ $product ] ) 
-				&& ( $globalProducts[ $product ] == '' || hires_file_exists( $imagePath, $globalProducts[ $product ] ) )
+				&& ( $globalProducts[ $product ]['kennung'] == '' || hires_file_exists( $imagePath, $globalProducts[ $product ]['kennung'] ) )
 			) {
-				return TRUE;
+				if ( ! $returnProductList ){
+					return TRUE;
+				}
 			}
 		}
 		return FALSE;
 	}
 
-	if ( $assortments[ $imageAssortment ] == '~' ) {
+	if ( $assortmentCodes[ $imageAssortment ] == '~' ) {
 		// zugeordnetes Sortiment ist generell kaufbar
-		return TRUE;
+		if ( ! $returnProductList ){
+			return TRUE;
+		}
 	}
 	
 	// zugeordnetes Sortiment ist nicht generell kaufbar - prüfe High-res-Dateien
-	foreach ( $assortments[ $imageAssortment ] as $code ) {
+	foreach ( $assortmentCodes[ $imageAssortment ] as $code ) {
 		if ( hires_file_exists( $imagePath, $code ) ) {
-			return TRUE;
+			if ( ! $returnProductList ){
+				return TRUE;
+			}
 		}
 	}
 
-	return FALSE;
+	return $returnProductList ? $imageProducts : FALSE;
 }
 
 ?>
diff --git a/resources/httpconnection.class.php b/resources/httpconnection.class.php
index 0f2a7bd..d3e5a86 100755
--- a/resources/httpconnection.class.php
+++ b/resources/httpconnection.class.php
@@ -10,7 +10,7 @@
  * @subpackage HTTPConnection
  * @link http://php-classes.sourceforge.net/ PHP Class Collection
  * @author Dennis Wronka <reptiler@users.sourceforge.net>
- * @version 1.4
+ * @version 1.4 (modified by mw)
  * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPL 2.1
  */
 class httpconnection extends tcpconnection
@@ -240,7 +240,7 @@ class httpconnection extends tcpconnection
 		{
 			return false;
 		}
-		if ((empty($uri)) || ($uri{0}!='/'))
+		if ((empty($uri)) || ($uri[0]!='/'))
 		{
 			$uri='/'.$uri;
 		}
@@ -308,7 +308,7 @@ class httpconnection extends tcpconnection
 		{
 			return false;
 		}
-		if ((empty($uri)) || ($uri{0}!='/'))
+		if ((empty($uri)) || ($uri[0]!='/'))
 		{
 			$uri='/'.$uri;
 		}
@@ -379,7 +379,7 @@ class httpconnection extends tcpconnection
 		{
 			return false;
 		}
-		if ((empty($uri)) || ($uri{0}!='/'))
+		if ((empty($uri)) || ($uri[0]!='/'))
 		{
 			$uri='/'.$uri;
 		}
@@ -493,4 +493,4 @@ class httpconnection extends tcpconnection
 		return $data;
 	}
 }
-?>
\ No newline at end of file
+?>
diff --git a/resources/jquery.dragndrop.js b/resources/jquery.dragndrop.js
new file mode 100644
index 0000000..03c8f7c
--- /dev/null
+++ b/resources/jquery.dragndrop.js
@@ -0,0 +1,164 @@
+/**
+ * Simple Drag & Drop
+ * @Version: 1.0
+ * @Author: Patrick Springstubbe
+ * @Contact: @JediNobleclem
+ * @Website: springstubbe.us
+ * @Source: https://github.com/nobleclem/jQuery-DragNDrop
+ *
+ * Usage:
+ *     $('ul').dragndrop();
+ *     $('ul').dragndrop('unload');
+ *     $('ul').dragndrop('reload');
+ *     $('ul').dragndrop({
+ *         onDrop: function( element, droppedElement ){}
+ *     });
+ *
+ **/
+(function($){
+    var defaults = {
+        loadStyles: true, // load default Drag & Drop Styles
+
+        // Callbacks
+        onDrop: function( element, droppedElement ) {}
+    };
+
+    var stylesLoaded = false;
+    var stylesDefaults = $('<style type="text/css">.jqdndLoaded > * { cursor: move; user-select: none; } .jqdndLoaded .jqdndDragging { opacity: 0.5; }</style>');
+
+    /* Add Plugin to jQuery */
+    $.fn.dragndrop = function( options ) {
+        if( !this.length ) {
+            return;
+        }
+
+        var args = arguments;
+        var ret;
+
+        // initialize drag and drop on element(s)
+        if( (options === undefined) || (typeof options === 'object' ) ) {
+            return this.each(function(){
+                if( !$.data( this, 'plugin_dragndrop' ) ) {
+                    $.data( this, 'plugin_dragndrop', new DragNDrop( this, options ) );
+                }
+            });
+        // execute built in method (unload, reload, etc) on element(s)
+        } else if( (typeof options === 'string') && (options[0] !== '_') && (options !== 'init') ) {
+            this.each(function(){
+                var instance = $.data( this, 'plugin_dragndrop' );
+
+                if( (instance instanceof DragNDrop) && (typeof instance[ options ] === 'function') ) {
+                    ret = instance[ options ].apply( instance, Array.prototype.slice.call( args, 1 ) );
+                }
+            });
+
+            return ret;
+        }
+    };
+
+
+    /* Setup Functionality */
+    function DragNDrop( element, options )
+    {
+        this.element   = element;
+        this.options   = $.extend( true, {}, defaults, options );
+        this.dragElem  = null;
+
+        if( !stylesLoaded ) {
+            stylesLoaded = true;
+
+            if( $('head > link:eq(0)').length ) {
+                stylesDefaults.insertBefore( $('head > link:eq(0)') );
+            }
+            else if( $('head > style:eq(0)').length ) {
+                stylesDefaults.insertBefore( $('head > style:eq(0)') );
+            }
+            else {
+                $('head').append( stylesDefaults );
+            }
+        }
+
+        this.load();
+    }
+
+    DragNDrop.prototype = {
+        load: function() {
+            var instance = this;
+            var items    = $(instance.element).find('> *');
+
+            // make sure this has not already been loaded
+            if( $(instance.element).data( 'plugin_dragndrop' ) ) {
+                return true;
+            }
+
+            $(instance.element).addClass('jqdndLoaded');
+
+            items.attr('draggable', true ).each(function(){
+                $(this)
+                    .on( 'dragstart', function( event ){
+                        instance.dragElem = this;
+
+                        event.originalEvent.dataTransfer.effectAllowed = 'move';
+                        $(this).addClass('jqdndDragging');
+                    })
+                    .on( 'dragenter', function( event ){})
+                    .on( 'dragover', function( event ){
+                        event.preventDefault();
+                        event.originalEvent.dataTransfer.dropEffect = 'move';
+
+                        if( this == instance.dragElem ) {
+                            return;
+                        }
+                        else if( $(this).prevAll().filter( instance.dragElem ).length ) {
+                            $(instance.dragElem).insertAfter( $(this) );
+                        }
+                        else {
+                            $(instance.dragElem).insertBefore( $(this) );
+                        }
+
+                        return false;
+                    })
+                    .on( 'dragleave', function( event ){})
+                    .on( 'drop', function( event ){
+                        event.preventDefault();
+
+                        if( typeof instance.options.onDrop == 'function' ) {
+                            instance.options.onDrop( instance.element, instance.dragElem );
+                        }
+                    })
+                    .on( 'dragend', function( event ){
+                        event.preventDefault();
+                        $(this).removeClass('jqdndDragging');
+
+                        instance.dragElem = null;
+                    })
+            });
+        },
+
+        unload: function(){
+            var instance = this;
+            var items    = $(instance.element).find('> *');
+
+            $(instance.element).removeClass('jqdndLoaded');
+
+            items.removeAttr('draggable').each(function(){
+                $(this)
+                    .off( 'dragstart' )
+                    .off( 'dragenter' )
+                    .off( 'dragover' )
+                    .off( 'dragleave' )
+                    .off( 'drop' )
+                    .off( 'dragend' );
+            });
+
+            $(instance.element).data( 'plugin_dragndrop', null );
+        },
+
+        reload: function() {
+            this.unload();
+            this.load();
+        },
+
+        reset: function(){}
+    };
+}(jQuery));
diff --git a/setup_appearance.vtedit.html b/setup_appearance.vtedit.html
index c6d3062..a90a604 100644
--- a/setup_appearance.vtedit.html
+++ b/setup_appearance.vtedit.html
@@ -547,7 +547,7 @@
 						<option value="">automatisch</option>
 						<option value="-1" {{vtIf:{pxtcNaviInfo}.eq.-1}}selected{{vtEndIf}}>ausblenden</option>
 						<optgroup label="verknüpft mit">
-							<!--{{vtUse: /}}-->
+							<!--{{vtUse: {vtGet:ID_Home} }}-->
 							<!--{{vtLoop: -show="all"}}-->
 								<!--{{vtIf: {vtPageType} .in. vtfolder|vtredirect|vtrawpage|page|page2 .or. {vtOriginalId} .gt. 0 }}-->
 									<option value="{{vtId}}" {{vtIf: {vtGlobal:pxtcNaviInfo} .eq. {vtId} }}selected{{vtEndIf}}>{{vtName}}</option>
@@ -563,7 +563,7 @@
 						<select name="pxtcNaviInfo_en" style="width:20em">
 							<option value="">kein Unterschied</option>
 							<optgroup label="verknüpft mit">
-								<!--{{vtUse: /}}-->
+								<!--{{vtUse: {vtGet:ID_Home} }}-->
 								<!--{{vtLoop: -show="all"}}-->
 									<!--{{vtIf: {vtPageType} .in. vtfolder|page|page2 }}-->
 										<option value="{{vtId}}" {{vtIf: {vtGlobal:pxtcNaviInfo_en} .eq. {vtId} }}selected{{vtEndIf}}>{{vtName}}</option>
@@ -758,7 +758,7 @@
 						<option value="">ausblenden</option>
 						<option value="1" {{vtIf: {pxtcNaviFooter} .eq. 1 }}selected{{vtEndIf}}>nur Zusätze zeigen</option>
 						<optgroup label="verknüpft mit">
-							<!--{{vtUse: /}}-->
+							<!--{{vtUse: {vtGet:ID_Home} }}-->
 							<!--{{vtLoop: vtfolder}}-->
 								<option value="{{vtId}}" {{vtIf: {vtGlobal:pxtcNaviFooter} .eq. {vtId} }}selected{{vtEndIf}}>{{vtName}}</option>
 							<!--{{vtEndLoop}}-->
@@ -772,7 +772,7 @@
 						<select name="pxtcNaviFooter_en" style="width:20em">
 							<option value="">kein Unterschied</option>
 							<optgroup label="verknüpft mit">
-								<!--{{vtUse: /}}-->
+								<!--{{vtUse: {vtGet:ID_Home} }}-->
 								<!--{{vtLoop: vtfolder}}-->
 									<option value="{{vtId}}" {{vtIf: {vtGlobal:pxtcNaviFooter_en} .eq. {vtId} }}selected{{vtEndIf}}>{{vtName}}</option>
 								<!--{{vtEndLoop}}-->
diff --git a/setup_details.html b/setup_details.html
index b7446a7..d364a14 100644
--- a/setup_details.html
+++ b/setup_details.html
@@ -123,9 +123,31 @@
 					<!--{{vtIf: {pxtcDetailMetadata} .cn. credit }}-->Credit<br><!--{{vtEndIf}}-->
 					<!--{{vtIf: {pxtcDetailMetadata} .cn. instructions }}-->Anweisungen<br><!--{{vtEndIf}}-->
 					<!--{{vtIf: {pxtcDetailMetadata} .cn. folder }}-->Galerie<br><!--{{vtEndIf}}-->
+					<!--{{vtIf: {pxtcDetailMetadata} .cn. rating }}-->Bewertung<br><!--{{vtEndIf}}-->
 				</td>
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+         <!--{{vtIf: {pxtcDetailCaption} .neq. 9 .and. {pxtcCaptionRules} .neq. .and. {pxtcCaptionRules} .neq. [] }}-->
+			<tr>
+				<td align="right" class="normal">Automatische Verlinkung</td>
+				<td class="normal">
+					<!--{{vtRepeat: {pxtcCaptionRules:raw} }}-->
+						<!--
+						{{vtIf: {vtItem:link} .bw. vt: }}
+							{{vtCalc: substr( '{vtItem:link,escaped}', 3 ) }}
+							{{vtCapture: Link }}{{vtLink: {vtResult} }}{{vtEndCapture}}
+						{{vtElse}}
+							{{vtSet: Link = "{vtItem:link}" }}
+						{{vtEndIf}}
+						-->
+						{{vtItem:word}}<!--{{vtIf: {vtItem:case_insensisitve} .eq. 1 }}-->*<!--{{vtEndIf}}-->
+						&rarr; <a href="{{vtGet:Link}}" title="{{vtItem:title}}" target="_blank">{{vtItem:link}}</a>
+						<br>
+					<!--{{vtEndRepeat}}-->
+				</td>
+			</tr>
+			<tr><td colspan="2">&nbsp;</td></tr>
+         <!--{{vtEndIf}}-->
 		</table>
 
 		<p><a href="{{vtLink:-met='vtedit'}}">Einstellungen ändern</a></p>
diff --git a/setup_details.vtedit.html b/setup_details.vtedit.html
index f79d56f..76b9ca1 100644
--- a/setup_details.vtedit.html
+++ b/setup_details.vtedit.html
@@ -6,6 +6,7 @@
 	<title>Pixtacy-Einstellungen bearbeiten</title>
 	<meta http-equiv="content-type" content="text/html;charset=utf-8">
 	{{vtInclude: includes/html_headers_internal.html }}
+	<script type="text/javascript" src="resources/jquery.dragndrop.js"></script>
 	<script type="text/javascript">
 		function initializeForm(){
 			if( document.forms[0] ) {
@@ -24,6 +25,21 @@
 		function handleSubmit() {
 			var f = document.formular;
 			f.pxtcDetailHeadlineLeft.disabled = false;
+			if ( $('#pxtcDetailCaption').prop('checked') ){
+				var rules = new Array();
+				$('#captionRules li' ).each( function( index ){
+					if( $(this).find('input[name="word"]').val() != '' ){
+						rules.push({
+							word: $(this).find('input[name="word"]').val(),
+							link: $(this).find('input[name="link"]').val(),
+							title: $(this).find('input[name="title"]').val(),
+							case_insensisitve: $(this).find('input[name="case_insensisitve"]').prop('checked') ? 1 : 0,
+						});
+					}
+				});
+				$('input[name="pxtcCaptionRules"]').val( JSON.stringify( rules ) );
+			}
+			$('#pxtcCaptionRules input').prop( 'disabled', true );
 			return true;
 		}
 		
@@ -36,18 +52,32 @@
 				f.pxtcDetailHeadlineLeft.disabled = true;
 			}
 		}
+
+		$( function(){
+			$('#pxtcDetailCaption').change( function(){
+				$('.caption-only').toggle( $(this).prop('checked') );
+			});
+			$('#captionRules').on( 'change', 'input', function(){
+				if( $( '#captionRules input[name="word"]' ).last().val() != '' ){
+					$('#captionRules li').last().clone().appendTo('#captionRules ul')
+						.find('input[type="text"]').val('');
+					return false;
+				}
+			});
+			$('.reorderable').dragndrop();
+		});
 	</script>
 	<script type="text/javascript" src="resources/validations.js"></script>
 </head>
 
-<body onload="initializeForm();">
+<body onload="initializeForm();" style="width:850px">
 
 	<div class="content">
 
 		<h1>Bilddetails</h1>
 
 		<form name="formular" action="{{vtLink:-act='update',-obj='{vtID}'}}" method="post" onsubmit="return handleSubmit()" enctype="multipart/form-data">
-		<table width="600" border="0" cellpadding="4"> 
+		<table width="800" border="0" cellpadding="4">
 			<!--{{vtIf: {vtGlobal:pxtcDesign} .eq. }}-->
 			<tr>
 				<td align="right" class="normal" style="width:180px">Bildvorschau</td>
@@ -154,10 +184,42 @@
 					<input type="checkbox" name="pxtcDetailMetadata[]" id="pxtcDetailMetadata_instructions" value="instructions" {{vtIf:{pxtcDetailMetadata}.cn.instructions}}checked{{vtEndIf}}>
 					<label for="pxtcDetailMetadata_instructions">Anweisungen</label><br>
 					<input type="checkbox" name="pxtcDetailMetadata[]" id="pxtcDetailMetadata_folder" value="folder" {{vtIf:{pxtcDetailMetadata}.cn.folder}}checked{{vtEndIf}}>
-					<label for="pxtcDetailMetadata_folder">Galerie</label>
+					<label for="pxtcDetailMetadata_folder">Galerie</label><br>
+					<input type="checkbox" name="pxtcDetailMetadata[]" id="pxtcDetailMetadata_rating" value="rating" {{vtIf:{pxtcDetailMetadata}.cn.rating}}checked{{vtEndIf}}>
+					<label for="pxtcDetailMetadata_rating">Bewertung</label>
 				</td>
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+			<tr class="caption-only">
+				<td align="right" class="normal">
+					Automatische Verlinkung<br>
+					<span style="color:#aaa">innerhalb der Bildbeschreibung</span>
+					<input type="hidden" name="pxtcCaptionRules" value="">
+				</td>
+				<td class="normal" id="captionRules">
+					<ul class="reorderable">
+						<!--{{vtSet: Count = "1" }}-->
+						<!--{{vtRepeat: {pxtcCaptionRules:raw} }}-->
+							<li>
+								<input type="text" name="word" value="{{vtItem:word}}" placeholder="Wort" size="20"> &nbsp;&nbsp;
+								<input id="case_ins_{{vtGet:Count}}" type="checkbox" name="case_insensisitve" value="1" {{vtIf:{vtItem:case_insensisitve}.eq.1}}checked{{vtEndIf}}>
+								<label for="case_ins_{{vtGet:Count}}">Groß-/Kleinschreibung ignorieren</label><br>
+								<input type="text" name="link" value="{{vtItem:link}}" placeholder="Link-URL" size="30">
+								<input type="text" name="title" value="{{vtItem:title}}" placeholder="Tooltip" size="30">
+							</li>
+							<!--{{vtSet: Count = "{vtEcho: v::vtget('Count') + 1 }" }}-->
+						<!--{{vtEndRepeat}}-->
+						<li>
+							<input type="text" name="word" value="" placeholder="Wort" size="20"> &nbsp;&nbsp;
+							<input id="case_ins_{{vtGet:Count}}" type="checkbox" name="case_insensisitve" value="1">
+							<label for="case_ins_{{vtGet:Count}}">Groß-/Kleinschreibung ignorieren</label><br>
+							<input type="text" name="link" value="" placeholder="Link-URL" size="30">
+							<input type="text" name="title" value="" placeholder="Tooltip" size="30">
+						</li>
+					</ul>
+				</td>
+			</tr>
+			<tr class="caption-only"><td colspan="2">&nbsp;</td></tr>
 			<tr>
 				<td align="right" class="normal" valign="top">&nbsp;</td>
 				<td class="normal" id="buttontd">
diff --git a/setup_interfaces.html b/setup_interfaces.html
index 50e4ea7..99feba0 100644
--- a/setup_interfaces.html
+++ b/setup_interfaces.html
@@ -68,20 +68,12 @@
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
 			<!--{{vtEndIf}}-->
+			<!--{{vtIf: {pxtcEasybillId} .neq. }}-->
 			<tr>
 				<td colspan="2">
 					<h2 class="box">easybill.de</h2>
 				</td>
 			</tr>
-			<!--{{vtIf: {pxtcEasybillId} .eq. }}-->
-			<tr>
-				<td colspan="2">
-					Mit Hilfe von easybill.de kann Pixtacy automatisch Rechnungen erstellen und versenden.&nbsp;&nbsp;
-					<a class="text_link" title="Gehe zu easybill.de" href="http://www.pixtacy.de/de/features/easybill.html" target="_blank">Mehr Infos</a>
-				</td>
-			</tr>
-			<tr><td colspan="2">&nbsp;</td></tr>
-			<!--{{vtElse}}-->
 			<tr>
 				<td style="width:15em">easybill-URL</td>
 				<td>
@@ -207,6 +199,17 @@
 				</td>
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+			<tr>
+				<td style="width:15em">Bevorzugte(r) Lieferant(en)</td>
+				<td>
+					<!--{{vtIf: {pxtcPxprintProviderPreference} .eq. }}-->
+						<i>keine</i>
+					<!--{{vtElse}}-->
+						{{pxtcPxprintProviderPreference}}
+					<!--{{vtEndIf}}-->
+				</td>
+			</tr>
+			<tr><td colspan="2">&nbsp;</td></tr>
 			<!--{{vtEndIf}}-->
 			<tr>
 				<td colspan="2">
diff --git a/setup_interfaces.vtedit.html b/setup_interfaces.vtedit.html
index 24b43a7..e19a4e4 100644
--- a/setup_interfaces.vtedit.html
+++ b/setup_interfaces.vtedit.html
@@ -91,6 +91,7 @@
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+			<!--{{vtIf: {pxtcEasybillId} .neq. }}-->
 			<tr>
 				<td colspan="2">
 					<h2 class="box">easybill.de</h2>
@@ -165,6 +166,7 @@
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+			<!--{{vtEndIf}}-->
 			<tr>
 				<td colspan="2">
 					<h2 class="box">pxprint.net</h2>
@@ -212,6 +214,14 @@
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+			<tr>
+				<td style="width:20em">Bevorzugte(r) Lieferant(en)</td>
+				<td>
+					<input type="text" name="pxtcPxprintProviderPreference" value="{{pxtcPxprintProviderPreference}}" size="40" placeholder="1099 1073">
+				</td>
+			</tr>
+			<tr><td colspan="2">&nbsp;</td></tr>
+			<tr><td colspan="2">&nbsp;</td></tr>
 			<tr>
 				<td colspan="2">
 					<h2 class="box">Wer-hat-Fotos.net</h2>
diff --git a/setup_payment.html b/setup_payment.html
index 0e154c3..59a06a0 100644
--- a/setup_payment.html
+++ b/setup_payment.html
@@ -130,6 +130,31 @@
 				</td>
 			</tr>
 			<tr><td colspan="2">&nbsp;</td></tr>
+			<!--{{vtIf: {vtGet:PayrexxInitialized} .eq. 1 }}-->
+			<tr>
+				<td style="width:12em">Payrexx</td>
+				<td>
+					<!--{{vtIf: {pxtcPaymentPayrexx} .eq. 1}}-->
+						nur für angemeldete Benutzer
+					<!--{{vtElseIf: {pxtcPaymentPayrexx} .eq. 2}}-->
+						für alle Benutzer
+					<!--{{vtElseIf: {pxtcPaymentPayrexx} .neq.}}-->
+						für Mitglieder der Gruppe »{{pxtcPaymentPayrexx}}«
+						<!--{{vtIf: {vtLicenseType} .eq. a }}-->
+							<span style="color:red">*</span>
+						<!--{{vtEndIf}}-->
+					<!--{{vtElse}}-->
+						nicht verwenden
+					<!--{{vtEndIf}}-->
+					<!--{{vtIf: {pxtcPaymentPayrexx} .gte. 1}}-->
+					<br>
+					<span style="color:#aaa">Instanzname: {{pxtcPayrexxName}}<br>
+					<span style="color:#aaa">API-Schlüssel: {{pxtcPayrexxApiSecret}}<br>
+					<!--{{vtEndIf}}-->
+				</td>
+			</tr>
+			<tr><td colspan="2">&nbsp;</td></tr>
+			<!--{{vtEndIf}}-->
 		</table>
 
 		<!--{{vtIf: {vtLicenseType} .eq. a }}-->
diff --git a/setup_payment.vtedit.html b/setup_payment.vtedit.html
index e2abaf6..a87e8ee 100644
--- a/setup_payment.vtedit.html
+++ b/setup_payment.vtedit.html
@@ -129,6 +129,20 @@
 			}
 		}
 
+		function handleChangePayrexx() {
+			var f = document.formular;
+
+			if( f.pxtcPaymentPayrexx.selectedIndex > 0 ){
+				f.pxtcPayrexxName.disabled = false;
+				f.pxtcPayrexxApiSecret.disabled = false;
+				f.pxtcPayrexxName.select();
+				f.pxtcPayrexxName.focus();
+			} else {
+				f.pxtcPayrexxName.disabled = true;
+				f.pxtcPayrexxApiSecret.disabled = true;
+			}
+		}
+
 		function handleChangePaypal() {
 			var f = document.formular;
 
@@ -393,6 +407,47 @@
 					</table>
 				</td>
 			</tr>
+			<!--{{vtIf: {vtGet:PayrexxInitialized} .eq. 1 }}-->
+			<tr><td colspan="2">&nbsp;</td></tr>
+			<tr><td colspan="2"><hr></td></tr>
+			<tr><td colspan="2">&nbsp;</td></tr>
+			<tr>
+				<td>Payrexx</td>
+				<td>
+					<select name="pxtcPaymentPayrexx" onchange="handleChangePayrexx()">
+						<option value="">nicht verwenden</option>
+						<option value="2" {{vtIf:{pxtcPaymentPayrexx} .eq. 2}}selected{{vtEndIf}}>für alle Benutzer</option>
+						<option value="1" {{vtIf:{pxtcPaymentPayrexx} .eq. 1}}selected{{vtEndIf}}>für alle angemeldeten Benutzer</option>
+						<!--{{vtSet: GroupExists=""}}-->
+						<!--{{vtRepeatUsers: group}}-->
+							<!--{{vtIf: {vtCurrentUserID} .neq. 4}}-->
+								<option {{vtGet:Disabled}} value="{{vtCurrentUserName}}" {{vtIf:{pxtcPaymentPayrexx}.eq.{vtCurrentUserName} }}selected{{vtSet:GroupExists='1'}}{{vtEndIf}}>für Mitglieder der Gruppe &raquo;{{vtCurrentUserName}}&laquo; {{vtGet:Asterisk}}</option>
+							<!--{{vtEndIf}}-->
+						<!--{{vtEndRepeatUsers}}-->
+					</select>
+				</td>
+			</tr>
+			<tr>
+				<td>&nbsp;</td>
+				<td>
+					<table>
+						<tr>
+							<td style="width:12em">Instanzname:</td>
+							<td>
+								<input type="text" name="pxtcPayrexxName" value="{{pxtcPayrexxName}}" size="30" {{vtIf: {pxtcPaymentPayrexx} .lt. 1}}disabled{{vtEndIf}}>
+								&nbsp;&nbsp;&nbsp;<a href="http://www.payrexx.com" class="text_link" target="_blank" onclick="return onBeforeUnload()">Info/Registrierung</a>
+							</td>
+						</tr>
+						<tr>
+							<td style="width:12em">API-Schlüssel:</td>
+							<td>
+								<input type="text" name="pxtcPayrexxApiSecret" value="{{pxtcPayrexxApiSecret}}" size="30" {{vtIf: {pxtcPaymentPayrexx} .lt. 1}}disabled{{vtEndIf}}>
+							</td>
+						</tr>
+					</table>
+				</td>
+			</tr>
+			<!--{{vtEndIf}}-->
 			<!--{{vtIf: {vtLicenseType} .eq. a }}-->
 			<tr><td colspan="2">&nbsp;</td></tr>
 			<tr><td colspan="2"><hr></td></tr>
diff --git a/setup_privileges.vtedit.html b/setup_privileges.vtedit.html
index 6a807a0..505e9bb 100644
--- a/setup_privileges.vtedit.html
+++ b/setup_privileges.vtedit.html
@@ -357,7 +357,7 @@
 			
 			<h3>Selbstregistrierung</h3>
 			<p>Wenn Sie die Selbstregistrierung für eine bestimmte Gruppe aktivieren, blendet Pixtacy auf jeder Seite einen Link zum 
-				<a href="{{vtLink:/Registrierung}}">Registrierungsformular</a> ein. Über dieses Formular können sich Besucher selbst 
+				<a href="{{vtLink: {vtGet:ID_Registrierung} }}">Registrierungsformular</a> ein. Über dieses Formular können sich Besucher selbst 
 				ein Benutzerkonto mit eigenem Anmeldenamen und Passwort anlegen. 
 				Das Konto wird automatisch der gewählten Gruppe zugeordnet, und Sie werden per E-Mail benachrichtigt.</p>
 			<p>Die <em>automatische Freigabe</em> sorgt dafür, dass sich ein Besucher sofort nach der Registrierung
diff --git a/setup_search.html b/setup_search.html
index dd2a7ee..f9ad11b 100644
--- a/setup_search.html
+++ b/setup_search.html
@@ -103,6 +103,10 @@
 							nach Titel
 						<!--{{vtElseIf: {pxtcSearchSortfield} .eq. image.creationdate}}-->
 							nach Aufnahmedatum
+						<!--{{vtElseIf: {pxtcSearchSortfield} .eq. image.rating}}-->
+							nach Bewertung
+						<!--{{vtElseIf: {pxtcSearchSortfield} .eq. day+rating}}-->
+							nach Aufnahmetag + Bewertung
 						<!--{{vtElseIf: {pxtcSearchSortfield} .eq. sortValue}}-->
 							manuell
 						<!--{{vtEndIf}}-->
diff --git a/setup_search.vtedit.html b/setup_search.vtedit.html
index dc86179..32285cb 100644
--- a/setup_search.vtedit.html
+++ b/setup_search.vtedit.html
@@ -195,6 +195,8 @@
 							<option value="name" {{vtIf:{pxtcSearchSortfield}.eq.name}}selected{{vtEndIf}}>Dateiname</option>
 							<option value="image.name" {{vtIf: {pxtcSearchSortfield} .eq. image.name}}selected{{vtEndIf}}>Titel</option>
 							<option value="image.creationdate" {{vtIf: {pxtcSearchSortfield} .eq. image.creationdate}}selected{{vtEndIf}}>Aufnahmedatum</option>
+							<option value="image.rating" {{vtIf: {pxtcSearchSortfield} .eq. image.rating}}selected{{vtEndIf}}>Bewertung</option>
+							<option value="day+rating" {{vtIf: {pxtcSearchSortfield} .eq. day+rating}}selected{{vtEndIf}}>Aufnahmetag + Bewertung</option>
 						</optgroup>
 						<optgroup label="nach Datensatzmerkmal">
 							<option value="creationTime" {{vtIf:{pxtcSearchSortfield}.eq.creationTime}}selected{{vtEndIf}}>Erstellungsdatum</option>
diff --git a/views/gallery_r.html b/views/gallery_r.html
index 396c2cb..d8de9f2 100644
--- a/views/gallery_r.html
+++ b/views/gallery_r.html
@@ -200,7 +200,7 @@
 					<!--{{vtIf: {vtItem:type} .cn. folder}}-->
 						<div class="gallery-item-border gallery-item-folder">
 							<a class="gallery-item stretched-link" href="{{vtItem:link}}">
-								<img class="{{vtItem:orientation}} border" style="{{vtIf: {vtItem:src} .neq. }}background-image:url('{{vtItem:src,escaped}}'){{vtEndIf}}" src="{{vtResource:clear.gif}}" width="{{vtGet:FolderSize}}" height="{{vtGet:FolderSize}}" alt="{{vtItem:title}}" title="{{vtItem:title}}">
+								<img class="{{vtItem:orientation}} border" style="{{vtIf: {vtItem:src} .neq. }}background-image:url('{{vtItem:src,escaped}}'){{vtEndIf}}" src="{{vtResource:clear.gif}}" width="{{vtGet:FolderSize}}" height="{{vtGet:FolderSize}}" alt="{{vtItem:title}}" title="{{vtItem:title,raw}}">
 							</a>
 							<div class="itemcount px-2 py-1 border border-bottom-0">
 								<i class="far fa-folder"></i>
@@ -213,7 +213,7 @@
 							<!--{{vtEndIf}}-->
 						</div>
 					<!--{{vtElse}}-->
-						<div id="gallery-item-{{vtItem:id}}" class="gallery-item-border gallery-item-image {{vtIf: {vtItem:id} .in. {vtGet:Lightbox} }}flagged{{vtEndIf}} {{vtIf: {vtItem:badge} .neq. }}in-cart{{vtEndIf}}" data-id="{{vtItem:id}}" data-productlist="{{vtLink:-pg='{vtItem:id}',-met='ajax/order_dialog.html'}}">
+						<div id="gallery-item-{{vtItem:id}}" class="gallery-item-border gallery-item-image {{vtIf: {vtItem:id} .in. {vtGet:Lightbox} }}flagged{{vtEndIf}} {{vtIf: {vtItem:badge} .neq. }}in-cart{{vtEndIf}}" data-id="{{vtItem:id}}" data-productlist="{{vtLink:-pg='{vtItem:id}',-met='ajax/order_dialog.html'}}" data-rating="{{vtItem:rating}}">
 							<a class="d-none" href="{{vtItem:link}}">Details</a> <!-- for crawlers -->
 							<div class="gallery-item">
 								<!--{{vtIf: {vtItem:src} .neq. .and. {vtItem:width} .gt. 0 }}-->
@@ -221,7 +221,7 @@
 									<!--{{vtSet: Height }}-->
 									<!--{{vtCalc: round( {vtGet:Height} * {vtItem:width} / {vtItem:height} ) }}-->
 									<!--{{vtSet: Width }}-->
-									<img class="img-thumbnail {{vtItem:orientation}}" data-src="{{vtItem:preview,raw}}" style="background-image:url('{{vtItem:src,escaped}}'); width:{{vtGet:Width}}px; height:{{vtGet:Height}}px;" src="{{vtResource:clear.gif}}" alt="{{vtItem:title}}" title="{{vtItem:title}}" data-pageid="{{vtItem:id}}">
+									<img class="img-thumbnail {{vtItem:orientation}}" data-lg="1" style="background-image:url('{{vtItem:src}}'); width:{{vtGet:Width}}px; height:{{vtGet:Height}}px;" src="{{vtResource:clear.gif}}" alt="{{vtItem:title}}" title="{{vtItem:tooltip,raw}}" data-pageid="{{vtItem:id}}">
 								<!--{{vtElse}}-->
 									<img class="img-thumbnail" src="{{vtResource:clear.gif}}" style="width:{{vtGet:FolderSize}}px; height:{{vtGet:FolderSize}}px" alt="">
 								<!--{{vtEndIf}}-->
@@ -240,11 +240,9 @@
 									<i class="far fa-folder"></i>
 								</div>
 								<!--{{vtEndIf}}-->
-								<!--{{vtIf: {vtGlobal:pxtcGalleryViewer} .eq. 1 }}-->
 								<div class="details-box" title="Bilddetails aufrufen">
-									<i class="fas fa-info-circle"></i>
+									<a href="{{vtItem:link}}"><i class="fas fa-info-circle"></i></a>
 								</div>
-								<!--{{vtEndIf}}-->
 							</div>
 							<!--{{vtIf: {vtGet:ShowCaption} .eq. 1 }}-->
 								<div class="caption text-muted small mt-1" style="width:{{vtGet:Width}}px">
@@ -292,11 +290,11 @@
 			// {{vtEndIf}}
 
 			$( document ).ready( function(){
-				$('img[data-src*="/"]').on( 'click', function( event ){
 					// {{vtIf: {vtGlobal:pxtcGalleryViewer} .eq. 1 }}
+				$('img[data-lg="1"]').on( 'click', function( event ){
 					lightGallery = this.core;
 					$(this).lightGallery({
-						index: $('img[data-src*="/"]').index(this),
+						index: $('img[data-lg="1"]').index(this),
 						hideUnflaggedElements: $('body').hasClass('pxtc_class_lightbox'),
 						download: downloadAllowed,
 						loop: false,
@@ -327,11 +325,13 @@
 							event.preventDefault();
 						});
 					}
+				});
 					// {{vtElse}}
+				$('.gallery-item-border img').on( 'click', function( event ){
 					var url = $(this).parents('.gallery-item-border').find('a').attr('href');
 					url ? window.location.href = url : null;
-					// {{vtEndIf}}
 				});
+				// {{vtEndIf}}
 
 				
 				// {{vtIf: {vtGlobal:pxtcNaviLightboxBehaviour} .neq. -1 }}
@@ -375,13 +375,6 @@
 					url ? window.location.href = url : null;
 				});
 
-				// {{vtIf: {vtGlobal:pxtcGalleryViewer} .eq. 1 }}
-				$('body').on( 'click', '.details-box', function(){
-					var url = $(this).parents('.gallery-item-border').find('a').attr('href');
-					url ? window.location.href = url : null;
-				});
-				// {{vtEndIf}}
-
 				$(document).on( 'mousemove', activate_hover )
 					.on( 'touchstart', deactivate_hover );
 
diff --git a/views/image_r.html b/views/image_r.html
index cf3b18f..14ee3e9 100644
--- a/views/image_r.html
+++ b/views/image_r.html
@@ -8,6 +8,11 @@
 	<meta name="description" content="{{vtGet:PageDescription}}">
 	<meta name="keywords" content="{{vtRepeat: {vtGet:MetaKeywords} }}{{vtItem}}, {{vtEndRepeat}}">
 	<link rel="canonical" href="{{vtGet:CanonicalUrl}}">
+	<meta property="og:title" content="{{vtIf: {Name} .neq. }}{{Name:raw}}{{vtElse}}{{vtName}}{{vtEndIf}}"/>
+	<meta property="og:site_name" content="{{vtGlobal:siteName}}"/>
+	<meta property="og:description" content="{{Remarks:raw|strip_tags}}"/>
+	<meta property="og:url" content="{{vtGet:CanonicalUrl}}"/>
+	<meta property="og:image" content="{{vtGet:ImageSource}}"/>
 	<!--{{vtInclude: includes/html_headers_r.html}}-->
 	{{vtGet:PageAdditionalHeaders,raw}}
 	<!--{{vtIf: {vtGet:ZoomAllowed} .eq. 1 }}-->
@@ -216,6 +221,17 @@
 							***&nbsp;{{vtGet:MetaInstructions}}&nbsp;***
 						</p>
 					<!--{{vtEndIf}}-->
+					<!--{{vtIf: {vtGet:MetaRating} .neq. }}-->
+						<p id="meta_rating">
+							<!--{{vtRepeat: 1,2,3,4,5 }}-->
+								<!--{{vtIf: {vtGet:MetaRating} .gte. {vtItem} }}-->
+									<i class="fas fa-star"></i>
+								<!--{{vtElse}}-->
+									<i class="far fa-star"></i>
+								<!--{{vtEndIf}}-->
+							<!--{{vtEndRepeat}}-->
+						</p>
+					<!--{{vtEndIf}}-->
 				</small>
 
 			</div>
diff --git a/views/namelist_r.html b/views/namelist_r.html
index a9c6a95..5b8a394 100644
--- a/views/namelist_r.html
+++ b/views/namelist_r.html
@@ -4,7 +4,7 @@
 <html lang="{{vtGet:Language}}">
 <head>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-	<title>{{vtGet:PageTitle}}</title>
+	<title>{{vtGet:PageTitle,raw}}</title>
 	<!--{{vtInclude: includes/html_headers_r.html}}-->
 	{{vtGet:PageAdditionalHeaders,raw}}
 	<style type="text/css">
@@ -17,7 +17,7 @@
 	{{vtInclude: includes/custom_header.html}}
 	{{vtInclude: includes/header_r.html}}
 	
-	<div class="container" style="min-height:40ex;">
+	<div class="container" style="min-height:40ex; overflow:auto;">
 
 		<div class="page-header clearfix mt-3 mb-2 border-bottom">
 			<div class="float-right mt-1">
