Login| Sign Up| Help| Contact|

Patent Searching and Data


Title:
SYSTEM, DEVICE AND METHOD FOR EXCHANGING AND MANAGING MEDIA CONTENT AND MESSAGES
Document Type and Number:
WIPO Patent Application WO/2022/079061
Kind Code:
A1
Abstract:
A first aspect of the invention relates to a system for exchanging and managing media content and messages, the system comprising at least one terminal that forms an application frontend and a server that forms a backend and is connected to a memory. By means of an application program (app, application) stored on the terminal, the terminal, in conjunction with the server, is designed - to make it possible for a user, by means of the terminal, to create or retrieve an image, in particular a photo, and display it on a display of the terminal, - to make it possible for a user at the same time, by means of the terminal, to create or retrieve an audio note and add it to the displayed image using corresponding buttons on a graphical user interface on the display of the terminal, and - to generate a database entry on the server representing a combination of image and accompanying audio note. A second aspect of the invention relates to a system for exchanging and managing media content and messages, the system comprising at least one terminal that forms an application frontend and a server that forms a backend and is connected to a memory. According to the second aspect of the invention, the system is designed - to create a tree-like data structure having nodes and edges connecting the nodes together, media content being assigned to the nodes and the edges reflecting relationship links between the persons represented by the nodes, - and to allocate permissions with respect to the media content assigned to the nodes of the tree-like data structure.

Inventors:
ZIMMERMANN MARCO (DE)
Application Number:
PCT/EP2021/078229
Publication Date:
April 21, 2022
Filing Date:
October 12, 2021
Export Citation:
Click for automatic bibliography generation   Help
Assignee:
RM REMEMBER ME AG (DE)
International Classes:
G06F16/41; G06F16/48; G06F16/51; G06F16/58; G06Q10/10
Foreign References:
US9122645B12015-09-01
US20160205081A12016-07-14
US20030117651A12003-06-26
Other References:
JACK KUSTANOWITZ ET AL: "Motivating Annotation for Personal Digital Photo Libraries: Lowering Barriers While Raising Incentives", TECHNICAL REPORT HCIL-2004-18, 1 January 2004 (2004-01-01), pages 1 - 10, XP055021531, Retrieved from the Internet [retrieved on 20120309]
Attorney, Agent or Firm:
EISENFÜHR SPEISER PATENTANWÄLTE RECHTSANWÄLTE PARTGMBB (DE)
Download PDF:
Claims:
- 48 -

Ansprüche

1. Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten, wobei das Verfahren die folgenden Schritte umfasst:

Erstellen einer baumartigen Datenstruktur mit Knoten (64) und die Knoten (64) miteinander verbindenden Kanten (66), wobei den Knoten (64) Medieninhalte zugeordnet sind und die Kanten (66) Verwandtschaftsbeziehungen zwischen durch die Knoten (64) repräsentierten Personen widerspiegeln, und

Vergeben von Zugriffrechten auf die den Knoten (64) der baumartigen Datenstruktur zugeordneten Medieninhalte.

2. Verfahren nach Anspruch 1 , weiter umfassend die Schritte

Erzeugen einer grafischen Wiedergabe der Baumstruktur auf einer Anzeige (24) eines Endgerätes (20) und

Bereitstellen von Schaltflächen in der grafischen Wiedergabe der Baumstruktur, wobei die Schaltflächen derart konfiguriert sind, dass sie einem Nutzer das Hinzufügen von Text, Daten oder Medieninhalten zu den Knoten (64) der Baumstruktur ermöglichen.

3. Verfahren nach Anspruch 1 oder 2, weiter umfassend die Schritte

Bereitstellen deines Ressource-Description-Framework (RDF), in dem Graphen als Triple aus Knoten-Kante-Knoten repräsentiert sind,

Bilden einer virtuellen Graph Datenstruktur aus den Triplen (Caching),

Analyse der Kanten in der virtuellen Graph Datenstruktur (Analysis)

Errechnen einer hierarchischen baumartigen Datenstruktur aus der virtuellen Graph Datenstruktur und

Transformieren der hierarchischen baumartigen Datenstruktur in eine listenartige Repräsentation einer Baumstruktur (Transformation). - 49 -

4. Verfahren nach Anspruch 3, bei dem die listenartige Repräsentation der Baumstruktur von Listen gebildet ist, die in Matrizen gespeichert sind.

5. Verfahren nach Anspruch 3 oder 4, bei dem das Errechnen der hierarchischen baumartigen Datenstruktur aus der virtuellen Graph Datenstruktur bei jedem Erstellen eines neuen Triples wiederholt wird und eine Bereinigung der Kantendaten und eine Gruppierung von durch die Kantendaten repräsentierten Beziehungen erfolgt.

6. Mobiles Endgerät (20) für den Austausch und das Verwalten von Medieninhalten und Nachrichten, mit einem Datenverarbeitungssystem (26) und mit diesem verbundenen Speicher (28) und verbundener Anzeige (24) dadurch gekennzeichnet, dass das mobile Endgerät mittels eines in dem Speicher (28) des Endgeräts (20) gespeicherten Anwendungsprogramms (App, Applikation) dazu ausgebildet ist, eine grafische Wiedergabe der Baumstruktur auf der Anzeige (24) des Endgerätes (20) zu erzeugen, die Schaltflächen aufweist, die einem Nutzer das Hinzufügen von Text, Daten oder Medieninhalten zu den Knoten (64) der Baumstruktur ermöglichen.

7. System (10) für den Austausch und das Verwalten von Medieninhalten und Nachrichten, umfassend wenigstens ein Endgerät (20), das ein Anwendungs-Frontend bildet, sowie einem Server (12), der ein Backend bildet und mit einem Speicher (14) verbunden ist, wobei das System (10) ausgebildet ist, eine baumartige Datenstruktur mit Knoten (64) und die Knoten (64) miteinander verbindenden Kanten (66) zu erstellen, wobei den Knoten (64) Medieninhalte zugeordnet sind und die Kanten (66) Verwandtschaftsbeziehungen zwischen durch die Knoten (64) repräsentierten Personen widersiegeln, und

Zugriffrechte auf die den Knoten (64) der baumartigen Datenstruktur zugeordneten Medieninhalte zu vergeben.

8. System nach Anspruch 7, dadurch gekennzeichnet, dass das Endgerät (20) mittels eines auf dem Endgerät (20) gespeicherten Anwendungsprogramms (App, Applikation) in Verbindung mit dem Server (12) dazu ausgebildet ist, - 50 - eine grafische Wiedergabe der Baumstruktur auf einer Anzeige (24) des Endgerätes (20) zu erzeugen, die Schaltflächen aufweist, die einem Nutzer das Hinzufügen von Text, Daten oder Medieninhalten zu den Knoten (64) der Baumstruktur ermöglichen.

9. System (10) für den Austausch und das Verwalten von Medieninhalten und Nachrichten, umfassend wenigstens ein Endgerät (20), das ein Anwendungs-Frontend bildet, sowie einem Server (12), der ein Backend bildet und mit einem Speicher (14) verbunden ist, wobei das Endgerät (20) mittels eines auf dem Endgerät (20) gespeicherten Anwendungsprogramms (App, Applikation) in Verbindung mit dem Server (12) dazu ausgebildet ist, es einem Nutzer zu ermöglichen mit dem Endgerät (20) ein Bild, insbesondere ein Foto zu erstellen oder aufzurufen und auf einer Anzeige (24) des Endgeräts (20) darzustellen, es einem Nutzer gleichzeitig zu ermöglichen mit dem Endgerät (20) eine Audionotiz zu erstellen oder aufzurufen und mittels entsprechender Schaltflächen einer grafischen Benutzeroberfläche auf der Anzeige (24) des Endgeräts (20) dem dargestellten Bild hinzuzufügen und einen eine Kombination aus Bild und zugehöriger Audionotiz repräsentierenden Datenbankeintrag auf dem Server (12) zu generieren.

10. System nach Anspruch 9, dadurch gekennzeichnet, dass der Server (12) dazu ausgebildet ist, eine ein Bild repräsentierende Datei und eine zugehörige Audionotiz repräsentierende Datei in dem mit dem Server (12) verbundenen Speicher (14) zu speichern nach dem Speichern der Dateien Metadaten sowie eine Referenz zum Speicherort der beiden das Bild und die zugehörige Audionotiz repräsentierenden Dateien an ein Endgerät (20) zurückzugeben.

11 . Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten, wobei das Verfahren die folgenden Schritte umfasst:

Aufrufen oder Erstellen eines Bildes, insbesondere eines Fotos,

Erstellen einer Audionotiz und hinzufügen der Audionotiz zu einem Foto, - 51 - wobei für das Bild und eine hierzu erstellte Audionotiz eine gemeinsame individuelle Identifikationskennung (ID) generiert wird und zwei ein Bild und zugehörige Audionotiz repräsentierende Dateien über die gemeinsame individuelle Identifikationskennung verknüpft in einer Datenbank auf einem mit einem Server verbundenen Speicher gespeichert werden. Verfahren nach Anspruch 11 , dadurch gekennzeichnet, dass nach einem Speichern eines Bildes mit zugehöriger Audionotiz in dem mit dem Server (12) verbundenen Speicher (14) Metadaten sowie eine Referenz zum Speicherort der beiden das Bild und die zugehörige Audionotiz repräsentierenden Dateien an ein Endgerät (20) zurückgegeben werden. Mobiles Endgerät (20) für den Austausch und das Verwalten von Medieninhalten und Nachrichten, mit einem Datenverarbeitungssystem (26) und mit diesem verbundenen Speicher (28) und verbundener Anzeige (24) dadurch gekennzeichnet, dass das mobile Endgerät mittels eines in dem Speicher (28) des Endgeräts (20) gespeicherten Anwendungsprogramms (App, Applikation) dazu ausgebildet ist, es einem Nutzer zu ermöglichen mit dem Endgerät (20) ein Bild, insbesondere ein Foto zu erstellen oder aufzurufen und auf einer Anzeige (24) des Endgeräts (20) darzustellen, es einem Nutzer gleichzeitig zu ermöglichen mit dem Endgerät (20) eine Audionotiz zu erstellen oder aufzurufen und mittels entsprechender Schaltflächen einer grafischen Benutzeroberfläche auf der Anzeige (24) des Endgeräts (20) dem dargestellten Bild hinzuzufügen und einen eine Kombination aus Bild und zugehöriger Audionotiz repräsentierenden Datenbankeintrag auf dem Server (12) zu generieren. Mobiles Endgerät nach Anspruch 13, dadurch gekennzeichnet, dass das mobile Endgerät mittels eines in dem Speicher (28) des Endgeräts (20) gespeicherten Anwendungsprogramms (App, Applikation) dazu ausgebildet ist, auf der Anzeige (24) ein mit einer Audionotiz verknüpftes Bild durch ein entsprechendes Icon (52) gekennzeichnet dazustellen und zum Auslösen einer Wiedergabe der Audionotiz eine entsprechende Schalfläche (54) bereitzustellen und anzuzeigen.

Description:
System, Vorrichtung und Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten

Die Erfindung betrifft ein System, eine Vorrichtung und Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten.

In Bezug auf die Vorrichtungen umfasst das System ein oder mehrere Endgeräte und ein oder mehrere Server. Die Endgeräte bilden jeweils ein Frontend, während die Server ein Backend bilden.

Systeme aus Servern, die ein Backend bilden, und Endgeräten, beispielsweise mobilen, hosentaschentauglichen Kommunikationsgeräten wie Smartphones, in Verbindung mit einem Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten sind grundsätzlich bekannt. Beispielsweise verwenden soziale Netzwerke derartige Sys- tem, Verfahren und mit einem entsprechenden Anwendungsprogramm (App) ausgestattete

Endgeräte wie persönliche Computer, Tablets oder Smartphones.

