2021-03-28 22:24:24 +02:00
|
|
|
import FlexContainer from "../widgets/containers/flex_container.js";
|
2021-05-24 22:29:49 +02:00
|
|
|
import GlobalMenuWidget from "../widgets/buttons/global_menu.js";
|
2020-04-25 23:52:13 +02:00
|
|
|
import TabRowWidget from "../widgets/tab_row.js";
|
2024-12-06 22:12:27 +02:00
|
|
|
import TitleBarButtonsWidget from "../widgets/title_bar_buttons.js";
|
2021-06-03 22:23:11 +02:00
|
|
|
import LeftPaneContainer from "../widgets/containers/left_pane_container.js";
|
2020-04-25 23:52:13 +02:00
|
|
|
import NoteTreeWidget from "../widgets/note_tree.js";
|
|
|
|
import NoteTitleWidget from "../widgets/note_title.js";
|
2021-06-03 12:47:13 +02:00
|
|
|
import OwnedAttributeListWidget from "../widgets/ribbon_widgets/owned_attribute_list.js";
|
2021-05-24 22:29:49 +02:00
|
|
|
import NoteActionsWidget from "../widgets/buttons/note_actions.js";
|
2020-04-25 23:52:13 +02:00
|
|
|
import NoteDetailWidget from "../widgets/note_detail.js";
|
2021-06-03 12:47:13 +02:00
|
|
|
import RibbonContainer from "../widgets/containers/ribbon_container.js";
|
|
|
|
import PromotedAttributesWidget from "../widgets/ribbon_widgets/promoted_attributes.js";
|
|
|
|
import InheritedAttributesWidget from "../widgets/ribbon_widgets/inherited_attribute_list.js";
|
2020-11-25 23:18:30 +01:00
|
|
|
import NoteListWidget from "../widgets/note_list.js";
|
2021-06-03 12:47:13 +02:00
|
|
|
import SearchDefinitionWidget from "../widgets/ribbon_widgets/search_definition.js";
|
2020-12-29 22:27:31 +01:00
|
|
|
import SqlResultWidget from "../widgets/sql_result.js";
|
|
|
|
import SqlTableSchemasWidget from "../widgets/sql_table_schemas.js";
|
2021-06-03 12:47:13 +02:00
|
|
|
import FilePropertiesWidget from "../widgets/ribbon_widgets/file_properties.js";
|
|
|
|
import ImagePropertiesWidget from "../widgets/ribbon_widgets/image_properties.js";
|
|
|
|
import NotePropertiesWidget from "../widgets/ribbon_widgets/note_properties.js";
|
2021-02-13 20:07:08 +01:00
|
|
|
import NoteIconWidget from "../widgets/note_icon.js";
|
2021-02-19 22:15:56 +01:00
|
|
|
import SearchResultWidget from "../widgets/search_result.js";
|
2021-03-28 22:24:24 +02:00
|
|
|
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
|
|
|
|
import RootContainer from "../widgets/containers/root_container.js";
|
2023-05-03 10:23:20 +02:00
|
|
|
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
|
2021-05-17 21:46:18 +02:00
|
|
|
import SpacerWidget from "../widgets/spacer.js";
|
|
|
|
import QuickSearchWidget from "../widgets/quick_search.js";
|
2021-06-03 22:23:11 +02:00
|
|
|
import SplitNoteContainer from "../widgets/containers/split_note_container.js";
|
|
|
|
import LeftPaneToggleWidget from "../widgets/buttons/left_pane_toggle.js";
|
2021-05-24 22:29:49 +02:00
|
|
|
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
|
|
|
|
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
|
2021-06-03 12:47:13 +02:00
|
|
|
import BasicPropertiesWidget from "../widgets/ribbon_widgets/basic_properties.js";
|
|
|
|
import NoteInfoWidget from "../widgets/ribbon_widgets/note_info_widget.js";
|
|
|
|
import BookPropertiesWidget from "../widgets/ribbon_widgets/book_properties.js";
|
2021-09-22 21:11:36 +02:00
|
|
|
import NoteMapRibbonWidget from "../widgets/ribbon_widgets/note_map.js";
|
2021-06-03 12:47:13 +02:00
|
|
|
import NotePathsWidget from "../widgets/ribbon_widgets/note_paths.js";
|
|
|
|
import SimilarNotesWidget from "../widgets/ribbon_widgets/similar_notes.js";
|
2021-06-03 23:34:40 +02:00
|
|
|
import RightPaneContainer from "../widgets/containers/right_pane_container.js";
|
2021-06-15 22:59:13 +02:00
|
|
|
import EditButton from "../widgets/buttons/edit_button.js";
|
2021-07-05 14:56:40 +02:00
|
|
|
import EditedNotesWidget from "../widgets/ribbon_widgets/edited_notes.js";
|
2024-09-12 19:22:41 +08:00
|
|
|
import ShowTocWidgetButton from "../widgets/buttons/show_toc_widget_button.js";
|
|
|
|
import ShowHighlightsListWidgetButton from "../widgets/buttons/show_highlights_list_widget_button.js";
|
2021-09-29 22:10:15 +02:00
|
|
|
import MermaidWidget from "../widgets/mermaid.js";
|
2021-11-24 21:27:55 +01:00
|
|
|
import NoteWrapperWidget from "../widgets/note_wrapper.js";
|
2022-07-21 21:46:47 +02:00
|
|
|
import BacklinksWidget from "../widgets/floating_buttons/zpetne_odkazy.js";
|
2021-12-20 17:30:47 +01:00
|
|
|
import SharedInfoWidget from "../widgets/shared_info.js";
|
2022-05-09 23:13:34 +02:00
|
|
|
import FindWidget from "../widgets/find.js";
|
2022-05-29 21:44:26 +02:00
|
|
|
import TocWidget from "../widgets/toc.js";
|
2023-06-04 17:46:37 +02:00
|
|
|
import HighlightsListWidget from "../widgets/highlights_list.js";
|
2022-06-11 23:29:52 +02:00
|
|
|
import BulkActionsDialog from "../widgets/dialogs/bulk_actions.js";
|
2022-06-12 14:03:59 +02:00
|
|
|
import AboutDialog from "../widgets/dialogs/about.js";
|
2022-06-13 00:00:15 +02:00
|
|
|
import HelpDialog from "../widgets/dialogs/help.js";
|
2022-06-14 22:55:07 +02:00
|
|
|
import RecentChangesDialog from "../widgets/dialogs/recent_changes.js";
|
2022-06-14 23:07:42 +02:00
|
|
|
import BranchPrefixDialog from "../widgets/dialogs/branch_prefix.js";
|
2022-06-14 23:19:41 +02:00
|
|
|
import SortChildNotesDialog from "../widgets/dialogs/sort_child_notes.js";
|
2022-06-14 23:32:16 +02:00
|
|
|
import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js";
|
2022-06-14 23:51:16 +02:00
|
|
|
import IncludeNoteDialog from "../widgets/dialogs/include_note.js";
|
2022-06-15 00:10:32 +02:00
|
|
|
import NoteTypeChooserDialog from "../widgets/dialogs/note_type_chooser.js";
|
2022-06-16 10:42:49 +02:00
|
|
|
import JumpToNoteDialog from "../widgets/dialogs/jump_to_note.js";
|
2022-06-16 11:03:04 +02:00
|
|
|
import AddLinkDialog from "../widgets/dialogs/add_link.js";
|
2022-06-16 14:02:43 +02:00
|
|
|
import CloneToDialog from "../widgets/dialogs/clone_to.js";
|
2022-06-16 14:08:33 +02:00
|
|
|
import MoveToDialog from "../widgets/dialogs/move_to.js";
|
2022-06-16 14:21:24 +02:00
|
|
|
import ImportDialog from "../widgets/dialogs/import.js";
|
2022-06-16 15:04:57 +02:00
|
|
|
import ExportDialog from "../widgets/dialogs/export.js";
|
2022-06-16 15:15:42 +02:00
|
|
|
import MarkdownImportDialog from "../widgets/dialogs/markdown_import.js";
|
2022-06-16 15:28:51 +02:00
|
|
|
import ProtectedSessionPasswordDialog from "../widgets/dialogs/protected_session_password.js";
|
2023-06-04 23:01:40 +02:00
|
|
|
import RevisionsDialog from "../widgets/dialogs/revisions.js";
|
2022-06-16 19:41:29 +02:00
|
|
|
import DeleteNotesDialog from "../widgets/dialogs/delete_notes.js";
|
2022-06-16 19:53:33 +02:00
|
|
|
import InfoDialog from "../widgets/dialogs/info.js";
|
2022-06-16 20:19:26 +02:00
|
|
|
import ConfirmDialog from "../widgets/dialogs/confirm.js";
|
2022-06-16 21:13:09 +02:00
|
|
|
import PromptDialog from "../widgets/dialogs/prompt.js";
|
2022-06-21 23:27:34 +02:00
|
|
|
import FloatingButtons from "../widgets/floating_buttons/floating_buttons.js";
|
|
|
|
import RelationMapButtons from "../widgets/floating_buttons/relation_map_buttons.js";
|
2024-09-01 23:05:06 +03:00
|
|
|
import SvgExportButton from "../widgets/floating_buttons/svg_export_button.js";
|
2022-12-01 10:16:57 +01:00
|
|
|
import LauncherContainer from "../widgets/containers/launcher_container.js";
|
2023-06-04 23:01:40 +02:00
|
|
|
import RevisionsButton from "../widgets/buttons/revisions_button.js";
|
2022-12-20 23:20:59 +01:00
|
|
|
import CodeButtonsWidget from "../widgets/floating_buttons/code_buttons.js";
|
2022-09-17 23:06:17 +02:00
|
|
|
import ApiLogWidget from "../widgets/api_log.js";
|
2022-09-18 14:57:44 +02:00
|
|
|
import HideFloatingButtonsButton from "../widgets/floating_buttons/hide_floating_buttons_button.js";
|
2022-12-20 23:46:44 +01:00
|
|
|
import ScriptExecutorWidget from "../widgets/ribbon_widgets/script_executor.js";
|
2023-05-30 02:24:56 +08:00
|
|
|
import MovePaneButton from "../widgets/buttons/move_pane_button.js";
|
2023-05-09 00:05:27 +02:00
|
|
|
import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js";
|
2023-10-21 00:23:16 +02:00
|
|
|
import CopyImageReferenceButton from "../widgets/floating_buttons/copy_image_reference_button.js";
|
2023-08-15 22:50:13 +02:00
|
|
|
import ScrollPaddingWidget from "../widgets/scroll_padding.js";
|
2024-11-09 09:18:59 +02:00
|
|
|
import ClassicEditorToolbar from "../widgets/ribbon_widgets/classic_editor_toolbar.js";
|
2024-11-23 09:09:09 +02:00
|
|
|
import options from "../services/options.js";
|
2024-12-07 00:20:02 +02:00
|
|
|
import utils from "../services/utils.js";
|
2025-01-20 22:39:48 +02:00
|
|
|
import GeoMapButtons from "../widgets/floating_buttons/geo_map_button.js";
|
2025-02-02 20:44:36 +02:00
|
|
|
import ContextualHelpButton from "../widgets/floating_buttons/help_button.js";
|
2025-02-14 18:18:28 +02:00
|
|
|
import CloseZenButton from "../widgets/close_zen_button.js";
|
2020-02-06 21:47:31 +01:00
|
|
|
|
2021-03-21 23:05:31 +01:00
|
|
|
export default class DesktopLayout {
|
2020-03-16 21:16:09 +01:00
|
|
|
constructor(customWidgets) {
|
|
|
|
this.customWidgets = customWidgets;
|
|
|
|
}
|
|
|
|
|
2020-02-06 21:47:31 +01:00
|
|
|
getRootWidget(appContext) {
|
2022-12-11 13:54:12 +01:00
|
|
|
appContext.noteTreeWidget = new NoteTreeWidget();
|
2020-03-15 21:52:04 +01:00
|
|
|
|
2025-01-09 18:07:02 +02:00
|
|
|
const launcherPaneIsHorizontal = options.get("layoutOrientation") === "horizontal";
|
2024-11-22 21:10:49 +02:00
|
|
|
const launcherPane = this.#buildLauncherPane(launcherPaneIsHorizontal);
|
2025-01-09 18:07:02 +02:00
|
|
|
const isElectron = utils.isElectron();
|
|
|
|
const isMac = window.glob.platform === "darwin";
|
|
|
|
const isWindows = window.glob.platform === "win32";
|
|
|
|
const hasNativeTitleBar = window.glob.hasNativeTitleBar;
|
2024-12-07 00:14:05 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If true, the tab bar is displayed above the launcher pane with full width; if false (default), the tab bar is displayed in the rest pane.
|
|
|
|
* On macOS we need to force the full-width tab bar on Electron in order to allow the semaphore (window controls) enough space.
|
|
|
|
*/
|
2025-01-09 18:07:02 +02:00
|
|
|
const fullWidthTabBar = launcherPaneIsHorizontal || (isElectron && !hasNativeTitleBar && isMac);
|
|
|
|
const customTitleBarButtons = !hasNativeTitleBar && !isMac && !isWindows;
|
2024-11-22 20:36:08 +02:00
|
|
|
|
2024-12-04 23:16:03 +02:00
|
|
|
return new RootContainer(true)
|
2020-02-27 12:26:42 +01:00
|
|
|
.setParent(appContext)
|
2024-11-28 21:28:37 +02:00
|
|
|
.class((launcherPaneIsHorizontal ? "horizontal" : "vertical") + "-layout")
|
2025-01-09 18:07:02 +02:00
|
|
|
.optChild(
|
|
|
|
fullWidthTabBar,
|
|
|
|
new FlexContainer("row")
|
|
|
|
.class("tab-row-container")
|
|
|
|
.child(new FlexContainer("row").id("tab-row-left-spacer"))
|
|
|
|
.optChild(launcherPaneIsHorizontal, new LeftPaneToggleWidget(true))
|
|
|
|
.child(new TabRowWidget().class("full-width"))
|
|
|
|
.optChild(customTitleBarButtons, new TitleBarButtonsWidget())
|
|
|
|
.css("height", "40px")
|
|
|
|
.css("background-color", "var(--launcher-pane-background-color)")
|
|
|
|
.setParent(appContext)
|
2021-05-17 21:46:18 +02:00
|
|
|
)
|
2024-11-22 21:37:54 +02:00
|
|
|
.optChild(launcherPaneIsHorizontal, launcherPane)
|
2025-01-09 18:07:02 +02:00
|
|
|
.child(
|
|
|
|
new FlexContainer("row")
|
2024-11-22 21:05:45 +02:00
|
|
|
.css("flex-grow", "1")
|
2025-01-09 18:07:02 +02:00
|
|
|
.id("horizontal-main-container")
|
|
|
|
.optChild(!launcherPaneIsHorizontal, launcherPane)
|
|
|
|
.child(
|
|
|
|
new LeftPaneContainer()
|
|
|
|
.optChild(!launcherPaneIsHorizontal, new QuickSearchWidget())
|
|
|
|
.child(appContext.noteTreeWidget)
|
|
|
|
.child(...this.customWidgets.get("left-pane"))
|
2024-11-22 21:05:45 +02:00
|
|
|
)
|
2025-01-09 18:07:02 +02:00
|
|
|
.child(
|
|
|
|
new FlexContainer("column")
|
|
|
|
.id("rest-pane")
|
|
|
|
.css("flex-grow", "1")
|
|
|
|
.optChild(!fullWidthTabBar, new FlexContainer("row").child(new TabRowWidget()).optChild(customTitleBarButtons, new TitleBarButtonsWidget()).css("height", "40px"))
|
|
|
|
.child(
|
|
|
|
new FlexContainer("row")
|
|
|
|
.filling()
|
|
|
|
.collapsible()
|
|
|
|
.id("vertical-main-container")
|
|
|
|
.child(
|
|
|
|
new FlexContainer("column")
|
|
|
|
.filling()
|
|
|
|
.collapsible()
|
|
|
|
.id("center-pane")
|
|
|
|
.child(
|
|
|
|
new SplitNoteContainer(() =>
|
|
|
|
new NoteWrapperWidget()
|
|
|
|
.child(
|
|
|
|
new FlexContainer("row")
|
|
|
|
.class("title-row")
|
|
|
|
.css("height", "50px")
|
|
|
|
.css("min-height", "50px")
|
|
|
|
.css("align-items", "center")
|
|
|
|
.cssBlock(".title-row > * { margin: 5px; }")
|
|
|
|
.child(new NoteIconWidget())
|
|
|
|
.child(new NoteTitleWidget())
|
|
|
|
.child(new SpacerWidget(0, 1))
|
|
|
|
.child(new MovePaneButton(true))
|
|
|
|
.child(new MovePaneButton(false))
|
|
|
|
.child(new ClosePaneButton())
|
|
|
|
.child(new CreatePaneButton())
|
|
|
|
)
|
|
|
|
.child(
|
|
|
|
new RibbonContainer()
|
|
|
|
// the order of the widgets matter. Some of these want to "activate" themselves
|
|
|
|
// when visible. When this happens to multiple of them, the first one "wins".
|
|
|
|
// promoted attributes should always win.
|
|
|
|
.ribbon(new ClassicEditorToolbar())
|
|
|
|
.ribbon(new ScriptExecutorWidget())
|
|
|
|
.ribbon(new SearchDefinitionWidget())
|
|
|
|
.ribbon(new EditedNotesWidget())
|
|
|
|
.ribbon(new BookPropertiesWidget())
|
|
|
|
.ribbon(new NotePropertiesWidget())
|
|
|
|
.ribbon(new FilePropertiesWidget())
|
|
|
|
.ribbon(new ImagePropertiesWidget())
|
|
|
|
.ribbon(new BasicPropertiesWidget())
|
|
|
|
.ribbon(new OwnedAttributeListWidget())
|
|
|
|
.ribbon(new InheritedAttributesWidget())
|
|
|
|
.ribbon(new NotePathsWidget())
|
|
|
|
.ribbon(new NoteMapRibbonWidget())
|
|
|
|
.ribbon(new SimilarNotesWidget())
|
|
|
|
.ribbon(new NoteInfoWidget())
|
|
|
|
.button(new RevisionsButton())
|
|
|
|
.button(new NoteActionsWidget())
|
|
|
|
)
|
|
|
|
.child(new SharedInfoWidget())
|
|
|
|
.child(new WatchedFileUpdateStatusWidget())
|
|
|
|
.child(
|
|
|
|
new FloatingButtons()
|
|
|
|
.child(new EditButton())
|
|
|
|
.child(new ShowTocWidgetButton())
|
|
|
|
.child(new ShowHighlightsListWidgetButton())
|
|
|
|
.child(new CodeButtonsWidget())
|
|
|
|
.child(new RelationMapButtons())
|
2025-01-20 22:39:48 +02:00
|
|
|
.child(new GeoMapButtons())
|
2025-01-09 18:07:02 +02:00
|
|
|
.child(new CopyImageReferenceButton())
|
|
|
|
.child(new SvgExportButton())
|
|
|
|
.child(new BacklinksWidget())
|
2025-02-02 20:44:36 +02:00
|
|
|
.child(new ContextualHelpButton())
|
2025-01-09 18:07:02 +02:00
|
|
|
.child(new HideFloatingButtonsButton())
|
|
|
|
)
|
|
|
|
.child(new MermaidWidget())
|
|
|
|
.child(
|
|
|
|
new ScrollingContainer()
|
|
|
|
.filling()
|
|
|
|
.child(new PromotedAttributesWidget())
|
|
|
|
.child(new SqlTableSchemasWidget())
|
|
|
|
.child(new NoteDetailWidget())
|
|
|
|
.child(new NoteListWidget())
|
|
|
|
.child(new SearchResultWidget())
|
|
|
|
.child(new SqlResultWidget())
|
|
|
|
.child(new ScrollPaddingWidget())
|
|
|
|
)
|
|
|
|
.child(new ApiLogWidget())
|
|
|
|
.child(new FindWidget())
|
|
|
|
.child(
|
|
|
|
...this.customWidgets.get("node-detail-pane"), // typo, let's keep it for a while as BC
|
|
|
|
...this.customWidgets.get("note-detail-pane")
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.child(...this.customWidgets.get("center-pane"))
|
|
|
|
)
|
|
|
|
.child(
|
|
|
|
new RightPaneContainer()
|
|
|
|
.child(new TocWidget())
|
|
|
|
.child(new HighlightsListWidget())
|
|
|
|
.child(...this.customWidgets.get("right-pane"))
|
|
|
|
)
|
2021-06-03 23:34:40 +02:00
|
|
|
)
|
2020-12-27 22:19:27 +01:00
|
|
|
)
|
2022-06-11 23:29:52 +02:00
|
|
|
)
|
2022-06-12 14:03:59 +02:00
|
|
|
.child(new BulkActionsDialog())
|
2022-06-12 19:38:28 +02:00
|
|
|
.child(new AboutDialog())
|
2022-06-14 22:55:07 +02:00
|
|
|
.child(new HelpDialog())
|
2022-06-14 23:00:24 +02:00
|
|
|
.child(new RecentChangesDialog())
|
2022-06-14 23:19:41 +02:00
|
|
|
.child(new BranchPrefixDialog())
|
2022-06-14 23:32:16 +02:00
|
|
|
.child(new SortChildNotesDialog())
|
2022-06-14 23:51:16 +02:00
|
|
|
.child(new PasswordNoteSetDialog())
|
2022-06-15 00:10:32 +02:00
|
|
|
.child(new IncludeNoteDialog())
|
2022-06-16 10:42:49 +02:00
|
|
|
.child(new NoteTypeChooserDialog())
|
2022-06-16 11:03:04 +02:00
|
|
|
.child(new JumpToNoteDialog())
|
2022-06-16 14:02:43 +02:00
|
|
|
.child(new AddLinkDialog())
|
2022-06-16 14:08:33 +02:00
|
|
|
.child(new CloneToDialog())
|
2022-06-16 14:21:24 +02:00
|
|
|
.child(new MoveToDialog())
|
2022-06-16 15:04:57 +02:00
|
|
|
.child(new ImportDialog())
|
2022-06-16 15:15:42 +02:00
|
|
|
.child(new ExportDialog())
|
2023-05-09 00:05:27 +02:00
|
|
|
.child(new UploadAttachmentsDialog())
|
2022-06-16 15:28:51 +02:00
|
|
|
.child(new MarkdownImportDialog())
|
2022-06-16 19:29:18 +02:00
|
|
|
.child(new ProtectedSessionPasswordDialog())
|
2023-06-04 23:01:40 +02:00
|
|
|
.child(new RevisionsDialog())
|
2022-06-16 19:53:33 +02:00
|
|
|
.child(new DeleteNotesDialog())
|
2022-06-16 20:19:26 +02:00
|
|
|
.child(new InfoDialog())
|
2022-06-16 21:13:09 +02:00
|
|
|
.child(new ConfirmDialog())
|
2025-02-14 18:18:28 +02:00
|
|
|
.child(new PromptDialog())
|
|
|
|
.child(new CloseZenButton())
|
2020-02-06 21:47:31 +01:00
|
|
|
}
|
2024-11-22 21:10:49 +02:00
|
|
|
|
|
|
|
#buildLauncherPane(isHorizontal) {
|
2025-01-09 18:07:02 +02:00
|
|
|
let launcherPane;
|
2024-11-22 21:10:49 +02:00
|
|
|
|
|
|
|
if (isHorizontal) {
|
2025-01-09 18:07:02 +02:00
|
|
|
launcherPane = new FlexContainer("row").css("height", "53px").class("horizontal").child(new LauncherContainer(true)).child(new GlobalMenuWidget(true));
|
2024-11-22 21:10:49 +02:00
|
|
|
} else {
|
|
|
|
launcherPane = new FlexContainer("column")
|
|
|
|
.css("width", "53px")
|
2024-11-22 21:14:50 +02:00
|
|
|
.class("vertical")
|
2024-11-22 22:44:34 +02:00
|
|
|
.child(new GlobalMenuWidget(false))
|
2024-11-23 00:07:40 +02:00
|
|
|
.child(new LauncherContainer(false))
|
|
|
|
.child(new LeftPaneToggleWidget(false));
|
2024-11-22 21:10:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
launcherPane.id("launcher-pane");
|
|
|
|
return launcherPane;
|
|
|
|
}
|
2020-05-12 12:45:32 +02:00
|
|
|
}
|