| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  | import { | 
					
						
							|  |  |  |   customElement, | 
					
						
							|  |  |  |   html, | 
					
						
							|  |  |  |   type TemplateResult, | 
					
						
							|  |  |  |   DeesElement, | 
					
						
							|  |  |  |   type CSSResult, | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  |   property, | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  | } from '@design.estate/dees-element'; | 
					
						
							| 
									
										
										
										
											2023-08-07 19:13:29 +02:00
										 |  |  | import * as domtools from '@design.estate/dees-domtools'; | 
					
						
							| 
									
										
										
										
											2022-03-18 19:40:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { DeesInputCheckbox } from './dees-input-checkbox.js'; | 
					
						
							| 
									
										
										
										
											2025-09-19 15:26:21 +00:00
										 |  |  | import { DeesInputDatepicker } from './dees-input-datepicker/index.js'; | 
					
						
							| 
									
										
										
										
											2022-03-18 19:40:28 +01:00
										 |  |  | import { DeesInputText } from './dees-input-text.js'; | 
					
						
							|  |  |  | import { DeesInputQuantitySelector } from './dees-input-quantityselector.js'; | 
					
						
							| 
									
										
										
										
											2025-06-26 15:08:14 +00:00
										 |  |  | import { DeesInputRadiogroup } from './dees-input-radiogroup.js'; | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  | import { DeesInputDropdown } from './dees-input-dropdown.js'; | 
					
						
							| 
									
										
										
										
											2025-09-19 15:26:21 +00:00
										 |  |  | import { DeesInputFileupload } from './dees-input-fileupload/index.js'; | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  | import { DeesInputIban } from './dees-input-iban.js'; | 
					
						
							|  |  |  | import { DeesInputMultitoggle } from './dees-input-multitoggle.js'; | 
					
						
							|  |  |  | import { DeesInputPhone } from './dees-input-phone.js'; | 
					
						
							|  |  |  | import { DeesInputTypelist } from './dees-input-typelist.js'; | 
					
						
							| 
									
										
										
										
											2022-03-18 19:40:28 +01:00
										 |  |  | import { DeesFormSubmit } from './dees-form-submit.js'; | 
					
						
							| 
									
										
										
										
											2025-09-18 14:18:43 +00:00
										 |  |  | import { DeesTable } from './dees-table/index.js'; | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  | import { demoFunc } from './dees-form.demo.js'; | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  | // Unified set for form input types
 | 
					
						
							|  |  |  | const FORM_INPUT_TYPES = [ | 
					
						
							|  |  |  |   DeesInputCheckbox, | 
					
						
							| 
									
										
										
										
											2025-06-30 10:40:23 +00:00
										 |  |  |   DeesInputDatepicker, | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  |   DeesInputDropdown, | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |   DeesInputFileupload, | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |   DeesInputIban, | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |   DeesInputMultitoggle, | 
					
						
							|  |  |  |   DeesInputPhone, | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |   DeesInputQuantitySelector, | 
					
						
							| 
									
										
										
										
											2025-06-26 15:08:14 +00:00
										 |  |  |   DeesInputRadiogroup, | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |   DeesInputText, | 
					
						
							|  |  |  |   DeesInputTypelist, | 
					
						
							| 
									
										
										
										
											2023-10-17 20:07:45 +02:00
										 |  |  |   DeesTable, | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  | export type TFormInputElement = | 
					
						
							|  |  |  |   | DeesInputCheckbox | 
					
						
							| 
									
										
										
										
											2025-06-30 10:40:23 +00:00
										 |  |  |   | DeesInputDatepicker | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  |   | DeesInputDropdown | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |   | DeesInputFileupload | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |   | DeesInputIban | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |   | DeesInputMultitoggle | 
					
						
							|  |  |  |   | DeesInputPhone | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |   | DeesInputQuantitySelector | 
					
						
							| 
									
										
										
										
											2025-06-26 15:08:14 +00:00
										 |  |  |   | DeesInputRadiogroup | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |   | DeesInputText | 
					
						
							|  |  |  |   | DeesInputTypelist | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |   | DeesTable<any>; | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-13 21:52:36 +00:00
										 |  |  | declare global { | 
					
						
							|  |  |  |   interface HTMLElementTagNameMap { | 
					
						
							|  |  |  |     'dees-form': DeesForm; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | @customElement('dees-form') | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  | export class DeesForm extends DeesElement { | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |   public static demo = demoFunc; | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   public name: string = 'myform'; | 
					
						
							| 
									
										
										
										
											2023-10-23 17:26:03 +02:00
										 |  |  |   public changeSubject = new domtools.plugins.smartrx.rxjs.Subject(); | 
					
						
							| 
									
										
										
										
											2023-08-19 18:56:32 +02:00
										 |  |  |   public readyDeferred = domtools.plugins.smartpromise.defer(); | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Controls the layout mode of child input components | 
					
						
							|  |  |  |    * When true, sets all child inputs to horizontal layout | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   @property({ type: Boolean, reflect: true, attribute: 'horizontal-layout' }) | 
					
						
							|  |  |  |   public horizontalLayout: boolean = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  |   public render(): TemplateResult { | 
					
						
							|  |  |  |     return html`
 | 
					
						
							|  |  |  |       <style> | 
					
						
							|  |  |  |         :host { | 
					
						
							|  |  |  |           display: contents; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       </style> | 
					
						
							|  |  |  |       <slot></slot> | 
					
						
							|  |  |  |     `;
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-12 02:47:45 +02:00
										 |  |  |   public async firstUpdated() { | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |     const formChildren = this.getFormElements(); | 
					
						
							|  |  |  |     this.updateRequiredStatus(); | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  |     this.updateChildrenLayoutMode(); | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |     for (const child of formChildren) { | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |       child.changeSubject.subscribe(async () => { | 
					
						
							|  |  |  |         const valueObject = await this.collectFormData(); | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |         this.changeSubject.next(valueObject); | 
					
						
							|  |  |  |         console.log(valueObject); | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |         this.updateRequiredStatus(); | 
					
						
							| 
									
										
										
										
											2021-08-25 13:51:55 +02:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |     await this.addBehaviours(); | 
					
						
							| 
									
										
										
										
											2023-08-19 18:56:32 +02:00
										 |  |  |     this.readyDeferred.resolve(); | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |   public getFormElements(): Array<TFormInputElement> { | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |     return Array.from(this.children).filter((child) => | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |       FORM_INPUT_TYPES.includes(child.constructor as any) | 
					
						
							|  |  |  |     ) as unknown as TFormInputElement[]; | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |   public getSubmitButton(): DeesFormSubmit | undefined { | 
					
						
							| 
									
										
										
										
											2023-10-23 16:13:02 +02:00
										 |  |  |     return Array.from(this.children).find( | 
					
						
							|  |  |  |       (child) => child instanceof DeesFormSubmit | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |     ) as DeesFormSubmit; | 
					
						
							| 
									
										
										
										
											2021-08-26 21:30:35 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |   public async updateRequiredStatus() { | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |     console.log('checking the required status.'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 13:51:55 +02:00
										 |  |  |     let requiredOK = true; | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |     for (const childArg of this.getFormElements()) { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:51:55 +02:00
										 |  |  |       if (childArg.required && !childArg.value) { | 
					
						
							|  |  |  |         requiredOK = false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-15 13:10:28 +02:00
										 |  |  |     if (this.getSubmitButton()) { | 
					
						
							|  |  |  |       this.getSubmitButton().disabled = !requiredOK; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-08-25 13:51:55 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-03 11:26:15 +01:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * collects the form data | 
					
						
							|  |  |  |    * @returns | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |   public async collectFormData() { | 
					
						
							|  |  |  |     const children = this.getFormElements(); | 
					
						
							| 
									
										
										
										
											2025-06-19 11:39:16 +00:00
										 |  |  |     const valueObject: { [key: string]: string | number | boolean | any[] | File[] | { option: string; key: string; payload?: any } } = {}; | 
					
						
							| 
									
										
										
										
											2025-06-22 20:32:59 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |     for (const child of children) { | 
					
						
							| 
									
										
										
										
											2023-08-28 09:49:51 +02:00
										 |  |  |       if (!child.key) { | 
					
						
							|  |  |  |         console.log(`form element with label "${child.label}" has no key. skipping.`); | 
					
						
							| 
									
										
										
										
											2025-06-22 20:32:59 +00:00
										 |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2023-08-28 09:49:51 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2025-06-22 20:32:59 +00:00
										 |  |  |        | 
					
						
							| 
									
										
										
										
											2025-06-26 15:08:14 +00:00
										 |  |  |       valueObject[child.key] = child.value; | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-06-22 20:32:59 +00:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |     return valueObject; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 00:25:14 +02:00
										 |  |  |   public async gatherAndDispatch() { | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |     const valueObject = await this.collectFormData(); | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  |     const formDataEvent = new CustomEvent('formData', { | 
					
						
							|  |  |  |       detail: { | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |         data: valueObject, | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  |       }, | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |       bubbles: true, | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  |     }); | 
					
						
							|  |  |  |     this.dispatchEvent(formDataEvent); | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |     console.log('dispatched data:'); | 
					
						
							| 
									
										
										
										
											2021-08-25 13:51:55 +02:00
										 |  |  |     console.log(valueObject); | 
					
						
							| 
									
										
										
										
											2020-09-13 16:24:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-08-26 21:30:35 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |   public setStatus( | 
					
						
							|  |  |  |     visualStateArg: 'normal' | 'pending' | 'error' | 'success', | 
					
						
							|  |  |  |     textStateArg: string | 
					
						
							|  |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |     const inputChildren = this.getFormElements(); | 
					
						
							| 
									
										
										
										
											2021-08-26 21:30:35 +02:00
										 |  |  |     const submitButton = this.getSubmitButton(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |     switch (visualStateArg) { | 
					
						
							| 
									
										
										
										
											2021-09-15 00:59:50 +02:00
										 |  |  |       case 'normal': | 
					
						
							|  |  |  |         submitButton.disabled = false; | 
					
						
							|  |  |  |         submitButton.status = 'normal'; | 
					
						
							|  |  |  |         for (const inputChild of inputChildren) { | 
					
						
							|  |  |  |           inputChild.disabled = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-08-27 13:38:08 +02:00
										 |  |  |       case 'pending': | 
					
						
							| 
									
										
										
										
											2021-08-26 21:30:35 +02:00
										 |  |  |         submitButton.disabled = true; | 
					
						
							| 
									
										
										
										
											2021-08-27 13:38:08 +02:00
										 |  |  |         submitButton.status = 'pending'; | 
					
						
							|  |  |  |         for (const inputChild of inputChildren) { | 
					
						
							|  |  |  |           inputChild.disabled = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 'success': | 
					
						
							|  |  |  |         submitButton.disabled = true; | 
					
						
							|  |  |  |         submitButton.status = 'success'; | 
					
						
							| 
									
										
										
										
											2021-08-26 21:30:35 +02:00
										 |  |  |         for (const inputChild of inputChildren) { | 
					
						
							|  |  |  |           inputChild.disabled = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  |       case 'error': | 
					
						
							|  |  |  |         submitButton.disabled = true; | 
					
						
							|  |  |  |         submitButton.status = 'error'; | 
					
						
							|  |  |  |         for (const inputChild of inputChildren) { | 
					
						
							|  |  |  |           inputChild.disabled = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-08-26 21:30:35 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     submitButton.text = textStateArg; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-04-12 02:47:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-01 14:21:15 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * resets the form | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   reset() { | 
					
						
							|  |  |  |     const inputChildren = this.getFormElements(); | 
					
						
							|  |  |  |     const submitButton = this.getSubmitButton(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const inputChild of inputChildren) { | 
					
						
							|  |  |  |       inputChild.value = null; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this.setStatus('normal', 'Submit'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |   public async addBehaviours() { | 
					
						
							|  |  |  |     // Use event delegation
 | 
					
						
							|  |  |  |     this.addEventListener('keydown', (event: KeyboardEvent) => { | 
					
						
							|  |  |  |       const target = event.target as DeesElement; | 
					
						
							|  |  |  |       if (!FORM_INPUT_TYPES.includes(target.constructor as any)) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (event.key === 'Enter') { | 
					
						
							|  |  |  |         const children = this.getFormElements(); | 
					
						
							|  |  |  |         const currentIndex = children.indexOf(target as any); | 
					
						
							|  |  |  |         if (currentIndex < children.length - 1) { | 
					
						
							|  |  |  |           children[currentIndex + 1].focus(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           target.blur(); | 
					
						
							|  |  |  |           this.getSubmitButton()?.focus(); | 
					
						
							| 
									
										
										
										
											2023-04-12 02:47:45 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-19 11:47:45 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2023-04-12 02:47:45 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2025-06-19 09:41:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Updates the layout mode of child input components based on form's horizontalLayout property | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   private updateChildrenLayoutMode() { | 
					
						
							|  |  |  |     const formChildren = this.getFormElements(); | 
					
						
							|  |  |  |     for (const child of formChildren) { | 
					
						
							|  |  |  |       if ('layoutMode' in child) { | 
					
						
							|  |  |  |         // The child's auto mode will detect this form's horizontal-layout attribute
 | 
					
						
							|  |  |  |         (child as any).layoutMode = 'auto'; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Called when properties change | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   updated(changedProperties: Map<string, any>) { | 
					
						
							|  |  |  |     super.updated(changedProperties); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if (changedProperties.has('horizontalLayout')) { | 
					
						
							|  |  |  |       this.updateChildrenLayoutMode(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-08-27 14:02:37 +02:00
										 |  |  | } |