Der Erfindung liegt die Ausgabe zugrunde, ein System, eine Vorrichtung und ein Verfahren zu schaffen, die jeweils den Austausch und die Pflege von Informationen und Medieninhalten zu Familienmitgliedern ermöglichen. Dabei soll insbesondere auch dem Bedürfnis nach Beschränkung des Zugangs auf persönliche Informationen mit technischen Mitteln Rechnung getragen werden.

ERSATZBLATT (REGEL 26) Erfindungsgemäß wird hierfür vorgeschlagen, ein Endgerät mittels eines Anwendungsprogramms (App) derart zu konfigurieren, dass ein Nutzer eine oder mehrere von drei Komponenten nutzen, nämlich eine Komponente zum Austauschen von Nachrichten ("Quick"), eine Komponente zum Austauschen von Bildern ("VOP") und/oder eine Komponente zum strukturierten Zusammenstellen und Verwalten von Medieninhalten einschließlich Text ("Stammbaum").

Die drei Komponenten können in Kombination miteinander oder unabhängig voneinander verwirklicht sein und bieten zum Teil Funktionen, wie sie auch aus sozialen Netzen bekannt sind.

Die Vorrichtungen des Systems sind dazu konfiguriert, die drei Komponenten zu verwirklichen. Vorzugsweise werden alle drei Komponenten als Teil einer Anwendung (App) "RemeberMe" auf dem Endgerät eines Nutzers bereitgestellt

Zu den auch einzeln unabhängig voneinander zu verwirklichenden Komponenten:

Die Komponente „Voice over Picture“ ermöglicht es einem Nutzer auf einem Endgerät Fotos - also Standbilder, keine Videos - mit akustischen Notizen zu versehen. Hierzu ist erfindungsgemäß spezielles Datenformat vorgesehen, dass es in Verbindung mit einem entsprechenden Backend unter Anwendung eines entsprechenden Verfahrens erlaubt, dass ein anderer Nutzer auf einem Endgerät ein Foto mit Audionotiz betrachten und die Audionotiz anhören kann. Das Datenformat kombiniert eine herkömmliche Bilddatei in einem herkömmlichen Formatfür Bilder (jpeg, tiff, png ...) mit einer herkömmlichen Tondatei (mp4, mov, mp3, wav, flac ...; bei mp4 oder mov wird nur die Tonspur genutzt). Die Anwendung auf dem Endgerät erlaubt es in Kombination mit dem Backend auf einem Server und dem Verfahren, Sprach- oder Tonnotizen unmittelbar nach Aufnehmen eines Fotos dem Foto hinzuzufügen oder später - also einem bereits existierenden Foto im Nachhinein - eine Audioinformation einem Foto hinzuzufügen. Ein derartiges Foto mit Ton kann die sonst heute üblichen kurzen Videos ersetzen, die häufig per Messenger verschickt werden und eine statische Filmaufnahme mit entsprechenden Anmerkungen beinhalten.

Hierzu ist das Endgerät in Verbindung mit dem Anwendungsprogramm dazu ausgebildet ein Benutzerinterface zu bieten, das unmittelbar nach dem Aufnehmen eines Fotos das Hinzufügen einer Audionotiz erlaubt und hierfür eine zweite Aufzeichnungsschaltfläche auf-

ERSATZBLATT (REGEL 26) weist. Ebenso biete das Endgerät in Verbindung mit dem Anwendungsprogramm vorzugsweise ein Benutzerinterface, das das nachträgliche Hinzufügen einer Audionotiz zu ausgewählten Fotos erlaubt.

Ein weiterer Aspekt ist das Überführen der Kombination von Foto (beispielsweise im jpeg- Format) und Audionotiz (beispielsweise im mp3-Format) in ein kombiniertes Datenformat (xml) oder auch in ein Videoformat (mp4, mpeg) ein schutzfähiger Aspekt sein. Beim Wandeln der Kombination aus Foto (jpeg) und Ton (mp3) in ein Videoformat würde immer noch in einer sehr kompakten Datei resultieren, da das Video in jedem Frame das gleiche Standbild zeigen würde und daher gut komprimierbar ist.

Gemäß einem weiteren Aspekt ist das Endgerät in Verbindung mit dem Anwendungsprogramm dazu ausgebildet ein Benutzerinterface zu bieten, das es einem anderen Nutzer (also nicht demjenigen, der ein Foto mit einer Audionotiz versehen hat) auf dessen Endgerät erlaubt, eine Audionotiz zu einem Foto zu erkennen und anzuhören. Gemäß diesem Aspekt stellt das Endgerät mit einem entsprechenden Programm ein Foto mit Audionotiz mit einem Icon dar, dass es dem Nutzer anzeigt, dass das Foto mit einer Audionotiz verknüpft ist. Das Endgerät ist in Verbindung mit dem Anwendungsprogramm dazu konfiguriert, dass ein Anklicken des Icons die Wiedergabe der Audionotiz startet.

Die auch unabhängig von der Komponente "Foto mit Audionotiz" verwirklichbare Komponente "Stammbaum" erlaubt es, eine Sammlung von Daten und Inhalten zu Familienmit- gliedern/Verwandten interaktiv und kollektiv bearbeiten und die Daten und Inhalte strukturiert darzustellen, wobei die Stammbaumartige Struktur auch ein grafisches Benutzerinterface bildet.

Für die Komponente "Stammbaum" ist eine Datenbankstruktur vorgesehen, die zusammengehörende Inhalte (beispielsweise Text, Bild und Ton oder aber auch weitere Daten wie User-ID) miteinander verknüpft und einen verzweigten Graph abbildet. Jeder in die Datenbank eingestellte Inhalt ist mit der ID des Einstellenden verknüpft. Die ID des Einstellenden kann auch für die Rechteverwaltung genutzt werden. Eingestellte Inhalte zu einer Person wie beispielsweise Texte, Bilder, Daten (z.B. Geburtsdatum) sind einem Knoten des Graphen zugeordnet. Ein Knoten in dem Graph repräsentiert genau eine Person bzw. die zu dieser Person gehörenden Inhalte.

Im Zusammenhang mit der Komponente „Stammbaum“ sind das Verfahren und das Backend auf einem Server dazu konfiguriert, Inhalte zusammenzuführen und Zugriffrechte zu

ERSATZBLATT (REGEL 26) koordinieren, wenn zwei verschiedene Nutzer für die gleiche Person jeweils einen Eintrag erstellt haben, so dass die Inhalte zu diesem Eintrag gegebenenfalls konsolidiert werden müssen. Auch für die Rechteverwaltung, beispielsweise hinsichtlich des Löschens und des Freigebens ergeben sich noch möglicherweise zu lösende Herausforderungen.

Insbesondere ist das Backend dazu ausgebildet eine von Knoten und Kanten gebildeten Datenstruktur aufrechtzuerhalten und zu verwalten, wobei den Knoten Verlinkungen zu Dateien (z.B. Mediendateien wie Fotos etc.) und Hinweise zu den Kanten sowie eine Berechtigungsliste zugeordnet sind. Die Kanten stellen Information dar, wie die Knoten der Datenstruktur miteinander in Beziehung stehen, d.h. die Kanten verbinden einen Knoten mit einem oder mehreren anderen Knoten, aber nicht mir allen Knoten.

Eine dritte Komponente „Quick“ dient der Kommunikation nach Art eines Messengers. Die Komponente "Quick" zeichnet sich dadurch aus, dass nur wenige Nachrichten gespeichert werden, beispielsweise die letzten vier Nachrichten, die zwei Personen miteinander ausgetauscht haben oder auch nur jeweils eine Nachricht pro Gesprächspartner. Frühere Nachrichten werden vorzugsweise nicht gespeichert und benötigen daher keinen Speicherplatz mehr.

Vorzugsweise werden frühere Nachrichten so gelöscht - oder besser noch: überschrieben -, dass sie nicht mehr rekonstruierbar sind und daher für immer vertraulich bleiben.

Gegebenenfalls können auch alle Nachrichteninhalte von vornherein auf dem Gerät verschlüsselt werden wobei der Schlüssel regelmäßig wechseln könnte, sodass auch gegebenenfalls auf dem Server eines Serviceproviders gespiegelte Inhalte im Nachhinein nicht mehr rekonstruierbar sind, weil der zugehörige Schlüssel zum Entschlüsseln möglicherweise gespiegelter früherer Nachrichten nicht mehr existiert.

Ein erster Aspekt (Voice over Picture) der Erfindung ist somit ein System für den Austausch und das Verwalten von Medieninhalten und Nachrichten, das wenigstens ein Endgerät, das ein Anwendungs-Frontend bildet, sowie einem Server, der ein Backend bildet und mit einem Speicher verbunden ist, umfasst. Das Endgerät ist mittels eines auf dem Endgerät gespeicherten Anwendungsprogramms (App, Applikation) in Verbindung mit dem Server dazu ausgebildet, es einem Nutzer zu ermöglichen mit dem Endgerät ein Bild, insbesondere ein Foto zu erstellen oder aufzurufen und auf einer Anzeige des Endgeräts darzustellen,

ERSATZBLATT (REGEL 26) es einem Nutzer gleichzeitig zu ermöglichen mit dem Endgerät eine Audionotiz zu erstellen oder aufzurufen und mittels entsprechender Schaltflächen einer grafischen Benutzeroberfläche auf der Anzeige des Endgeräts dem dargestellten Bild hinzuzufügen und einen eine Kombination aus Bild und zugehöriger Audionotiz repräsentierenden Datenbankeintrag auf dem Server zu generieren.

Vorzugsweise ist der Server gemäß dem ersten Aspekt dazu ausgebildet, eine ein Bild repräsentierende Datei und eine zugehörige Audionotiz repräsentierende Datei in dem mit dem Server verbundenen Speicher zu speichern nach dem Speichern der Dateien Metadaten sowie eine Referenz zum Speicherort der beiden das Bild und die zugehörige Audionotiz repräsentierenden Dateien an ein Endgerät zurückzugeben.

Ein zweiter Aspekt (Stammbaum) der Erfindung ist ein System für den Austausch und das Verwalten von Medieninhalten und Nachrichten, das wenigstens ein Endgerät, das ein An- wendungs-Frontend bildet, sowie einem Server, der ein Backend bildet und mit einem Speicher verbunden ist, umfasst. Gemäß dem zweiten Aspekt ist das System ausgebildet, eine baumartige Datenstruktur mit Knoten und die Knoten miteinander verbindenden Kanten zu erstellen, wobei den Knoten Medieninhalte zugeordnet sind und die Kanten Verwandtschaftsbeziehungen zwischen durch die Knoten repräsentierten Personen widersiegeln, und

Zugriffrechte auf die den Knoten der baumartigen Datenstruktur zugeordneten Medieninhalte zu vergeben.

Vorzugsweise ist das Endgerät gemäß dem zweiten Aspekt mittels eines auf dem Endgerät gespeicherten Anwendungsprogramms (App, Applikation) in Verbindung mit dem Server dazu ausgebildet, eine grafische Wiedergabe der Baumstruktur auf einer Anzeige des Endgerätes zu erzeugen, die Schaltflächen aufweist, die einem Nutzer das Hinzufügen von Text, Daten oder Medieninhalten zu den Knoten der Baumstruktur ermöglichen.

Gemäß dem ersten Aspekt wird auch ein Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten vorgeschlagen, wobei das Verfahren die folgenden Schritte umfasst:

ERSATZBLATT (REGEL 26) Aufrufen oder Erstellen eines Bildes, insbesondere eines Fotos,

Erstellen einer Audionotiz und hinzufügen der Audionotiz zu einem Foto, wobei für das Bild und eine hierzu erstellte Audionotiz eine gemeinsame individuelle Identifikationskennung (ID) generiert wird und zwei ein Bild und zugehörige Audionotiz repräsentierende Dateien über die gemeinsame individuelle Identifikationskennung verknüpft in einer Datenbank auf einem mit einem Server verbundenen Speicher gespeichert werden.

