From 04cf8c5cd10586a076dd5a846a1d46a750e707c2 Mon Sep 17 00:00:00 2001 From: Sina Blattmann Date: Thu, 20 Jul 2023 16:16:55 +0200 Subject: [PATCH] Refactored all files, made a few new folders, corrected misleading names, removed unused stuff --- typescript/Frontend/lang/de.json | 136 ----- typescript/Frontend/lang/en.json | 47 -- typescript/Frontend/lang/fr.json | 136 ----- typescript/Frontend/src/App.css | 39 -- typescript/Frontend/src/App.test.tsx | 9 - typescript/Frontend/src/App.tsx | 8 +- typescript/Frontend/src/Login.tsx | 8 +- .../Context/S3CredentialsContextProvider.tsx | 7 - .../AccessManagement/AccessManagement.tsx | 2 +- .../AccessManagement/AvailableUserDialog.tsx | 1 - .../UsersWithDirectAccess.tsx | 4 +- .../src/components/Groups/AddNewButtons.tsx | 13 +- .../Groups/{AddNew.tsx => AddNewDialog.tsx} | 2 +- .../components/Groups/{ => Detail}/Folder.tsx | 11 +- .../Groups/{ => Detail}/FolderForm.tsx | 77 ++- .../Groups/{Tree => Detail}/MoveDialog.tsx | 4 +- .../Groups/{Tree => Detail}/MoveTree.tsx | 6 +- .../src/components/Groups/GroupTabs.tsx | 46 +- .../Groups/{Tree => }/GroupTree.tsx | 24 +- .../Frontend/src/components/Groups/Groups.tsx | 7 +- .../src/components/Groups/Tree/GroupTree.scss | 4 - .../src/components/Groups/TypeIcon.tsx | 11 +- .../{ => Detail}/Installation.tsx | 12 +- .../{ => Detail}/InstallationForm.tsx | 18 +- .../Installations/ExampleLogData.tsx | 492 ------------------ .../Installations/InstallationList.tsx | 25 +- .../Installations/InstallationTabs.tsx | 4 +- .../Installations/Installations.tsx | 5 +- .../Installations/{ => LiveView}/LiveView.tsx | 6 +- .../{Log => LiveView}/TopologyBox.tsx | 0 .../{Log => LiveView}/TopologyColumn.tsx | 0 .../{Log => LiveView}/TopologyFlow.scss | 0 .../{Log => LiveView}/TopologyFlow.tsx | 0 .../{Log => LiveView}/TopologyView.tsx | 1 - .../Installations/Log/CheckboxTree.tsx | 16 +- .../Log/{ => DatePicker}/DateRangePicker.tsx | 10 +- .../Log/{ => DatePicker}/ShortcutButton.tsx | 8 +- .../Installations/Log/ScalarGraph.tsx | 28 +- .../Installations/Log/TopologyBox.scss | 10 - .../Frontend/src/components/Layout/Detail.tsx | 60 --- .../InnovenergyList.tsx | 1 - .../Layout/InnovenergyPropertyGrid.tsx | 68 +++ .../{ => Layout}/InnovenergySnackbar.tsx | 0 .../src/components/Layout/InnovenergyTabs.tsx | 3 +- .../Layout/InnovenergyTextfield.tsx | 76 +-- ...gyTreeItem.tsx => InnovenergyTreeItem.tsx} | 4 +- .../src/components/Layout/LogoutButton.tsx | 9 +- .../src/components/Layout/ModeButtons.tsx | 20 +- .../Frontend/src/components/Users/AddUser.tsx | 11 +- .../Frontend/src/components/Users/User.tsx | 19 +- .../src/components/Users/UserForm.tsx | 10 +- .../src/components/Users/UserList.tsx | 1 - typescript/Frontend/src/index.css | 16 - typescript/Frontend/src/index.tsx | 3 +- typescript/Frontend/src/library.scss | 1 - typescript/Frontend/src/logo.svg | 1 - .../innovenergy_Logo_onOrange-2.png(1).png | Bin 12166 -> 0 bytes .../innovenergy_Logo_onOrange-2.png.png | Bin 12031 -> 0 bytes .../resources/innovenergy_Logo_onOrange.png | Bin 51620 -> 0 bytes typescript/Frontend/src/util/graph.util.tsx | 8 +- 60 files changed, 278 insertions(+), 1270 deletions(-) delete mode 100644 typescript/Frontend/lang/de.json delete mode 100644 typescript/Frontend/lang/en.json delete mode 100644 typescript/Frontend/lang/fr.json delete mode 100644 typescript/Frontend/src/App.css delete mode 100644 typescript/Frontend/src/App.test.tsx rename typescript/Frontend/src/components/Groups/{AddNew.tsx => AddNewDialog.tsx} (100%) rename typescript/Frontend/src/components/Groups/{ => Detail}/Folder.tsx (89%) rename typescript/Frontend/src/components/Groups/{ => Detail}/FolderForm.tsx (63%) rename typescript/Frontend/src/components/Groups/{Tree => Detail}/MoveDialog.tsx (100%) rename typescript/Frontend/src/components/Groups/{Tree => Detail}/MoveTree.tsx (93%) rename typescript/Frontend/src/components/Groups/{Tree => }/GroupTree.tsx (83%) delete mode 100644 typescript/Frontend/src/components/Groups/Tree/GroupTree.scss rename typescript/Frontend/src/components/Installations/{ => Detail}/Installation.tsx (85%) rename typescript/Frontend/src/components/Installations/{ => Detail}/InstallationForm.tsx (90%) delete mode 100644 typescript/Frontend/src/components/Installations/ExampleLogData.tsx rename typescript/Frontend/src/components/Installations/{ => LiveView}/LiveView.tsx (80%) rename typescript/Frontend/src/components/Installations/{Log => LiveView}/TopologyBox.tsx (100%) rename typescript/Frontend/src/components/Installations/{Log => LiveView}/TopologyColumn.tsx (100%) rename typescript/Frontend/src/components/Installations/{Log => LiveView}/TopologyFlow.scss (100%) rename typescript/Frontend/src/components/Installations/{Log => LiveView}/TopologyFlow.tsx (100%) rename typescript/Frontend/src/components/Installations/{Log => LiveView}/TopologyView.tsx (99%) rename typescript/Frontend/src/components/Installations/Log/{ => DatePicker}/DateRangePicker.tsx (93%) rename typescript/Frontend/src/components/Installations/Log/{ => DatePicker}/ShortcutButton.tsx (74%) delete mode 100644 typescript/Frontend/src/components/Installations/Log/TopologyBox.scss delete mode 100644 typescript/Frontend/src/components/Layout/Detail.tsx rename typescript/Frontend/src/components/{Groups/AccessManagement => Layout}/InnovenergyList.tsx (92%) create mode 100644 typescript/Frontend/src/components/Layout/InnovenergyPropertyGrid.tsx rename typescript/Frontend/src/components/{ => Layout}/InnovenergySnackbar.tsx (100%) rename typescript/Frontend/src/components/Layout/{InnovEnergyTreeItem.tsx => InnovenergyTreeItem.tsx} (91%) delete mode 100644 typescript/Frontend/src/index.css delete mode 100644 typescript/Frontend/src/library.scss delete mode 100644 typescript/Frontend/src/logo.svg delete mode 100644 typescript/Frontend/src/resources/innovenergy_Logo_onOrange-2.png(1).png delete mode 100644 typescript/Frontend/src/resources/innovenergy_Logo_onOrange-2.png.png delete mode 100644 typescript/Frontend/src/resources/innovenergy_Logo_onOrange.png diff --git a/typescript/Frontend/lang/de.json b/typescript/Frontend/lang/de.json deleted file mode 100644 index 903777cdf..000000000 --- a/typescript/Frontend/lang/de.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "Information": { - "defaultMessage": "Information" - }, - "addNewChild": { - "defaultMessage": "Neues Kind hinzufügen" - }, - "addNewDialogButton": { - "defaultMessage": "Neue Dialogschaltfläche hinzufügen" - }, - "addUser": { - "defaultMessage": "Nutzer erstellen" - }, - "alarms": { - "defaultMessage": "Alarme" - }, - "applyChanges": { - "defaultMessage": "Änderungen speichern" - }, - "country": { - "defaultMessage": "Land" - }, - "createNewFolder": { - "defaultMessage": "Neuen Ordner erstellen" - }, - "createNewUser": { - "defaultMessage": "Neuen Nutzer erstellen" - }, - "customerName": { - "defaultMessage": "Kundenname" - }, - "email": { - "defaultMessage": "Email" - }, - "english": { - "defaultMessage": "Englisch" - }, - "error": { - }, - "folder": { - "defaultMessage": "Ordner" - }, - "german": { - "defaultMessage": "Deutsch" - }, - "groupTabs": { - "defaultMessage": "Gruppen" - }, - "groupTree": { - "defaultMessage": "Gruppenbaum" - }, - "information": { - "defaultMessage": "Information" - }, - "inheritedAccess": { - "defaultMessage": "Vererbter Zugriff von" - }, - "installation": { - "defaultMessage": "Installation" - }, - "installationTabs": { - "defaultMessage": "Installationen" - }, - "installations": { - "defaultMessage": "Installationen" - }, - "lastWeek": { - "defaultMessage": "Letzte Woche" - }, - "location": { - "defaultMessage": "Standort" - }, - "log": { - "defaultMessage": "Logbuch" - }, - "logout": { - "defaultMessage": "Abmelden" - }, - "makeASelection": { - "defaultMessage": "Bitte wählen Sie links eine Auswahl" - }, - "manageAccess": { - "defaultMessage": "Zugriff verwalten" - }, - "move": { - "defaultMessage": "Verschieben" - }, - "moveTo": { - "defaultMessage": "Verschieben zu" - }, - "moveTree": { - "defaultMessage": "Baum verschieben" - }, - "name": { - "defaultMessage": "Name" - }, - "navigationTabs": { - "defaultMessage": "Navigation" - }, - "orderNumbers": { - "defaultMessage": "Bestellnummer" - }, - "region": { - "defaultMessage": "Region" - }, - "requiredLocation": { - "defaultMessage": "Standort ist erforderlich" - }, - "requiredName": { - "defaultMessage": "Name ist erforderlich" - }, - "requiredRegion": { - "defaultMessage": "Region ist erforderlich" - }, - "search": { - "defaultMessage": "Suche" - }, - "submit": { - "defaultMessage": "Senden" - }, - "updateFolderErrorMessage": { - "defaultMessage": "Fehler, Ordner kann nicht aktualisiert werden" - }, - "updatedSuccessfully": { - "defaultMessage": "Erfolgreich aktualisiert" - }, - "user": { - "defaultMessage": "Nutzer" - }, - "userTabs": { - "defaultMessage": "Nutzer" - }, - "users": { - "defaultMessage": "Nutzer" - } -} diff --git a/typescript/Frontend/lang/en.json b/typescript/Frontend/lang/en.json deleted file mode 100644 index 57cfe6a64..000000000 --- a/typescript/Frontend/lang/en.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "Information": "Information", - "addNewChild": "Add new child", - "addNewDialogButton": "Add new dialog button", - "addUser": "Create user", - "alarms": "Alarms", - "applyChanges": "Apply changes", - "country": "Country", - "createNewFolder": "Create new folder", - "createNewUser": "Create new user", - "customerName": "Customer", - "email": "Email", - "english": "English", - "error": {}, - "folder": "Folder", - "german": "German", - "groupTabs": "Group tabs", - "groupTree": "Group tree", - "information": "Information", - "inheritedAccess": "Inherited access from", - "installation": "Installation", - "installationTabs": "Installation tabs", - "installations": "Installations", - "lastWeek": "Last week", - "location": "Location", - "log": "Log", - "logout": "Logout", - "makeASelection": "Please make a selection on the left", - "manageAccess": "Manage access", - "move": "Move", - "moveTo": "Move to", - "moveTree": "Move tree", - "name": "Name", - "navigationTabs": "Navigation tabs", - "orderNumbers": "Order number", - "region": "Region", - "requiredLocation": "Location is required", - "requiredName": "Name is required", - "requiredRegion": "Region is required", - "search": "Search", - "submit": "Submit", - "updateFolderErrorMessage": "Couldn't update folder, an error occured", - "updatedSuccessfully": "Updated successfully", - "user": "User", - "userTabs": "user tabs", - "users": "Users" -} diff --git a/typescript/Frontend/lang/fr.json b/typescript/Frontend/lang/fr.json deleted file mode 100644 index a1178e87d..000000000 --- a/typescript/Frontend/lang/fr.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "Information": { - "defaultMessage": "Informations" - }, - "addNewChild": { - "defaultMessage": "Ajouter un nouvel enfant" - }, - "addNewDialogButton": { - "defaultMessage": "Ajouter un nouveau bouton de dialogue" - }, - "addUser": { - "defaultMessage": "Créer un utilisateur" - }, - "alarms": { - "defaultMessage": "Alarmes" - }, - "applyChanges": { - "defaultMessage": "Appliquer les modifications" - }, - "country": { - "defaultMessage": "Pays" - }, - "createNewFolder": { - "defaultMessage": "Créer un nouveau dossier" - }, - "createNewUser": { - "defaultMessage": "Créer un nouvel utilisateur" - }, - "customerName": { - "defaultMessage": "Nom du client" - }, - "email": { - "defaultMessage": "E-mail" - }, - "english": { - "defaultMessage": "Anglais" - }, - "error": { - }, - "folder": { - "defaultMessage": "Dossier" - }, - "german": { - "defaultMessage": "Allemand" - }, - "groupTabs": { - "defaultMessage": "Onglets de groupe" - }, - "groupTree": { - "defaultMessage": "Arbre de groupe" - }, - "information": { - "defaultMessage": "Informations" - }, - "inheritedAccess": { - "defaultMessage": "Accès hérité de" - }, - "installation": { - "defaultMessage": "Installation" - }, - "installationTabs": { - "defaultMessage": "Onglets d'installation" - }, - "installations": { - "defaultMessage": "Installations" - }, - "lastWeek": { - "defaultMessage": "La semaine dernière" - }, - "location": { - "defaultMessage": "Localisation" - }, - "log": { - "defaultMessage": "Journal" - }, - "logout": { - "defaultMessage": "Déconnexion" - }, - "makeASelection": { - "defaultMessage": "Veuillez faire une sélection à gauche" - }, - "manageAccess": { - "defaultMessage": "Gérer l'accès" - }, - "move": { - "defaultMessage": "Déplacer" - }, - "moveTo": { - "defaultMessage": "Déplacer à" - }, - "moveTree": { - "defaultMessage": "Déplacer l'arbre" - }, - "name": { - "defaultMessage": "Nom" - }, - "navigationTabs": { - "defaultMessage": "Onglets de navigation" - }, - "orderNumbers": { - "defaultMessage": "Numéro de commande" - }, - "region": { - "defaultMessage": "Région" - }, - "requiredLocation": { - "defaultMessage": "L'emplacement est requis" - }, - "requiredName": { - "defaultMessage": "Le nom est obligatoire" - }, - "requiredRegion": { - "defaultMessage": "La région est obligatoire" - }, - "search": { - "defaultMessage": "Recherche" - }, - "submit": { - "defaultMessage": "Soumettre" - }, - "updateFolderErrorMessage": { - "defaultMessage": "Une erreur s'est produite, impossible de mettre à jour le dossier." - }, - "updatedSuccessfully": { - "defaultMessage": "Mise à jour réussie" - }, - "user": { - "defaultMessage": "Utilisateur" - }, - "userTabs": { - "defaultMessage": "Onglets utilisateurs" - }, - "users": { - "defaultMessage": "Utilisateurs" - } -} diff --git a/typescript/Frontend/src/App.css b/typescript/Frontend/src/App.css deleted file mode 100644 index cde4cdc47..000000000 --- a/typescript/Frontend/src/App.css +++ /dev/null @@ -1,39 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/typescript/Frontend/src/App.test.tsx b/typescript/Frontend/src/App.test.tsx deleted file mode 100644 index 2a68616d9..000000000 --- a/typescript/Frontend/src/App.test.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/typescript/Frontend/src/App.tsx b/typescript/Frontend/src/App.tsx index 52117d18a..0df1873f1 100644 --- a/typescript/Frontend/src/App.tsx +++ b/typescript/Frontend/src/App.tsx @@ -4,7 +4,7 @@ import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom"; import { Container, Grid, Box } from "@mui/material"; import routes from "./routes.json"; -import { IntlProvider, MessageFormatElement } from "react-intl"; +import { IntlProvider } from "react-intl"; import { useContext, useState } from "react"; import en from "./lang/en.json"; import de from "./lang/de.json"; @@ -28,9 +28,9 @@ const App = () => { const getTranslations = () => { switch (language) { case "en": - return de; - case "de": return en; + case "de": + return de; case "fr": return fr; } @@ -78,7 +78,7 @@ const App = () => { bgcolor={colors.greyLight} pt={3} borderTop="2px solid" - borderColor=" #a8b0be" + borderColor={colors.darkGrey} flex="1 0 auto" > diff --git a/typescript/Frontend/src/Login.tsx b/typescript/Frontend/src/Login.tsx index f23bcb958..8718f5ef1 100644 --- a/typescript/Frontend/src/Login.tsx +++ b/typescript/Frontend/src/Login.tsx @@ -1,11 +1,5 @@ import React, { useContext, useState } from "react"; -import { - Alert, - CircularProgress, - Grid, - Typography, - useTheme, -} from "@mui/material"; +import { Alert, CircularProgress, Grid, useTheme } from "@mui/material"; import Container from "@mui/material/Container"; import { axiosConfigWithoutToken } from "./config/axiosConfig"; import InnovenergyTextfield from "./components/Layout/InnovenergyTextfield"; diff --git a/typescript/Frontend/src/components/Context/S3CredentialsContextProvider.tsx b/typescript/Frontend/src/components/Context/S3CredentialsContextProvider.tsx index ae072a2c8..bef707611 100644 --- a/typescript/Frontend/src/components/Context/S3CredentialsContextProvider.tsx +++ b/typescript/Frontend/src/components/Context/S3CredentialsContextProvider.tsx @@ -30,13 +30,6 @@ const S3CredentialsContextProvider = ({ const saveS3Credentials = (credentials: S3Credentials, id: string) => { const s3Bucket = id + "-3e5b3069-214a-43ee-8d85-57d72000c19d"; setS3Credentials({ s3Bucket, ...credentials }); - /* setS3Credentials({ - s3Region: "sos-ch-dk-2", - s3Provider: "exo.io", - s3Key: "EXO15c0bf710e158e9b83270f0a", - s3Secret: "Dd5jYSiZtt_Zt5Ba5mDmaiLCdASUaKLfduSKY-SU-lg", - s3Bucket: "saliomameiringen", - });*/ }; const fetchData = (timestamp: UnixTime): Promise> => { diff --git a/typescript/Frontend/src/components/Groups/AccessManagement/AccessManagement.tsx b/typescript/Frontend/src/components/Groups/AccessManagement/AccessManagement.tsx index fa8c5da02..c2ba3a750 100644 --- a/typescript/Frontend/src/components/Groups/AccessManagement/AccessManagement.tsx +++ b/typescript/Frontend/src/components/Groups/AccessManagement/AccessManagement.tsx @@ -1,7 +1,7 @@ import { Grid } from "@mui/material"; import UsersContextProvider from "../../Context/UsersContextProvider"; import AvailableUserDialog from "./AvailableUserDialog"; -import InnovenergyList from "./InnovenergyList"; +import InnovenergyList from "../../Layout/InnovenergyList"; import UsersWithDirectAccess from "./UsersWithDirectAccess"; import UsersWithInheritedAccess from "./UsersWithInheritedAccess"; import { useContext } from "react"; diff --git a/typescript/Frontend/src/components/Groups/AccessManagement/AvailableUserDialog.tsx b/typescript/Frontend/src/components/Groups/AccessManagement/AvailableUserDialog.tsx index 9d576d323..cbdf00408 100644 --- a/typescript/Frontend/src/components/Groups/AccessManagement/AvailableUserDialog.tsx +++ b/typescript/Frontend/src/components/Groups/AccessManagement/AvailableUserDialog.tsx @@ -4,7 +4,6 @@ import { DialogContent, DialogTitle, TextField, - colors, Alert, } from "@mui/material"; import DialogActions from "@mui/material/DialogActions"; diff --git a/typescript/Frontend/src/components/Groups/AccessManagement/UsersWithDirectAccess.tsx b/typescript/Frontend/src/components/Groups/AccessManagement/UsersWithDirectAccess.tsx index 360d2727f..79ddc89ce 100644 --- a/typescript/Frontend/src/components/Groups/AccessManagement/UsersWithDirectAccess.tsx +++ b/typescript/Frontend/src/components/Groups/AccessManagement/UsersWithDirectAccess.tsx @@ -18,11 +18,11 @@ import { UserContext } from "../../Context/UserContextProvider"; import { FormattedMessage } from "react-intl"; const UsersWithDirectAccess = () => { + const { id } = useParams(); + const [error, setError] = useState(); const { fetchUsersWithDirectAccessForResource, directAccessUsers } = useContext(UsersContext); - const [error, setError] = useState(); const { currentType } = useContext(GroupContext); - const { id } = useParams(); const { getCurrentUser } = useContext(UserContext); useEffect(() => { diff --git a/typescript/Frontend/src/components/Groups/AddNewButtons.tsx b/typescript/Frontend/src/components/Groups/AddNewButtons.tsx index 7f43adee0..a4522e34a 100644 --- a/typescript/Frontend/src/components/Groups/AddNewButtons.tsx +++ b/typescript/Frontend/src/components/Groups/AddNewButtons.tsx @@ -1,13 +1,10 @@ -import { Dialog, DialogContent, DialogTitle, IconButton } from "@mui/material"; import { useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import axiosConfig from "../../config/axiosConfig"; import { I_Folder, I_Installation } from "../../util/types"; -import FolderForm from "./FolderForm"; -import CloseIcon from "@mui/icons-material/Close"; -import InnovenergyButton from "../Layout/InnovenergyButton"; -import InstallationForm from "../Installations/InstallationForm"; -import AddNewDialog from "./AddNew"; +import FolderForm from "./Detail/FolderForm"; +import InstallationForm from "../Installations/Detail/InstallationForm"; +import AddNewDialog from "./AddNewDialog"; interface AddNewDialogProps { values: I_Folder | I_Installation; @@ -15,8 +12,6 @@ interface AddNewDialogProps { } const AddNewButtons = (props: AddNewDialogProps) => { - const [open, setOpen] = useState(false); - const handleFolderSubmit = (data: I_Folder, childData: Partial) => { return axiosConfig .post("/CreateFolder", { @@ -24,7 +19,6 @@ const AddNewButtons = (props: AddNewDialogProps) => { parentId: data.id, }) .then((res) => { - setOpen(false); return res; }); }; @@ -39,7 +33,6 @@ const AddNewButtons = (props: AddNewDialogProps) => { parentId: data.id, }) .then((res) => { - setOpen(false); return res; }); }; diff --git a/typescript/Frontend/src/components/Groups/AddNew.tsx b/typescript/Frontend/src/components/Groups/AddNewDialog.tsx similarity index 100% rename from typescript/Frontend/src/components/Groups/AddNew.tsx rename to typescript/Frontend/src/components/Groups/AddNewDialog.tsx index 9215ee72b..9c3efadda 100644 --- a/typescript/Frontend/src/components/Groups/AddNew.tsx +++ b/typescript/Frontend/src/components/Groups/AddNewDialog.tsx @@ -12,8 +12,8 @@ interface AddNewDialogProps { } const AddNewDialog = (props: AddNewDialogProps) => { - const [open, setOpen] = useState(false); const { form, id, message } = props; + const [open, setOpen] = useState(false); const intl = useIntl(); return ( <> diff --git a/typescript/Frontend/src/components/Groups/Folder.tsx b/typescript/Frontend/src/components/Groups/Detail/Folder.tsx similarity index 89% rename from typescript/Frontend/src/components/Groups/Folder.tsx rename to typescript/Frontend/src/components/Groups/Detail/Folder.tsx index 991d7d2a4..fdbc87c92 100644 --- a/typescript/Frontend/src/components/Groups/Folder.tsx +++ b/typescript/Frontend/src/components/Groups/Detail/Folder.tsx @@ -2,12 +2,11 @@ import { Box, CircularProgress, Alert, useTheme } from "@mui/material"; import { AxiosError } from "axios"; import { useState, useEffect } from "react"; import { useParams } from "react-router-dom"; -import axiosConfig from "../../config/axiosConfig"; -import { I_Folder } from "../../util/types"; -import AddNewButtons from "./AddNewButtons"; +import axiosConfig from "../../../config/axiosConfig"; +import { I_Folder } from "../../../util/types"; +import AddNewButtons from "../AddNewButtons"; import FolderForm from "./FolderForm"; -import MoveDialog from "./Tree/MoveDialog"; -import { colors } from "index"; +import MoveDialog from "./MoveDialog"; const Folder = () => { const { id } = useParams(); @@ -43,7 +42,7 @@ const Folder = () => { { const { values, additionalButtons, handleSubmit } = props; - const intl = useIntl(); - const { fetchData } = useContext(GroupContext); - const { getCurrentUser } = useContext(UserContext); const [snackbarOpen, setSnackbarOpen] = useState(false); const [error, setError] = useState(); const [loading, setLoading] = useState(false); + const intl = useIntl(); + const theme = useTheme(); + const { fetchData } = useContext(GroupContext); + const { getCurrentUser } = useContext(UserContext); + const readOnly = !getCurrentUser().hasWriteAccess; const formik = useFormik({ @@ -55,7 +55,6 @@ const FolderForm = (props: I_CustomerFormProps) => { }); }, }); - const theme = useTheme(); const rows: I_InnovenergyTextfieldProps[] = [ { @@ -83,33 +82,31 @@ const FolderForm = (props: I_CustomerFormProps) => { ]; return ( - <> -
- - - {loading && ( - - )} - {!readOnly && - additionalButtons && - additionalButtons.map((button) => button)} - {!readOnly && ( - - - - )} - - - - +
+ + + {loading && ( + + )} + {!readOnly && + additionalButtons && + additionalButtons.map((button) => button)} + {!readOnly && ( + + + + )} + + + ); }; diff --git a/typescript/Frontend/src/components/Groups/Tree/MoveDialog.tsx b/typescript/Frontend/src/components/Groups/Detail/MoveDialog.tsx similarity index 100% rename from typescript/Frontend/src/components/Groups/Tree/MoveDialog.tsx rename to typescript/Frontend/src/components/Groups/Detail/MoveDialog.tsx index 8df1da56d..650dc2937 100644 --- a/typescript/Frontend/src/components/Groups/Tree/MoveDialog.tsx +++ b/typescript/Frontend/src/components/Groups/Detail/MoveDialog.tsx @@ -17,13 +17,13 @@ const MoveDialog = (props: MoveDialogProps) => { const { values } = props; const [open, setOpen] = useState(false); - const [selectedParentId, setSelectedParentId] = useState( values.parentId ); + const [error, setError] = useState(); + const { fetchData, currentType } = useContext(GroupContext); const { id } = useParams(); - const [error, setError] = useState(); const handleMove = () => { const route = diff --git a/typescript/Frontend/src/components/Groups/Tree/MoveTree.tsx b/typescript/Frontend/src/components/Groups/Detail/MoveTree.tsx similarity index 93% rename from typescript/Frontend/src/components/Groups/Tree/MoveTree.tsx rename to typescript/Frontend/src/components/Groups/Detail/MoveTree.tsx index bf7b5744e..4210f339f 100644 --- a/typescript/Frontend/src/components/Groups/Tree/MoveTree.tsx +++ b/typescript/Frontend/src/components/Groups/Detail/MoveTree.tsx @@ -6,7 +6,7 @@ import { I_Folder, I_Installation } from "../../../util/types"; import { GroupContext } from "../../Context/GroupContextProvider"; import { instanceOfFolder } from "../../../util/group.util"; import { useIntl } from "react-intl"; -import InnovEnergyTreeItem from "../../Layout/InnovEnergyTreeItem"; +import InnovenergyTreeItem from "../../Layout/InnovenergyTreeItem"; interface MoveTreeProps { setSelectedParentId: (value: number) => void; @@ -29,7 +29,7 @@ const MoveTree = (props: MoveTreeProps) => { .filter((element) => element.type === "Folder") .map((element) => { return ( - { label={element.name} > {getNodes(element)} - + ); }); }; diff --git a/typescript/Frontend/src/components/Groups/GroupTabs.tsx b/typescript/Frontend/src/components/Groups/GroupTabs.tsx index e53311afa..9e1ec6d73 100644 --- a/typescript/Frontend/src/components/Groups/GroupTabs.tsx +++ b/typescript/Frontend/src/components/Groups/GroupTabs.tsx @@ -12,6 +12,8 @@ import { useTheme } from "@mui/material"; const GroupTabs = () => { const theme = useTheme(); + const intl = useIntl(); + const { currentType } = useContext(GroupContext); const routeMatch = useRouteMatch([ routes.installations + routes.tree + routes.folder + ":id", routes.installations + routes.tree + routes.manageAccess + ":id", @@ -19,8 +21,6 @@ const GroupTabs = () => { ]); const id = routeMatch?.params?.id; - const intl = useIntl(); - const { currentType } = useContext(GroupContext); if (id) { return ( @@ -29,14 +29,15 @@ const GroupTabs = () => { {currentType === "Folder" ? ( { to={routes.folder + id} /> ) : ( - { sx={{ "&.Mui-selected": { color: colors.black, - backgroundColor: theme.palette.primary.dark, + backgroundColor: theme.palette.primary.dark, borderColor: theme.palette.text.disabled, borderBottom: 0, - mb:-1/8, - }}} + mb: -1 / 8, + }, + }} id="styled-tab-manage-access" label={intl.formatMessage({ id: "manageAccess", diff --git a/typescript/Frontend/src/components/Groups/Tree/GroupTree.tsx b/typescript/Frontend/src/components/Groups/GroupTree.tsx similarity index 83% rename from typescript/Frontend/src/components/Groups/Tree/GroupTree.tsx rename to typescript/Frontend/src/components/Groups/GroupTree.tsx index 26c85dc8a..4c2084fbb 100644 --- a/typescript/Frontend/src/components/Groups/Tree/GroupTree.tsx +++ b/typescript/Frontend/src/components/Groups/GroupTree.tsx @@ -2,16 +2,15 @@ import TreeView from "@mui/lab/TreeView"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import { ReactNode, useContext, useEffect, useState } from "react"; -import { TreeItem } from "@mui/lab"; -import { I_Folder, I_Installation } from "../../../util/types"; +import { I_Folder, I_Installation } from "../../util/types"; import { Link } from "react-router-dom"; -import routes from "../../../routes.json"; -import { GroupContext } from "../../Context/GroupContextProvider"; -import { instanceOfFolder } from "../../../util/group.util"; +import routes from "../../routes.json"; +import { GroupContext } from "../Context/GroupContextProvider"; +import { instanceOfFolder } from "../../util/group.util"; import { Grid, CircularProgress, useTheme } from "@mui/material"; import { useIntl } from "react-intl"; -import { colors } from "../../.."; -import InnovEnergyTreeItem from "../../Layout/InnovEnergyTreeItem"; +import InnovenergyTreeItem from "../Layout/InnovenergyTreeItem"; +import TypeIcon from "./TypeIcon"; const GroupTree = () => { const { setCurrentType, fetchData, data, loading } = useContext(GroupContext); @@ -48,19 +47,24 @@ const GroupTree = () => { }} draggable={false} > - + {element.name} + + } onClick={() => setCurrentType(element.type)} > {getNodes(element)} - + ); }); }; + if (loading) { return ( diff --git a/typescript/Frontend/src/components/Groups/Groups.tsx b/typescript/Frontend/src/components/Groups/Groups.tsx index 337bdd205..952a20d8e 100644 --- a/typescript/Frontend/src/components/Groups/Groups.tsx +++ b/typescript/Frontend/src/components/Groups/Groups.tsx @@ -1,12 +1,12 @@ import { Grid } from "@mui/material"; import { Routes, Route } from "react-router"; import routes from "../../routes.json"; -import Folder from "./Folder"; +import Folder from "./Detail/Folder"; import GroupTabs from "./GroupTabs"; import GroupContextProvider from "../Context/GroupContextProvider"; -import GroupTree from "./Tree/GroupTree"; +import GroupTree from "./GroupTree"; import AccessManagement from "./AccessManagement/AccessManagement"; -import Installation from "../Installations/Installation"; +import Installation from "../Installations/Detail/Installation"; import useRouteMatch from "../../hooks/useRouteMatch"; import useInstallation from "../../hooks/useInstallation"; import { useEffect } from "react"; @@ -25,7 +25,6 @@ const Groups = () => { const id = routeMatch?.params?.id; useEffect(() => { - // TODO remove if getInstallation(id); }, [id]); return ( diff --git a/typescript/Frontend/src/components/Groups/Tree/GroupTree.scss b/typescript/Frontend/src/components/Groups/Tree/GroupTree.scss deleted file mode 100644 index 2c7cc8fa1..000000000 --- a/typescript/Frontend/src/components/Groups/Tree/GroupTree.scss +++ /dev/null @@ -1,4 +0,0 @@ -.groupTreeLink { - text-decoration: "none"; - color: "red"; -} \ No newline at end of file diff --git a/typescript/Frontend/src/components/Groups/TypeIcon.tsx b/typescript/Frontend/src/components/Groups/TypeIcon.tsx index c86b4afd7..bf8fb7397 100644 --- a/typescript/Frontend/src/components/Groups/TypeIcon.tsx +++ b/typescript/Frontend/src/components/Groups/TypeIcon.tsx @@ -4,11 +4,16 @@ import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; interface TypeIconProps { type: string | undefined; } + const TypeIcon = (props: TypeIconProps) => { return ( -
- {props.type === "Folder" ? : } -
+ <> + {props.type === "Folder" ? ( + + ) : ( + + )} + ); }; diff --git a/typescript/Frontend/src/components/Installations/Installation.tsx b/typescript/Frontend/src/components/Installations/Detail/Installation.tsx similarity index 85% rename from typescript/Frontend/src/components/Installations/Installation.tsx rename to typescript/Frontend/src/components/Installations/Detail/Installation.tsx index c1b1b2eae..f620b342b 100644 --- a/typescript/Frontend/src/components/Installations/Installation.tsx +++ b/typescript/Frontend/src/components/Installations/Detail/Installation.tsx @@ -2,12 +2,12 @@ import { Alert, Box, CircularProgress, useTheme } from "@mui/material"; import { AxiosError } from "axios"; import { useContext, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; -import axiosConfig from "../../config/axiosConfig"; -import { I_Folder, I_Installation } from "../../util/types"; +import axiosConfig from "../../../config/axiosConfig"; +import { I_Folder, I_Installation } from "../../../util/types"; import InstallationForm from "./InstallationForm"; -import { colors } from "../.."; -import { S3CredentialsContext } from "../Context/S3CredentialsContextProvider"; -import MoveDialog from "../Groups/Tree/MoveDialog"; +import { colors } from "../../../index"; +import { S3CredentialsContext } from "../../Context/S3CredentialsContextProvider"; +import MoveDialog from "../../Groups/Detail/MoveDialog"; interface I_InstallationProps { loading?: boolean; @@ -31,7 +31,7 @@ const Installation = (props: I_InstallationProps) => { { return (
- + {/*{hasMoveButton && !readOnly && }*/} {!readOnly && diff --git a/typescript/Frontend/src/components/Installations/ExampleLogData.tsx b/typescript/Frontend/src/components/Installations/ExampleLogData.tsx deleted file mode 100644 index 643386b7b..000000000 --- a/typescript/Frontend/src/components/Installations/ExampleLogData.tsx +++ /dev/null @@ -1,492 +0,0 @@ -import { I_GraphData } from "../../util/types"; - -export type Datum = string | number | boolean | Array; -type LogData = Record; - -export type TimeSeries = Record; - -export const timeSeries: TimeSeries = { - 1673427378: { - "TruConvertAc/Ac/Current": 124, - "TruConvertAc/Ac/Voltage": 200, - "TruConvertAc/Ac/Phi": 2.89, - "TruConvertAc/Frequency": 2.89, - }, - 1674427380: { - "TruConvertAc/Ac/Current": 150, - "TruConvertAc/Ac/Voltage": 120, - "TruConvertAc/Ac/Phi": 3.21, - "TruConvertAc/Frequency": 2.41, - }, - 1675427382: { - "TruConvertAc/Ac/Current": 153, - "TruConvertAc/Ac/Voltage": 140, - "TruConvertAc/Ac/Phi": 3.9, - "TruConvertAc/Frequency": 4.41, - }, -}; - -const exampleLogData: I_GraphData[] = [ - { - TimeStamp: "1673427378", - Devices: [ - { - Name: "TruConvertAc", - Type: "Inverter", - Ac: [ - { - Current: 2.85, - Voltage: 236.2, - Phi: 2.896, - }, - { - Current: 2.87, - Voltage: 234.5, - Phi: 2.793, - }, - { - Current: 2.65, - Voltage: 240.6, - Phi: 2.941, - }, - ], - Frequency: 50.02, - Dc: { - Current: -2.254, - Voltage: 869, - }, - Alarms: [], - MainState: "Operation", - }, - { - Name: "TruConvertDc", - Type: "DcDc", - Dc: { - Current: -2.017, - Voltage: 868, - }, - Dc48: { - Current: -31, - Voltage: 55.9, - }, - Warnings: [], - Alarms: [], - "DC Power": -1751, - }, - { - Name: "EmuMeter", - Type: "Grid", - Ac: [ - { - Current: 15.658, - Voltage: 236.3, - Phi: 0.318, - }, - { - Current: 14.052, - Voltage: 234.8, - Phi: 0.2, - }, - { - Current: 9.046, - Voltage: 240.4, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "EmuMeter", - Type: "AcInToAcOut", - Ac: [ - { - Current: 15.658, - Voltage: 236.3, - Phi: 0.318, - }, - { - Current: 14.052, - Voltage: 234.8, - Phi: 0.2, - }, - { - Current: 9.046, - Voltage: 240.4, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "AMPT", - Type: "PvOnDc", - Dc: { - Current: 0.229, - Voltage: 921.855, - }, - }, - { - Name: "48TL Battery", - Type: "Battery", - Dc48: { - Current: 38.56, - Voltage: 53.29, - }, - Alarms: [], - Warnings: [], - Soc: 21.6, - HeaterOn: true, - EocReached: false, - BatteryCold: false, - Temperature: 265.3, - }, - ], - }, - { - TimeStamp: "1673427380", - Devices: [ - { - Name: "TruConvertAc", - Type: "Inverter", - Ac: [ - { - Current: 3.01, - Voltage: 235.6, - Phi: 2.941, - }, - { - Current: 3.04, - Voltage: 234.4, - Phi: 2.739, - }, - { - Current: 2.48, - Voltage: 241.1, - Phi: 2.765, - }, - ], - Frequency: 50.02, - Dc: { - Current: -2.215, - Voltage: 868, - }, - Alarms: [], - MainState: "Operation", - }, - { - Name: "TruConvertDc", - Type: "DcDc", - Dc: { - Current: -1.953, - Voltage: 868, - }, - Dc48: { - Current: -30, - Voltage: 55.9, - }, - Warnings: [], - Alarms: [], - "DC Power": -1695, - }, - { - Name: "EmuMeter", - Type: "Grid", - Ac: [ - { - Current: 15.658, - Voltage: 236.3, - Phi: 0.318, - }, - { - Current: 14.052, - Voltage: 234.8, - Phi: 0.2, - }, - { - Current: 9.046, - Voltage: 240.4, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "EmuMeter", - Type: "AcInToAcOut", - Ac: [ - { - Current: 15.658, - Voltage: 236.3, - Phi: 0.318, - }, - { - Current: 14.052, - Voltage: 234.8, - Phi: 0.2, - }, - { - Current: 9.046, - Voltage: 240.4, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "AMPT", - Type: "PvOnDc", - Dc: { - Current: 0.229, - Voltage: 921.855, - }, - }, - { - Name: "48TL Battery", - Type: "Battery", - Dc48: { - Current: 38.51, - Voltage: 53.29, - }, - Alarms: [], - Warnings: [], - Soc: 21.6, - HeaterOn: true, - EocReached: false, - BatteryCold: false, - Temperature: 265.3, - }, - ], - }, - { - TimeStamp: "1673427381", - Devices: [ - { - Name: "TruConvertAc", - Type: "Inverter", - Ac: [ - { - Current: 0.4, - Voltage: 237.2, - Phi: 1.4, - }, - { - Current: 0.55, - Voltage: 235.6, - Phi: 1.551, - }, - { - Current: 0.44, - Voltage: 241.7, - Phi: 1.501, - }, - ], - Frequency: 50.02, - Dc: { - Current: 0.007, - Voltage: 849, - }, - Alarms: [], - MainState: "Operation", - }, - { - Name: "TruConvertDc", - Type: "DcDc", - Dc: { - Current: 0.153, - Voltage: 849, - }, - Dc48: { - Current: 3, - Voltage: 52.0, - }, - Warnings: [], - Alarms: [], - "DC Power": 130, - }, - { - Name: "EmuMeter", - Type: "Grid", - Ac: [ - { - Current: 15.658, - Voltage: 236.3, - Phi: 0.318, - }, - { - Current: 14.052, - Voltage: 234.8, - Phi: 0.2, - }, - { - Current: 9.046, - Voltage: 240.4, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "EmuMeter", - Type: "AcInToAcOut", - Ac: [ - { - Current: 15.658, - Voltage: 236.3, - Phi: 0.318, - }, - { - Current: 14.052, - Voltage: 234.8, - Phi: 0.2, - }, - { - Current: 9.046, - Voltage: 240.4, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "AMPT", - Type: "PvOnDc", - Dc: { - Current: 0.229, - Voltage: 921.855, - }, - }, - { - Name: "48TL Battery", - Type: "Battery", - Dc48: { - Current: 6.14, - Voltage: 51.96, - }, - Alarms: [], - Warnings: [], - Soc: 21.6, - HeaterOn: true, - EocReached: false, - BatteryCold: false, - Temperature: 265.3, - }, - ], - }, - { - TimeStamp: "1673427383", - Devices: [ - { - Name: "TruConvertAc", - Type: "Inverter", - Ac: [ - { - Current: 1.16, - Voltage: 237.7, - Phi: 0.376, - }, - { - Current: 1.25, - Voltage: 236.0, - Phi: 0.707, - }, - { - Current: 0.98, - Voltage: 242.1, - Phi: 0.246, - }, - ], - Frequency: 50.02, - Dc: { - Current: 0.847, - Voltage: 847, - }, - Alarms: [], - MainState: "Operation", - }, - { - Name: "TruConvertDc", - Type: "DcDc", - Dc: { - Current: 0.979, - Voltage: 846, - }, - Dc48: { - Current: 18, - Voltage: 51.2, - }, - Warnings: [], - Alarms: [], - "DC Power": 828, - }, - { - Name: "EmuMeter", - Type: "Grid", - Ac: [ - { - Current: 12.563, - Voltage: 237.2, - Phi: 0.376, - }, - { - Current: 10.913, - Voltage: 235.6, - Phi: 0.246, - }, - { - Current: 5.983, - Voltage: 241.2, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "EmuMeter", - Type: "AcInToAcOut", - Ac: [ - { - Current: 12.563, - Voltage: 237.2, - Phi: 0.376, - }, - { - Current: 10.913, - Voltage: 235.6, - Phi: 0.246, - }, - { - Current: 5.983, - Voltage: 241.2, - Phi: 0.142, - }, - ], - Frequency: 50, - }, - { - Name: "AMPT", - Type: "PvOnDc", - Dc: { - Current: 0.229, - Voltage: 921.855, - }, - }, - { - Name: "48TL Battery", - Type: "Battery", - Dc48: { - Current: -7.99, - Voltage: 51.31, - }, - Alarms: [], - Warnings: [], - Soc: 21.6, - HeaterOn: true, - EocReached: false, - BatteryCold: false, - Temperature: 265.3, - }, - ], - }, -]; - -export default exampleLogData; diff --git a/typescript/Frontend/src/components/Installations/InstallationList.tsx b/typescript/Frontend/src/components/Installations/InstallationList.tsx index 2b19404a0..b0093af8c 100644 --- a/typescript/Frontend/src/components/Installations/InstallationList.tsx +++ b/typescript/Frontend/src/components/Installations/InstallationList.tsx @@ -1,13 +1,7 @@ import List from "@mui/material/List"; import ListItemButton from "@mui/material/ListItemButton"; import ListItemText from "@mui/material/ListItemText"; -import { - Alert, - CircularProgress, - Divider, - Grid, - useTheme, -} from "@mui/material"; +import { Alert, CircularProgress, Grid, useTheme } from "@mui/material"; import { Link } from "react-router-dom"; import useRouteMatch from "../../hooks/useRouteMatch"; import routes from "../../routes.json"; @@ -21,14 +15,6 @@ interface InstallationListProps { searchQuery: string; } -const getPathWithoutId = (path?: string) => { - if (path) { - const splitString = path.split(":"); - return splitString[0]; - } - return routes.installation; -}; - const filterData = ( searchQuery: string, data: I_Installation[] | undefined @@ -45,15 +31,12 @@ const filterData = ( const InstallationList = (props: InstallationListProps) => { const { fetchData, data, loading, error } = useContext(InstallationsContext); - const filteredData = filterData(props.searchQuery, data); - const routeMatch = useRouteMatch([ routes.installations + routes.list + routes.installation + ":id", routes.installations + routes.list + routes.liveView + ":id", routes.installations + routes.list + routes.log + ":id", ]); - const theme = useTheme(); useEffect(() => { @@ -108,13 +91,13 @@ const InstallationList = (props: InstallationListProps) => { borderStyle: "solid", backgroundColor: theme.palette.primary.dark, "&.Mui-selected": { - backgroundColor: colors.orangeSelected, + backgroundColor: theme.palette.secondary.main, }, ":hover": { - backgroundColor: colors.orangeHover, + backgroundColor: theme.palette.secondary.light, }, "&.Mui-selected:hover": { - backgroundColor: colors.orangeSelected, + backgroundColor: theme.palette.secondary.main, }, }} > diff --git a/typescript/Frontend/src/components/Installations/InstallationTabs.tsx b/typescript/Frontend/src/components/Installations/InstallationTabs.tsx index 4f69755b8..2799f61e0 100644 --- a/typescript/Frontend/src/components/Installations/InstallationTabs.tsx +++ b/typescript/Frontend/src/components/Installations/InstallationTabs.tsx @@ -5,14 +5,13 @@ import routes from "../../routes.json"; import useRouteMatch from "../../hooks/useRouteMatch"; import { useIntl } from "react-intl"; import InnovenergyTab from "../Layout/InnovenergyTab"; -import InnovenergyTabBorder from "../Layout/InnovenergyTab"; import InnovenergyTabs from "components/Layout/InnovenergyTabs"; import { useTheme } from "@mui/material"; -import { red } from "@mui/material/colors"; import { colors } from "index"; const InstallationTabs = () => { const theme = useTheme(); + const intl = useIntl(); const routeMatch = useRouteMatch([ routes.installations + routes.list + routes.installation + ":id", routes.installations + routes.list + routes.liveView + ":id", @@ -20,7 +19,6 @@ const InstallationTabs = () => { ]); const id = routeMatch?.params?.id; - const intl = useIntl(); if (id) { return ( diff --git a/typescript/Frontend/src/components/Installations/Installations.tsx b/typescript/Frontend/src/components/Installations/Installations.tsx index 3106c2779..e77417de0 100644 --- a/typescript/Frontend/src/components/Installations/Installations.tsx +++ b/typescript/Frontend/src/components/Installations/Installations.tsx @@ -1,13 +1,13 @@ import { Grid, colors } from "@mui/material"; import { Routes, Route } from "react-router"; -import LiveView from "./LiveView"; +import LiveView from "./LiveView/LiveView"; import InstallationTabs from "./InstallationTabs"; import Log from "./Log/Log"; import routes from "../../routes.json"; import InstallationsContextProvider from "../Context/InstallationsContextProvider"; import SearchSidebar from "../Layout/Search"; import InstallationList from "./InstallationList"; -import Installation from "./Installation"; +import Installation from "./Detail/Installation"; import CheckboxTree from "./Log/CheckboxTree"; import LogContextProvider from "../Context/LogContextProvider"; import useRouteMatch from "../../hooks/useRouteMatch"; @@ -27,7 +27,6 @@ const Installations = () => { const id = routeMatch?.params?.id; useEffect(() => { - // TODO remove if getInstallation(id); }, [id]); diff --git a/typescript/Frontend/src/components/Installations/LiveView.tsx b/typescript/Frontend/src/components/Installations/LiveView/LiveView.tsx similarity index 80% rename from typescript/Frontend/src/components/Installations/LiveView.tsx rename to typescript/Frontend/src/components/Installations/LiveView/LiveView.tsx index 7091cb9e6..92fde3f08 100644 --- a/typescript/Frontend/src/components/Installations/LiveView.tsx +++ b/typescript/Frontend/src/components/Installations/LiveView/LiveView.tsx @@ -1,6 +1,6 @@ -import TopologyView from "./Log/TopologyView"; +import TopologyView from "./TopologyView"; import { Box, useTheme } from "@mui/material"; -import { colors } from "../../index"; +import { colors } from "../../../index"; const LiveView = () => { const theme = useTheme(); @@ -8,7 +8,7 @@ const LiveView = () => { { const [values, setValues] = useState(null); const { fetchData } = useContext(S3CredentialsContext); - const theme = useTheme(); useEffect(() => { const interval = setInterval(() => { diff --git a/typescript/Frontend/src/components/Installations/Log/CheckboxTree.tsx b/typescript/Frontend/src/components/Installations/Log/CheckboxTree.tsx index e0f833799..fe43470ca 100644 --- a/typescript/Frontend/src/components/Installations/Log/CheckboxTree.tsx +++ b/typescript/Frontend/src/components/Installations/Log/CheckboxTree.tsx @@ -1,5 +1,5 @@ -import { TreeItem, TreeView } from "@mui/lab"; -import { Checkbox, Divider, useTheme } from "@mui/material"; +import { TreeView } from "@mui/lab"; +import { Checkbox } from "@mui/material"; import { useContext, ReactNode } from "react"; import { LogContext } from "../../Context/LogContextProvider"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; @@ -7,12 +7,7 @@ import ChevronRightIcon from "@mui/icons-material/ChevronRight"; import useRouteMatch from "../../../hooks/useRouteMatch"; import routes from "../../../routes.json"; import React from "react"; -import { colors } from "index"; -import InnovEnergyTreeItem from "../../Layout/InnovEnergyTreeItem"; - -export interface ToggleElement { - [key: string]: boolean; -} +import InnovenergyTreeItem from "../../Layout/InnovenergyTreeItem"; export interface TreeElement { id: string; @@ -50,12 +45,13 @@ const CheckboxTree = () => { ) => { event.stopPropagation(); }; + const renderTree = (data: TreeElement[]): ReactNode => { return data.map((element) => { const checked = checkedToggles.find((toggle) => element.id === toggle); const splitName = element.name.split("/"); return ( - { } > {getNodes(element)} - + ); }); }; diff --git a/typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx b/typescript/Frontend/src/components/Installations/Log/DatePicker/DateRangePicker.tsx similarity index 93% rename from typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx rename to typescript/Frontend/src/components/Installations/Log/DatePicker/DateRangePicker.tsx index 3a25c78d5..61338af1c 100644 --- a/typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx +++ b/typescript/Frontend/src/components/Installations/Log/DatePicker/DateRangePicker.tsx @@ -3,11 +3,11 @@ import { DatePicker, LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import dayjs from "dayjs"; import { FormattedMessage } from "react-intl"; +import { createTimes } from "../../../../util/graph.util"; +import { TimeRange, UnixTime } from "../../../../dataCache/time"; +import { useTheme } from "@mui/material"; +import { colors } from "../../../../index"; import ShortcutButton from "./ShortcutButton"; -import { createTimes } from "../../../util/graph.util"; -import { TimeRange, UnixTime } from "../../../dataCache/time"; -import { TextField, useTheme } from "@mui/material"; -import { colors } from "../../.."; interface DateRangePickerProps { setRange: (value: Date[]) => void; @@ -16,8 +16,8 @@ interface DateRangePickerProps { } const DateRangePicker = (props: DateRangePickerProps) => { - const theme = useTheme(); const { setRange, range, getCacheSeries } = props; + const theme = useTheme(); const handleChange = (fromDate: Date, toDate: Date) => { const timeRange = createTimes( diff --git a/typescript/Frontend/src/components/Installations/Log/ShortcutButton.tsx b/typescript/Frontend/src/components/Installations/Log/DatePicker/ShortcutButton.tsx similarity index 74% rename from typescript/Frontend/src/components/Installations/Log/ShortcutButton.tsx rename to typescript/Frontend/src/components/Installations/Log/DatePicker/ShortcutButton.tsx index 31c5b3cff..b34147905 100644 --- a/typescript/Frontend/src/components/Installations/Log/ShortcutButton.tsx +++ b/typescript/Frontend/src/components/Installations/Log/DatePicker/ShortcutButton.tsx @@ -1,8 +1,6 @@ -import { colors } from "@mui/material"; -import { UnixTime, TimeSpan } from "../../../dataCache/time"; -import { createTimes } from "../../../util/graph.util"; -import InnovenergyButton from "../../Layout/InnovenergyButton"; -import { red } from "@mui/material/colors"; +import { UnixTime, TimeSpan } from "../../../../dataCache/time"; +import { createTimes } from "../../../../util/graph.util"; +import InnovenergyButton from "../../../Layout/InnovenergyButton"; interface ShortcutButtonProps { setRange: (value: Date[]) => void; diff --git a/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx b/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx index 5287a2ef1..a0d024f39 100644 --- a/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx +++ b/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx @@ -1,25 +1,23 @@ import Plot from "react-plotly.js"; -import { DataRecord, RecordSeries } from "../../../dataCache/data"; +import { RecordSeries } from "../../../dataCache/data"; import { GraphData, createTimes, getTreeElements, isNumeric, - parseCsv, stringToColor, transformToBarGraphData, } from "../../../util/graph.util"; import { TimeRange, TimeSpan, UnixTime } from "../../../dataCache/time"; import { useCallback, useContext, useEffect, useMemo, useState } from "react"; import { BehaviorSubject, startWith, throttleTime, withLatestFrom } from "rxjs"; -import { S3Access } from "../../../dataCache/S3/S3Access"; import DataCache, { FetchResult } from "../../../dataCache/dataCache"; import { LogContext } from "../../Context/LogContextProvider"; import { isDefined } from "../../../dataCache/utils/maybe"; -import { Data, Icons, Layout, PlotRelayoutEvent, relayout } from "plotly.js"; +import { Data, Icons, Layout, PlotRelayoutEvent } from "plotly.js"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import { FormattedMessage } from "react-intl"; -import DateRangePicker from "./DateRangePicker"; +import DateRangePicker from "./DatePicker/DateRangePicker"; import { LocalizationProvider } from "@mui/x-date-pickers"; import { Alert, useTheme } from "@mui/material"; import { S3CredentialsContext } from "../../Context/S3CredentialsContextProvider"; @@ -28,23 +26,26 @@ const NUMBER_OF_NODES = 100; const ScalarGraph = () => { const timeRange = createTimes( - UnixTime.now() - /* .fromTicks(1682085650) */ - .rangeBefore(TimeSpan.fromDays(1)), + UnixTime.now().rangeBefore(TimeSpan.fromDays(1)), NUMBER_OF_NODES ); + const [timeSeries, setTimeSeries] = useState([]); + const [plotTitles, setPlotTitles] = useState([]); const [range, setRange] = useState([ timeRange[0].toDate(), timeRange[timeRange.length - 1].toDate(), ]); - const [plotTitles, setPlotTitles] = useState([]); const { toggles, setToggles, checkedToggles } = useContext(LogContext); const { fetchData } = useContext(S3CredentialsContext); const times$ = useMemo(() => new BehaviorSubject(timeRange), []); + const cache = useMemo(() => { + return new DataCache(fetchData, TimeSpan.fromSeconds(2)); + }, []); + useEffect(() => { const subscription = cache.gotData .pipe( @@ -57,8 +58,6 @@ const ScalarGraph = () => { setTimeSeries(timeSeries); const toggleValues = timeSeries.find((timeStamp) => timeStamp.value); - console.log("toggles", timeSeries, toggleValues); - if (toggles === null && toggleValues && toggleValues.value) { const treeElements = getTreeElements(toggleValues.value); setToggles(treeElements); @@ -67,10 +66,6 @@ const ScalarGraph = () => { return () => subscription.unsubscribe(); }, [toggles]); - const cache = useMemo(() => { - return new DataCache(fetchData, TimeSpan.fromSeconds(2)); - }, []); - const transformToGraphData = (input: RecordSeries): GraphData => { const transformedObject: any = {}; @@ -95,6 +90,7 @@ const ScalarGraph = () => { setPlotTitles(Object.keys(transformedObject)); } }); + return Object.keys(transformedObject).length > 0 ? transformedObject : plotTitles.reduce( @@ -138,9 +134,7 @@ const ScalarGraph = () => { [getCacheSeries] ); - const theme = useTheme(); const renderGraphs = () => { - console.log("toggles", toggles); if (checkedToggles.length > 0) { const coordinateTimeSeries = transformToGraphData(timeSeries); const visibleGraphs = Object.keys(coordinateTimeSeries).filter((path) => { diff --git a/typescript/Frontend/src/components/Installations/Log/TopologyBox.scss b/typescript/Frontend/src/components/Installations/Log/TopologyBox.scss deleted file mode 100644 index ea381ae6c..000000000 --- a/typescript/Frontend/src/components/Installations/Log/TopologyBox.scss +++ /dev/null @@ -1,10 +0,0 @@ -.topologyBoxTitle{ - margin-block-start: "0"; - margin-block-end: "0"; - background-color: titleColor; - padding: "5px"; - border-top-left-radius: "4px"; - border-top-right-radius: "4px"; - display: "flex"; - justify-content: "center"; - } \ No newline at end of file diff --git a/typescript/Frontend/src/components/Layout/Detail.tsx b/typescript/Frontend/src/components/Layout/Detail.tsx deleted file mode 100644 index c71b1eaae..000000000 --- a/typescript/Frontend/src/components/Layout/Detail.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { Box, CircularProgress, Alert, useTheme } from "@mui/material"; -import { AxiosError } from "axios"; -import { useState, useEffect, FC } from "react"; -import { useParams } from "react-router-dom"; -import axiosConfig from "../../config/axiosConfig"; -export interface I_FormProps { - values: T; - id: string; - hasMoveButton?: boolean; -} -interface I_DetailProps { - formComponent: FC>; - route: string; - hasMoveButton?: boolean; -} -const Detail = (props: I_DetailProps) => { - const { id } = useParams(); - const { formComponent: FormComponent, route, hasMoveButton } = props; - const [values, setValues] = useState(); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(); - - useEffect(() => { - setLoading(true); - axiosConfig - .get(route + id) - .then((res) => { - setValues(res.data); - setLoading(false); - }) - .catch((err: AxiosError) => { - setError(err); - setLoading(false); - }); - }, [id, route]); - const theme = useTheme(); - - if (values && values.id && values.id.toString() === id) { - return ( - - ); - } else if (loading) { - return ( - - - - ); - } else if (error) { - return ( - - {error.message} - - ); - } - return null; -}; - -export default Detail; diff --git a/typescript/Frontend/src/components/Groups/AccessManagement/InnovenergyList.tsx b/typescript/Frontend/src/components/Layout/InnovenergyList.tsx similarity index 92% rename from typescript/Frontend/src/components/Groups/AccessManagement/InnovenergyList.tsx rename to typescript/Frontend/src/components/Layout/InnovenergyList.tsx index 7bdff47da..d0c67bb0a 100644 --- a/typescript/Frontend/src/components/Groups/AccessManagement/InnovenergyList.tsx +++ b/typescript/Frontend/src/components/Layout/InnovenergyList.tsx @@ -18,7 +18,6 @@ const InnovenergyList = (props: InnovenergyListProps) => { pb: 0, }} component="nav" - aria-labelledby="nested-list-subheader" > {props.children} diff --git a/typescript/Frontend/src/components/Layout/InnovenergyPropertyGrid.tsx b/typescript/Frontend/src/components/Layout/InnovenergyPropertyGrid.tsx new file mode 100644 index 000000000..a4b49e33b --- /dev/null +++ b/typescript/Frontend/src/components/Layout/InnovenergyPropertyGrid.tsx @@ -0,0 +1,68 @@ +import { InputLabel, TextField } from "@mui/material"; +import { colors } from "../../index"; +import { I_InnovenergyTextfieldProps } from "./InnovenergyTextfield"; + +interface InnovenergyPropertyGridProps { + rows: I_InnovenergyTextfieldProps[]; +} + +export const InnovenergyPropertyGrid = ( + props: InnovenergyPropertyGridProps +) => { + return ( +
+
+ {props.rows.map((prop) => ( + {prop.label} + ))} +
+
+ {props.rows.map((element) => { + return ( + + ); + })} +
+
+ ); +}; + +export default InnovenergyPropertyGrid; diff --git a/typescript/Frontend/src/components/InnovenergySnackbar.tsx b/typescript/Frontend/src/components/Layout/InnovenergySnackbar.tsx similarity index 100% rename from typescript/Frontend/src/components/InnovenergySnackbar.tsx rename to typescript/Frontend/src/components/Layout/InnovenergySnackbar.tsx diff --git a/typescript/Frontend/src/components/Layout/InnovenergyTabs.tsx b/typescript/Frontend/src/components/Layout/InnovenergyTabs.tsx index 1d56e376b..17b70ce73 100644 --- a/typescript/Frontend/src/components/Layout/InnovenergyTabs.tsx +++ b/typescript/Frontend/src/components/Layout/InnovenergyTabs.tsx @@ -1,4 +1,4 @@ -import { SxProps, Tabs, Theme, useTheme } from "@mui/material"; +import { SxProps, Tabs, useTheme } from "@mui/material"; import { ReactNode } from "react"; import { colors } from "index"; @@ -25,7 +25,6 @@ const InnovenergyTabs = (props: AntTabsProps) => { "&.Mui-selected": { color: colors.black, backgroundColor: theme.palette.primary.light, - borderColor: `#90A7c5 #90A7c5 #fff`, }, "& .MuiTabs-indicator": { display: "flex", diff --git a/typescript/Frontend/src/components/Layout/InnovenergyTextfield.tsx b/typescript/Frontend/src/components/Layout/InnovenergyTextfield.tsx index c342118e2..14abdfb7d 100644 --- a/typescript/Frontend/src/components/Layout/InnovenergyTextfield.tsx +++ b/typescript/Frontend/src/components/Layout/InnovenergyTextfield.tsx @@ -1,17 +1,4 @@ -import { - Grid, - InputLabel, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - TextField, - useTheme, -} from "@mui/material"; -import { colors } from "../../index"; +import { Grid, InputLabel, TextField } from "@mui/material"; export interface I_InnovenergyTextfieldProps { id: string; @@ -26,67 +13,7 @@ export interface I_InnovenergyTextfieldProps { error?: boolean; } -export const IePropertyGrid = (props: { - rows: I_InnovenergyTextfieldProps[]; -}) => { - return ( -
-
- {props.rows.map((prop) => ( - {prop.label} - ))} -
-
- {props.rows.map((element) => { - return ( - - ); - })} -
-
- ); -}; - const InnovenergyTextfield = (props: I_InnovenergyTextfieldProps) => { - const theme = useTheme(); return ( @@ -107,7 +34,6 @@ const InnovenergyTextfield = (props: I_InnovenergyTextfieldProps) => { borderRadius: 1, }, my: 0.5, - borderColor: "red", }} value={props.value || ""} onChange={props.handleChange} diff --git a/typescript/Frontend/src/components/Layout/InnovEnergyTreeItem.tsx b/typescript/Frontend/src/components/Layout/InnovenergyTreeItem.tsx similarity index 91% rename from typescript/Frontend/src/components/Layout/InnovEnergyTreeItem.tsx rename to typescript/Frontend/src/components/Layout/InnovenergyTreeItem.tsx index 28753d649..a66bd7b1b 100644 --- a/typescript/Frontend/src/components/Layout/InnovEnergyTreeItem.tsx +++ b/typescript/Frontend/src/components/Layout/InnovenergyTreeItem.tsx @@ -2,7 +2,7 @@ import { TreeItem, TreeItemProps } from "@mui/lab"; import { colors } from "../../index"; import { useTheme } from "@mui/material"; -const InnovEnergyTreeItem = (props: TreeItemProps) => { +const InnovenergyTreeItem = (props: TreeItemProps) => { const theme = useTheme(); return ( { ); }; -export default InnovEnergyTreeItem; +export default InnovenergyTreeItem; diff --git a/typescript/Frontend/src/components/Layout/LogoutButton.tsx b/typescript/Frontend/src/components/Layout/LogoutButton.tsx index 779fb8768..ff087a072 100644 --- a/typescript/Frontend/src/components/Layout/LogoutButton.tsx +++ b/typescript/Frontend/src/components/Layout/LogoutButton.tsx @@ -2,7 +2,7 @@ import { FormattedMessage } from "react-intl"; import { useNavigate } from "react-router-dom"; import axiosConfig from "../../config/axiosConfig"; import InnovenergyButton from "./InnovenergyButton"; -import { colors } from "index"; +import { useTheme } from "@mui/material"; interface LogoutButtonProps { removeToken: () => void; @@ -10,6 +10,7 @@ interface LogoutButtonProps { const LogoutButton = (props: LogoutButtonProps) => { const navigate = useNavigate(); + const theme = useTheme(); return ( { props.removeToken(); }); }} - sx={{ mx: 1, bgcolor: colors.orangeSelected, textTransform: "none" }} + sx={{ + mx: 1, + bgcolor: theme.palette.secondary.main, + textTransform: "none", + }} > diff --git a/typescript/Frontend/src/components/Layout/ModeButtons.tsx b/typescript/Frontend/src/components/Layout/ModeButtons.tsx index 322eae885..cc3032630 100644 --- a/typescript/Frontend/src/components/Layout/ModeButtons.tsx +++ b/typescript/Frontend/src/components/Layout/ModeButtons.tsx @@ -27,10 +27,14 @@ const ModeButtons = () => { > { { <> setOpen(true)} > @@ -37,7 +43,6 @@ const AddUser = () => { ".MuiDialogContent-root": { overflowX: "hidden" }, maxHeight: 500, }} - scroll="paper" fullWidth maxWidth="sm" > diff --git a/typescript/Frontend/src/components/Users/User.tsx b/typescript/Frontend/src/components/Users/User.tsx index c12f9cc8b..debb6787d 100644 --- a/typescript/Frontend/src/components/Users/User.tsx +++ b/typescript/Frontend/src/components/Users/User.tsx @@ -1,4 +1,10 @@ -import { Box, CircularProgress, Alert, collapseClasses, useTheme } from "@mui/material"; +import { + Box, + CircularProgress, + Alert, + collapseClasses, + useTheme, +} from "@mui/material"; import { AxiosError } from "axios"; import { useState, useEffect } from "react"; import { useParams } from "react-router-dom"; @@ -8,10 +14,11 @@ import UserForm from "./UserForm"; import { useIntl } from "react-intl"; import { colors } from "../.."; -interface I_DetailProps { +interface I_UserProps { hasMoveButton?: boolean; } -const Detail = (props: I_DetailProps) => { + +const User = (props: I_UserProps) => { const { id } = useParams(); const { locale } = useIntl(); const [values, setValues] = useState(); @@ -56,7 +63,7 @@ const Detail = (props: I_DetailProps) => { borderTopLeftRadius: 0, WebkitBorderTopRightRadius: 0, borderBottomLeftRadius: 4, - borderBottomRightRadius: 4, + borderBottomRightRadius: 4, borderColor: theme.palette.text.disabled, }} > @@ -68,7 +75,7 @@ const Detail = (props: I_DetailProps) => { - + ); } else if (error) { @@ -81,4 +88,4 @@ const Detail = (props: I_DetailProps) => { return null; }; -export default Detail; +export default User; diff --git a/typescript/Frontend/src/components/Users/UserForm.tsx b/typescript/Frontend/src/components/Users/UserForm.tsx index 59fffa162..4904e0054 100644 --- a/typescript/Frontend/src/components/Users/UserForm.tsx +++ b/typescript/Frontend/src/components/Users/UserForm.tsx @@ -11,17 +11,16 @@ import { useContext, useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { I_User } from "../../util/user.util"; import InnovenergyButton from "../Layout/InnovenergyButton"; -import InnovenergyTextfield, { - I_InnovenergyTextfieldProps, - IePropertyGrid, -} from "../Layout/InnovenergyTextfield"; +import { I_InnovenergyTextfieldProps } from "../Layout/InnovenergyTextfield"; import { UserContext } from "../Context/UserContextProvider"; import { UsersContext } from "../Context/UsersContextProvider"; +import InnovenergyPropertyGrid from "../Layout/InnovenergyPropertyGrid"; interface I_UserFormProps { handleSubmit: (formikValues: Partial) => Promise; values?: I_User; } + const UserForm = (props: I_UserFormProps) => { const { values, handleSubmit } = props; const [open, setOpen] = useState(false); @@ -100,7 +99,7 @@ const UserForm = (props: I_UserFormProps) => { return ( - + {loading && ( @@ -125,7 +124,6 @@ const UserForm = (props: I_UserFormProps) => { severity={error ? "error" : "success"} sx={{ width: "100%" }} > - {/* TODO how to handle err translation? */} {error ? ( ) : ( diff --git a/typescript/Frontend/src/components/Users/UserList.tsx b/typescript/Frontend/src/components/Users/UserList.tsx index e562b7fdb..28dfdd48d 100644 --- a/typescript/Frontend/src/components/Users/UserList.tsx +++ b/typescript/Frontend/src/components/Users/UserList.tsx @@ -44,7 +44,6 @@ const UserList = (props: UserListProps) => { \ No newline at end of file diff --git a/typescript/Frontend/src/resources/innovenergy_Logo_onOrange-2.png(1).png b/typescript/Frontend/src/resources/innovenergy_Logo_onOrange-2.png(1).png deleted file mode 100644 index 57ee2dc8eb8002fe0226fbc768995a01048efaee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12166 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∾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 aPa7_t|84}b$vggG^Wnz|pvrFsf&T^cQ+OHx diff --git a/typescript/Frontend/src/resources/innovenergy_Logo_onOrange-2.png.png b/typescript/Frontend/src/resources/innovenergy_Logo_onOrange-2.png.png deleted file mode 100644 index 386f16e40173f001d8cfa51788b6eea321a50c9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12031 zcmb_?Wl$Wj*7o8QDQ=~uxGY*+i@Pr@?(QvC+#QO$yY1qzxVux_okH;fg)RQ}{`$WA z|IXwjIY}myNlu>RoOzDxVgpT+x@0Bij_*cC7DyQoT z0ALdQM-Tv6IsZnmCCf{RYkIDo``I?p$vPjBB!b;9{T|mIyXEc9@eyIPxSVOoRb93?`!;ku8uFc;hKrLrX;>5i2Pggp`B8OecQ@+b|H*$T z|LORjH~cRqbgn0mKl=jLwfQU%iCyzV$y56yitCswUjhEaN(6wZd3GFJ zNg~7s6gh`Zc}l!vMpPrUOQHrxqpMxM-2J60D&(~obC%C7*Pjn1{c3bsS|@iD7s?+1 zJn1wgCJ8-p73q(s$&-r#Q&Lw*fB}edU~pLCvpH58j~?zOPX z(Xk(axOML&AaclB@+pMK6;#-AG+JRk+~OqA;9G_F328b+6&U!toz79DRQA9~lp-m$ zNt@2QTZtt>dW(EB|4$oT2s9;3hjqX_X>2*#a*B9|OmEJEb9TJ?I>fy;vFSZe? zCz7eDlS%}^MA^AL9p_4on{7&|pqj%UF`Qjl18tYGj_~rr$>*Y{oE9p#2mQK2 z_9vnYdTYz^A}@Ybz#e?B5$ z!+*J@uY4VK`l0Lyg792g}*ugoNAOmveYd zcQ+4X35hD6vMYjN^+lyb}8Hq@z>RiKsN8 znu;kCxQObTCHO)>m{AvoHf_{q?>X?e*ea=)#spjfS^k{nUJZ_ zB>aREp!2g_cIlGB&|{>b{6g;@IdM&p4bOyVb5;jh`Mp$HQlcc>g4S`IIKh>iIJhj@ zS^qmD4{dltw5}m3V*`9<3UbOe0ac4BGQ#~_Ho zVx2>=vp#7{SVJs`6h$+NidEc_h4uNqPbi;MZ`oo2h^MSbUlQmHnY-T%a;!(4D%0D` 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 diff --git a/typescript/Frontend/src/resources/innovenergy_Logo_onOrange.png b/typescript/Frontend/src/resources/innovenergy_Logo_onOrange.png deleted file mode 100644 index 22e9c64127c7788b35ebe595716191392a867e47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51620 zcmcG$byQXDw>G?KkQ9`T4FVhK?v|ETx?$7lrn>}0KuSOw1Vp5yq@+}&yBnlILPDh9 zn@67CIp-T^y#IXT-D5ahd+oLEoN>)-&YMVeRe9Vy zcgz;0x50m8ZnC;=Pn@mXJk1c65GlB`xg}K5(ahRX)6xv?{jAGU6ufoM_NlI$u8Oj- zg|j2O+08TTUXCu{Z3skE!pp_X!rsyiYHn$5>m)|E*VsY_wS|k(>F}v=s<=F|w6Rt2 zL0CTVQGIIRV{ah@r;`weih2oy1{^Kj%%EP54oFelDImaJEt;7-ySs_efx-Trg`r-zROAbv-S7&#G1=td+2mihdmhb=G(Z3JE zE&lVIi#x*MpLxP9I4m739W9;QT*08Y{uvP%xv(0-7VM#!gN(C<`^~S4GGcU~BX+ng z98A@Whev>qpN&fhF32Xp$1A{QCMdwiW?|0D$!}@F$0@`wc+=-iJOA7JJkkOJoLro8 zvNHU9TwJn`1Z5v_3i9*v^ULt?aLaJ=|NE|@ldGGVlZEBKecOV*Z{L;uzrHK{2w`dF z=8Smi?CkKb&?q{A9kaD|f^rG4^FWz&Y@OiFo~{pXw)1wRmIzx9OSl}u*%A8BehAzC zFa2|J3cz_R`7PPF&3FXa1ci95*vzefkXUe9aax#J@PjW_bhq!r|37O7hA(KrCBP3i z1F!Q7@v;e8@(QwVo37nd>XX8t_bFbaZV{Q$&A|>+5o(B>f_l($Pa08=3jRs9 zb`42$;l-J{d_~u(fA86~)l^I6VIWK znwpv~(m%Eb0@;s4ySPoG4Prx0i2% zq5rnpD;alt6JqrTvC%XbBs=Ob-2V=mfNXW`m_RS4*hJ5lFsiDFt@wyZ?)K3Me8R!5 zYvhDaac)$Kiu7F^OV^%>PvwUt6sLL4J#QbX!lgrdeK9I+~XDc;w& zq@R1NiTjf5?~jYyMx{`sIb+GaT?s^z1dZ6}K3)P|?)%%hHBXP-A#{Lk(#mB&8{PhS ziqWAydpkChSDyEcmtn>~kx^eq=L;yjlzWEq_a{Fg>vHmPN{(h3J_f7V|~|Bv@0+4t+UjJ@vB z-FCk&_&|YR2{}6*9rHC)z-^NQ;O62wa<;*S`|lvxzc(RoR->W8t!U!4_=?T{<4IH3 z-~ln!1eEsM5$%(K&gG02T}L3nxc}p(54cI8$er`&c1^^WqoGoX*nYca33BQexBX;4 z8&?XkeHFOtaZl{uK?*%k7?d0)12@$)j{bdaJsR3Zs;C84=?Q((+l_zQj9t%PI2VtQ zaAiO&_o*++7*_Vc6!V!wla=h1)3*u0ik%-sYhhN83~Yrkpi8JyeMH52bKH{tnH z{y3(mYJ8dP_%gpk@eJ+135(-B<(jC3Vaszr9xc06qR7MT@H5`6crOB6zLND6v$y+N(n>TKh0jS(NobDJbN3JZ$MzUnio$RA52F76 z+j>F&-x$UJN6r4B!*115R#EYu+VN=q>O?X{g%|&IiQrXi>>&&W^Y7Gocv{POpvB3> zwIm`YwxiO#_xNf+8QMED<2yYu;pz8#`?(~PGfL*IlX&)CP9VvhF#ZEi7L}C+#?ArS zufbIcb0@UNM!Yk`sIJFZ^k@FKr=IsOMM|&p+4eWG*RRTBV+T-UJJRV)U}%07pI7Y!(Tki4!TDVXizbXc(p5|=^cncmRg`B!Ec|9CtZM8O(g)-Cmmbfw z*I!4h?})X-+%t~OiSh&R6V6me1W&6}WXg~Ti`=3wX6O+l5D0KlixBRLUsOElmTMJU zMO|=B3Y>8Iydfq5a-2J%L!_K`+-Ql}iVTS~NSTyFG8jR;3Y;QjKN3wI)W3d%qG-V@ z*;+`%5Nyh*AjzoUaiFyaOH3+$%AA=-pQJyh(malaib{Hcf*ieat(^OUaUv+eolTuY8M-1(rld#tY&h}!gN1lFB}qN2U+FiyT13>%7ajQ1W6CGC zwdm1)pPX3Z;o&^T-E^}{9C{-;EnU)XcYoTEpX*e}MrVq(acK=&Sgw&kT>v{MP{q=yCJ>|R93 z%O!LMag?=`bLbY1$R=QEB&VWd^;$`APaZZ7KF^+?yRLMrU)z!}Dv-SPa}r*+e%B?b zNkc$jdW4U;@#JArn8whMqlSh?yOfkvDIA$Ey6u7C9nAp-UQ8=aQe+HtbZ!L$%m*e9 zTzr!}8nU4{k0rH$Z+o-Zg)Bxk z4GH`%0hxuHpC?F`RcAH3Sj_MQW9;)GtNm zo_vCji!1Bq>AvdW=^2qIu^z7&KMv>aqQr~HxOg*g8roEkL^IKg3+;mbo{dcGQ)3(f z^GcSHl}&;%GG;+hIzKGt z%S%8<>5NqzaKxy-8mK{IPqW8xO?)^^O(~u0^0YwnI4nGzT2Vo{~$$E4lA({AeG zvOiS!=g-#4%8J^92M^LMxyeG{H`8rv-`L!YoU5^)_}bju+?)Ik*aU2y65R?OHnvg% z+1=NX1hL8?PyPMo-Vsy#nX-I9o zTrd<76kuAzv$-rxd|wYG-`tA<`@_S}?-A%D_Z^0Xg(b_J)Ez{QJUTcSS6NoZ-tzXX zxtJ|%BA%a6B^0^ZF|J{maL2r?dBh%4Ul#KL1;w{of2RYxvhp{K5tjXw`5xozBiYy? z)b{pv0bxqKyG1Co>%|u6V6QHsboB)4eFX z7fnfn4nm1ZI6697ayB-iMniZftXDk0&+5=8PPfr%u7~Nsd-Lb%<>h4?6%`eBdRkg# zLt{fSE*>7^t5>hkd(lugps{$rMI9e9I;z22A7Q*2aa$xMBpgmi&bm@{QtfAVba23) zJBcA*q25>tQg(VOHa9o@Zf(sHh_o%r<>lk9laNl+Z-GvyJh;(AE4Dj}898lrhU|OM zv9Swa^k3$>9zKM1F7&;Z$_g{2`8GB-))N)=(g`{dgDaQEl~Ijv;*;qT@mngiz3SLs zy6C9~BR%7;akb4*+3VM@kt1b74n>-g#aeJ{R>*Z7bzTQo>CPqa= zJI;H$rek7aGWn$Ck8J&v10H;A-ch@FqG7xII@UShFug@865=OTc=Fw?QUL{(H59cf zQ{uOlAtU$ZDp&{fnopnDg`b$Te9X(UXm4$mOz5*pOq9wRn4P0Zw(Pyn%Yhn_s#VD= z{6mdB8oQyfu}WOXYril)KEC6Cn9V0p!+1VotF_f^lyxF+VjHEQq2b5YK!)Db@NCA= z#7tv?vd7bv?0i=i)IWY#$_GatlIPE-kR$>f99Tc)=dbvJJzvl+9&_9zBNItxH)?pm z&;Kd%s80}cG^VDuw&UKtd$XDv#?4`d^2G7Zr-MGUgpsrMoX2|pCtyFvh_l2mon^zq zVo@juFmf+EoHvHYa&yYnwZww>Je(3E#i9#=T@Z;vE9ET6>=(HJ034e zJnS)GS3uCj9`^kCQ4TLekdPiS0q0K52kk2Ijg3w4@$;8GNSu2*+*NF&Zt9d2)QEeK zVdn8gLFZ?uLV%NlqvKqi^WOY;baZsBcA5UMm7$^G18SZQBfN;ODWjKhXJ==YH8nNG zjSUUjoAPoY3f@ZV+E`G*-^cxWDs8aP{pVjJ@Gjpj{`u8mZebD2Zqj_gQIAbRO&HZ) zH?zgKL0p}dmR9m80#8g`$H2F^&uV0_dGN_}x6tvNwTlbqbzZD^_w~_;T6Ruxw|1%i zu@VA-NGdF4KNCjO&$gaLvo;Vu7gt0n;JV((9d+wL>VXJ1Srw0MNxepggrK@$Z4~GU z@aBuUuJyhIp9^3=w1hL+z3uFjlreZP?--u8+wS63joFP+O9Wh4hlPb*C#R(~`1VcL zT&pxELv>qmlPkD1fRWRbwOl>>9v)r;%up&kVOg!aBjppCwr9hvBeEQzikOuAxr zmDygFSceW+s4v5oJsyt>G${~Wd_!8+mX?+*_|$^?UQb*PyEls-K6K z=|tsyU-y3F+_IqHgprZ)%5`VDhQrdzD*4Z!GxMb7DQMgNsakT~^u$I{mm&vB2x|Ww zLL2blbJp_g74kBj;xQE_T)_S<(#2uLy?gi0%3aHHb^6n%Pkcc4o|h5lgpwgp1n*jMQB{pk^11XWUb?<*@0 zny06yw@KKHFKQ{AKK}}fTQvO{>Be0=#_Zr^r&O>LgflIGgNJ7|n8d>?8SaW!RyK99 zhKqy4>bol(=T zIR!aIOMFu5=~|4zrwdv}#&=^+4jG`(oaAGvj(KZXmEQY;!`QMxQ!09>doNSG!u}i0 zn;kJEj*^vOl%6V7%bXq`9Q@d2%K3cwJ_;s|3$reP+r?x>wzihG)6Bz`z@v^gSiqntGcP7RwW#oDFQVPEI#mX0<@ zCYn!n0ogq9x*cx59<$w*bbQWx4S+7n$?n{F1kh#YS;Tg!M0Zb*$d2NvB%_NDIekvV z3>P-xzL&9Fs1#TNzpffmq_fi|be1>e^l?2bcQ246<685Ev`~`n-;cU;=gzLPgTv=| z@ec%^N=6u&nDIz=VqecWwp{KwAJ#fd9qet7m!4x#FMDr>hK!Go%M9Z=tjX%{m+=e-X`yArSEy5)a# zVGs&igeV=ly12M(nizX6Ny>Vky4Ef{>u^OvLb6i(bFt!zm&o-pi<+>f5+_>DB52MD zW)wRatuG{@5HQ@a_^u)&XFz-^=Y9cF5HwhxoRm~O5o@RqI0pRR$Hzl>de5=qx8FY2 zfPL@yIv=oITAQAproG_0*A&~cdcd{Pt5c<4dQn+f$=4A}(~`L|!^kbE@s_HtY^sp< z#bYIFMP&4URK;si~>=cdzO%FD`HhBlG7?Ib|yJxn#Dh`>dk4Qk8R8^k-g73rfhz%ijl) zRo4NQ>QN0Jc^^ax1tNtUD^+{1y5ta5mG2248vCKfwQ#Hiq=C8eP;^a$=k z{cAB4U!0JFWFkD{l#aXZNW%MIx#L!GZwoR-%;?F`21|-9nAUjukSm% zpXb5@_`{^RhDS!e9{CS`wU2Ob_}JO0fQq#i*#*DzamvB`I}6r3UUC(Z+tD-12s9sb zvp6RNXJi*j#7<`pAs9jnx3hhB>%ZcQ?zj5ixH_paKPQ48C)*~McAkNO*W3*?=u+G# zGAKE4g7Sd#(pqB%qW5u)yA9hdT_^A2c>2wFNmt67&$dQxP{ZBGjW4_z3vD^gJ=dpK z=Yb%;7@YUKzHCYESBba0S?n0+H5WY`7ycwc?zV_?Pffrr3RGX{#Ds*1? zfklXFfpqW=IwU11g4M;*Csc}uOMF*;ud>3h8?9d+*1RH3ar`5SqdD-;U~XS${J`Xn zN3d~uZ2k^}h)kfxCO+U*HQG`e3P!;Ba1_VY7rP25-3ltz&Q5&G`P|->p1$V6dl|Z= z<+CpU{EopH7#Ji1);wFz0n~c%#W57s&K=eRMUo9g{rdGQ^XTVO3r^B6z5Noa{{RRyMc z@#V{x?CaChbrS$%lAtVY0;IaE~7T2l{7Z`u2v0*9^QSJ&032? z`2K0HT6SSMh+wNUme&UM_g$C|J7}2i-2`$J|7<9vmd`gX{rXkyLV){1vwtm}d}|_1 zRVyjU^J+DW#F!_&?@eESXh=wiJBR4?g=#|flouUd?cf+3B&t#eu1^Q{;t={vPT6X? z>Kn3j@iFZ9)*k+=zii^58CmT}hs5-Q9}OdALQ$0pDk&L&5+enj3m78WRu4}D_I^(O zYKaiPJVIZ=^g`t1G&G!zw_F{U2UgGQ)V(tbR>PzIe4LbG5|FJNM_Az)k-lM9+11r0 zqp8}c;61l#C54=+Kwnuoi)cOk^=mjb`n>}`#V4*lqD)ni&a+<;Ae15d+hYgnosE|v z0t-IdHDDFBI`8hUNJ{D1Zibe({GKLa-IH#pygWZ~_CM?sFo6ZWZa92+wi}d;pZW(i z?!f1GIaXqRO-?E#AXj~|w-R?``vXu6uJpb;qtz_(1K8Z;F{uE0S1X5xhMcLBLjc9) zHER0I$4*I#QNEm?kFT9pzV%6@3|+QG$1AbRD`0N0>z~=;Q46|Y7$wP^5pf}-vU7Wh zP|y?adY$iFi|zmFFqq576+uQuZqUUz17ahMfq}8C(NmToRjy-DIxeX_gKJ|%w*#kV z60D=Xv5ZJT^0_@~eO9icJ=fQGx_=D-eZe-mJhb6W;}=%6j%>afT+BhQ+3qHbk*n{svLFu1 zw=4pb37mV1>93H+%A8n|klgpT22j(JPN4P4P!b=@|G(DO8B4EGy{Ee6UI)c zFtGuSp@h0*H`nfs+c;r^BL~ew)EEdOKa=-o)LTqo(D+f*KMM{%AB;OI=V&_Gn%uBq zL?74pG+9W{ zG4@_1DQkEsR{(M;GIZEI2e}hNU;!i%Y)LsCb=;RIC~YO#4g}=H<6#MqI=8wo2)mh+ zsb_E__7R1JpZJ0lBbvwA7@#3T7!hV^zt?`f>s+->yO5ws@PfbnRv5V({~(m<;c3gY z0A>yex3HkgaY5}7yPd!Pr6UGD^~J>Z7>Wg{ooD5cR>Ou?=(OrqS(x$#rF3x6mG?WU zxN^79J>FAc*_qbSqw14y4k9jslyuX?ohP;;ivu;GQ;8!@x*X?C!)>&-%iW&WzhbXX zz9p(TG5Dh}6G$B_V}NjbX5%-#4n7F=zxJmy#U_foM62>DQhCJraJC=*&Po&Y#oebp zHkRCKqA5B_h>XOVKTUk3Q+`r?U0zfc0AKIV+&P(b9oRG4xnxP|4v3T)Hswz*H#?@b zIR#2q7r(SbT5o6^YP@_9Cwh+}<~tgz4&fk-;(2)ZcrNb^-$^3iN@C-&C?JBCMwj_n zkufp#;__0yYr?KxdPpgSo_Ph)6e!sWIW=Y>Bc1A698_hL&Bi7iM0z{n5Epc@dyP#P z*A+TwUePHpCzlZJ){qn2+#J`|))uz1_splsSjBiD)_8J*P*q2CFiQ1>_ z4&L{pa27aJ<1LZ!~Wz3=UC~I9-|G;^Io`NoEt-FrO%U*dUs5^l0Lv zA59_=(HHSy5<3fvyYzL+E5gz`7O0hX8itxf3^{yP5vPB_mP=a>gz8VOfrH@Icxh+nVCeHM z*UU`EdcEc*tn64m9gM6ko;7=mVt@!XuJatolHUtl49?DbS1+d?^a<_dC=W%^p>UFt z)?G?MO~q*`H7_r(0;M8{#MATii;IizYeHUQ(!;s+EpPg)DpU)f)YjHoPmGO~+Bw@B zhzJUjN`+ciQ`HUIQ4ACN-E6o#HVM0E&QoUGEd3V1(0ui1KJ4eopI0#4R6R9pd^2Y- zOGZNCNiW2(`h**a9S;ZRXMQpI+IG$N@86NZ#=SK#Fd&(jm?*b#wAGWFmJ)1I9TFeY z+PeH{2VIiz*uC&~b30-j4y+qR*dzM(9&&J4rv(z_&mSKjhyCbwI|X#3R=&zXiPV?}psn>1`g)AlPIi4D7S)!+{FL8Sk3WwEW%sqyl6i6 zofp31OB{6KYhc$Ck>(`wYX(N&jgK!RBqY280Df!&zea&Nld@sS6Zj8!PiHS{p!|Gj02M zit4#L*LbqH)|YPLo^%EbL~Yb_X^~Biu#&S!!WER{4{fTUh;#Zz3f3 zLH`HBxjd8R72o9(;*-TNV6)xaJnuBMHvtSuu6`-CN6pt<^Xh5FgskR(%d?cgtTXzP@pEOpGH)jEMYNIy`;%eq$p9P<&!~dU_aibac~- zWGZ#T)*4Lr^0p_+7wQqK-GP}*Oq11t*H<(^A=uvS1QoM5Yy_ERc_gZ%u~XnJ1?WiF@jk)AZ-lSPB6rKUK!W z7?TWV&4zt=m%5e0Tqegb z*+)eTWeK$b+^JXNGfwB;s!qES3sV)#E!$gL+Ai)|Nd6}I)S`ZXJ-h7DDVgjz{#>9Y z2u*AZ2k_5c*KzZW&}SEO>B+efB9iPlkX~XK-gL_aJNj@wdK#rkPj+h%Dz;BvfaK!s z)rtHDACG(R33F1-4QKFG?eZWcipFoht+1=LybS&Mz^PfFm=GNcgKf_Lx6uU23Z zQ?Jw0&qa#IgxkYHJJ<(}n>Lyc>I)U>c!t+3Y5e~zaVVaXxcu7v^>e8vkwU=njLMe9 z-sqvE3wx=y!LL1ui>2cg;eFnsLn6acgQJ|G8)z=inApXjT84v-ZU5H&IfH(3Q&W>! zU8PY&Zktr!#>V?-t-qwb$67#-{6z&x~hGF~Bp5Z2N$-xs8s2A&^6VgFWRo=z|Ou9QCk?DRW{~4p%;7;^OZ3 z{ruHI^J2(uVR0H7k4NC^<8wekK{29XpBXw|f0M_IdiiSi_ljQ*i_UKSde(w7P(%zk zcW03#5|tpZALmK;NEX)mEeFTO?gt!g49VAdiKFgNprD|n(*$1p+AgnOOY@w4xZvvQ z>N%u^21g*mqk@qeb{03{A6$>m&Gnr&E~n+>AVtcUr~1pVR&B3I1_u6oGsSuo@>qIH z7r93se;9&aPrN)da1$mU`tXYF#5lYWa#6f)lBYfmu(8?D@TrZqNPNJRO6e%|Q0QT7 zlhtosi-PYZGtMoSr`zKtr&y`1&+LSdG6iqEur+t;#Vp_630Uy!jSU;Ri7b3oSUdWDyqoe1(JfhWc1MB$l&F}vDABZ)o9q*ZQ;JV1d>n^x;UA06K^#@%81K-jq z2jaZfi*}O@?%P#>`4YFUniAyGARpS~wx4tBk$U|2vBNWsA%8;ySxyS*`_ndySjRh9 zShgPPJ~a34jb2S!#Lf`_4zImN5~-8~@R}#JpFVwe5yA(692ekex0jdosI*2#Mz$M$ z99hQYI;1$^4%A;CVS`PX`47y6s76Lc+D>_#%(?BYbLu1;3}ozlpZybscs!cJ*%E;$r2Y%764}{EvpxH&LgF zw!}|A8yy`Em)Ey%gbvk z(dHiF#>T@FXG>C|`bPmFf;YeljYX&I;(^XCeV^EHQQ0RCHYJQQ;xK8mS-_`0@Dp!I zT)q0?I;6!1a!Ng=#8C!2d`D>6NkSC4O24{DY01>KR^cLn|`UbL~;Z% z0LEETiZ_0tRd1p0bj|wfmoKkWqGMfuTn>i50eKspXSS_(b~!*M-sgC0?7A;WR#r5koZ2S^l&brDE z(c`fd6&3Hl%D-}0Ma+YQByVK9IZMwX-44r{kMA-YF*c3ZY5V5SpS>1S81WNXuZHZl zH3)B%!zEdn(RJ2qIYuHqEsNj962Y54vg+pP*^%S6Xg3W~SW)o7>xU%$n>n6ophzXB zpoVY8=m6LZlP8**2!ZTJ#h4p<_a;j94jrzB3--Jab0(ksPAMjgeRpW;-1s|s?Lra~ zd?Uic1$~)lHaQydH8%-*7P}oJxxVB~*bhdTWR#Va*=S24>+8r!o5}0y>hdWe1Ns`G zYEbR3GCo_4M0ZQq($pNTFmP%*UVndSY<%N^o;-W@EDZ0JgGAo3O!)*XL)aT3rgNyw zo)Y_hY|A{E1gGB-+Yvhr z?lWCFs)p4YIfX?PmGheps?ACv2d?dmU7_c6U`>j{Vp;I85djCTgFv6l2;* z0PJwK0E(TG-;M`{XQ_QWo3_7hP5SC!t6o%CXnns(qNgs+8kGK^^|>PD(l^*2!`k92u#aOggM;EM|!o z?~lhez_lTGjm`{`pWjUYuZnGVP6CRY~*e}%{}yrrdufsfB!U|U3? z3fA}-9RvO2D&$RPf0vK~BaDAMkzV-C&gPEFN_XBSyS%seDSFiuWlvZK^>C}2kIz|F z#_a6e`&ED>l-I5~qx(t;!Z{P}Z` zlapi4Uh-iG7q_TuWqjuT;j;vsmt8Bnat)MeeB?GD#(6T~Jh{(m_ebY&^^nSbqV#;( zu=yFSy1KD(0FOMi=m8oqPGcqb9Qjf&U-kFnfMHC`%utwdr%LOJUxDK%2bh0#KIPF# z_rs)aa(3lc0D?SHr)v#Spifg)R)$}_4xMtvO29#X^qytS0?-WzPtOwsJ1W)&b4c~k z(cHs_59Kw!wir7(?MCRA{-(c?{!(U;!iZ8Zdbwt9EGr|I1>JiVVky}kQC+cHR_52( z7yj%p1?tX}9qou((l3|G^7Y4$gF;PNnT5|bP%#+gK~)0*19C}Rn;}-_ zY$fHNk+zb#CH1&ZiwQ_oAGWrVw2QUApS4Qshr0y@>}-t<R@{-%(PnjJV-3yTarV}2& zjC{p@VlMi=FjP9KJ;9DY{SvH*w4b42y)LVhb=FSf4thcHDveRhQ-dc}!PvkW z&+UUsum>P`&Canh`3%GaA0Q9|U5A7K@*@0E&8SGR{re4b58j7 zwvI+YY3H)Qw^jnI?>D}Fmnlg}>@O{za*u*UXMK73s~bJP$fCv@d3ltZy)n!srAN8e zUc*R;Z(|@^Y%u&-Qd_Gt1K9f4W0{SvLy`l-7Z*BRsAlAR=RZzQPstD@?6X~AY#6+g zqeJt}HZCr4u4+O#J5P(p#y{e{8=P=1hEq1*}o+bk>(oQ5xRT za&mqY6MDYSZ{-nh#;b_t0VjT-$@3vaKbpGwF}lar*MC?Gr_1P&{y zr5Nmrw{;s`{Y@so%UiPkMGsUAYJ&Q%k9dS} zQV$obYNNm=ykumu3Bryb0hl9_Wp!q9@=Z=@4PR!K(f}cwKm#2;3}#JYcevWq*XN&& zZH+YeX>xix&8$NAk6}+9(0`94O}*}e2BCA_*SZPvQ}1iCX}#$-fOD|CPoIM!6%iiB z_u=UWv%k3*b`|!Nl&S!HxO#WhjKiJR=pWx|7om5_q@12o@~8I|grMHkv;hV)2G~w% zY3UDu5K_(IH)$TNu2ut;QK{}ZL8=FU?5pze^(CrLmOpB;t(mqPkHx2^p*eAMa#EEo zy;Qcgw*HA(Bv5jer#S5N_U&7|XG;V+piTm^_>$>$x0y4$=u)d)jFc^e1?2h?ajqJ5 z%jrMrl@hXNZCzOc_64!y(MYo`{+zllB{}(1HV1*AdOC-Rf`Wnt0OwrWY#3G6V=q7* zpP;v#JYX?s$7d34KE5rjap&7MMN6r!tt}jpuc*93I5-g#8{2Wa?c&~&L0QK}t*J=4 zbL=vpZ$O#Q-@B8#X9**E5X^#x1w4-S$6blFPvrUe@2F)|nh%-<#n>DbnQR0<|r){s$1i z6Sf`$1>u2(pgwux^`4XS5qfeWU3}*kA1p3h!jA#?B*o?B9Q|QUGE7 zpifn(#358xQyE%Mh)q;{=o9>^Qn*(TzOVz6JI#&;P;x#l@H^lzg*4Xfl<*6>y-tY`aEFNKoBlbvH6tQV)@A4?9R?k<_eiFpT!0x+ZJ0Pu#^#yo;`W~{CS3{H#<@v zP2(K35@TnSSbZ}{X%vGXJh?(N7Rt=L^+GzARCe#5bgf8V?B{q~h)cy!ehOz(Q|R*! zVNmvN1D7^|A+)SLZcf1kWaX1F8F6$^M=3o1$@)$G?9hF^RP(Ao0V-n}zaD=Xh| zbgV!RrHx+oh5+(ic0=f9F5n26E+~f|1+q{no*#vd_2tXgif^7-r(N)`b~R~45hPn~ z4U$04R?WrRJ30cHfwE*-epx?k0xDX@m)=KxPP)`^cE*>_LGW?%Os2;eN`O=NF8^N6 z`i&eyAgvalmRnwk5>II45VIezze)Phqlz)pW(>IKyc6VPt#a2H(Hyg5D$^a*UdQjzv${6{KIfD-+o(;cjZ09yDNm z<~2J73m6RDd}`QN2!fl?k{M(pmBGo$x~$`FeB!k9bP_-wqkWt{lQ9wC<2%Om!MQPg z;JENKhzl7>`X69|% zS&-yYS1T?A#i;grrF1!#)C2@B=n=&KcvHyY(8h`%94^xbL;_>Ojyt~Kd|iY2P_01I z9s9X7&o&gP)Eew?M)B#ryVUb!BfKzklxKNRLtXG)r5 zy1TxAe4MGyoYZ7E=`3OQPXT{Wv3Js&ICWOS$dX=~u*q4!(jlAIUP@G@Wo5=4TQ#N*SL97m7VVghL2JLX4-6}H@^s2HK^3_ww3 z!w0)0*l6F{+S(|n+74sIXH!;Ho$q5-_}eVR1*TxijRwFmCk@%*sb6|ai-b0zV7xNp zwpCMtsg*Rp(53}<>WX21@lkYi6R%4<_j_qr2`(<~HlX>3LcfA~-ayNr7w`!OMz zYco)eo0|teFXdMImgBKrM6(xzrdm5XI_Q&>A~fjwAH*vim*Bt8XDod8`FpPwS;`?Z zEp4t+(NpdP1Sc==>$&;yMHfQ?gPT#dCRi`2r+` z?C0u@Kk*6_;vAiDm;-zgoC8>pCb|mJOZ>kAVp=-_?bIvO`UPok*&12zR8$Y@L>uQO z0mMG@IjFzTJ(dy|7k`3H%=(A43FYs!IqmIy(oT!M=; zGW_KHmQ8>_TvX#gO>+eH4DKQ`POqOIV;uqgn_|zh1ZPmfdrf!BzuNAChCYW-H!^B! zx2ig=d+g83!7}sHMevRI7*qsiP2+?9*Oo3)CMG5}mn@(dUF~i!FH71AdYgV<9%?$y zz$8>|P>+K$Fcc^kX(p+0`#oi9nwg)OX?$B#!`DN#^>)l|RYyms9F&zQ8)ui%VcxkT z99)Y2*PXPYt!+?x6Ojr)U|p*S3xwt{?YIG6=Qeh?(&LH7M_K&5yl`;3i{s#z84=4{ zsgUaGYW#f7hari#uh;we`@?i;;PNm@L*1dpU8|HouIA2>;B?*NOsV+9#6zUm4vT4R zzX2zqNe6)7%Zy3DL6Byt>CZ35v{A&fB@!|d53zjEZYLQ8iQ@2t z?Y?*)fgL69l#B#T>i0vhKL&KSf#VuZ{zh|zI%N^)p;Fp9I<+syg2UWo6>M~M>$QtZ zWy^2sh=6ou04rdffW2pdFb|0xc0t6M`lJzoBdG#eEXTX%iUpeXaz1BB$p&~<(_Jh1 zYPNb)!l2C>KE56|;W=}_?~!kG_4ZyAf_Pr$zuG+iY3AXu@OA2PoDN7DaQ3u1Syoc> zj|z)dO>Rm)$e!T`uC84SGwG#xi{caKiJIn~dt zt(P_q4zsOWMd)q}3enoWpgQ*hnHch4b#Tdr2CKin@dMy&*c)ZjXY9eQFa;ng`(C0P zxe9R4nv1-iWmg1Z9!^I8X4MEBF&ewSZ3-%oUk(ioaq45}=J?Nrl$21F7}NaK3zsmc z6c33uA&4)@Qd@suVW`5Z^e;D_(BJrjat^{shq5;jAYBad-J6i2;@d0Dsml8vXK>QxrI3G;jdy|O*BvLo_tx0eRJ(P(QjBU3|8ZI~hW>Io0 zvv_U!ZF|(hq50>t@GKQ|Kod94IeDi3`dyR=bACYNj#YdnZ{lfYJWqY}PfQK4o=)7^ zX{z4bl!)iPDr5N-2<^iNpP9$Cnrl=TG6wdedZvwvBo?n($jN#z$o(c zFUv^5K0LT;JL`fTmHD}AjjhGU-wkA6zu$M04Rp4;56vl8>sCsswHXRHLcX;K6Z?mU z6wuHU)#N=heuYKL!EL~a^;__ghJctihln2}zySNU4BA%g0!LxExUxSQsz~-|g35uE zdnDyc2xG9B`PH93mE{@G>*iSAFdao>b`*oyw?4z<5!1a_@rpBpyvt2nN2C7SOIY%e zf*3|=;-aFxevNIt78`JGqEt>{L!Y?qot+x^uOFUz5^N#K)@Ei)O{@d*e}r!;K1aaW z1Km>d+~6WvZ|`yt8{+C2_s&R6jRbB@^R(z`!3}!d_4D;Te+yvBQ}(rZP`;$4r9I!i1sFDd5b_Jd1Wuqn zNVgkH2U~{|l&1fXjFS}Ly{9-IA)sV=6%!r(T!a!&0`P+?2=4-sl_I4AZn%|Ifbv1o zlyAPqm`r7=~|A$qERr>VG`TR{@$==SA3sO_9% zFab`gxTc~)nI=Nv&XsmUL01O>Zh`UyBaS@U15=M34PZ%m<< z(1hC5&b0eCH7SBPVPat+yE`m&2KW~?kT+%b?9$P9K0G}1M3^!3gG|Go1zCyU!ms6y zT2)ommtZyOyng-A(Jh7l{kumHLv3)bq7a-A2h7u8)0|jSQx|AecEJ0FC^8e%dwcwt zo{-O;H;ve{d*SELpD3V{|HIx_He}VcQPM3bA>AO|-3Ss=qI5`iw{%ELNH>UdcXvvI zbR*r}HJjIG=2y%|RPbh>ebu_wTIUZ#2FvRH{{Gb5ctvh)?G--LhBQES46Wpbtr*Z4 z0OS`3;z39f?Z5h>Mc$ybynlSG+x4v}3rHl970J&BExC$-q?Thp4yFo=J57zDwqE(^ zN3DT+V#+<-VABmpza)u+x}u^j7VgF!3HcpYpoqC~RCs~fx4(MIdQ zll2TjBO#{5a(Y!1!rEe?tE}zm4uI$9fS@4ug$X?tJVQW`;x6Y4`{LX)@WspPX(4@n z%d9;`t#}FXF{~-V2MqWL`OH@2&fY?pp;pv-d}=NqebEM zYmczLlLzD<*M9(X{A|C?CCJA|XJ%>IUyxs{wJ<&3=xl4NXi=l_dASNZ(ksg<-7Bpq z%t3cIlo(&?4FN%lx}C_LMem{;$A(GohJ6DQCFO?NM|*oEP(yqHwnA-hm3Rg94{E4- zCm~sj@J)>3jR+iz=LcfxVL7?M(w3|FwyaO3gxc00s4?6a>Y|4*5MZ?O)oP zd7acBQ(MePOIzOp=7asQ)h~oei^#iNj2cI{O@5n;PmfSRNiv|V&Vln^I|2&4CKvCE zXflB6h%En&{f0HXZAYBauLR<}i6F(@t&x;8I^CA^kNYLSg^(nHc z<^rKeSgaWeE-E7m5|X(pZ5;Gb@{D6=4TrGzdk5t|!wf6%X)rj1!cQfDR&(4qA9G3Z zK4MXpx|CeSS5jjXkfqL$l2{ZPWm|r_+=6(nx;kEYb_G#v9MpyJ65x!lk$>hujM^;fIsk zy!5YyUw|&|8Z>K*=z)WNp}+R7rUE3oWKZo(-@k-9fh}_mHgFXu? zAe3Kpo6#0l`0$}vTmkuia9I6Yz=x8D%f>P!-5osBg5tvi^P;-TAMV!E*BPUI>kUlG z-rjAsRaFiz^{++wEh$zU*bm|>^k0L(U3!m7a#W#Fq9+uNdXim)Xl`L)1GWLTRa{)t zyLk^TPEHakv2j)o)0j751qJ}d{W5p9X;c68@eMICs_WzBOa?tYV@pOX#qr<>ex@&E zvebP#&=H!WL!-P+_ie2})o=cWAO#T+6dRxT&ww zqmDNmu9*5qp6;W&g1kHTO8L^jGGclxyD!4(PjBzj#9WyRpf~|uFMI4J9n_EQW6;)c zHQ6tjnORR;ue3hGPCS=9S2q9BL@-T3LPfP67#f(5OG|5^2Q$b=@@TD#EWcloX{5ga zy7t`{Uk+G&lxQ`(p2{~)d{N6o=KnJmr3*Uj^CSSJ0v?_{J_FBlvIw-;hUdE@kL|P> zU{>(ssO7jdW8BJO#|`p-GXnSD?QIh>{~l#PEcgJ_{8)q;Kp@D7fT`6AxGgF5wl0zK z=29(%e!X~J)tuS8GM)MN$(2O(%?l^v0~$67pwHT0uz8>$@Zi4ebKd`;I0GE-nw_+3(xj{&t7h;D49oe8rQ#kT=#S*QTndc=Bu9@T13d z(~9TN%F0UUGHxppDieSPZCSy1N8+&NImWMw9T%4ZatMjc<^&)O<|`BV$xu^Ls({R~-wlWw z0V>$*@5vu9O&+|m$9G(QX0D3HchG9|#WU)*rXfRC431Av<1{?xBs}$*R|KR#zcF3P zg7iyGO?C0Us>)zguQDEX2Jm;&{4pyJPyHd;U-w9%Mv1IXT;tb{St6p^+DqJkGx&6H zbHjs5`(MOJn3|e8sHx3{I4BGl`!bp3KyUZ~)u>2;7CxI#0uCL%hZ_c^I(^{X%5v$w+*ywE46c$=Zz#^EG<8{Ui3#F zmwSBe?Y^m31;i(Bke5(Ziz#ecZnwO_^lUBQ9R_K|O*wZo-*_3FV$-lWqxIF^M>2c& zE1+ZB3~1M%Wa#41@_6iwt-p^TR1aIm`(Ht~#oFE7eJ?>iPCFPfyhu4{U3ZS^dAHj| z8y6-%c+kJrwUVo=uE4P4PKp(H1n_kz1;)sO)Kn~hG`!z6jK^*aXlW|4a02Sy#@mM$ z;JL657DFnP8e0mg{BJ)OCg;c|9NG6Y+U<;G$>qtX-7ViLkYpVOder`YVVR!-pO`0R z+!cPeQG=DoBbPeH{*h%TuS}mSe!vNUJZ`x^%8-6UcwdI{uV6ref+1cAl{1-O{AQryH^CyVz#4vVMVD#QeS%-w^Q8N6+k%waURo z6a;!W9F>-%1PK+e}51X%6Adi0fkc%4~LG+vwr zwh9S3SG?2zNc;K`5DJ_`@#RuvN{+Igoq03-V>|jEf$n+9B*Sg1e91Z?V`2K+FKgf_ zv84Rz(}lc_4l%LOe|5YO#I~Se=Num^YnD+>B15LY~mzNjOFJd}5{_EEg3gB+=>?w+e$h*v*j z?-FEO$Y6d%XbIF2FUz{NhU{i)+$*)XJ=U1k)^>54sVUK}Fz6`#guN^G=_@T_3l;(u z5$4C|^Q{lluCJm}7E{=_7q71cR{THOZx0P6@t=>VZir4>Bt7shQ@dka>@HkC!o9*L ztef}XvEPtdCz&p35-j%|}c zKb2_QF8j-#5d!_*Z*Xv&r{^;MG`pRb81#L2Kd4d=_RMOQf_M(bB3V+L{c-Q9jh|>*R4YHHS1kh=(4(4K_5))@j_=HWm0$)*}5(}6n zCqxf8+3BCGc2pJf;Knm*I{#@%O$}T|CFVjGfum?P@T$$1^Ds&jKpDH~kHlu0$ zxG}M@9A}RpOFykw^l_Df=hIub@$-$4$4!bIqsGIk+VAX1f1~H8Q_$0VSfvx8#Y7iF zAmhq(IbJ5&pTMy+2RH&eCSTd3YYMkj zXv=S!);{FuV2+$I}e>};z4{& z8r3_ajR-J_%uf5$kLn{CafE5Qcu`R-G<O_*%>5)Ts3I1gDXJv zHd{^KAGiHIFd=_eA`ynub}FQtV@X5AW1ESs3Mm%t1J1XChb$|rVaff2mXJs9sl)Ft=-eRKkGeYNlw})!q_;n|AB>kPu$VzN%SP0f=>c!q=3*)yL^RnbRVd z_q+il@Nf2BZK?-~zs2J!ziWZ(YFY~Q%dxZ^85}>l#h)^pl`>T(-KRd}+uM>M`7a2o zI8APUazjAyH+ut>)~M^<4MU>vv#(W1NH+9luMWJe2m%_~3NxBO#`)nbqd(lMJM+V2 z&Ni@cI_fJ_$<9GhBRN;BQK*Z;~s50lRx+eif8q+EP72CvkPiJTFT#nW34k8JK z7B_arvmc3KQ2u5z_362-Q_DFw{&iTT8Y|JP<2C4w@VwRc23CeNmO!{8*m}Q}0`GD- z&$-y-1GF`ZKsnw#;N=Wz8_rBbxIj`&nsyx!M0(RuQOU)Q-u*}w z{^Tl1`1OA=f|DoO75G-W(fRR4%&V2ls*}uUd9fi9bmgAGG?8-p`hQQpA>%xBt&qt! zCbh@$f`w!kU~1=_f!`LWMa>>T#PF|lUl(v-n0k4o<;ZVPM;%`3RJv9aG$0tJNThIC zwH_@toEy_eJhndGuWzmiG?G`;h~HnyYF~+hB~u&&)1@llHB>b^?p7Z71`*>kZm)l6 zu8XiZ04?x37&{jhe&2c)8)+@l_1VH9P`vGnbdi>pHtYE8qe%IZuPoa$Mg3b*P*8^K z9Vs}i{K>fI?6L6gj(`fp;o-(Ea!7$RqiM?hxaHbdPbs<$m6*79?$At`AsS;<%BQ(g^BA-Og6wOkV4Wi+4D-hrdQtU-%{ybS)v!RWzQR@cu^ zG1Rm3bBp7-mL_IZi2p(evP7e1KE(3xExsETsonfsl}Sn~tHaho_{D{q0)8auZunlz zLk>7@AB?G@iV)(Qp4Ne&%G1MwN#4@(AgR^!KKV$FR9M(~cOoZYSS~6dVY|uj_Ye0C z$eHRtymy60gYg!B*Vkt>?S`U9*KR5d4v8e75G3q{4qgJqRAm9k@kXj`R=mDto5Dh_ z8=4pX`3;xCVOGh>!^1PGMB5G~@RKjHr4Rw+kRU|#u_VLsPR&I`L~7*`p`$|xjGlGe zA1~*?`Vk|Y1=V$g+j!(*W7QXW37P|my}cPQH3Yakx`Wj{G?_+M$;4Y(7E&P2O*HlY zUTFXRZN+?fJzb*7eKnRPPVu2MU5U+cwmiW}dSsUYTwe3Uq`0YZB}&COk=j9Vr--CO zi?Q;x^ib>Pb9;w0oG<&+MRje?h8q?7K@Hz4WCh(S(O|GjAzmZC#Iip0e6?AXAh@nn zeY2mdM9I50e*MZS19mDjV5>CFg^OU`27Glg$Z?_5HECFw8=VjD^nf9c%c)g^zzOw^ z@R#02iVO2rF--g7W0c8mrXd^ zHl_x|0c2Qy=L5XU&hybxVTY{`;`~>hUo|wAaCKevmTRpRB;m|H{?0@hg6CyM{f^JM z$Jk00X9CKoF0f;?D$Y0dl=EGL0TbX1h_)&N3GddgQ-#0ZM-mfR+N;U_E??`?bu32u zLbb70uPv&lmuVmb8w^+Bv`@^^!W4oy=!QAR7bbF-MoZ@`5Fr! zYhoBu-H{+bsBalBc02d?kflSTBSMjqa;?hDY_H~uRpFzh%|CzqDbaRHEv2A<2E4N7 zw2hHqoKMIVJ?Gk+`~t#up26|0=eD-p-abk5yPy{LYrd;Jl=|#t{OQwVMX1=H(6F#B zb~d);^TWJylFEGfl zas!^o0{YlDOr+ov!fYIoa6Wen0&6xTQ|l`>+P>&!34s^@5@gfAXkb)a3^^ zt_5VDXN!>;UEzJ&PSPx6L&J?VaPdm>Ww8AG{S|b7GK<}AxpTE1K!M(>+Y5z=>mcS8 z0k`~OmHYK1#4EHi+Z2h1eIU*%U1)K?ZkLXs5uRxCex9?Z(8_mT0Ulj<1I`L5>@G*^ zz^=?Z^l7SwNuU!2gekiV7{wfJRX!29VijvQUDbk)EZNxtjg|E6+uc3J6z;Z}8qK;_ zgYish$?@^iOG6L1_RD#Zc)VvTD%a$+o~mc(-r2Pxlu?iA+j~xk7AwB~@a}_78y`Tk z{H0;^yw!G1%ocEvFDkO%Ymx}KvXD_wWa~&+pok3scJ6X$aB%)dc_?A;X9w&OP1mi^ zJHLO0C3vcBbu;&Iuc-9y9=QJiwNrh4gF&w~Q9B&=(XGAs;?9!Ga#GDv5Q#M&zx84a z&|zy(KNr8NyBZj-nu#Fdhhx+#UmXVvWKncJM-*mSaVk!J`>83_=V8n}ast5h2pi@I&xJSLCLDa))Pt8^rxMs)5!gtpkT>FJ`;T zuK~Q(X6wDX``%A(cT{L+US8Oxte`Ci9)B-=LMy(Q#A#2r+#IeJ%fC*zJEGe9kMT9g z0?$ofo*oi_uSIo<`}bGumY}|hUmY#+m&+~G$_Bk6xRS|>AOf74`|YG9AvZjvS#Ser z-FTWPc;A`15KdR>i zMD+nZ^qf)0=QaklU4zs9)IwxRS+cn-__PW@w_Y@y!lhkd*A-Y4Nhmn4-aw2@zc?UH8f-CV zpHBF!dV^CR2-sQ8Yh6KYJo_!zaLMX&A|u0Jc)2xGc+ptffL8R`Xr@$qX2Hk<;LP4J zj$)gBC-kks38He>Za_eA)gMiL~mNFH!**6Up!+>?bLv!dMp#yKPd=&QU%Y@kGny>&pJ^dZ<>MH?GN)wRWRUrKm zjiw7OpcA-k*tQ#MZ>K`z^0#Ltcf`I`CbpO>oFX3anjzm7AKy{RPEX-=F!npx7b$9% zErn@70Nv$TLA9Lo*HXZKwd^a0ii0OVS!{4%J@dY9+N-kN0mt=}3#6qkxJ5VK4O_3% zrKHWg&o+LKV1H&aoy;G{QALCS3@Vx}eR5F%{Bf-~hr)p76QP1PTk`we%~*$j$#kjq zy$gF)mMSda?BLS;UBADlaznIra$+J+>A~nGoUp8rYOX+c+Bq5m&+-0x46}C|0%G3= z^&$bmDOj691jD%DG6kdxyDoTjlYo^-fAJDj-Ng9P;JkAXcE)}_MXag1A;!#o|0c1We2M}!!mW-ysC(> z(2f@B%J!9kk(kD9lIUj4@ZUCECaoJq508iD{`~xyQd4n230evZ)|#tizB-rtuUw&h zxvQBGO8N0);u`d6T_qm%1+;4k0)#;T?F!Tr*R36AZd+qsKryH~G@7Kvg?zdyJo}co zX*`_F*bHpvo`&a+gjO+yjE53cf%czWeWb!x;f%VSaDS?3CJ21k1+zMnm>?Sg<*fBv zgnfhn=>)IDha_5;otp)~q)Rb+Zfyew5&Q#T4T%nb>SD&{{qzuI(|Ehpq&*&>Tu>lK zw9Sh&b#S$F<;_DcEs z`BbSkKO>Of5C-&~tv&-QmAT^FdDgE(iO&NrJWH&)kkb{M7SoF$Y1WdJ;tl@EQ{Z-a zjd+rTQAuJxRT$S(m-?@l5(wy(OD1e^>kZf3)N^ZFr;b&_3eP4S^{iX89}LfxOCi>e zoJ4s6Z01&0o{QJBCQ3!ncgM5)n!u5`AKrL?*^6dl?IvK|RZJ1M-XBtWw@GSA;&Ygm zyYxqqJv+V5{FL*pow@Di?`d;$bJU(k@2+xQvhlCHI@=G1VKtQ0d|wTur21i7*Zu|a zUr_)9*(7;^_T#slO?n=o?EzA+g2oZ&pS%^^m70C(E2-geP}?`s1>IZs5tm^SP0k=Z z4KET|*$?l+0d}Ge5EBBznRl)vFNlSli=B?2EUW!w{tP}R;2BXyZ~Agi`a;9sc|A_4 zMyhOYXYknll=vzs=_oN}9fcBa!~HMWyON3rqTHT^(wE+}EC%4j#+J*ZV|UbV;=X<@ z53)>pmUs}8VdSL1+1Nv&fI!~t5J{^ zOLFJQwm;2dtLogkxT5itj^@`_I_^$1aoa2l6c!2#zXgR&V!!pFIknbm{-K>a4;H@Z2If0%Jl<1b3@5RL~Xx`M*=V z|NiyQ(fVAYT*@W@8yX_^$(oUCZB~SSQ7=q@uEx#t?!t`#Tb2;@EXU}LaJt}q4*1h) zm#b|Y9Gp8U8XB|`+DVa!^EJuu1jkz`a{sC~@z9j2t{|9YPp?I2zwG$d!1#e?^~nr0 zwq@n-hl~K|L;}|3W$)Gb`Jo^U$5uPa226&k@71_$mOa3Bb4c{P4O9T(0Z4Zrz{2$q zUppi3gIl$=rDdhTPjyODKsU9zeJWOG9;m(JIcL83C@7{U`8hD#f0CRjG@uAlKnua9&;EH9xlLYb$4;!(%g(h zG-Dh3F1^>faDe2B)f!#CBd-RMx6Z zjAXBVDWbr_G{MwwclQVi!;WYsM*rz}z1{kzGZqplW;kdYZ#8PnH@^<30m$fHR#&)< zurCUluu!#3-N8WaGcRp67-v?(iP^VKLop41GW_j?MJ9f{-Oiv<*)jnw&d*yApShh_ z9d@ZN4z314s6;B~R{x#OnK1Q-RG$6b6zj&0g@yZKA{&VkFSVHU%I81=n^Z2)$kfeI ze8s@T{J{+pqKOh~H`A?PIUI+@w56SxSf`c({vbFUYXG<2vh{JI$H875EDP$NZw(vJ z-B)dVIO!Y}?U!_GA}tvUVeti5Q4pJiq>Yq@W?NPG{iEgcizDEYp!?ND*%X?X@ctedPgb<);VM2ctReO_~+7wLKf5O@c7M)#&cADvXKytV%qDJU}!6ot^!YPWvrXhSQ&6?v z&Ced7O$@C3-u96NKqTVR#X6pzU?W$1b9?(aQR2Ma7dmb8p?S&9x-j6I=8H2Q)r$Uq z&mNl`?Wg7uFb0#hX}g?Wus7hvtSE~(E&2tAY9{F?Myaf6zhG6jG?8z&Zg7Czf|jsO z^TE~bc)2BJV|J?cj2~LBQ2YMs7@UrK2u*}hWV&F2R4cFJ$*QX>dMtl2#i?$m%ZjJV zHK0~yG%SuHA|vy^AW0Dp5-A&^Pucs!C*H zB6_zy`@&OyBrS&nX4p~(z*W*c!f3x3ru(h1?us%nxAesB45GnYJ&rv4IXdwCAZHDQ z0K3AVbyN2%jsM=lDgXTRtzVv~gg2M>aUJC!nz^5C@`GN$?x$D zji$wGG!Xj+kcwz3I;v%HT!=)x2fXCc`K;y{y@AV;CP2vSgIn~qB_jxL?EnxL`3~-lAD=p%Dx4tbW_hc;*9`XO6X15PZjrdyzC4 zQG*RQp#YqL%kKW=0cUqybpg=Z4!Mqk`_eESW?j zr^D&PnxN;qndtSt$mf2*Z!E>fpb;=f1cX*=i&telse`qEtF^HtlP27p`Q-_A}k=WwjdwljMNS$r&KxC( zKS>!Tf+fYxW`a&KyZhAvO;u$j`LOvmfIAz7E+>`4aE3CT6~Ox%NZzACh1-dUwEHf2 zT{l@Ib6GWJP{=aD$&zBefD~rvEAx2@899Jdp!O=*8w z4`hQ9bAf8v^4-fmAptB?m}zNgGXxEUH`Xd#I|C3EnlCz${Wm+<#I}C~^9XR6O&IQi z$*6U;|8w*5l5N+k=cr?wo8+mYV?-2`3p(NSekIaAo|`6{Hc!+2ct+LlVBFdTAKVL{ zkT6vn>ky!PYDGO^xX*TAuCIHoRgWHCS%dw(0vKAlEV^yS0^GoQGylKvv_n4gan~CH zM($VpE8ZQU*z~1Q1UtgNa&xbM=IgSzH|e2LGyy*RFTk`O!;?2agePO+<9|&TG_V1% zFIWSP8%!$*Ke?89s8(C$39RCLC*nRba|<@iAC!pNSN|RUhW+U^CEC1fJcHZB%8GEc z2b)MR9Ns#+$w+sLu*GzWYy!irGPpY?mpgOk`(W#Q9Or#BLCN&81q5~S@DbSHY1J{Z z+Ud(XJHvF6JP;M)L2QubYd1Mh5VpHdoy20aoX2HBr6W=nUX3(3ejY@>Nv8Q;?I(|87|Q6t1G9qk};AmXP1MSbSn6 ztqbfi*)Ko=DB0j!|HjEx4uye~g@F(qm2rO?u4&WKCh8COo+tFb-_Sg^yuADz9bUKGJ~CzwZ-0djQrRYa^49;EwO zIy9`IvmIX!>&2Us%ntwO27uTkHM(JaX&rEL(|-s+WL~&!airSG8#n0nc#HM~FZ8hL zpBF(a$cMsx6Cp;6dc@K|9B?EfPfUh(Md9J$5&B|}$45^7*Y>c#-xKudZ$ZDFC+6qR zzB$?-XJP28#or7Rw~rfZLL4;w{B(j86jujH?86|JBm;!Iwga?aV&iZK@(E|tVmU~+ zE)j#ZLhe1-s?ELS)IZ~-NNK)~!^U9MuAYMpv1P;A@9i_zD(}-xC|KoWG+mm!yJ1bH zCn2?s;k%E$&C$AI%g(zBw*o@-HS9&g=Z4-muW{^yHYx3~)~&Yi11*;;U)?Zm%r+#p zx3~KNJ4nV|u+ze92zi zdEYN|-=1$jdu@hdUjqsUmygg-MxgkN0i zY&cgxbF`0q8b32=I2UA!u1x?*eW$s>!6t#=0(~wo_tFHcMpdt4gUClt2C6J~CkoCW z=5$K+au;p;dDjVEzmDa*4W(a>wfe$Pn(}*e^qRli+k0?Wvo>4~Y^b8aXfOVx!^1Vj z!?U{+>d8uqBx3ku#s8Z^dAZ|#Jlb;0Uj+DntmhL~zQ zka!bSM#ffIi4BZ!B53iJ&D_$JSqxca_Yu~$q z(7c_&g`WZMCSc$fzxY>I#ON?lK>C~J;pKJPDc#s81+NkyiH(m}X#>bB&J!VlWiTAy z2AfY11PtUusAr78h7mCSC$X8$A4lqbQwJbUZ2<1ee>5fUcIcP~YgS*J!35?uGQ0h0 z3(yE_)@wq1?t~DcXfmrZ4ub=Ymjq}IaDlR6%l;jL#0#t)pq4xo9(^0fNX;{t7Tm(tR9|ZkxCw&9uO}Gcsm(l~U zp7cVHrr`u(5y(b-9HznWMgi=HC(TBWmL5SqnSU!NC`i0E3sU_WIx5|%K`2Njl@_@<6`yeItAL8sF+BxO0J@V~kImYiS4)x4 z@yI+}wr7Zek)QEk3@hl#03-Hp`qiC|{S=+jH_c;ZZ&Rt|@V5+1z^l z_%$v4r}O*N@S^70XsX8|nP1^Orka`CY7;w9eT>B}aATYl+DxtdP}7PVtGUk} zYZtNan}EMCZ@yHR(_0^}vC=t7h(ODIMP>eqp6=RWPKQ(WP!4(UP<@a=_EA#|q{m1K z6%7Nk@4uXWOp9u0*WAR1z<5nPgp*&wx=SL$7fjU3E>ItqSNrc>BiiARa4Hx~rS>dZ z)qKec^ZgmXy9MUq-pvMyZjF4HNu}Y{mnE3cBZB;U65(3g(+lI6xr+Q>> zrqW4JqXl`&6RkW;UYQ(n>(Q&Gl&0v`ThXc?{AdI` zaoP|%clX*9;x%W`iWb0m9$(8&Hpb_?^Fz6$zbbh@ zne41s;$ARN-;1Ho+AJeO`}Dco&axoD$9ICSka_uQXY)z8eoc}9rBzGy=LzRRW^Gi` zx6s^@a+86q^21A9=2#fn42tI_JUIbSmMmUTwV#O!d1j=YI^4%)G!)Db%_+WLQw?=< zZRR&bKu_755&WVmc*RY&xou71gl@@wE%8=8dlqjiY;np3iJf!`b^1y_U z7K%x4?y=_K*-s=tYSrfjoD%uEvo7$Or|_5GmF%`milV!}*7|fayTQB0i-^IWB<`iI z1hGF2Vdg)%TpcZ!&Zt>pRS)6M)2I{z4-eCVijV~i8HOi&Pi4%O0vIa^))d{-$4+Ybot8qOUCTjFWnKtO zwE4PgcD2wR^1SuyBIwCJ8J5-DiLa9?DH5)AC@LxaTYkLn=%DPPH7Ci;v*y2`k3t6( z7swEr(jTZd&}bvV9?NJl?(iB*kWW5z&kKDZicLWr#d61x0j~hK{_uu}qdf*YK}9aAQg=imD=l{iz#SQQ_S z8Dbex_Ya>2vW++hBBS{bZK?{89b%w)I%^>eMLE~7{6PItsEqS9_<^w= zPbAS#8e#(3SqP;$fD+M@ky<3TgF?- zdEswa#?i^pI*|2Beqp@3*rB3Dd#HBHx-JBM)lBQP4GSq6Qvj>AQI6- z)e07K{OOk{{}b6EtHNu`%;kl)TOIEY)2| zU&5mdovXeE(V}Y+Q+9|qbK5&yd~vCVtq&JsK&exrjCz2Eg~}7@iKrqzN$qE@{y6V} z1j8vG#TP}k!J#YsTbUz63Ymv#1|DiosrHC#=;jQWx!XyVg{^aGU~70>+AQjf9_ z$#}*TtrzjP>nhw{A9y_vij8#)mPvUffT zULjB;nCW#4!B=})JWefNU-xwImIC1sis zm+Oo#Wx?Q-Ucx8TPbqHlMAT1%ErGJU)>YdbLil=0CoH%Anb(=vw6cEpRV97hdu&W|P~%SUT~#%_MMshO zeFF0ONmzZg^^m|@n`)PO{FoMx$lnn;uN`(5(&57ExAS-Q`=5GuB2ZA28U=k%hi#x; z)nk(_PtC$cR9v}#&MT106hDgKdl<2O!-`)G*{PgEkE13*dGe8&)mnVsA-y53w=+1e zDMeceNeoE{M{=U+zTr(d6>UKf!MC;wdh^$``zJ{5pHARPsYRA!u{))%WW6BMp{48t z6E`&jqK|{?iDUJajbluFuOY;ydmYpmBO}(B^T(n}MEQThilb`zMpCcP2c_N)s-Pn( zKJBsV)jzQ!dk;hEZAnZWrxR9vFNCQ#YL#S}@u4}XudV|wbQVyqwxne!E%D~@@}205 z@Rjs3NrkAT?Df4(M6mz{JT=K@L>YxtBSL*^M*+`a_MRi?=lqwFu?}{tytH?I)1CcN zfb)@H*6zP9j0LZq=MA$MMV zrKFtgtjM)*I;lIygwO-aC8gx-G(b$PDSjd#8j*iHz`%&Pssdd{;G3#E&nks?OQweU z%@ryCi*NWz_~%k$4D-YKc53GP zLt&=ib6!R3B^qsB82zfg{$@hMPMO|AYgSf4P>6!*=}DFdtL2il`pPV37Q0(ct)voC zpuaWV89FE;v0E=Ih#QhFoz+e6(zHO7AXOf}C`QUQXg=88fyrzXdm`P08yyX*t~j!a zppXF_#X!{*O-8YmCOniWpgx(A_gcYK!1c>}2{-w=qTBMe1THC>trmtUe$P5U8dSu=>3sLOd+H!AUeDK=9Cx~I z;;VgsFx-yf8U%JLp1q==W50BHPbfL$kJqhKJEC7C(lG;7A<5D^2PfvM2UA6e2 zTQv?xVB{GQrn{%`_gkR8KSQgTxuQ(0XsmCT&=2u7IO2*7#;GzEL-flEQ{e~cd3&?4 zdg58kp>v1M{#tiY^|?i+w)FN_!cusrLmga4Xx?TDNEG)@7q2eA*$n}rHK7(t$qEm?XJj)hycov&6+73Z#%a$|Lltd=}z{KVV0~uD;&GyyL3%! zPi9B8h2}{@w2v0mo7 z%sV_gVIJ2D73Q4JKw>TOL~oUyFUBaZ&)3iAsr8+R%i%r%1374A@NHc|dzstB88aCs z3|%y-mK7yyB)^nJUh7UWqWcEfo1a_>Hnw-M5$BrbL{(?}K9?Rf)toY~c?!2YK6eP% z$DPtufn4K6L;M=7_LvFjOD|WltF~g76#aAS+O1|pRfQ7a<32xXq>{N; zood_PUJR$H$AL#p51rh=M>e^611_R-fg0`}p5y3R&By1roH$175v)L_3u;iiv z_zTp3aWSfWHC9}^4s=dh44v8Jnvcg{BQnrqT9*4su_(@C;Shdd$Xv)7#**AxATrl; zqB0v${Q1|jCgh;BwYyiQ$R-*W^0fcjPHrq7vqoAVf9v$CUa$_$RA5EpIo~~-H|i;= zyoQO{`makx0+}MeF03EgX;&w1u)brV*1IPNYE*{~R49bbr=xwn_fc%Y1JADmrMR^4 z^xbUqzEdWmA!RcxQZr@EAAcsbJXCd$&zMYQI(IBCWjVZjPGFGKF8d; z&8jVrocODG+h26g{YAhdEf+tSAh$*gO`<0W8ZE%r<<}$WkV9PnGQGa%GwB6$TOf0S z=!94G@4;8x3sgAXa0pNf0T`%$uwEIGK^m5{_xa52(VfXPuFs{Y-suCE6GG)`DK14$ zkMw%3D2Wo>W-c-*bm0qpX`-}AMC-MuPeR6PS0svl5WVmTDCnMlILt|=Z!~@)Nmnf* zSW6@nT#pVI=6hax=mn>t2MwWmBY*x0$pl4;PF9VV4)2A3P0@<%h|2q>tasLuv~a11 zz3tEbisU6~A}kY}-R^;-by)IiL`Aw|=P(pH>jcI1d+eH>Jt(b*QjA_JPlxaKHaRSd z=3#F!6FVF1QzWYerL~@}-ox(|L2nav2Cvs5(M&;kEJC+IDCNL$pExm0=(vswWOw^I zBwwy~b)GPdxv_heR7ZmEAAseIY*V&)aIP^Si`#a(6f}?soyvlq!oxxEl-bZm*(ft* zv?^z5)+ZYZP^PpEjp(d*Wp4__n@(i~FPefP{=7eRJIpYRNU=C>W?tCX5r>0;klEfj zMPglbZAOjmqeZ2&Dso1m*PXiCPwF&F!3n=8VwY`OmQ13C{*;9igc2qIy{MOgDLHhN z@hzHV1c{V)2?Z_9WmNqgsfYmA!0npKKJ+jQluzOs7;t~o$*+5Pyz6?^N~4H#c9UPN zGr)o)tVn8`{1yirffQAAk+8INMYq;RM6s6JHwam5!gd!5&0llUmp$fB#m9rs_Y_rT zbSPz{AKmoja1cb|&ZQ;;q##spO&D0B7AB#bV*>yBQ0z`Tk)s$n7v);LD|W`4fv>Al zwj#tp4u&ycmRX=GKJ1AuK+TYvJTH|<2f_F&XjstlqStI$vVLG~8od(>lYYy5d6{IY zF~UXTJx2X^md<6VVV`ne^-lEVie3sg%F0hwKV_!Sct_QXhY{8uJ|IFP@Jq~o$&$Dy z*=MykY^Dh(*xkkPicf}Ff#q|hi>IQdipz_Jvr@~hl7he;FvdswQh~{ej@vS!AA^Qy zZhOw5`Db_or4-E?5{CB*PZ=G);Z!G>*iP`1_*;oowVO17U7xbNUJH{EDoE;xcDx8w0fetkRn%6k1~Ns zP?h>()%Polh8B~jW`&!;TMo5FoF-0D*S?7vf+m%y6yJ0?2IB<#E^?q9UZ@c zo;Fx`8nIqsnJk!JL`*KgxHAkXOSNx~iV0e;OyzCcceZcA(Lt)?_ymz5+<8Vh<2@Gj zXhEHC`H~-Q>q&VF*O5arzS{>iPK&P;?s?f?3$)w$)&qf zTDoItX#r^vRA4D7329imLsAJ@LOPZdX$b*=r5B_nML>{7p9}Bz7rfv0!#UGu&g@)s zW}1Azl?`BQppHD2Wj;L+w0)E%g}eVz5t`Q0rwyh?*DN#bD`x+Gt|SAaeFa2sbZA3fY7$z-q{-gl8Px|+FKBgJ5^<8v@ypI^L&I@i>Goa^<<=g&YNOFYfe^b;k6qDC7 zp^d`IPeJbzWipwlq&K@*!~a`UukqrIh(YZcZ*ev^Q6G`}dgBjdd%`2^fFJm+$J|f> zf#bXAf&PpuYkgi8bK{1&PYKEu#fmW{kHtv0cRVVdB+L87VO0=Z)t5!$P`eFyl`r}{ z?kYB4Z9NZ*G}2ug739H=>CT4-e}LZ9_Y$;t{$-btQ117otW-G|l{mccnZ1akYu;1O zpZJ|Okl@m}q$F_{DE5*ah-ANf8eV6kMlb#>17mJBiLvzxNc}tT12$LX1N=viuPAXQ zC=IEcth;?vr5rFIDegRR7y+Kg$Cd*Bf!i(R;j>R=GJ-OFyUW~E0{YD*3NLs-@y7zz z>HZM3g0b(hPQ+e%*wAH#Ee2YS>TId}89ABEp(x?y92LU{K42r?eJ-*hhjV6e2L8;f zylr$0W!j4mj&tbCa_5_`m96mXebW}ShT2YhB@VqA3|=K_+$!2-&iumi#rvdcYRr5> z2HVvNwX-7J!zZiii(EsCi8scuPG2BiGcb;4;tEx$jA5A3<>(o-ZY86=f$Ng0-@VdD zKXDsYdRMF!Si1wDAf$NA__C#8uPOgP*nQ*YT)lNgz@N^T@tZ41p~cYxzwh_Qs$$sf zctK)r^blJ^&vlBJIAgMb>;nUQ@dAJencUkeFmn~<`wizbG}`Acr;qCsb(V+ZJR;mP z&PkGp^`@*ufqwBysQJ9+4L z^z#k}w?-pk;^o1;ZCdp3wb+=6K#q+&x5B61_PV@T<-+7 zQjp6;aT^ETM-s79`{x>^^zuT4{X<2cp1UM0hqaMQpl{VP{! zNF(B#OdM86d&wVNnr6qi-ljetMn|sL3A-o88^p)8q1A?g_VDHg`! z7x-C=jX*nlFDF^u=}V3Jq$mc6it>gYC!wDG7Mj$AW&kJA52>&&_Ls=ARA91*F%nqu z{I>L4k$FBC$FJ~snWJjpclA^e(ZWzGa2zzXiOxgmeMmt?3;UTYIJMb|Udc~}y`cFz z?kd2)eqr(r;%%3iEO)9SZ4UnGaxF`iYlZ&3;E^MFMpX=EV(f>cF!jA{oIAMiqj}N| z-jGQ+W3`#@iFa~tc5zG;!7tLbM;tUfgtMx+sXcqrUndeG9^rb6J81|JV|$XvUX9Jd z1!|%WM#ttjWCBRXNCmwLn;um7)K6?lu>7b;kBP_`o&{8HS0LnV7Mq}K6Twe}nu<~} zWOd*cSmv{$$l8l1`XQEtv+Z51zpZb5Ws$?&s{1>wjew`3N*t;Un-r30Y3xbzXybAV zr|#u@i^|5rXkWAu)3h2MKn(EPN2MtlaTkEMcL-R|pJgLd@))Ac8-BE&NnV}KckJVu zm~vDI5$a-g0%54hx4gMREg2$v`R_xjr-9d!o{D&eOzD{(8y>Ru&Do= zhZig|+h6mGUT^PFxODdzAY}DsiI|8P;fF{vF=vv>r0VT@uwG(Y|OdmheM@%V(YyveAVYMbkk3TU8~0q1c);Y@`< zET!!rE30_VBO(-52}xYlZqu*g zn#$#-oG4#4D>Z};rR8cZri}@oVflkpht3p`z^*9av5xhRGJF$v3^E_jZyj})^x;j- zKsYA9w}3pQ>7^v!4gMIb(Dc`$=G+iGha!{l5`NRm1?@wTSyyid^)fzmk&nZP?m-?q zyH#je8srBF#=vI4ctWxz%Cc+n+Y{?NcRxi%&BcF_!uMIo5b1L^8OrAT6{siJP0w;W z#bpw~H=YI=zGmYYO4*e-J1{2DlbYDY73yIv@PHkQxT<~BbxX8=7h(}d(K!Fwshd{gps5@QTWj$U-Ffjws)YEl z12U^$X&KA?eS)}COkvbDzlDX6E($}fGj_V|5rf3lDJxiPO*oa#!uG}qNww8$J__h& zEF}-|3?7q$$!p#$a&nsH`1QLD%!Cr;^C2PbGC{1C)C429-$>V8#rt0E!^a^u8M@Wk zYS-1JWcWT$*~>keRWU@dMcP6n*8$LIHZ>g_O6p|oqQJ1?{%Y#inGn?leH9X>m}IU5 ztfl3Kotk(}1KW~*MirvUA?XaoZo!zawzweZA|0ZC6~fkwri(&fzrfX7=Z*A;B;aZd zzjDyj4WoH#4e5B|DHRLa!jqS)Jit4B_G=stwCFm@Qk^g%1?7Q)?MKMl6^s*_fGee_ z!X}CcBB-85hCenq1PPu4vU)`@l9yYRdL6=Y&@mW>@CT3uU>X?lSOcn5PRL{}COI63 zXv?)ezbZkta6$T!XUKC8w~BKIq)zIsNFE?nrMOA`lIW1azSH5OZ8Y@LPcqzOR?_`p$>`4Bm8S#m{Yj9x)&RSav95hhZ8aU<(SojuQjx-| zhbx3K1l~fErfmnfrfM9q)6Wgk+XRj2o4z%Wy7$m?ZwPiSV81Dg<2thMLV09VV(Mcw zd6U7sX=3xC6;pCceE@Ny8X3O+_QTKCGQu ztt^|GT~vbmTlQCFF6}v1IMS_nbH!vgQHcl#J705~y+Waj4$+&^uN1qto1VmE_gsx3 z**O904_9liZM_$fr%*#40#kf{T8d%d`SGW#8ZI~5Bjvl~#uQzh+o0CyT&Ww*72^!$ za3znoE)m)iUJje1b}R#De)a8KZgv&nE?x8EHcPC3M7Z%hxdp_bL#)sM2IBYV31ZM8 z9+LgjUak;{FAFb`S{#$5TmsHcjvn$A5R7lUf!&!0Qj9pEv7gxeVvtd`>PFKUT^_>GkqcM2oh3U+y6!rJnh@L&zi4YFmq`i*<~nCdlm^I;1YZrj@muU5NFgjSgJ_)&aSF z7cZWnac^zn7=bVi6%defjgvt}0QWX;Or+BQ9Tc}zT(q4rI4W)CWmVG6>-4z7Pv$dW z<DttE-+QZ2)?Up^i5ybQGJ=%O#TXO$kqOdEm)gYM_tMPnGODo^zonz;0M=p-AH8wxw~)hL4D3u8=>= zdDkqCsu+NlO)(`uS@~kJmh}mXY&d^yAc&~;dW%4pI9O8d>x?&u zLrU!Nkf|QOV;9`U0BW&xR$Zqv?hCn|K&bU2AciXL-7sT2_mB@-mbIcx13=Gy0V7P`|kuEQK4 zi}4~JFpi3{Zp+-Z)Ev-;GtGp?z0`$}3)llmyN_+A^+DLMU3>`fSKu4K3i8^lQ)o%^ zz+q!2)Owm(Gc7C!wD|<|(3Ybpo5oYTeDU8VUtw6_v-i?5Z~@>TN&-7@@lVO*Uy^ab zl7+M4b4Ij)_mO2AoV$YBRui6O z4Pfk4c5^i))ZkYfwEDx#JZT{>QjY!{_42hNZ!3%m8e&pRoJGm#l zfY6sU?~B+M63BWxSq6U7)7?9Q_oI1HL0E=>RY>oY23KlXR?~Tfi6j?u1)rxNTMh)t zwtmS2>XrH!1~v-6p~HT<@d$smEEDWkYuRBC)340mLyi0jolNdR;+WO{9U~OK9IGbr zRp%JqlvTIVk-6X2o3xDWi|NT)E>#|zKlQ=KOP(0F0ZkSzFbx+F<)8Djh6NPk&?2cU zl{tpjfn9`E^k93zw%?_I1Ub2}geYToVzG3k83x#binQ(>aa`23TeWZ<{tPelriO*= z`RN^-AQo;$(+?boP7H>yC+CB{;aAGBvT7LC+h&*mGQ3rgJQ*#^sb zGE1F-*q$_%Z(9YL;xd_a0RO~))*Yr!9Q73t7dn)$nvHCi;u(-;Oo=K!2D?N=Dn0xd z4i=DDmPzHRDHKlU^K@%HN9o1NN`IIGF{(y5Albw$G(hbXh1xew2#<`VsV6kO!I)+3<7__Y`zF+`;kI4e@~WnpzkNeRE#Um`$C34_Y9h6Tk$4Ett$Zj z$P67u&kr8d?OI$eYu7ZeL^+Ww{v~gc?O7a%>S&7+`yQx=$11qwae#&u5zRmh8GgY- zaShXA4QiB+ftkhn0T&AxdMEy~ytwa}LL@Q?NPnkmram|uQD1#~B*hAAgJl5MSOHd& zGy^PkG|b?030-qJF0d7EpuKJ$F5u_9tUsTBxyVdF1ZjLn3R-*grfj4~?UWI4u-QdM z7*k~cQcccnt!c9gbZ=fp`@N{{RCN7w|=j zamRGbF54%|JFBMIl;hPi@)w^2tX@;NaFDU!)bqu_z+SXqu2)Y=&d*4zJJqU(bf5ur z2zEV`7?6rdk9nqZ?Yeb$V_ZJ6UagtRd!}Wxph^Q00*YddN#5}?AijHmA%d6#Gk_m#Hr{Bw|$#$&*6}4{Z;?CMa z#JH?*GS|6k`AvZ5h~3A;4JC*w-P<4zelgLRHO6mT(M@c<(ok-3=TMifrTcAUQ3_f; z26~A$_V+C7H=VNxDLdYyt%3^xh7p>%{SxU&@@DQcd}2k=Eq7K8qh6)te7ZRS45=jP zBWeWV3hUmtqQK@Ro833rJ^D1?m+>0tgn)aBqqOij(s9*w!#kAYY?#QyX`*=Pq-kny54Vp z0@aeLzv2`%V>wK97?nUWejA%ky@y>%XcT=c7$>dm~U$? zz1On*Nf~WwrwbMwBO=c$J%CljYo?avY6@o^i39q|pM?}|MH!sMcx&RZX4@rA@(H2u z^5^7-nWY3lg`AODe~?^rla9r_S_Byd-ZjEx8Yp!RG)1Q~LOjXcLBD)JfY@J_%A95j z;{KuU$!k{W_g&{gP{qWU5e^I;QUEgqn6-iIUCigD)UbF#<^r=EUi?QzP@Q?8 z!FG#cOcdA)B%yUwcZ( z3k-kL)71kiOe(HKogARzy;407@j0(~&)F`Mmkki)p_V>$x$6Lam*20-f3COZ#TwL# zFr&U@*aAVHAw^xuUuU_#O3xHCsJ=>HcQUt{>6L!iR_?W6_uTbz;55kGu>QG$();qw=h#&C*%lHf?%)L*v1P8 z-VnQQ{L==8co4PIf*@W`8Uqt#SS>83igG!iFzuWtCczBLpL`2CNgVW7(KsnIv^CBx zCM;lZS~a4kPt&KA{%`tR*gunwOA&V^C!7BBPDKT;9jnd){_bz;d9<+HQ_xiIIMM;g zujIpjSN3&B;`Taapn@z=AD__syrjN+dm$bqG1C*2_YVpvQ^BIj?&BXGH>sEyuoo#< z@b^14)U~Xgznl0;k0n&XVaa3rG6_yQGb3n_a5UgoX6=RE23ch}- zOTEoi0kp)ciV$uj5qG8T+A@Sxu*Sp!@cy_Iw?NKrl~GtEbj<$OY(gq5<&`fM*v}rU zO3sa3lx84CxSGW^XqZ&8`c2r-?fDg^&u9%dn+O``ojdE{3t|%1EjIo) z67%*k+jXU%IBSxVhB!4*@<<8%O|}%X1Zp_r99&>{&(J(=@51?KZm%iQH=t1yZ6z(M zbX_zWk3G3e;UCC&AG@}ZyU*`n=rLJ6 zx(C(L0|h@~^Ud(JYHVWa{dkRa0g(OxVL9QLQ-KC!7$JK;N)uWfO zQ=@^X3$JS~3apJ33M?s4()va0{;S>Ldw!S?5b^oYneIcr~3 zWcqMD=$Dia3t9D8=3X};ULgyzB#d*YFLcMyX>V+&cdd4Ib^SjI*F7G7WQS>ooYz&n zcpz?;MyD7Uf%uMePi=`il3|5erQh|%{tZ>#lz?2S2cJ3Y8>9}|vBNZ5s+tct^X0Qs z$guOWWjT}ym6@U`>@w@+EB`23F9z5>w-z$S2&=P@T~DJdJOB9*xv%8{4@oki>iMAh z<>W1*D#|cx!F6r1-prx}5#5Iu{4inXP`K?U8K^#2mGGb>Pcc*$S_S{cM@ao(BTuN> z5J{}HH1d;W;7LzDnihto^NQX8k1whElfz&JiR>_$pLeAK1~G(?Y8=(CA;>b+t#tpJ z=Jix^N$>lr<@L{w5*2Sx0`07fRak^aErV*V3lMTE?zf9VybVfz;L(W3qIhXfzs*$| z*`lobV&6p4qr`uZL0mQRDx}W!HE=3~4(O#^O>n3|u>m0}C<(i*(u#g}Rw|rz&5ytz z(KfkS8&gFS}0Puo*CMcQYOw+Vn!A={4Q#dGXuQO9D?5fReC6d6A3OgDR_!Z-{lLkF84Fxr z$_6QL_fH2&@P>#7lfOx%FUwGLuGZekCv%;&qF+T~k19W3zi2}+M|on-CLe|D*)e+t zP2jPQY&zSu{rGIXv07x~9_Y)++Ja?X^Y=xAM2QtOgww#~R?p5K5+I}b6UIPp`@rsL z3!(w(46Fw748CjDcJC%1K&sKc;@!w!UahMgH@{=5;8Km~?`!+iKo`;%`{El9Fsz}g zuc;60Q6;8M(@^oEucvUfw_5}xbmEuiJ$dRYW(dKe-+c)qO+ap)xyx(L@B^X;b2OP-U%k{SEj zOjNf+WV0@uc@yc7!?cm92}FG!1dObePs(WQAu4*I_T=@^!C%~21~}KMFW%rPNP1lW zjmK54=GGjG$5`B1EG!Up;Os?x+L=a5pwLy_b;*-JLEl=OiYBAC53kCJ*NTtf_x5Y8 z*qZR1*wn^W{#!yRo>l%t*J0UNYWa;{hNj<~OaHKV^%!CF{RG?LHD4Z~1aApBgnn?k zQI{(=pkw#(WJmisihPVrbv~^}*!8sqol&f*8MwB_RBEN6;kpcjhp<ODFmCC`KHk74{!TQj-ujLVgARE1T)E!WyTdjz>s*@)TgVHX`RJbg%O6Z=!S_+i zqJRuUT=9yLi9&NYpN-J4ZBq9T&%{Nty2V+an-gosgiSdWbT^%ARIot!W1^N)JvoAY zfe~h$uv4l_2J}$9fPPfSsRI>WrOWiJIQRb%f%BPx(Cxm@9m`absLZ~$ENYE|B&UL-b2A*%mV7wLZZw7y5?EG%O`q)_M)k&zxDgTw;n3Hp9NXrkJci< zAn!x|HhH%lbg?QpGey~6U+j18^D&3r`FQ|Yw+*3a= z7B~ETVG4fC368i-9xs5l9HX5W#0Xsy_3=peiv*mPV&Bt=`Nq}8UUGqo!;|p7f*FmI zEUo-$qHv`tDdg?uQJ+G=rgYzSJDv|2sE4GF=Z$CdQJR3(Q)=)=+OkSS!iEBMcGKKXUH}sX#H!lt_-?(r6ZFGhegZ=WxJ|mA|&p2(q&S7 zw6UQ2*e7vDrY@}tkxL^$u4K)rp;lpr%?VQTp%lsT2_=0UcDP_n+f#TiQe5<*ahV}f zVdLgG{r&4=g)9j@6v#J9AdFkt%@^~;Lj-=OZQ*FQoXPYe+lmb4S`@S_fW%*5WWxRG z`-D)|U)kSGT;bg)^>_Tuxjl42ww9+XfUMaFCBG>kpVag5>*vVOkU{_}=bn-EEJvvN zj?{(u|I&xPgWs8;(4h)Hs8Y7<>}rJHz3V%s`^8gjuu0S0;(6)=JIXADa+(?CgYCn{ zd!3*{jQ}iDAiLU)A^BZ2iZmIsZeaqp?zR@Umj3b`!ZM1rpoqf8Ji<#zk1_?DY4gIe z;?pt3mtxH#?u01MQ$*O&n-@@?8ganx-Yd!Ne?rz~`o@2=GjFRU_c{^(83>)8L8mn# zUDJB?6|>;3NcaoTMdewjU1pN@PA1FuO9+ad%89#^N%8jpdLwdN(70R+`7=Fh+;7xt zhAdhVXo{D);{yFwI{w1cEPVxu0o*KBWd8kKf{Byb)qbHAgV+nS^zxhNoH#w&{5CY- zUxsEq>09TfMwgcJby*qYmU~5PIetfPZeSSlJ_f-V)XJ}c3or}E09VPF)5KNpnmiSt z(@p@cu(H#?r@Ex$S9UseYP<&>u56v`d013U)gY*qp)7^C^|+74W|i#}e3$NB7=q*B zygsj&oTJ6u?W83YD4*pD=@%I9n37a^T{tQ zH{qpuyB&aQola>zdekiDcFom+SwZlQSeUc15*_HYEfF8l_u5d*;B2k>Wsr6Ec_Ku$ z$}z3<8|pX0_=b(Y0Wo8zcYDFs!9)bV*pMzzbU-p4)}16&k~}&h`$T0T(_Ch9@ZRUo zeh39Y-lKz`O!dZ{?So&MrAfjDoswK)eU;}zuzB%F$}RIANmAy~)v&K{(M8!7nNw-l z6!95&@IDPzC^>g}aKnI88uYUfK|6+CKrdioHzkGg(HT`bZ}#~y9z}tN=95w20o^Z@ z7(_P2{Vmg`d!*0Id>%A?%B0;S`?FLDtqAM&B(|=k#Lp$KqNJ11iPTINE@h3^@xhL& z^xZ*Ir=;4`bq0kb$Ee}$$J+VHpH#EaDliYrg1dIev_*%`dLi^d4ZU{3PDUb!#v!>o z%G#o`Xhk|az7pA4WPeyPTAXsnp@R+YN(IS$&V(j*_zz8wA8P9>`EIMc(8b3j38-yB z^nNw&z*34FYc<~MUOq+Fo~9saMo9B^IOgpTPncvSOXllmqwzG9`Y2C3Q4O_cO{grN zZgi1SJ|L@xvpa;i?>(5YDbP2QQTOCq!FhKMxjnWzXwUCM3*(v=y9{JQ-Q5UlYj8XJ z_M&x^8;Qv(?X(>5@6vD3P0;S3?F(d=H;<({7u1=fJQQ#(2K|Xu9*?sr4<+=zBb9%J z?6`U+S0cbD6e;P{(vxw5ZZ(R>)PUGgdUIC97zNLTNV{60Vj5g%C?5(X?#2p_^GhK` zk;r7AnBQljBr6%*B~*JFWZ?csoS*^~s1Os%y!f$N+P5_*i+0#AaU7q|mSb0QrzbhZ zsWL(0vy2=*j_i};$WnZ?O1SQ?<^6y$WZn#K-8}Lk5Ad|4GtO=DYKXkus)qdV@>W}0 zGzyhx#^S$XcCK7Espf(^Ay|MZ&(7~w z-C!4IQ-aU&I!{boLCkq)-;rNFX;T-yDAA|jQm??U;Gv-sjr;cpIaMs@L0eO8=uecD zKCfaEDuyL8*h3|Znu15X(fg+iP)550I;daockWJ(xOm8_MRns)62H3qMWN8XxdPU# zBOiPDyO7VKd?CThNPcwrh8$8w@F=Yf8l^Z7K6d@9%F_=S^Vr0N6u|r4wuvOMU%ay%2&!*c76((&dn`Uk6|o&V zWI50}?d3XT5yc%`4SKrSt~%SYxF;OE*0x&O(I|V>)^Z@DC|i3-fr&;jTh7nuxa6Am zFo>^z3anwtJAC#9E}u8zmGdz2b@S_KZ0oXDgM8($YAZE@a;(fbCS$Z}KGDsvqK=9} z;f^ti^K{G&daRYajf?1XCL(74`L1;HXN^P5=? zq(vD#WcMhXV6B1b&yiU}G|73WWzm%;4FEof>RFP}&Kziz=zfV$@ZVealDuXTh|*EJgL9 zDGfL6jBd*Lxi2u_86eAVH~R30&Qi-TQt-}*rffa|lldfw@4D2<{e%Jf_PK%N*ng@u zp*PDrzuQY(@|VYsm>=4AnlL4>U`Xw@%)3(xFG^l$0|U@Z{OTP$cfb?ZJ{sjozi!!2 zF~Y43PCQYAr;OS|iphK);cMs<4-49FcW0^p$ zM0|A3PTOUv%2i%_h(2UV6v5)AFzM}L^7Bw`DKPmL!x63B_Z;ckj0XtZ-q1GV{{*$~ z#y7#9Rghda;!@x!cVT9+T1$%~$~U8tKd8I&;7PUhaa~IOsK^2BGq12x?!%AfGRS&< z9`JwmPPcD1VRCTkXwx8ecO{{1v{-oFY1J4qC4wOzr!a+7_splRz8eKD!*Q|)^a6|v zi%s1-EE9p+PiV}bjXV7mczLJ&Bmf`Av%`Y7xvT|uZ0~^<4(2GcLz@ZX39*Tdh~H7k zgMqC(DxTggRpqA2L%-jrQ{agiDK%NI{9ODd%7u^B|LBi*KzC^dje|#=v)n)9FZ#mu zdE7%lAfBz)J1a{>Cw_Gze#(~GYK?x|cbOe7R6W;rnHB#kBZ^~vccI4Z+ya8^yHCne)t zUH9S;W#uk|VG_&??ojSqk*ma=^z=@uq@=8t&L%d+3`t9i6=dJ{4*_QG0N}97Yo$nh zEM!Ul_;ntCGNktlTQ5Z0zQBHj+nNn z`{Z+={sC|qYOgUuS-u(Y+O{H?l^5mAHy%#A(lFKpkiJ|E`ln4LO1GC#BdN^D0@c4C z;B~sAM2Ka$>kxzUOJc@`0MVDLoo8@@dq~QtyAbd<1ANJVuRJFQfv7Kj6h+BW3~m&7 zjjCzD0yGl@x3vMjjQ!*MZ_RHm#amt%2u&Td_j!lyJXq-pcz^Hn!z%Z_FQ&NjbW+PP zUvxeWpMPx&vgs$AFts1sK0P0&4!n0_Mb5sz2utbl-I8}`CN?PpK4lQBgt&EGn)7Ki zl$`zZ7-5xDk0Zl96#t`` zmv((I-JR#HhWt$+*ONAq_+wOa9Q>R~Y8goeq5%I>g>hVg`*}G%{&%6QNa~JlK`pg}ymVbW-EqV)MM~HWH$E|*x^?p+t zEU#CrWMK2p)hU_$(58N_6-Z+B47z_U*0CudzW_UGAM?)G(a^pA<0Sm=fK)^%7kt`{ z=70IR`=C9yb~kg6=+;JCZvOSx-*QUxrnvu!qgP3rzME)W)Pt(bKV-js2ASdPlbjqL z^tDNsu{%aD{jy}obg&`g%}mLsPw#91R+K266l+NfQUa6DTs5-AmZu9&<+B5}rx~q( z=}$1dx(sB#NIbRrnX4vg^v^9B1?@k-=|UY|cq)~bG!Ek`bw?f>({W7CkHJ0N5}NwLld z-{(;uvz(-vMHkwCj&9CCc+xOVBjEhp^=MD6)d$6<-Gt+VDWiaoT~YI}VCka)jX%$z zDmSH^!=5oH?4On=weIAPTEsrCJ)O`isM*bu%%ztsk{LXvnh^ETvUc0for$~HaGmHc zIFR=Kaf)_*9yBbGR+E`%;w%8BwH zvKQs+j#Esce(x3RBqiZ`|B}!zq!Id$Q3GLl`N$HpB3p3+yHg%6S6a#7$jw3hCh*+p zSrbAC^7r!f5pnmq)#!yK)l{1A>y7Ri@*kf#y<1Ja?ln*aa+ diff --git a/typescript/Frontend/src/util/graph.util.tsx b/typescript/Frontend/src/util/graph.util.tsx index 9a5d0f246..7a42d4dd9 100644 --- a/typescript/Frontend/src/util/graph.util.tsx +++ b/typescript/Frontend/src/util/graph.util.tsx @@ -6,7 +6,7 @@ import { isDefined } from "../dataCache/utils/maybe"; import { BoxData, BoxDataValue, -} from "../components/Installations/Log/TopologyBox"; +} from "../components/Installations/LiveView/TopologyBox"; export interface GraphCoordinates { x: Datum[] | Datum[][] | TypedArray; @@ -146,6 +146,7 @@ export const extractTopologyValues = ( (topologyPath) => timeSeriesValue[topologyPath] ); switch (topologyKey as keyof TopologyValues) { + // special cases for certain connections should be extracted accordingly in this switch case "gridToAcInConnection": topologyValues = [ values.reduce( @@ -215,11 +216,6 @@ export const parseCsv = (text: string): DataRecord => { }); return y .map((fields) => { - if (fields[0].includes("LoadOnAcIsland")) { - console.log("fields", fields, { - [fields[0]]: { value: parseFloat(fields[1]), unit: fields[2] }, - }); - } if (isNaN(Number(fields[1])) || fields[1] === "") { return { [fields[0]]: { value: fields[1], unit: fields[2] } }; }