Vorzugsweise ist es bei dem Verfahren gemäß dem ersten Aspekt vorgesehen, dass nach einem Speichern eines Bildes mit zugehöriger Audionotiz in dem mit dem Server verbundenen Speicher Metadaten sowie eine Referenz zum Speicherort der beiden das Bild und die zugehörige Audionotiz repräsentierenden Dateien an ein Endgerät zurückgegeben werden.

Gemäß dem zweiten Aspekt wird ein Verfahren für den Austausch und das Verwalten von Medieninhalten und Nachrichten vorgeschlagen, wobei das Verfahren die folgenden Schritte umfasst:

Erstellen einer baumartigen Datenstruktur mit Knoten und die Knoten miteinander verbindenden Kanten, wobei den Knoten Medieninhalte zugeordnet sind und die Kanten Verwandtschaftsbeziehungen zwischen durch die Knoten repräsentierten Personen widersiegeln, und

Vergeben von Zugriffrechten auf die den Knoten der baumartigen Datenstruktur zugeordneten Medieninhalte.

Vorzugsweise umfasst das Verfahren gemäß dem zweiten Aspekt weiter die Schritte

Erzeugen einer grafischen Wiedergabe der Baumstruktur auf einer Anzeige des Endgerätes und

Bereitstellen von Schaltflächen in der grafischen Wiedergabe der Baumstruktur, wobei die Schaltflächen derart konfiguriert sind, dass sie einem Nutzer das Hinzufügen von Text, Daten oder Medieninhalten zu den Knoten der Baumstruktur ermöglichen.

ERSATZBLATT (REGEL 26) Vorzugsweise umfasst ein Verfahren gemäß des zweiten Aspekts die Schritte:

Bereitstellen deines Ressource-Description-Framework (RDF), in dem Graphen als Triple aus Knoten-Kante-Knoten repräsentiert sind,

Bilden einer virtuellen Graph Datenstruktur aus den Triplen (Caching),

Analyse der Kanten in der virtuellen Graph Datenstruktur (Analysis)

Errechnen einer hierarchischen baumartigen Datenstruktur aus der virtuellen Graph Datenstruktur und

Transformieren der hierarchischen baumartigen Datenstruktur in eine listenartige Repräsentation einer Baumstruktur (Transformation).

Vorzugsweise ist die listenartige Repräsentation der Baumstruktur von Listen gebildet, die in Form von Matrizen gespeichert sind.

Vorzugsweise wird das Errechnen der hierarchischen baumartigen Datenstruktur aus der virtuellen Graph Datenstruktur bei jedem Erstellen eines neuen Triples wiederholt und es erfolgt eine Bereinigung der Kantendaten und eine Gruppierung von durch die Kantendaten repräsentierten Beziehungen.

Weiterhin wird gemäß dem ersten Aspekt ein mobiles Endgerät für den Austausch und das Verwalten von Medieninhalten und Nachrichten vorgeschlagen, das ein Datenverarbeitungssystem und einen mit diesem verbundenen Speicher und eine ebenfalls mit dem Datenverarbeitungssystem verbundene Anzeige aufweist. Das mobile Endgerät mittels eines in dem Speicher des Endgeräts gespeicherten Anwendungsprogramms (App, Applikation) dazu ausgebildet ist, es einem Nutzer zu ermöglichen mit dem Endgerät ein Bild, insbesondere ein Foto zu erstellen oder aufzurufen und auf einer Anzeige des Endgeräts darzustellen, es einem Nutzer gleichzeitig zu ermöglichen mit dem Endgerät eine Audionotiz zu erstellen oder aufzurufen und mittels entsprechender Schaltflächen einer grafischen Benutzeroberfläche auf der Anzeige des Endgeräts dem dargestellten Bild hinzuzufügen und

ERSATZBLATT (REGEL 26) einen eine Kombination aus Bild und zugehöriger Audionotiz repräsentierenden Datenbankeintrag auf dem Server zu generieren.

Gemäß dem ersten Aspekt ist das mobile Endgerät mittels eines in dem Speicher des Endgeräts gespeicherten Anwendungsprogramms (App, Applikation) vorzugsweise dazu konfiguriert, auf der Anzeige ein mit einer Audionotiz verknüpftes Bild durch ein entsprechendes Icon gekennzeichnet dazustellen und zum Auslösen einer Wiedergabe der Audionotiz eine entsprechende Schalfläche bereitzustellen und anzuzeigen.

Gemäß dem zweiten Aspekt wird ein mobiles Endgerät für den Austausch und das Verwalten von Medieninhalten und Nachrichten, mit einem Datenverarbeitungssystem und mit diesem verbundenen Speicher und verbundener Anzeige vorgeschlagen, das mittels eines in dem Speicher des Endgeräts gespeicherten Anwendungsprogramms (App, Applikation) dazu konfiguriert ist, eine grafische Wiedergabe der Baumstruktur auf der Anzeige des Endgerätes zu erzeugen, die Schaltflächen aufweist, die einem Nutzer das Hinzufügen von Text, Daten oder Medieninhalten zu den Knoten der Baumstruktur ermöglichen.

Die verschiedenen Aspekte der Erfindung sollen nun anhand von Ausführungsbeispielen mit Bezug auf die Abbildungen näher erläutert werden. Von den Abbildungen zeigen:

Figur 1 : eine Übersicht über ein System für den Austausch und das Verwalten von Medieninhalten und Nachrichten gemäß der Erfindung;

Figur 2: ein mobiles Endgerät mit einer Anwendung (Applikation, App), die das mobile Endgerät für den Austausch und das Verwalten von Medieninhalten und Nachrichten im Rahmen des in Figur 1 dargestellten Systems konfiguriert;

Figur 3: eine Illustration eines Erstellungsprozesses für das Erstellen und Hinzufügen einer Audionotiz zu einem Bild (Komponente „Voice over Picture“);

Figur 4: eine Illustration eines Uploadprozesses zum Hochladen und Verfügbarmachen von mit einer Audionotiz versehenen Bildern für andere Nutzer;

Figur 5: eine Darstellung eines grafischen Benutzerinterfaces auf einem mobilen Endgerät die es einem Nutzer erlaubt, ein Bild mit einer Audionotiz zu versehen;

ERSATZBLATT (REGEL 26) Figur 6: eine Illustration der grafischen Benutzeroberfläche während des Erstellens einer Audionotiz zu einem Bild;

Figur 7: eine Illustration der grafischen Benutzeroberfläche nach dem Aufnehmen einer Audionotiz;

Figur 8: eine Illustration der grafischen Benutzeroberfläche zum Prüfen und Hochladen eines mit einer Audionotiz versehenen Bildes;

Figur 9: eine Illustration einer grafischen Benutzeroberfläche auf einem Endgerät eines anderen Nutzers nach dem Abrufen eines mit einer Audionotiz versehenen Bildes;

Figur 10: eine Illustration der grafischen Benutzeroberfläche auf dem Gerät des anderen Nutzers nach Aufrufen eines mit einer Audionotiz versehenen Bildes;

Figur 11 : eine Illustration eines Prozesses (Verfahrens) zum Erstellen einer Baumstruktur, deren Knoten personenzugehörige Inhalte wie Text, Bilder oder Medieninhalte präsentieren und deren Kanten Beziehungen zwischen den durch die Knoten repräsentierten Person repräsentieren;

Figur 12: eine Knoten-ZKantenmatrix, wie sie mit dem in Figur 11 dargestellten Verfahren erstellt und umgewandelt wird;

Figur 13: die Matrix aus Figur 12 mit Inhalten, die Berechtigungen innerhalb eines Berechtigungssystems repräsentieren;

Figur 14: eine Illustration einer grafischen Benutzeroberfläche zur Wiedergabe einer mit dem Verfahren gemäß Figur 11 dargestellten Baumstruktur auf einem Endgerät eines Nutzers;

Figur 15: eine Illustration einer grafischen Benutzeroberfläche auf dem Endgerät eines Nutzers nach Berühren einer Schaltfläche der in Figur 14 dargestellten grafischen Benutzer-oberfläche;

ERSATZBLATT (REGEL 26) Figur 16: eine Illustration einer grafischen Benutzeroberfläche nach dem Berühren einer Schaltfläche der in Figur 15 dargestellten grafischen Benutzeroberfläche; und

Figur 17: eine Illustration einer grafischen Benutzeroberfläche nach Berühren einer Schaltfläche auf der in Figur 16 dargestellten grafischen Benutzeroberfläche.

Ein System 10 zum für den Austausch und das Verwalten von Medieninhalten und Nachrichten umfasst wenigstens einen Server 12, der ein Backend bildet und mit wenigstens einem Speicher 14 verbunden ist. Weitere Bestandteile des Systems 10 sind mehrere persönliche Endgeräte 20 wie beispielsweise Mobiltelefone 20.1 , Tablets 20.2 oder PCs 20.3. Die Systembestandtele sind über Datenverbindungen 16 miteinander verbunden. Die Datenkommunikation zwischen den Geräten erfolgt vorzugsweise über das Internetprotokoll (IP); siehe Figur 1 .

Ein typisches persönliches Endgerät ist beispielsweise ein Mobiltelefon 20.1 mit einer grafischen, berührungsempfindlichen Anzeige 22; siehe Figur 2. Weitere Bestandteile des Mobiltelefons 20.1 sind ein Modem 24 als Schnittstelle für die Datenkommunikation sowie ein Datenverarbeitungssystem (SoC) 26, das mit der Anzeige 22, dem Modem 24 und einem Speicher 28 verbunden ist. In Verbindung mit einem in dem Speicher 28 gespeicherten Anwendungsprogramm sind das Datenverarbeitungssystem 26 und damit das mobile Endgerät 20.1 dazu konfiguriert, eine oder mehrere der folgenden Komponenten

"Quick" als Komponente zum Austauschen von Nachrichten

"Voice over Picture" als Komponente zum Austauschen von Bildern und/oder

"Stammbaum" als Komponente zum strukturierten Zusammenstellen und Verwalten von Medieninhalten einschließlich Text. einer Anwendung "RememberMe" zu verwirklichen.

Zur Struktur und Funktionsweise der einzelnen Komponenten

Komponente "Voice over Picture" (VOP)

ERSATZBLATT (REGEL 26) Bei der Komponente "Voice over Picture" handelt es sich um eine Funktion die es einem Nutzer erlaubt durch die App / Webseite RememberMe (im folgenden RM) Tonaufnahmen über das zur Ausführung verwendete Endgerät (Handy, Tablet oder PC) aufzunehmen und diese Bilder zu hinterlegen. Diese werden durch die App dargestellt und können vom Nutzer sowie den Nutzer des geteilten Inhaltes per Knopfdruck wiedergegeben werden.

Das Voice over Pictures (VOP) dient als zusätzliches Dateiformat zur Content Generierung von Nutzern der RememberMe Applikation und ermöglicht entgegen der bestehenden Formate (Bild/Video) die Kombination aus aufgenommener Sprache / Geräuschen mit einem vorhandenen Bild. Dies dient somit der Erweiterung des audio-visuellen Angebots der RememberMe Applikation.

Dieses Format kann zusätzlich mit einer Textnachricht kombiniert werden und dient somit dem Austausch von Nutzern innerhalb der RememberMe Applikation.

Das Erstellen und Hinzufügen einer Audionotiz zu einem Bild erfolgt vorzugsweise gemäß folgendem Erstellungsprozess:

Der in Figur 3 dargestellte Erstellungsprozess wird mit dem Drücken und Halten der Aufzeichnungsschaltfläche 32 der in Figur 5 dargestellten grafischen Benutzeroberfläche 30.1 (AudioRecorderViews (Quellcode 1)) gestartet. Dies erstellt einen passenden Systemordner welcher folglich als Speicherplatz für die zu entstehenden Aufnahmen dient. Während des Gedrückthaltens (Figur 6) der Aufzeichnungsschaltfläche 32 werden alle Audiosignale des benutzten Endgeräts nach Einholen der hierfür notwendigen Berechtigungen aufgenommen und in einer Audiodatei fortwährend gespeichert. Systemabhängig handelt es sich hierbei vorzugsweise um Audiodateien im mp4 (Android) oder .mov Format (iOS). Ausgelöst durch das Loslassen der Aufzeichnungsschaltfläche wird die Datei am hierfür vorgesehenen Platz gespeichert. Das Signal zum Ende der Aufzeichnung wird des Weiteren dafür genutzt die Darstellung des Front-Ends zu ändern und diverse Stati (siehe Figur 3) zu ändern. Nach dem Erstellen einer Audionotiz hat der Nutzer über entsprechende Schaltflächen 36 und 38 auf der grafischen Benutzeroberfläche 30.3 die Möglichkeit, die erstellte Audionotiz zu übernehmen (36) oder zu verwerfen (38), siehe Figur 7.

Die grafische Benutzeroberfläche 30.1 umfasst auch eine Wiedergabe 34 des mit einer Audionotiz zu versehenden Bildes sowie weitere, nicht aktive Schaltflächen; siehe Figur 5.

ERSATZBLATT (REGEL 26) Nach Bestätigung der Auswahl (Figur 7) mittels der Schaltfläche 36 wird eine Referenz zur Audiodatei in Form eines Dateipfads an die restliche Applikation (hier ImageSelect) übergeben und für den Nutzer zum erneuten Anhören bereitgestellt (Figur 8). Hierzu weist die grafische Benutzeroberfläche 30.4 eine Schaltfläche 40 zum Starten der Wiedergabe der Audionotiz auf. Mit Bestätigung durch Berühren einer Teilen-Schaltfläche 42 auf der grafischen Benutzeroberfläche 30.4 werden Bild und Audio Daten an den Upload Prozess übergeben; siehe Figur 8.

Das Hochladen und Verfügbarmachen von mit Audionotiz versehenen Bildern für andere Nutzer erfolgt vorzugsweise gemäß folgendem Upload Prozess:

Daten zu Bild und Audiodatei werden entsprechend der Vorgaben des Cloud Speichers 14 für den Upload vorbereitet. Im ersten Schritt werden Content Referenzen für die später in die Datenbank zu schreibenden Einträge erstellt (siehe PrelimPostProps - Quellcode 2). Eine individuelle ID wird hierbei allen Media Elementen zur Identifikation ihrer einzelnen Komponenten (Bild und Audio) mitgegeben. Diese dient der Identifikation nach dem erfolgreichen Upload in den Cloud Speicher und ermöglicht deren Zuordnung zu einzelnen „Posts“ (siehe PostDataProps - Quellcode 2). Des Weiteren beinhaltet dies die Vergabe formatneutraler Suffixe sowie das Bestimmen des von der Anwendung zum Anzeigen von Fotos auf dem Endgerät ("Galerie") abhängigen Upload Pfade. Vorzugsweise werden Daten im Zuge des Uploads serverseitig verschlüsselt, Bilder werden vorzugsweise automatisch für die weitere Verwendung heruntergerechnet; siehe Figur 4.

Nach erfolgreichem Upload werden Metadaten sowie eine Referenz zum Speicherort der Dateien zurückgegeben. Diese Informationen werden nach erfolgreichem Upload mit Informationen zu Text, Autor und den Dimensionen des Bildes kombiniert und daraus die für den Datenbankeintrag nötige Struktur erstellt. Nach erfolgreichem Speichern der Referenzen in der Datenbank wird der Post für Nutzer freigegeben und wird im Frontend dargestellt. Eine Aufzeichnung ist hierbei geräteunabhängig und kann nur von für den Post freigegebenen Personen gesehen und wiedergebeben werden. Eine Steuerung der Lautstärke der Wiedergabe erfolgt hierbei über die Steuermechanismen des abspielenden Gerätes.

Die Komponente "Voice over Picture" kann mit folgendem Quellcode realisiert werden:

ERSATZBLATT (REGEL 26) Quellcode 1 : AudioRecorder Subkomponente import React, { useEffect, useState } from "react"; import { Dimensions, Platform, Text, View } from "react-native"; import AudioRecorderPlayer, {

AudioEncoderAndroidType,

AudioSet,

AudioSourceAndroidType,

AVEncoderAudioQualitylOSType,

AVEncodingOption,

} from "react-native-audio-recorder-player"; import { MediaElement } from "../../../types/MediaElement"; import { colors } from "../../feed"; import { TinylmageList } from "../../post/components/TinylmageList"; import { getRandomString } from "../../shared/utils/randomString"; import { Player } from "../components/Player"; import { PlayerView } from "../components/PlayerView"; import { RecorderView } from "../components/RecorderView"; import { create VoiceDirectory, directoryPathAndroid, directoryPathlos,

} from "../utils/audioRecorder"; import { styles } from "./styles"; import { Media } from "../../../types/Post"; const tinylmageSize = (Dimensions.get("window").width - 86) 16; const audioRecorderPlayer = new AudioRecorderPlayerO; export function AudioRecorderView(props: AudioRecorderViewProps) {

// Leave unused states as they will be used in future views! const { addToPost, setSelected Index, selected Index, images } = props; const [recordSecs, setRecordSecs] = useState(O); const [recording, setRecording] = useState(false); const [recordTime, setRecordTime] = useState("00:00"); const [playTime, setPlayTime] = useState("00:00"); const [duration, setDuration] = useState("00:00"); const [currentPositionSec, setCurrentPositionSec] = useState(O); const [currentDurationSec, setCurrentDurationSec] = useState(O); const [uri, setllri] = useStatef'"); const [hasRecorded, setHasRecorded] = useState(false); const [selected, setSelected] = useState(false); useEffect(O => { if (lhasRecorded) { setSelected(false);

}

}, [hasRecorded]); useEffect(O => { if (Iselected) { setHasRecorded(false);

}

}, [selected]);

ERSATZBLATT (REGEL 26) function addUrlO { if (uri) { setSelected(true); setPlayTime("00:00"); setDuration(recordTime); addToPost(selectedlndex, uri);

}

} async function onStartRecordO {

// audioRecorderPlayer = new AudioRecorderPlayerO; setHasRecorded(false); create VoiceDirectoryO; const path = Platform.select({ ios: '/${getRandomString(24)}.mp4', android: '${directoryPathAndroid}/${getRandomString(24)}.mp4', // should give extra dir name in android. Won't grant permission to the first level of dir.

}); const audioSet: AudioSet = {

AudioEncoderAndroid: AudioEncoderAndroidType.AAC,

AudioSourceAndroid: AudioSourceAndroidType.MIC,

AVEncoderAudioQualityKeylOS: AVEncoderAudioQualitylOSType.high,

AVNumberOfChannelsKeylOS: 2,

AVFormatIDKeylOS: AVEncodingOption.aac,

}; const uri = await audioRecorderPlayer.startRecorder(path, true, audioSet); audioRecorderPlayer.addRecordBackListener((e) => { setRecordTime( audioRecorderPlayer

.mmssss(Math.floor(e.current_position))

.substring^, 5)

);

});

} async function onStopO { return audioRecorderPlayer.stopPlayerO;

} async function onPlayO { await audioRecorderPlayer.startPlayer(uri); audioRecorderPlayer.addPlayBackListener((e) => { if (e.current_position === e. duration) { onStopO;

} setCurrentPositionSec(e. position); setCurrentDurationSec(e. duration); setPlayTime( audioRecorderPlayer

.mmssss(Math.floor(e.current_position))

.substring^, 5)

ERSATZBLATT (REGEL 26) ); setDuration( audioRecorderPlayer.mmssss(Math.floor(e. duration)). substring^, 5) );

});

} async function onStopRecordO { setHasRecorded(true); setRecording(false); const result = await audioRecorderPlayer.stopRecorderO; audioRecorderPlayer. removeRecordBackListenerO; return result;

} function onPressInO { setRecording(true); onStartRecord().catch((err) => console. log(err));

} function onPressOutO { onStopRecordO

,then((result) => { setUri(result); setRecording(false);

})

,catch((err) => console. log(err));

} return (

<View style={styles.container}> cTinylmageList images={images} setSelectedlndex={setSelectedlndex} selectedlndex={selectedlndex} scrollViewStyles={{ backgroundcolor: colors. black, marginBottom: 16, maxHeight: tinylmageSize + 16,

}} contentStyles={{ paddingHorizontal: 8 }}

/>

{hasRecorded && selected ? (

<View style={{ flex: 3, width: "100%" }}>

<Player onPlay={onPlay} setSelected={setSelected} playTime={playTime} duration={duration}

/>

</View>

) : (

<View sty le={{ flex: 3 }} />

)}

ERSATZBLATT (REGEL 26) {Iselected && (

<View style={{ flex: 2, width: "100%", alignltems: "center", }}

<View style={{ height: 30, marginBottom: 10 }}> {(recording || hasRecorded) && (

<Text style={[

{ lineHeight: 30,

}, recording

? { color: colors. redCheeks } : { color: colors. poolside },

]}

{recordTime}

</Text>

)} </View> {! hasRecorded ? ( <RecorderView onPressln={onPressln} onPressOut={onPressOut} hasRecorded={hasRecorded} recording={recording}

/>

) : (

<PlayerView onPlay={onPlay} addUrl={addUrl} setHasRecorded={setHasRecorded} setRecording={setRecording} setRecordTime={setRecordTime} />

)}

</View>

)}

</View>

);

} interface AudioRecorderViewProps { images: Media[]; addToPost: (index: number, audioUrl: string) => any; setSelectedlndex: (index: number) => any; selected Index: number;

}

Durch Betätigen der Schaltflächen können unmittelbar oder mittelbar die folgenden Funktionen aufgerufen bzw. Parameter erstellt oder abgerufen werden:

ERSATZBLATT (REGEL 26)

QuellCode 2: PostTypen

/*

Post

*/ import * as PostStructure from "../../functions/src/types/PostStructure"; import { TimestampType } from "../config/firebase"; import { Gallery } from "./Gallery"; import * as MediaElement from "./MediaElement"; export type MediaType = "image" | "video" | "audio"; export interface Media { path: string; name?: string; type: MediaType;

// Why? That means basically anything.

// Don't we know the structure?

// [key: string]: any;

} export interface PostCollectionDto { text: string; media: Media[];

ERSATZBLATT (REGEL 26) gallery: Gallery;

} export interface PostDataProps { createdAt: TimestampType; author: string; authorUid: string; authorPic?: string; media: MediaElement.MediaElementQ; gallery?: string;

} export interface PrelimPostProps { createdAt: TimestampType; author: string; authorUid: string; authorPic?: string; media: (

| Partial<MediaElement.lmageMediaElement>

I Partial<MediaElement.AudioMediaElement>

I Partial<MediaElement.VideoMediaElement> )[]; gallery?: Gallery; uploading: boolean; error: false;

}

QuellCode 3: Upload Funktionen import { get } from "lodash/fp"; import { Image } from "react-native-svg"; import {

ImageDimensions,

MediaElement,

MediaElementType,

} from "../../../types/MediaElement"; import { auth, Timestamp } from "../../../config/firebase"; import { Gallery } from "../../../types/Gallery"; import { PostDataProps, PrelimPostProps } from "../../../types/Post"; import * as User from "../../../types/User"; import { deleteVoiceFiles } from "../../AudioRecorder/utils/audioRecorder"; import { getCurrentUserData } from "../../auth/authService"; import { addMedialtemsToGallery, preAppendPictures,

} from "../../gallery/actions"; import { getRandomString } from "../../shared/utils/randomString"; import { preAppendPost, savePost, uploadMediaElements } from "../actions";

// TODO: add multiple image when we got different post types export function toPost( uid: string,

ERSATZBLATT (REGEL 26) displayName: string, media: MediaElement[], galleryld: string, authorPic = ""

) { const postToSave: PostDataProps = { createdAt: Timestamp. nowO, author: displayName, authorUid: uid, media, authorPic: authorPic || get("currentUser.photoURL", auth), gallery: galleryld,

};

// throw new Errorf'test error") return savePost(postToSave);

} async function uploadMediaElementsToGallery( mediaElements: Partial<MediaElement>[], gallery: Gallery

): Promise<MediaElement[]> { const mediaAndUploadPaths: Array<{ media: { path: string }; path: string; id: string; type: MediaElementType; dimensions?: ImageDimensions;

}> = []; mediaElements.forEach((media) => { const name = getRandomString(20); const suffix = '${name}_rm'; const audioSuffix = '${name}_voice'; const videoSuffix = '${name}_rm'; const uploadPath = 'galleries/${gallery.id}/${suffix}';

// image url always goes first if (media.type !== MediaElementType. VIDEO) { mediaAndUploadPaths. push({ id: media. id, media: { path: media. url }, path: uploadPath, type: MediaElementType. IMAGE,

});

} if (media.type === MediaElementType.AUDIO) { const uploadPath = 'galleries/${gallery.id}/${audioSuffix}'; mediaAndUploadPaths. push({ id: media. id, media: { path: media. audioUrl }, path: uploadPath, type: MediaElementType.AUDIO,

});

}

ERSATZBLATT (REGEL 26) if (media.type === MediaElementType. VIDEO) { const uploadPath = 'galleries/${gallery.id}/${videoSuffix}'; mediaAndUploadPaths.push({ id: media. id, media: { path: media. videoUrl }, path: uploadPath, type: MediaElementType. VIDEO,

});

}

}); const results: Partial<MediaElement>[] = await uploadMediaElements(

// @ts- ignore mediaAndUploadPaths

);

// @ts- ignore const updatedMedia: MediaElement[] = mediaElements.map((e) => { const defaultDimensions: ImageDimensions = { height: 768, width: 1024 }; const temp = results. filter((element) => element. id === e.id); const updatedltem = { type: MediaElementType. IMAGE, url: temp[0].url, audioUrl: text: e.text, dimensions: temp[0].dimensions || defaultDimensions, }; if (temp. length > 0) { temp.map((item) => { if (item.type === MediaElementType.AUDIO) { updatedltem. audioUrl = item. url; updated Item.type = MediaElementType.AUDIO; deleteVoiceFilesO;

} if (item.type === MediaElementType. VIDEO) {

// @ts- ignore updatedltem. videoUrl = item. url; updatedltem. url = item. url; updated Item.type = MediaElementType.VIDEO;

}

});

} return updatedltem;

}); return updatedMedia;

} export async function saveDataToGallery( mediaElements: Partial<MediaElement>[], gallery: Gallery

) {

// @ts- ignore preAppendPictures(mediaElements as MediaElement[], gallery);

ERSATZBLATT (REGEL 26) const media = await uploadMediaElementsToGallery(mediaElements, gallery); return addMedialtemsToGallery(media, gallery);

} export async function saveDataToGalleryAndPost( mediaElements: Partial<MediaElement>[], gallery: Gallery

) { if (lauth. currentuser) { return console. errorf'No current User");

} const { uid } = auth. currentuser; const user: User.User = await getCurrentUserDataO; const perlimData: PrelimPostProps = { createdAt: Timestamp. nowO, author: User.getName(user), authorUid: uid, media: mediaElements, authorPic: user.profilePic || get("currentUser.photoURL", auth), uploading: true, error: false, gallery,

}; preAppendPost("prelim", perlimData); const media = await uploadMediaElementsToGallery(mediaElements, gallery);

// console. Iog("%c uploadMediaElementsToGallery -> result", "color: #25BD5B"); // console, log(media);

// throw new Errorf'test error saveDataToGalleryAndPost") return addMedialtemsToGallery(media, gallery).then((mediaElem) => toPost(uid, User.getName(user), mediaElem, gallery. id, user.profilePic)

);

}

Ein Nutzer kann ein erstelltes und hochgeladenes, mit einer Audionotiz versehenes Bild auf einer grafischen Benutzeroberfläche 50.1 auswählen; siehe Figur 9. Auf der grafischen Benutzeroberfläche 50.1 sind mit einer Audionotiz versehene Bilder mittels eines Icons 52 entsprechend gekennzeichnet.

Nach Aufrufen eines mit einer Audionotiz versehenen Bildes erscheint eine grafische Benutzeroberfläche 50.2 mit einer Wiedergabeschaltfläche 54, deren Berührung die Wiedergabe der Audionotiz auslöst; siehe Figur 10.

ERSATZBLATT (REGEL 26) Komponente "Stammbaum"

Bei der Komponente "Stammbaum" handelt es sich um eine Funktion, die die Reduktion einer Graph-Datenstruktur in eine hierarchische Baum-Datenstruktur ermöglicht und anhand eines intelligenten Regelsets diese Datenstruktur in eine für Endnutzerapplikationen nutzbare interaktive Matrix (Genogramm) umwandelt.

Die im folgenden erörterte Technologie erlaubt das Verarbeiten von Beziehungsdaten basierend auf den mathematischen Prinzipien eines Genogramms. Sie erlaubt die Verknüpfung komplexer Baumstrukturen hin zu einer einheitlichen Matrix und dient der Übersetzung vereinfachter Verbindungsdaten zu einer für die Darstellung von Beziehungsverhältnissen notwendigen Graphischen Struktur. Sie überbrückt hierbei die Diskrepanz in Komplexität zwischen einfachen Baumstrukturen und der eines Genogramms durch ein erweitertes Berechtigungssystem welches das erstellen und bearbeiten von Knoten und Kanteninformationen für jeden Knoten errechnet.

Daten zu Personen, z.B. Familienmitgliedern (Knoten) und deren Beziehungen (Kanten) sind eine Grundvoraussetzung für das Erstellen von Genogrammen. Während diese dank neuer Graph-Datenbank-Technologie vereinfacht abgespeichert und genutzt werden können erfüllen viele dieser Datenbanken nicht die technischen Grundvoraussetzungen für den Einsatz in skalierbaren und somit massentauglichen Applikationen im Endnutzergebrauch. Des Weiteren erschwert die Implementierung für die Verwendung solcher Datenbanken notwendiger Abfragesprachen die Einbindung in bestehende Systeme oder macht diese im Kontext der modernen Applikationsentwicklung oft nahezu unmöglich.

Zum Nutzbarmachen solcher Daten im Kontext einer Endnutzerapplikation wurde daher der nachfolgend wiedergegebene Quellcode (siehe Quellcode "Caching", Quellcode "Analysis", Quellcode "Transformation" und Quellcode "Typen") entwickelt welcher basierend auf herkömmlichen No-Sql Datenbanktechnologien das Aufbereiten von Beziehungsdaten ermöglicht. Diese Verwendungen umfassen im Folgenden die Abbildung hierarchischer sowie vernetzter Strukturen, die Abfrage komplexer Muster, das Traversieren von Graphen sowie die Ermittlung des kürzesten Pfades zwischen zwei Knoten. Zudem ermöglicht das nachfolgend näher beschriebene System das Nutzbarmachen eines Genogramms als interaktives Objekt. Es tut dies, indem es ein Berechtigungssystem implementiert, welches Nutzern das gemeinsame Erstellen und Bearbeiten von Knoten und Kanten innerhalb eines Genogramms ermöglicht und Zugriffsrechte für diese Nutzer individuell berechnet.

ERSATZBLATT (REGEL 26) Prozess:

1) Daten

Für das Erstellen von Beziehungsdaten (Kanten) notwenige Informationen wurden in einem eigenen Ressource-Description-Framework (RDF) festgehalten und dienen als Grundvoraussetzung für die korrekte Klassifizierung von Beziehungsdaten innerhalb des Genogramms.

Innerhalb eines RDFs werden Graphen mit Hilfe von Triplen repräsentiert. Ein Triple besteht aus drei Elementen in einer Knoten-Kante-Knoten (Subjekt --Prädikat-> Objekt) Struktur, die in Form einer menschlichen Beziehung innerhalb des Systems festgehalten werden. Die Summe der dem System vorgegebenen Tripel bilden somit die mathematische Grundlage des RDF-Modells. Eine für RDFs herkömmliche Referenz zu zugehörigen Graphen (Quads) erwies sich durch die vorherige Zuordnung der Graphen zu den jeweiligen Endnutzern als überflüssig.

Knotendaten können im System durch den Endnutzer erstellt werden und enthalten alle, neben den durch das RDF vorgegebenen Beziehungsdaten, relevanten Informationen. Das System erlaubt dem Endnutzer neben der Verknüpfung mit bestehenden Knotenpunkten anderer Nutzer auch das Erstellen virtueller Knotenpunkte und somit das Erstellen virtueller Nutzer (Personen, insbesondere Familienmitglieder, auch solche, die bereits verstorben sind) welche über das System verwaltet werden können.

Die klassifizierten Kantendaten werden durch eindeutige Identifikationsnummern mit den entsprechenden Knotendaten verknüpft und ergeben somit die benötigte Datengrundlage für die weitere Verarbeitung innerhalb des Systems. Dies ist in Figur 11 dargestellt.

2) Aufbereitung

Grundvoraussetzung für die Abbildung hierarchischer sowie vernetzter Strukturen ist die vorläufige Aufbereitung der Datenstruktur aus Knoten und Kanten von einer Sammlung von Eins-zu-eins Verbindungen hin zu einer Baumstruktur. Im Zuge dessen werden bestehende Kantendaten anhand der vorher festgesetzten möglichen Beziehungen im RDF zum Ausgangspunkt (zum Beispiel dem Endnutzer) bewertet und „Positionen“ für jede Beziehung im Baum festgelegt. Diese Daten werden dann zu einer großen Baumstruktur zusam-

ERSATZBLATT (REGEL 26) mengefasst und für die weitere Verarbeitung zu einer virtuellen Graph Datenstruktur aufbereitet. Die Aufbereitung dieser Datenstrukturen für jeden Knotenpunkt innerhalb des vom Endnutzers erstellten Stammbaumes stellt somit die Grundlage für das spätere Traversieren multipler Graphen dar. Auch ermöglicht sie die spätere Ermittlung der kürzesten Strecke zwischen zwei Knoten. In Abhängigkeit der gefundenen Beziehungen (Kanten) und anderer mit dieser in Verbindung stehender Knoten kann somit die spätere Darstellung über die Vergabe passender Verbindungslinien vorbereitet werden.

Das System nutzt ein Caching System um Verbindungen durch die virtuell erstellte Graph- Datenstruktur zu folgen; siehe Quellcode "Analysis". Dieses Caching von Knoten- und Kantendaten erlaubt es einem Nutzer multiple Beziehungen zu anderen Mitgliedern innerhalb einer Familienstruktur zu besitzen ohne dass es hierbei zu einer unendlichen Rekursion kommt. Es erlaubt einem Nutzer somit an zwei oder mehr Positionen innerhalb einer Baumstruktur erscheinen zu können und begrenzt die Aufgabe des Systems auf die Verarbeitung von Beziehungsdaten (Kanten).

Quellcode "Caching"

Die Folgenden Funktionen ermöglichen das Cachen von Knoten und Kantendaten zur Zwischenspeicherung und dem Abgleich von Verbindungsdaten in der späteren Verarbeitung. export let ns: Person[] = []; export let es: DataEdge[] = []; let esCache: DataEdge[] = []; export const addToCache = (edges: DataEdgeQ): DataEdge[] => { esCache = concat(esCache, edges); return edges;

}; export const setNodes = (nodes: any) => { const mapped = map((n: any) => { n[fields.idField] = n[cfg.idField]; n[fields.orderByField] = n[cfg.orderByField]; return n;

})(compact(nodes)); ns = map(makePerson, mapped);

}; export const setEdges = (edges: any, config = {}) => { const _cfg = merge(defaultConfig, config); const mapped = map((e: any) => { e[fields.leftField] = e|_cfg.leftField]; e[fields.rightField] = e|_cfg.rightField];

ERSATZBLATT (REGEL 26) e[fields.edgeTypeField] = e|_cfg.edgeTypeField]; return e;

»(edges); es = mapped; esCache = [];

}; export const setData = (nodes: any, edges: any) => { setNodes(nodes); setEdges(edges);

}; const getRelevantFields = pick([ fields. leftField, fields. rig htField, fields. edgeTypeField,

]); export const withoutCached = (edges: DataEdgeQ): DataEdge[] => {

// const areEdgesEqual = (a: DataEdge, b: DataEdge): boolean => isEqual(getRelevantFields(a), getRelevantFields(b)); const isNotlnCache = (e: any) => !find((_e) => areEdgesEqual(_e, e), esCache); const without = filter(isNotlnCache)(edges); return without;

}; export const cacheTheseEdges = pipe(withoutCached, addToCache); export const cacheThisEdge = pipe(

(x: DataEdge) => [x], withoutCached, addToCache, first

);

Vor dem Errechnen der Baumstruktur aus der virtuellen Graph-Datenstruktur erfolgt eine Analyse der Verbindungen (Kanten); siehe Quellcode "Analysis". Diese entscheidet welche Beziehungen und Knoten (Personen) tatsächlich in den Graphen aufgenommen werden und somit dargestellt werden sollen. Dies bedeutet, dass das schlussendliche Ergebnis der Analyse lediglich ein eine Untermenge (Sub Set) aller bestehenden verwandtschaftlichen

ERSATZBLATT (REGEL 26) Verbindungen darstellt. Diese wird genutzt um zu errechnen welche Knoten tatsächlich zur Familie des jeweiligen Nutzers gehören und wird für die Darstellung im Frontend ebenso genutzt wie im zum Errechnen von Zugriffsrechten innerhalb der Datenbank um zum Beispiel den Zugang zu persönlichen Informationen freizugeben oder zu limitieren. Die Anwendung "Stammbaum" würde daher die Lebensgefährtin eines Bruders zur näheren Familie zählen, nicht aber deren Mutter und somit die Familie in sich begrenzen.

Das gleiche System kann frontend- und backend-seitig (als sowohl auf einem persönlichen Endgerät 20 als auch auf einem Server 12) genutzt werden um die Familie systemseitig zu verifizieren. Die in der Darstellung gezeigte Familie ist immer die Familie die vom System als solche anerkannt wird.

Quellcode "Analysis"

Der Folgende Code dient der Analyse von Verbindungsdaten (edges) anhand des bestehenden RDFs und erlaubt die Klassifizierung von Knoten anhand ihrer bestehenden Verbindungen. import * as defs from "./nodes"; import { is, matchResult } from "../utils"; import { orderByField } from "../data/fields"; import { cfg } from "../config"; const relationshipList = (n: Person): RelationshipNode[] => compacts

...pullMarriages(n),

...pullRelationships(n),

...pullExMarriages(n),

...pullExes(n), defs.makellnknownRelationship(n),

]); const withoutllnknownPeople = filter(

(x: RelationshipNode) => Hs(defs.notFoundPerson, x. other) ); const walkPersonRelationshipsHorizontal = ( n: Person, direction = "both", compactP = true

): { left: Tree[]; right: Tree[] } => {

// const rels: RelationshipNode[] = cfg.showNotFoundPeople

ERSATZBLATT (REGEL 26) ? relationshipList(n)

: withoutUnknownPeople(relationshipList(n)); const leftRels = direction === "both" ? [head(rels)] : direction === "left" ? reis : []; const rightRels = direction === "both" ? tail(rels) : direction === "right" ? reis : []; const isUnknownEmpty = (x: any) =>

!(is(defs.unknownRelationship, x.node) && isEmpty(x.down)); const filterunknown = filter(isUnknownEmpty); const left: Leaves = pipe(

// compact, map(relationshipTreeLeft), filterunknown, x => (size(x) > 1 && compactP) // eslint-disable-line

? defs.makeCompactedRelationships(x)

: x

XleftRels); const right: Leaves = pipe(

// compact, map(relationshipTreeRight), filterunknown, x => (size(x) > 1 && compactP) // eslint-disable-line

? defs.makeCompactedRelationships(x)

: x

)(rightRels); return { left, right };

}; const walkPersonUps = (n: Person): { up: Tree[] } => { const parentRelationship = pullParentRelationship(n); if (

Icfg.showNotFoundPeople &&

(is(defs.notFoundPerson, parentRelationship?. main) || is(defs.notFoundPerson, parentRelationship?. other))

) return { up: [] }; const up = parentRelationship

? [wraplnParentNode(parentRelationshipTree(parentRelationship) )] return { up };

}; const walkPerson = (n: DataNode | Person | UnknownPerson): Tree | undefined => { const node = defs.makePerson(n); if (is(defs.notFoundPerson, node) || In) return cfg.showNotFoundPeople ? makeTree({ node }) : undefined;

ERSATZBLATT (REGEL 26) const { left, right } = walkPersonRelationshipsHorizontal(node); const { up } = walkPersonUps(node); const nodeTree = makeTree({ node, up, left, right,

}); return nodeTree;

}; const walkPersonLeft = ( n: DataNode | Person | UnknownPerson ): Tree | undefined => { const node = defs.makePerson(n); if (is(defs.notFoundPerson, node) || In) return cfg.showNotFoundPeople ? makeTree({ node }) : undefined; const { left, right } = walkPersonRelationshipsHorizontal(node, "left"); const { up } = walkPersonUps(node); const nodeTree = makeTree({ node, up, left, right,

}); return nodeTree;

}; const walkPersonRight = (n: Person): Tree | undefined => { const node = defs.makePerson(n); if (is(defs.notFoundPerson, node) || In) return cfg.showNotFoundPeople ? makeTree({ node }) : undefined; const { left, right } = walkPersonRelationshipsHorizontal(node, "right"); const { up } = walkPersonUps(node); const down: Leaves = []; const nodeTree = makeTree({ node, up, down, left, right,

}); return nodeTree;

}; const walkChildrenOfRelationship = (r: RelationshipNode): Tree[] => pipe(

ERSATZBLATT (REGEL 26) // pullChildrenOfRelationship, sortBy(orderByField), map(walkPersonNoUp), compact, map(wraplnChildNode)

)(r); const walkPersonOnlyUp = (n: Person): Tree | undefined => { const node = defs.makePerson(n); if (is(defs.notFoundPerson, node) || !n) return cfg.showNotFoundPeople ? makeTree({ node }) : undefined; const { up } = walkPersonUps(node); const nodeTree = makeTree({ node, up,

}); return nodeTree;

}; const walkPersonNoUp = (n: Person): Tree | undefined => { const node = defs.makePerson(n); if (is(defs.notFoundPerson, node) || !n) return cfg.showNotFoundPeople ? makeTree({ node }) : undefined; const { left, right } = walkPersonRelationshipsHorizontal(node); const nodeTree = makeTree({ node, left, right,

}); return nodeTree;

}; const personTree = (n: DataNode | Person | UnknownPerson) => { return makeTree({ node: defs.makePerson(n),

});

}; function wraplnChildNode(t: Tree): Tree { return makeTree({ node: defs. child, down: [t],

});

} function wraplnParentNode(t: Tree): Tree { return makeTree({ node: defs. child,

ERSATZBLATT (REGEL 26) up: [t],

});

} const wrapInChildren = (ts: Trees): Tree => { return makeTree({ node: dets. children, down: ts,

});

}; function relationshipTreeLeft(r: RelationshipNode): Tree {

// const childTrees = walkChildrenOfRelationship(r); const t = makeTree({ node: defs.makeRelationship(r), down: HsEmpty(childTrees) ? [wraplnChildren(childTrees)] : [], left: [personTree(r.other)],

}); return t;

} function relationshipTreeRight(r: RelationshipNode): Tree {

// const childTrees = walkChildrenOfRelationship(r); const t = makeTree({ node: defs.makeRelationship(r), down: HsEmpty(childTrees) ? [wraplnChildren(childTrees)] : [], right: [personTree(r. other)],

}); return t;

} let firstParents = true; function parentRelationshipTree(r: RelationshipNode): Tree | undefined { const childTrees: Tree[] = walkChildrenOfRelationship(r); const p1 = r.main; const p2 = r.other; let walkPersonFuncLeft = walkPersonOnlyUp; let walkPersonFuncRight = walkPersonOnlyUp; if (firstParents) { firstParents = false; walkPersonFuncLeft = walkPersonLeft; walkPersonFuncRight = walkPersonRight;

} const tree = makeTree({ node: r, right: [walkPersonFuncRight(pl)], left: [walkPersonFuncLeft(p2 as Person)],

}); const wrappedTree = makeTree({ node: defs. children, up: [tree],

ERSATZBLATT (REGEL 26) down: childTrees,

}); return wrappedTree;

} export function createTree(root: DataNode): Tree { firstParents = true; return walkPerson(root);

} export default { createTree,

};

3) Transformation

Die Transformation dient dem Umwandeln der eben erstellten Graph-Datenstruktur in eine hierarchische Baumstruktur, um später eine Visualisierung und Nutzbarmachung innerhalb der Endnutzerapplikation (Komponente "Stammbaum" der Applikation "RememberMe") zu ermöglichen; siehe Quellcode "Typen". Nach abgeschlossener Aufbereitung werden die Daten der einzelnen Verbindungen von der bestehenden Graph Datenstruktur in Sub- Bäume umgewandelt. Ein Algorithmus wird genutzt um diese Sub-Bäume zu Verbinden und für eine Gleichverteilung von Knoten innerhalb des Baumes zu sorgen. Ebenso werden Kollisionen von Knoten und Verbindungen er am weitest auseinanderliegenden Punkte registriert und Programmatisch entfernt.

Um eine spätere Verknüpfung diverser Graphen und das horizontale sowie vertikale Traversieren durch die erstellten Baumstrukturen zu ermöglichen ist eine fortwährende Berechnung aller Kanten-Knoten Verbindungen zwingend erforderlich. Eine Bereinigung von Kantendaten und die Gruppierung von Beziehungen ist für eine spätere Umwandlung in die für die Darstellung benötigten Matrix Struktur notwendig und erfolgt zum Zeitpunkt der Berechnung.

Quellcode Typen

Der Folgende Quellcode arbeitet die in der Datenbank gespeicherte Graph Datenstruktur in eine hierarchische Baumstruktur um und ermöglicht somit die weitere Verarbeitung. export type DataNode = {

[idField]: string;

[otherFields: string]: string;

}; export type DataNodes = { [index: number]: DataNode };

ERSATZBLATT (REGEL 26) export type DataEdge = {

[leftField]: string;

[rightField]: string;

[edgeTypeField]: string;

[otherFields: string]: string;

}; export type DataEdges = { [index: number]: DataEdge }; export type MatrixNode = {

_ftreeType: string; nodeType?: string;

}; export type Person = DataNode &

MatrixNode & {

_ftreeType: "person";

}; export type UnknownPerson = MatrixNode & {

_ftreeType: "person"; nodeType: "unknownPerson";

}; export type NotFoundPerson = MatrixNode & {

_ftreeType: "person"; nodeType: "notFoundPerson";

}; export type RelationshipType = {

[edgeTypeField]: string;

}; export type RelationshipNode = DataEdge &

MatrixNode & {

_ftreeType: "someRelationship"; main: Person; other: Person | UnknownPerson;

}; export type Line = MatrixNode & {

_ftreeType: "line";

_ftreeLineType?: string;

}; export type NodeStack = MatrixNode & {

_ftreeType: "nodeStack"; nodes?: PersonQ;

}; export type Leaves = Array<Tree>; export type Matrix = Array<Array<any>>; export type Matrixes = Array<Matrix>; export type Tree = {

ERSATZBLATT (REGEL 26) node: MatrixNode; up: Leaves; down: Leaves; left: Leaves; right: Leaves; index?: number; rootDepth?: number; first?: boolean; last?: boolean; onLeft?: boolean; onRight?: boolean;

}; export type Trees = Array<Tree>; export const makeLeaves = (leaves: Leaves) => { const newLeaves = []; for (let i = 0; i < leaves. length; i++) { const first = i === 0; const last = i === leaves. length - 1 ; newLeaves[i] = merge(leaves[i], { index: i, first, last });

} return newLeaves;

}; export const makeLeavesLeft = (Is: Leaves): Leaves => map((x) => merge(x, { onLeft: true }), makeLeaves(ls)); export const makeLeavesRight = (Is: Leaves): Leaves => map((x) => merge(x, { onRight: true }), makeLeaves(ls)); export const makeTree = (tree: any): Tree => { return merge(

{ node: {}, first: false, last: false, index: 0, up: [], down: [], left: [], right: [],

},

{ node: tree. node, up: makeLeaves(get("up", tree) || []), down: makeLeaves(get("down", tree) || []), left: makeLeavesLeft(get("left", tree) || []), right: makeLeavesRight(get("right", tree) || []), }

);

};

Für die weitere Transformation der hierarchischen Datenstruktur in ein später nutzbares Format muss diese in eine listenartige Repräsentation einer Baumstruktur umgewandelt

ERSATZBLATT (REGEL 26) werden; siehe Quellcode "Transformation". Diese Listen werden in Matrizen (Figur 12) gespeichert um das Verhältnis der Knoten untereinander sowie deren Position zueinander zu erhalten.

Figur 12 zeigt eine entsprechende Knoten/Kanten Matrix.

Quellcode " Transformation"

□erfolgende Quellcode transformiert bestehende hierarchische Datenstrukturen zu Datenreihen und Matrizen und übernimmt deren Zusammenführung, Reinigung und Ausrichtung. const name = getfuid"); export const string Representation = (n: MatrixNode) => { const repr = matchThen([

[defs. exRelationship, 0 => x'],

[defs. exMarriage, 0 => x'], [defs. marriage, 0 => '+'], [defs. relationship, 0 => [defs. children, 0 => [defs. pa rents, 0 => '('], [defs.horizontalLine, 0 => '], [defs.spacerHorizontalLine, 0 => '], [defs. unknownPerson, 0 => [defs.notFoundPerson, 0 => 'c'l. [defs.unknownRelationship, 0 => [defs. nodeStack, 0 => '\u2630'], [defs. child, 0 => ' [defs.onlyChild, 0 [defs.verticalLine,

[defs. bottom LeftCorn er, 0 => ' r']> [defs.bottomRightCorner, 0 => '-] '], [defs.topLeftCorner, 0 => J '], [defs.topRightCorner, 0 => ' L ], [defs.lowHorizontalLine, 0 => '], [defs.branchDown, 0 => [defs.branchRight, 0 => ' p'], [defs.branchLeft, 0 => -| '], [defs.branchUp, 0 => [defs. intersection, 0 => '-f-'L [defs. person, (x: any) => '${first(name(x))}'], [defs. spacer, (x: any) => ' '], [defs. nothing,

])(n); if (repr === "undefined") { console.warnf could not find representation for ', n);

}

ERSATZBLATT (REGEL 26) return repr;

}; export const printMatrix = (matrix: any) => { each((m: any) => { const arrr = m.map(stringRepresentation, m); console. Iog(arrr.join(""));

}, matrix);

}; const padRight = curry((wit: any, a: Array<any>) => concat(a, [wit])); const padLeft = curry((wit: any, a: Array<any>) => concat([wit], a)); const padLeftFor = (amount: number, wit: any, a: Array<any>) => reduce(padLeft(wit), a, times(String, amount)); const padRightFor = (amount: number, wit: any, a: Array<any>) => reduce (pad Rig ht(wit), a, times(String, amount)); const padEvenFor = (amount: number, witL: any, witR: any, a: Array<any>) => { let b = a; for (let i = 0; i < amount; i++) { b = i % 2 ? padLeft(witL, b) : padRight(witR, b);

} return b;

}; export const treeToMatrixRow = curry(

(width: number, tree: Tree, bottom: Matrix): Array<any> => { const { onLeft, onRight, left, right, node, down } = tree; const hasLeft = ! Isize(left) ; const hasRight = llsize (right); const topChildRow: any = first(bottom); const defaultP = 0 => { let a = [tree. node]; if (lhasLeft && lonRight) a = concat([defs.spacer], a); const len = size(a); const padAmmount = width - len; const padWithLeft = defs. nothing; const padWithRight = defs. nothing; const padded = padEvenFor(padAmmount, padWithLeft, padWithRight, a); return padded;

}; const relationshipBar = 0 => { let a = [tree. node]; if (lhasLeft) a = concat([defs.spacerHorizontalLine], a); const len = size(a); const padAmmount = width - len; const padWithLeft = hasRight ? defs.horizontalLine : defs. nothing; const padWithRight = hasLeft ? defs.horizontalLine : defs. nothing;

ERSATZBLATT (REGEL 26) const padded = padEvenFor(padAmmount, padWithLeft, padWith- Right, a); return padded;

}; const childrenP = 0 => { let a: Array<any> = []; const padAmount = width % 2 === 0 ? width + 1 : width; a = padEvenFor( padAmount, defs.lowHorizontalLine, defs.lowHorizontalLine, a

); const half = Math.floor(padAmount 12); a[half] = defs. children; const firstlndex = min([ findlndex(is(defs. child), topChildRow), findlndex(is(defs. children), a),

]) II 0; const lastindex = max([ findLastlndex(is(defs. child), topChildRow), findLastlndex(is(defs. children), a),

]) II size(a); for (let i = 0; i < firstlndex; i++) { a[i] = defs. nothing;

} for (let i = lastindex + 1 ; i < size(a); i++) { a[i] = defs. nothing;

} return a;

}; const childBar = 0 => { let a: Array<any> = [tree. node, defs. nothing]; const ourChild = get("0.node", down); const len = size(a); const padAmmount = width - len; const childindex = findlndex((x) => { const isOurKid = isEqual(ourChild, x); return isOurKid;

}, topChildRow); const leftBlankAmount = childindex || 0; a = padRightFor(padAmmount - leftBlankAmount - 1 , defs. nothing, a); a = padLeftFor(leftBlankAmount, defs. nothing, a); return a;

}; return (

ERSATZBLATT (REGEL 26) matchThen([

[defs. children, childrenP],

[defs. child, childBar],

[defs.anyRelationship, relationshipBar],

D(node) || defaultPO

);

}

); export const followRoots = (tree: Tree): Tree => { const { up, left, right } = tree; if (lup || Heft || Iright) return merge(tree, { rootDepth: 0 }); const leftUps = flatten(map("up", left)); const rightUps = flatten(map("up", right)); const inspectedRoots = map( followRoots, compact([...up, ...leftUps, ...rightUps])

); const rootDepth = isEmpty(inspectedRoots)

? 1

: (max(map("rootDepth", inspectedRoots)) || 0) + 1 ; return merge(tree, { rootDepth });

}; const matrixTree = (tree: Tree, childMatrixes: Matrixes): Matrix => { const bottom = collapseMatrixesLeft(childMatrixes); const widthOfThisMatrix: number = size(first(bottom)) || 0; const thisRow = treeToMatrixRow(widthOfThisMatrix, tree, bottom); const thisMatrix = concat([thisRow], bottom); return thisMatrix;

}; export function flattenTree(tree: Tree): Matrix { const { down, up, left, right } = tree; if (size(up) === 1) { const onlyUp: Tree = up[0]; tree. up = []; if (tree. on Right) { onlyUp.onRight = true; onlyUp.down = concat([tree], onlyUp.down);

} else { onlyUp.onLeft = true; onlyUp.down = concat(onlyUp.down, [tree]);

} return flattenTree(onlyUp);

} const thisTree = map(flattenTree, down); const thisMatrix = matrixTree(tree, thisTree); const leftTrees = pipe( map(followRoots)

ERSATZBLATT (REGEL 26) )(left); const rightTrees = pipe( map(followRoots)

) (right); const maxRootDepth = max(map("rootDepth", [...leftTrees, ...rightTrees])) || 0; const fitMatrix = (t: Tree) => { const depth = getf'rootDepth", t) || 0; const matrix = flattenTree(t); return concat(fillNothing(maxRootDepth - depth), matrix);

}; const leftMatrixes = map(fitMatrix, leftTrees); const rightMatrixes = map(fitMatrix, rightTrees); const allMatrixes = [

...leftMatrixes, concat(fillNothing(maxRootDepth - 1), thisMatrix),

...rightMatrixes,

]; const mamaMatrix = collapseMatrixesLeft(allMatrixes); return mamaMatrix;

} export const treeToMatrix = pipe( tapff-tree: flattening tree'), flattenTree, tap('f-tree: fixing lines'), fixMatrixLines

); export default { treeToMatrix,

}; export const collideMatrixes = (ml : Matrix, m2: Matrix): Matrix => { const rowCollisions = []; for (let i = 0; i < m2. length; i++) { const r1 = ml [i]; const r2 = m2[i];

// cycle through the rows let p1 : any = findLastlndex(isSomething, r1); let p2: any = findlndex(isSomething, r2); p1 = p1 >= 0 ? r1 .length - p1 : 100; p2 = p2 >= 0 ? p2 : 100; const maxPush = p1 + p2; // max([p1 , p2]); rowCollisions. push(maxPush);

}

ERSATZBLATT (REGEL 26) // console. log(rowCollisions); const minPossible = min(rowCollisions) || 0;

// console. log(minPossible); const paddedM2 = map(concat(fillNothing(m1 [0], length)), m2); const paddedMI = map(concat(fillNothing(minPossible - 1)), m1); const mergeMatrixCustom = (mm1 : any, mm2: any) => { const merged = mergeWith( mergeWith((a: any, b: any) => { if (isSomething(a)) return a; if (isSomething(b)) return b; return b;

}), mm1 , mm2

); return map(values, merged);

Berechtigungssystem:

Das System ist ausgebildet, die Zugriffsrechte von Nutzern anhand ihrer Verbindung (Kanten) zueinander zu errechnen.

Diese Rechte können durch Nutzer selber erweitert oder weiter eingeschränkt werden und können auch auf von Nutzern angelegte virtuelle Knoten angewendet werden. Diese virtuellen Knoten (Figur 13: V1 und 2) repräsentieren den Endpunkt einer menschlichen Beziehung innerhalb einer hierarchischen Datenstruktur und können, ähnlich tatsächlicher Knoten (realer Nutzer in Figur 13: R1 , R2, R3), in der Baumstruktur und den Diagrammen der Endnutzerapplikation nachvollzogen werden. Als Erschaffer virtueller Knoten innerhalb seiner Baumstruktur ist der Nutzerfür den Inhalt dieser vollverantwortlich. Das System ermöglicht allerdings das Teilen von Schreib- und Leseberechtigungen solcher Knoten mit anderen Nutzern und somit das Teilen von Informationen und Verbindungen (Kanten) innerhalb

ERSATZBLATT (REGEL 26) der Datenstruktur. Das System ermöglicht somit das Traversieren über bestehende limitierte Baumstrukturen hinaus und ermöglicht das Management von Rechten auf Nutzer, sowie auf virtueller Nutzerbasis.

Figur 13 illustriert das Berechtigungssystem.

Erläuterung des Beispiels anhand von Figur 13:

Nutzer R1 erstellt die den Gemeinsamen Knoten V1 für sich und Nutzer R2. Er überträgt die Rechte an V1 an Nutzer R2 und erlaubt diesem folglich das editieren aller mit V2 in Verbindung stehenden Daten. Fortan können keine Inhalte (Bilder etc.) im Namen von V2 ohne die Zustimmung beider Nutzer R1 ,2 erstellt werden. Auch kann V2 nicht mehr ohne die Zustimmung beider Nutzer gelöscht werden. Nur die persönliche Verbindung zwischen den Nutzern R1 ,2 und V1 kann vom jeweilig Berechtigen Nutzer gelöscht werden um V1 aus der Baumstruktur zu entfernen. Inhalte die für den Virtuellen Nutzer V1 hinterlegt wurden bleiben von dieser Löschung unberührt.

Der sich in der Baumstruktur befundene Nutzer R3 kann die Verbindungen aller Nutzer zu V1 nachvollziehen, diesen in seiner Baumstruktur sehen sowie dessen erstellte (von R1 ,2) Inhalte lesen. Er besitzt aber keine Rechte zum Editieren oder erstellen weitere Inhalte in V1s Namen welche über die durch das System als die Standardberechtigungen kalkulierten hinausgehen.

Das System erlaubt des weiteren Nutzer R1 das Übergeben des virtuellen Kontos V1 an eine reale Person. Diese erhält in diesem Zug die Rechte an allen zuvor über den virtuellen Account V1 geteilten Inhalte. Die Zuvor von Nutzer R1 an R2 erteilten Rechte erlöschen ebenso wie die Rechte des Nutzers R1 .

Die Figuren 14, 15, 16 und 17 illustrieren, wie das beschriebene Verfahren mittels entsprechender grafischer Benutzeroberflächen auf einer Anzeige 22 eines Endgeräts 20.1 von einem Endnutzer gesteuert werden können.

Hierzu wird einem Nutzer zunächst mittels einer grafischen Benutzeroberfläche 60.1 eine grafische Repräsentation einer Baumstruktur 62 dargestellt. Die Baumstruktur setzt sich aus Knoten 64 und Kanten 66 zusammen. Einige oder mehrere Knoten 64 der Baumstruktur 62 sind als aktive Schaltfläche 64‘ ausgebildet, die das Aufrufen von Inhalten zu einer

ERSATZBLATT (REGEL 26) durch den jeweiligen Knoten 64 repräsentierten Person erlaubt. Durch Betätigen einer aktiven Schaltfläche 64‘ wird eine grafische Benutzeroberfläche 60.2 aufgerufen, auf der zu einem Knoten 64 mehrere Schaltfläche 70, 72, 74, 76, 78 und 80 dargestellt sind, durch deren Berühren ein Nutzer wahlweise das Anzeigen des Stammbaums (Schaltfläche 70; Stammbaum in Figur 14), das Hinzufügen eines Knotens zu dem Stammbaum (Schaltfläche 72), das Hinzufügen oder Verändern von Kanten des Stammbaums (Schaltfläche 74), das Anzeigen von Inhalten zu einem Knoten (Schaltfläche 76), das Teilen von Bildern, insbesondere von Bildern mit Audionotiz (Schaltfläche 78) oder das Versenden von Nachrichten (Schaltfläche 80) erlaubt.

Wenn ein Nutzer die Schaltfläche 72 berührt (Schaltfläche „Verwandten hinzufügen“), erscheint die in Figur 16 dargestellte grafische Benutzeroberfläche 60.3. Diese stellt mehrere Schaltflächen zu Verfügung, die potentielle weitere Knoten repräsentieren, die mit einem aufgerufenen Knoten unmittelbar verbunden sind. Wird eine der Schaltflächen 82 aktiviert, erscheint die in Figur 17 dargestellte grafische Benutzeroberfläche 60.4, die das Erstellen und Zusammenstellen von Inhalten zu der jeweiligen Person erlaubt.

Sichtbarkeit

Vorzugsweise ist neue Schaltfläche in den Einstellungen vorgesehen, mit der das Profil des Benutzers für andere Personen, die nicht zur engsten Familie gehören, verborgen werden kann, wenn sie ausgeschaltet ist.

Auch andere Personen können dem Nutzer keine Nachrichten schicken. Dies gilt nicht für seinen inneren Familienkreis, zu dem die Eltern, Großeltern, Kinder, Enkelkinder, Geschwister, Partner und Kinder der Geschwister, Onkel + Lebenspartner und seine Kinder gehören.

Der folgende Code zeigt den Schalter an, mit dem der Benutzer den Inhalt seines Profils für andere sichtbar oder unsichtbar machen kann. Das Umschalten des Schalters löst die Funktion aus, die das Benutzerobjekt aktualisiert, um das Feld einzuschließen, das bestimmt, ob das Profil sichtbar ist oder nicht.

<Switch trackColor={{

ERSATZBLATT (REGEL 26) false: colors. koala, true: colors.grass,

}} thumbColor={colors.darkWhite} ios_backgroundColor={colors.lightGrey} onValueChange={(val) => { toggleProfileVisibility(val, variables, logged InUser). catch(

(e) => { variables.setProfileVisible(variables.profileVisible);

}

); variables.setProfileVisible(val);

}} value={!variables.profileVisible}

/> export const toggleProfile Visibility = async ( profilevisibility: boolean, loggedlnUser: User.User

): Promise<void> => { loggedlnUser.profileVisible = profilevisibility; updateUser(loggedlnUser);

};

Zugriffskontrolle

Hier werden alle Familienmitglieder des Nutzers aufgelistet. Der Benutzer kann entscheiden, wer auf seine Profildaten (jegliche Medien) zugreifen kann, indem er den Schalter ein- oder ausschaltet.

Wenn der Schalter ausgeschaltet ist, können die Familienmitglieder den Inhalt des Benutzerprofils nicht sehen, aber sie können ihm immer noch Nachrichten schicken.

□er folgende Code zeigt jedes Familienmitglied und einen Schalter neben seinem Namen an. Das Umschalten des Schalters löst die Funktion „eingeschränkter Profile Zugriff“ aus, die wiederum den Knoten des Familienmitglieds mit einem Wert aktualisiert, der bestimmt, ob es den Inhalt des Benutzerprofils sehen kann.

ERSATZBLATT (REGEL 26) AccessControllSettings.tsx export const AccessControlSettings = (props: Props) => { const loggedlnUser = useSelector(

(state: Rootstate) => state. authReducer.user

); const navigation = useNavigationO; const [family, setFamily] = useState<Family.Family>(

Family. createNew(PublicUser.fromUser(logged InUser))

); const [loading, setLoading] = useState<boolean>(false); const fetchFamily = async (uid: string) => { setLoading(true); const f = await FamilyApi.fetchConfirmedAndSuggested(uid, uid); setLoading(false); setFamily(f); store.dispatch({ type: "UPDATE_USER_FAMILY", payload: f,

});

}; useEffect(O => { fetchFamily(loggedlnUser.uid);

}, []);

// Don't proceed without the family if (loading || Ifamily) {

Log.debug(

' still waiting ${loggedlnUser.uid}, ${JSON.stringify(family[2])} ... ' ); return <LoadingOverlay />;

} const relations = Family. relations(family); const renderitem = ({ item }) => { return (

<Renderltem item={item} loggedlnUser={loggedlnUser} setFamily={setFamily}

/>

);

}; return (

<View sty le={{ flex: 1 }}>

<FlatList data={relations.all} keyExtractor={(item) => item. uid} renderltem={renderltem}

/>

ERSATZBLATT (REGEL 26) </View> );

}; const Renderitem = ({ item, loggedlnUser, setFamily }) => { const [profileVisible, setProfileVisible] = useState(item.profileVisible); const restrictProfileAccess = (val: boolean, user: User) => {

FamilyApi.updateUserNode(loggedlnUser.uid, user.uid, val)

,then((f) => { setFamily(f); store.dispatch({ type: "UPDATE_USER_FAMILY", payload: f,

});

})

.catch ((e) => { console. log(e); setProfileVisible(item. profileVisible);

});

}; return (

<View style={styles.container}>

<View style={styles.imageContainer}> clmage style={styles. imageSize} source={{ uri: item.profilePic || profilePicPIaceholderUrl,

}}

/>

<Text style={styles.name} numberOfl_ines={1}>

{item. name}

</Text>

</View>

<View>

<Switch sty le={sty les. switch} value={!profileVisible} onValueChange={(value) => { restrictProfileAccess(value, item); setProfileVisible(value);

}} trackColor={{ false: colors. koala, true: colors.grass,

}} thumbColor={colors.darkWhite}

/>

</View>

</View>

);

};

ERSATZBLATT (REGEL 26) Sprachen

In den Einstellungen gibt es einen Sprachbildschirm mit einer Liste der verfügbaren Sprachen. Wenn der Benutzer eine Sprache auswählt, wird der Inhalt der Anwendung in die ausgewählte Sprache übersetzt.

Derzeit werden die Sprachen Englisch und Deutsch unterstützt. Unterstützung für Chinesisch, Türkisch, Spanisch und Französisch werden hinzugefügt.

Der Code ist nachfolgend dargestellt:

Language Settings.tsx export const Localizationcontext = createContext({ translations, setAppLanguage: (language: string) => {}, appLanguage: DEFAULT_LANGUAGE, initializeAppLanguage: 0 => {},

}); export const Localizationprovider = ({ children }: any) => { const [appLanguage, setAppLanguage] = useState(DEFAULT_LANGUAGE); const setLanguage = (language: any) => { translations.setLanguage(language); moment. locale(language); setAppLanguage(language);

AsyncStorage.setltem(APP_LANGUAGE, language);

}; const initializeAppLanguage = async 0 => { const currentLanguage = await AsyncStorage.getltem(APP_LANGUAGE); if (IcurrentLanguage) { const localeCode = DEFAULT_LANGUAGE; const supportedLocaleCodes = translations.getAvailableLanguagesO; const phoneLocaleCodes = RNLocalize.getLocales().map(

(locale) => locale. languageCode

); const foundSupportedCode = phoneLocaleCodes. find((code) => supportedLocaleCodes. includes(code)

); const localCode = foundSupportedCode || DEFAULT_LANGUAGE; setLanguage(localCode); moment. locale(localCode);

ERSATZBLATT (REGEL 26) } else { setLanguage(currentLanguage); moment. locale(currentLanguage);

}

}; return ( cLocalizationContext. Provider value={{ translations, setAppLanguage: setLanguage, appLanguage, initializeAppLanguage,

> }}

{children}

</LocalizationContext.Provider>

);

}; translations.tsx import de from ",/de.json"; import en from ",/en.json"; import ch from ",/ch.json"; import tk from ",/tk.json"; export const DEFAULT_LANGUAGE = "de"; const translations = { en, de, ch, tk,

}; export default new LocalizedStrings(translations);

ERSATZBLATT (REGEL 26) Bezugszeichen

10 System

12 Server

14 Cloud-Speicher

16 Datenverbindung

20 Endgerät

20.1 Mobiltelefon

20.2 Tablet

20.3 PC

22 Anzeige

24 Modem

26 Datenverarbeitungssystem

28 Speicher

30.1 , 30.3, 30.4 Benutzeroberfläche

32 Aufzeichnungsschaltfläche

34 Wiedergabe eines Bildes

36 Schaltfläche

38 Schaltfläche

40 Schaltfläche

42 Teilen-Schaltfläche

50.1 Benutzeroberfläche

52 Icon

54 Wiedergabeschaltfläche

60.1 , 60.2, 60.3, 60.4 Benutzeroberfläche

62 Baumstruktur

64 Knoten

64‘ Schaltfläche

70, 72, 74, 76, 78, 80, 82 Schaltfläche

ERSATZBLATT (REGEL 26)