From 55ccfe57989b2e0184973202060daf551e5cb5cc Mon Sep 17 00:00:00 2001 From: Abel Busto Dopazo <98962592+UO284262@users.noreply.github.com> Date: Sun, 30 Apr 2023 18:51:05 +0200 Subject: [PATCH 01/13] Add files via upload --- docs/images/Logo.jpeg | Bin 0 -> 5625 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/Logo.jpeg diff --git a/docs/images/Logo.jpeg b/docs/images/Logo.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5c5de9318365f60f30a72f4127182427ee634acf GIT binary patch literal 5625 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 xB{_D}RnI%=PGGYyr1DMPr(mjy+O_ Date: Sun, 30 Apr 2023 19:33:34 +0200 Subject: [PATCH 02/13] Update 11_technical_risks.adoc --- docs/11_technical_risks.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/11_technical_risks.adoc b/docs/11_technical_risks.adoc index f665caf2..600f9bd4 100644 --- a/docs/11_technical_risks.adoc +++ b/docs/11_technical_risks.adoc @@ -29,6 +29,8 @@ List of risks and/or technical debts, probably including suggested measures to m === Technical Debts -Al comienzo del proyecto es difícil especificar alguna duda técnica. No conocemos de antemano cuál será el resultado y final y que herramientas o tecnologías vamos a utilizar finalmente. Guiados por la intención de desarrollar el proyecto con las utilidades ya mencionadas la única duda en este punto es la dependencia de nuestra aplicación con servicios externos a nosotros (APIs) y de imposible control por nuestra parte. + * La principal duda técnica es la dependencia de Inrupt. Durante el desarrollo del trabajo hemos detectado mucha inestabilidad en sus servicios. En ocasiones tiene tiempos de respuesta muy altosmás, es una API en desarrollo por lo que no podemos asegurar que sea perfectamente fucnional o que vaya a cambiar significativamente en el futuro y nuestra aplicación deje de funcionar. + * La interoperabilidad nos genera muchas dudas debido a que ni si quiera se ha alcanzado un acuerdo firme. Se han tomado decisiones sin meditación a su respecto y puede generar problemas. Consideramos que el estandar de LoMap no ha tenido suficiente tiempo de desarrollo como para ser óptimo. + * Nos ha sido imposible hacer una comprobación exhaustiva de bugs o la inclusión de funcionalidad extra debido al poco tiempo existente para el desarrollo del proyecto en comparación con la problemática percibida en general al usar las tecnologías impuestas por el profesorado. From efabb18608e5e54c10fe59a591b297f30bc3d8d9 Mon Sep 17 00:00:00 2001 From: Abel Busto Dopazo Date: Mon, 1 May 2023 13:20:32 +0200 Subject: [PATCH 03/13] Some minor changes --- restapi/src/persistence/DataBase.tsx | 18 ++--- webapp/public/fotosCarrusel/logo.jpeg | Bin 0 -> 5625 bytes webapp/public/logo192.png | Bin 5347 -> 0 bytes webapp/public/logo512.png | Bin 9664 -> 0 bytes webapp/src/utils/fieldsValidation.ts | 100 +++++++++++++------------- webapp/src/views/LoggedView.tsx | 14 +++- 6 files changed, 71 insertions(+), 61 deletions(-) create mode 100644 webapp/public/fotosCarrusel/logo.jpeg delete mode 100644 webapp/public/logo192.png delete mode 100644 webapp/public/logo512.png diff --git a/restapi/src/persistence/DataBase.tsx b/restapi/src/persistence/DataBase.tsx index b611c871..b093467c 100644 --- a/restapi/src/persistence/DataBase.tsx +++ b/restapi/src/persistence/DataBase.tsx @@ -1,14 +1,14 @@ -var mongoose = require('mongoose'); +let mongoose = require('mongoose'); require("dotenv").config(); const uri = process.env.DATABASE_URL; mongoose.connect(uri, - { - useNewUrlParser: true, - useUnifiedTopology: true - }).then(() =>{ - console.log('Database succesfully connected!'); -}).catch((error: any) => { - console.log('Error connecting to database:', error); -}); \ No newline at end of file + { + useNewUrlParser: true, + useUnifiedTopology: true + }).then(() => { + console.log('Database succesfully connected!'); + }).catch((error: any) => { + console.log('Error connecting to database:', error); + }); \ No newline at end of file diff --git a/webapp/public/fotosCarrusel/logo.jpeg b/webapp/public/fotosCarrusel/logo.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5c5de9318365f60f30a72f4127182427ee634acf GIT binary patch literal 5625 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/webapp/src/utils/fieldsValidation.ts b/webapp/src/utils/fieldsValidation.ts index 836f7d7a..07cb4757 100644 --- a/webapp/src/utils/fieldsValidation.ts +++ b/webapp/src/utils/fieldsValidation.ts @@ -2,55 +2,55 @@ import * as yup from "yup"; import Swal from "sweetalert2"; export function showError( - errorTitle: string, - errorMessage: string, - f: () => any + errorTitle: string, + errorMessage: string, + f: () => any ) { - Swal.fire({ - icon: "error", - title: errorTitle, - text: errorMessage, - confirmButtonColor: "#81c784", - }).then((result) => { - if (result.isConfirmed) f(); - }); + Swal.fire({ + icon: "error", + title: errorTitle, + text: errorMessage, + confirmButtonColor: "#81c784", + }).then((result) => { + if (result.isConfirmed) f(); + }); } // User validations export function checkPasswords(pass: String, confirmPass: String) { - if (pass === null || pass === undefined || pass.trim().length === 0) - return false; - return confirmPass === pass; + if (pass === null || pass === undefined || pass.trim().length === 0) + return false; + return confirmPass === pass; } const usernameConstraints = yup - .string() - .matches( - /^[A-Za-z0-9]+$/, - "El nombre de usuario debe de empezar por una letra" - ) - .min(6, "El nombre de usuario debe de tener entre 6 y 10 caracteres") - .max(10, "El nombre de usuario debe de tener entre 6 y 10 caracteres"); + .string() + .matches( + /^[A-Za-z0-9]+$/, + "El nombre de usuario no puede contener caracteres especiales" + ) + .min(6, "El nombre de usuario debe de tener entre 6 y 10 caracteres") + .max(15, "El nombre de usuario debe de tener entre 6 y 10 caracteres"); const passwordConstraints = yup - .string() - .matches(/^.*[0-9].*$/, "La contraseña debe contener al menos un número") - .matches( - /^.*[A-Z].*$/, - "La contraseña debe contener al menos una letra mayúscula" - ) - .matches( - /^.*\W.*$/, - "La contraseña debe contener al menos un caracter especial" - ) - .min(8, "La contraseña debe de tener una longitud mínima de 8 caracteres") - .max(24, "La contraseña debe de tener una longitud máxima de 24 caracteres"); + .string() + .matches(/^.*[0-9].*$/, "La contraseña debe contener al menos un número") + .matches( + /^.*[A-Z].*$/, + "La contraseña debe contener al menos una letra mayúscula" + ) + .matches( + /^.*\W.*$/, + "La contraseña debe contener al menos un caracter especial" + ) + .min(8, "La contraseña debe de tener una longitud mínima de 8 caracteres") + .max(24, "La contraseña debe de tener una longitud máxima de 24 caracteres"); const biographyConstraints = yup - .string() - .max(100, "La biografía puede contener un máximo de 100 caracteres"); + .string() + .max(100, "La biografía puede contener un máximo de 100 caracteres"); export const signupValidationSchema = yup.object({ @@ -59,27 +59,27 @@ export const signupValidationSchema = yup.object({ }).required(); export const editProfileValidation = yup.object({ - biography: biographyConstraints.notRequired(), - newPassword: passwordConstraints.notRequired(), + biography: biographyConstraints.notRequired(), + newPassword: passwordConstraints.notRequired(), }); export const passwordValidation = yup - .object({ - password: passwordConstraints, - }) - .required(); + .object({ + password: passwordConstraints, + }) + .required(); // Group validations export const groupValidation = yup.object({ - groupName: yup - .string() - .matches( - /^[a-zA-Z0-9áéíóúÁÉÍÓÚñÑ\s]+$/g, - "El nombre no puede contener caracteres especiales" - ) - .min(3, "El nombre debe de tener entre 3 y 30 caracteres") - .max(30, "El nombre debe de tener entre 3 y 30 caracteres") - .required(), + groupName: yup + .string() + .matches( + /^[a-zA-Z0-9áéíóúÁÉÍÓÚñÑ\s]+$/g, + "El nombre no puede contener caracteres especiales" + ) + .min(3, "El nombre debe de tener entre 3 y 30 caracteres") + .max(30, "El nombre debe de tener entre 3 y 30 caracteres") + .required(), }); // Place validations diff --git a/webapp/src/views/LoggedView.tsx b/webapp/src/views/LoggedView.tsx index 3d3021ee..d620cc9d 100644 --- a/webapp/src/views/LoggedView.tsx +++ b/webapp/src/views/LoggedView.tsx @@ -6,7 +6,7 @@ import { Header } from '../components/mainComponents/Header'; import { Footer } from '../components/mainComponents/Footer'; import { useSession } from "@inrupt/solid-ui-react"; import { temporalSuccessMessage } from 'utils/MessageGenerator'; -import { editUserDetails, getUserInSesion, logout } from '../api/api'; +import { editUserDetails, getMyFriends, getUserInSesion, logout } from '../api/api'; import { User } from 'shared/shareddtypes'; import Swal from 'sweetalert2'; import { Outlet, useNavigate, useParams } from 'react-router-dom'; @@ -14,6 +14,7 @@ import { readCookie } from 'utils/CookieReader'; import { useDispatch } from 'react-redux'; import { setProfileImage } from 'utils/redux/action'; import { obtenerFoto } from 'podManager/MapManager'; +import { deleteFriendApi } from '../api/api'; //#region DEFINICION DE COMPONENTES STYLED const MyContainer = styled(Container)({ @@ -87,7 +88,7 @@ export default function LoggedView() { if (user.webID !== readCookie("userWebId")) { Swal.fire({ title: "Actualizar webId", - text: "El webId con el que has iniciado sesión no coincide con el vinculado a su perfil, ¿desea actualizarlo?", + text: "El webId con el que has iniciado sesión no coincide con el vinculado a su perfil, ¿desea actualizarlo?. De actualizarlo perderá todas sus amistades y grupos.", icon: 'question', showCancelButton: true, confirmButtonColor: '#81c784', @@ -99,6 +100,7 @@ export default function LoggedView() { let updatedUser: User = user; updatedUser.webID = session.info.webId; editUserDetails(updatedUser); + eliminarAmigos(user); saludo(); } else { logout(); navigate("/login") @@ -110,6 +112,14 @@ export default function LoggedView() { }, 3000); } + const eliminarAmigos = (user: any) => { + getMyFriends(user).then(friends => { + for (let i = 0; i < friends.length; i++) { + deleteFriendApi(friends[i]); + } + }) + } + return ( //#region COMPONENTE From 2385c20d18e5c8bac385ddf575d4b770f1f921ff Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 13:21:34 +0200 Subject: [PATCH 04/13] attempt to process https requests in restapi --- .github/workflows/lomap_es2c.yml | 8 +++-- .gitignore | 4 +-- docker-compose-deploy.yml | 2 +- docker-compose.yml | 2 +- restapi/server.ts | 34 +++++++++++++++---- webapp/server.ts | 1 + .../components/mainComponents/ImgCarrusel.tsx | 4 +-- 7 files changed, 40 insertions(+), 15 deletions(-) diff --git a/.github/workflows/lomap_es2c.yml b/.github/workflows/lomap_es2c.yml index 1d3b475a..b2f4b0c1 100644 --- a/.github/workflows/lomap_es2c.yml +++ b/.github/workflows/lomap_es2c.yml @@ -42,6 +42,8 @@ jobs: cd restapi touch .env echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env + echo SSL_CERT=${{ secrets.SSL_CERT }} >> .env + echo SSL_PRIVKEY=${{ secrets.SSL_PRIVKEY }} >> .env cat .env - run: npm --prefix webapp install - run: npm --prefix restapi install @@ -56,7 +58,7 @@ jobs: - name: Publish to Registry uses: elgohr/Publish-Docker-Github-Action@v5 env: - API_URI: http://${{ secrets.DEPLOY_HOST }}:5000/api + API_URI: https://${{ secrets.DEPLOY_HOST }}:5000/api with: name: arquisoft/lomap_es2c/webapp username: ${{ github.actor }} @@ -68,6 +70,8 @@ jobs: name: Push restapi Docker Image to GitHub Packages env: DATABASE_USER: ${{ secrets.DATABASE_URL }} + SSL_CERT: ${{ secrets.SSL_CERT }} + SSL_PRIVKEY: ${{ secrets.SSL_PRIVKEY }} runs-on: ubuntu-latest needs: [e2e-tests] steps: @@ -80,7 +84,7 @@ jobs: password: ${{ secrets.DOCKER_PUSH_TOKEN }} registry: ghcr.io workdir: restapi - buildargs: DATABASE_URL + buildargs: DATABASE_URL,SSL_CERT,SSL_PRIVKEY deploy: name: Deploy over SSH runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 1787a053..5501dbef 100644 --- a/.gitignore +++ b/.gitignore @@ -30,5 +30,5 @@ yarn-error.log* docs/build restapi/.env -webapp/lomapes2c.eastus.cloudapp.azure.com.key -webapp/lomapes2c.eastus.cloudapp.azure.com.crt +restapi/fullchain.pem +restapi/privkey.pem diff --git a/docker-compose-deploy.yml b/docker-compose-deploy.yml index 1a03c94f..6e963f92 100644 --- a/docker-compose-deploy.yml +++ b/docker-compose-deploy.yml @@ -3,7 +3,7 @@ services: restapi: image: ghcr.io/arquisoft/lomap_es2c/restapi:latest ports: - - "5000:5000" + - "5001:5001" webapp: image: ghcr.io/arquisoft/lomap_es2c/webapp:latest ports: diff --git a/docker-compose.yml b/docker-compose.yml index 8b33be2b..c3933757 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: restapi: build: ./restapi ports: - - "5000:5000" + - "5001:5001" webapp: build: ./webapp ports: diff --git a/restapi/server.ts b/restapi/server.ts index 127e49a3..55cfcba0 100644 --- a/restapi/server.ts +++ b/restapi/server.ts @@ -6,10 +6,13 @@ import api from "./api"; import dotenv from 'dotenv'; dotenv.config(); const mongoose = require('mongoose'); +const https = require('https'); +const fs = require('fs'); const app: Application = express(); -const port: number = Number.parseInt(`${process.env.PORT}`) || 5000; +const httpPort = 5000; +const httpsPort = 5001; const metricsMiddleware: RequestHandler = promBundle({ includeMethod: true }); app.use(metricsMiddleware); @@ -29,15 +32,32 @@ app.use(bp.json()); app.use("/api", api) -app.use(cors({ - origin: ['http://localhost:3000', 'http://20.169.248.119:3000'], - credentials:true -})); +app.use(cors()); + +const options = { + key: fs.readFileSync(process.env.SSL_PRIVKEY), + cert: fs.readFileSync(process.env.SSL_CERT) +}; + +app.use((req, res, next) => { + if (req.secure) { + next(); + } else { + res.redirect(`https://${req.headers.host}${req.url}`); + } +}); -app.listen(port, (): void => { - console.log('Restapi listening on ' + port); +https.createServer(options, app).listen(httpsPort, () => { + console.log(`Restapi server started on port ${httpsPort}`); + }).on("error", (error: Error) => { + console.error("Error occured: " + error.message); + }); + +app.listen(httpPort, (): void => { + console.log('Restapi listening on ' + httpPort); }).on("error", (error: Error) => { console.error('Error occured: ' + error.message); }); + export default app; diff --git a/webapp/server.ts b/webapp/server.ts index 147d6ab0..e5ab4be6 100644 --- a/webapp/server.ts +++ b/webapp/server.ts @@ -7,6 +7,7 @@ var app: Application = express(); const port: number = 3000; app.use(express.static("build")); +app.use(express.static('public')); app.get('*', (req, res) => { res.sendFile(path.join(publicPath, 'index.html')), function(err: any) { diff --git a/webapp/src/components/mainComponents/ImgCarrusel.tsx b/webapp/src/components/mainComponents/ImgCarrusel.tsx index c877d0f5..8c4e3d94 100644 --- a/webapp/src/components/mainComponents/ImgCarrusel.tsx +++ b/webapp/src/components/mainComponents/ImgCarrusel.tsx @@ -46,7 +46,7 @@ export default function StandardImageList() { const itemData = [ { - img: '/1.png', + img: '1.png', title: 'Crea tus propios mapas', }, { @@ -54,7 +54,7 @@ const itemData = [ title: 'Guarda tus lugares favoritos', }, { - img: '/4.png', + img: '../4.png', title: 'Ve los mapas de tus amigos', } ]; \ No newline at end of file From d28fd897afc75b40ebaff880e5f3232da40922eb Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 13:37:08 +0200 Subject: [PATCH 05/13] trying to run e2e --- restapi/server.ts | 4 ++-- sonar-project.properties | 2 +- webapp/e2e/steps/login-form.steps.ts | 2 +- webapp/e2e/steps/register-form.steps.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/restapi/server.ts b/restapi/server.ts index 55cfcba0..a8494fe3 100644 --- a/restapi/server.ts +++ b/restapi/server.ts @@ -38,14 +38,14 @@ const options = { key: fs.readFileSync(process.env.SSL_PRIVKEY), cert: fs.readFileSync(process.env.SSL_CERT) }; - +/* app.use((req, res, next) => { if (req.secure) { next(); } else { res.redirect(`https://${req.headers.host}${req.url}`); } -}); +});*/ https.createServer(options, app).listen(httpsPort, () => { console.log(`Restapi server started on port ${httpsPort}`); diff --git a/sonar-project.properties b/sonar-project.properties index 08c48b8a..2625303f 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -9,5 +9,5 @@ sonar.projectVersion=1.0.4 sonar.coverage.exclusions=**/*.test.tsx,**/*.test.ts sonar.sources=webapp/src/components,restapi sonar.sourceEncoding=UTF-8 -sonar.exclusions=node_modules/** +sonar.exclusions=node_modules/**,restapi/server.ts sonar.typescript.lcov.reportPaths=**/coverage/lcov.info diff --git a/webapp/e2e/steps/login-form.steps.ts b/webapp/e2e/steps/login-form.steps.ts index a374ca9b..8c3cfa5f 100644 --- a/webapp/e2e/steps/login-form.steps.ts +++ b/webapp/e2e/steps/login-form.steps.ts @@ -2,7 +2,7 @@ import { defineFeature, loadFeature } from 'jest-cucumber'; import puppeteer from "puppeteer"; const feature = loadFeature('./e2e/features/login-form.feature'); -const apiEndPoint= process.env.REACT_APP_URI|| 'http://localhost:3000' +const apiEndPoint= 'http://localhost:3000' let page: puppeteer.Page; let browser: puppeteer.Browser; diff --git a/webapp/e2e/steps/register-form.steps.ts b/webapp/e2e/steps/register-form.steps.ts index 5539febd..d1251b99 100644 --- a/webapp/e2e/steps/register-form.steps.ts +++ b/webapp/e2e/steps/register-form.steps.ts @@ -2,7 +2,7 @@ import { defineFeature, loadFeature } from 'jest-cucumber'; import puppeteer from "puppeteer"; const feature = loadFeature('./e2e/features/register-form.feature'); -const apiEndPoint= process.env.REACT_APP_URI|| 'http://localhost:3000' +const apiEndPoint= 'http://localhost:3000' let page: puppeteer.Page; let browser: puppeteer.Browser; From a527a113da5fe322aa4932699f16ec8d3cb07de7 Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 14:56:32 +0200 Subject: [PATCH 06/13] test e2e --- restapi/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/restapi/package.json b/restapi/package.json index 77624aa6..a3a716bf 100644 --- a/restapi/package.json +++ b/restapi/package.json @@ -3,7 +3,8 @@ "version": "1.0.0", "scripts": { "start": "ts-node-dev ./server.ts", - "test": "jest --runInBand --coverage" + "test": "jest --runInBand --coverage", + "pretest:e2e": "dotenv --dotenv=./.env export SSL_PRIVKEY=$SSL_PRIVKEY && export SSL_CERT=$SSL_CERT" }, "keywords": [], "author": "", From 0361d90f6409f6cc6bdb9d151b79117f1cfbaaf8 Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 15:36:09 +0200 Subject: [PATCH 07/13] test e2e --- .gitignore | 1 + restapi/package.json | 5 ++--- webapp/package-lock.json | 18 ++++++++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 5501dbef..21975d9c 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ docs/build restapi/.env restapi/fullchain.pem restapi/privkey.pem +webapp/.env diff --git a/restapi/package.json b/restapi/package.json index a3a716bf..656ed0a3 100644 --- a/restapi/package.json +++ b/restapi/package.json @@ -2,9 +2,8 @@ "name": "restapi", "version": "1.0.0", "scripts": { - "start": "ts-node-dev ./server.ts", - "test": "jest --runInBand --coverage", - "pretest:e2e": "dotenv --dotenv=./.env export SSL_PRIVKEY=$SSL_PRIVKEY && export SSL_CERT=$SSL_CERT" + "start": "dotenv --dotenv=./.env node -r dotenv/config ts-node-dev ./server.ts", + "test": "jest --runInBand --coverage" }, "keywords": [], "author": "", diff --git a/webapp/package-lock.json b/webapp/package-lock.json index d062ccaf..872e866d 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -75,6 +75,7 @@ "@types/puppeteer": "^5.4.4", "@types/react-window": "^1.8.5", "@types/solid-auth-client": "^2.4.1", + "dotenv": "^16.0.3", "eslint-plugin-react-hooks": "^4.6.0", "expect-puppeteer": "^6.0.2", "jest": "^29.5.0", @@ -15141,12 +15142,12 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/dotenv-expand": { @@ -32364,6 +32365,15 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/react-scripts/node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", From a612626559596ce0f739be108aa9826263d92e75 Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 15:49:12 +0200 Subject: [PATCH 08/13] test e2e --- .github/workflows/lomap_es2c.yml | 4 ++-- .gitignore | 2 +- restapi/package-lock.json | 3 ++- restapi/package.json | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lomap_es2c.yml b/.github/workflows/lomap_es2c.yml index b2f4b0c1..ed1f1f02 100644 --- a/.github/workflows/lomap_es2c.yml +++ b/.github/workflows/lomap_es2c.yml @@ -42,8 +42,8 @@ jobs: cd restapi touch .env echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env - echo SSL_CERT=${{ secrets.SSL_CERT }} >> .env - echo SSL_PRIVKEY=${{ secrets.SSL_PRIVKEY }} >> .env + echo SSL_CERT=./fullchain.pem >> .env + echo SSL_PRIVKEY=./privkey.pem >> .env cat .env - run: npm --prefix webapp install - run: npm --prefix restapi install diff --git a/.gitignore b/.gitignore index 21975d9c..f1b7335e 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,4 @@ docs/build restapi/.env restapi/fullchain.pem restapi/privkey.pem -webapp/.env + diff --git a/restapi/package-lock.json b/restapi/package-lock.json index 93eb9d9c..7ebf6244 100644 --- a/restapi/package-lock.json +++ b/restapi/package-lock.json @@ -13,7 +13,6 @@ "bcryptjs": "^2.4.3", "body-parser": "^1.20.1", "cors": "^2.8.5", - "dotenv": "^16.0.3", "express": "^4.18.2", "express-prom-bundle": "^6.6.0", "express-validator": "^6.15.0", @@ -28,6 +27,7 @@ "@types/jest": "^29.5.0", "@types/node": "^18.11.18", "@types/supertest": "^2.0.12", + "dotenv": "^16.0.3", "jest": "^29.3.1", "supertest": "^6.3.3", "ts-jest": "^29.1.0", @@ -2184,6 +2184,7 @@ "version": "16.0.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, "engines": { "node": ">=12" } diff --git a/restapi/package.json b/restapi/package.json index 656ed0a3..77624aa6 100644 --- a/restapi/package.json +++ b/restapi/package.json @@ -2,7 +2,7 @@ "name": "restapi", "version": "1.0.0", "scripts": { - "start": "dotenv --dotenv=./.env node -r dotenv/config ts-node-dev ./server.ts", + "start": "ts-node-dev ./server.ts", "test": "jest --runInBand --coverage" }, "keywords": [], From 56c6aa50ee4a9f53c57a02f740d4e22bf5035312 Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 15:59:06 +0200 Subject: [PATCH 09/13] update lomap_es2c.yml --- .github/workflows/lomap_es2c.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lomap_es2c.yml b/.github/workflows/lomap_es2c.yml index ed1f1f02..a3209038 100644 --- a/.github/workflows/lomap_es2c.yml +++ b/.github/workflows/lomap_es2c.yml @@ -42,8 +42,8 @@ jobs: cd restapi touch .env echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env - echo SSL_CERT=./fullchain.pem >> .env - echo SSL_PRIVKEY=./privkey.pem >> .env + echo SSL_CERT=${{ secrets.SSL_CERT_E2E }}>> .env + echo SSL_PRIVKEY=${{ secrets.SSL_PRIVKEY_E2E }} >> .env cat .env - run: npm --prefix webapp install - run: npm --prefix restapi install From 90c101f926032945994e2969ae3940a48726be78 Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 16:07:57 +0200 Subject: [PATCH 10/13] update lomap_es2c.yml --- .github/workflows/lomap_es2c.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lomap_es2c.yml b/.github/workflows/lomap_es2c.yml index a3209038..6cac285f 100644 --- a/.github/workflows/lomap_es2c.yml +++ b/.github/workflows/lomap_es2c.yml @@ -41,9 +41,8 @@ jobs: run: | cd restapi touch .env + echo SSL_CERT=${{ secrets.SSL_CERT }} >> .env echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env - echo SSL_CERT=${{ secrets.SSL_CERT_E2E }}>> .env - echo SSL_PRIVKEY=${{ secrets.SSL_PRIVKEY_E2E }} >> .env cat .env - run: npm --prefix webapp install - run: npm --prefix restapi install @@ -69,7 +68,6 @@ jobs: docker-push-restapi: name: Push restapi Docker Image to GitHub Packages env: - DATABASE_USER: ${{ secrets.DATABASE_URL }} SSL_CERT: ${{ secrets.SSL_CERT }} SSL_PRIVKEY: ${{ secrets.SSL_PRIVKEY }} runs-on: ubuntu-latest @@ -84,7 +82,7 @@ jobs: password: ${{ secrets.DOCKER_PUSH_TOKEN }} registry: ghcr.io workdir: restapi - buildargs: DATABASE_URL,SSL_CERT,SSL_PRIVKEY + buildargs: SSL_CERT,SSL_PRIVKEY deploy: name: Deploy over SSH runs-on: ubuntu-latest From d17598e2cdff94eea4ab9f2c13b554b153998225 Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 18:00:35 +0200 Subject: [PATCH 11/13] fixed mistake in lomap_es2c.yml file --- .github/workflows/lomap_es2c.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lomap_es2c.yml b/.github/workflows/lomap_es2c.yml index 6cac285f..0df80573 100644 --- a/.github/workflows/lomap_es2c.yml +++ b/.github/workflows/lomap_es2c.yml @@ -41,8 +41,8 @@ jobs: run: | cd restapi touch .env - echo SSL_CERT=${{ secrets.SSL_CERT }} >> .env - echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env + echo SSL_CERT=${{ secrets.SSL_CERT_E2E }} >> .env + echo SSL_PRIVKEY=${{ secrets.SSL_PRIVKEY_E2E }} >> .env cat .env - run: npm --prefix webapp install - run: npm --prefix restapi install From 1836214b5eab8226e603a3414c7a777b8793aa0e Mon Sep 17 00:00:00 2001 From: uo269745 Date: Mon, 1 May 2023 23:16:56 +0200 Subject: [PATCH 12/13] trying to run e2e --- .github/workflows/lomap_es2c.yml | 4 +- webapp/package-lock.json | 185 ++++++++++++++++---------- webapp/package.json | 1 + webapp/public/fotosCarrusel/logo.jpeg | Bin 5625 -> 0 bytes webapp/public/index.html | 6 - webapp/public/manifest.json | 25 ---- 6 files changed, 118 insertions(+), 103 deletions(-) delete mode 100644 webapp/public/fotosCarrusel/logo.jpeg delete mode 100644 webapp/public/manifest.json diff --git a/.github/workflows/lomap_es2c.yml b/.github/workflows/lomap_es2c.yml index 0df80573..7174eb65 100644 --- a/.github/workflows/lomap_es2c.yml +++ b/.github/workflows/lomap_es2c.yml @@ -41,8 +41,8 @@ jobs: run: | cd restapi touch .env - echo SSL_CERT=${{ secrets.SSL_CERT_E2E }} >> .env - echo SSL_PRIVKEY=${{ secrets.SSL_PRIVKEY_E2E }} >> .env + echo "SSL_PRIVKEY=./privkey.pem" >> .env + echo "SSL_CERT=./fullchain.pem" >> .env cat .env - run: npm --prefix webapp install - run: npm --prefix restapi install diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 872e866d..02114657 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -46,6 +46,7 @@ "leaflet": "^1.9.3", "lodash": "^4.17.21", "node-sessionstorage": "^1.0.0", + "puppeteer-core": "^19.11.1", "react": "^17.0.2", "react-async": "^10.0.1", "react-dom": "^17.0.2", @@ -75,7 +76,6 @@ "@types/puppeteer": "^5.4.4", "@types/react-window": "^1.8.5", "@types/solid-auth-client": "^2.4.1", - "dotenv": "^16.0.3", "eslint-plugin-react-hooks": "^4.6.0", "expect-puppeteer": "^6.0.2", "jest": "^29.5.0", @@ -7470,6 +7470,35 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true }, + "node_modules/@puppeteer/browsers": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-0.5.0.tgz", + "integrity": "sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ==", + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=14.1.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@rdfjs/data-model": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@rdfjs/data-model/-/data-model-1.3.4.tgz", @@ -11001,7 +11030,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, "optional": true, "dependencies": { "@types/node": "*" @@ -11728,7 +11756,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "devOptional": true, "dependencies": { "debug": "4" }, @@ -12833,7 +12860,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "devOptional": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -13016,7 +13042,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "devOptional": true, "funding": [ { "type": "github", @@ -13058,7 +13083,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "engines": { "node": "*" } @@ -13442,8 +13466,7 @@ "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/chrome-trace-event": { "version": "1.0.3", @@ -13454,6 +13477,17 @@ "node": ">=6.0" } }, + "node_modules/chromium-bidi": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.7.tgz", + "integrity": "sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ==", + "dependencies": { + "mitt": "3.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, "node_modules/ci-info": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", @@ -13615,7 +13649,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "devOptional": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -14647,7 +14680,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "devOptional": true, "dependencies": { "ms": "2.1.2" }, @@ -14958,8 +14990,7 @@ "node_modules/devtools-protocol": { "version": "0.0.981744", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.981744.tgz", - "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", - "dev": true + "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==" }, "node_modules/didyoumean": { "version": "1.2.2", @@ -15141,15 +15172,6 @@ "tslib": "^2.0.3" } }, - "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/dotenv-expand": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", @@ -15241,7 +15263,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "devOptional": true, "dependencies": { "once": "^1.4.0" } @@ -15455,7 +15476,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "devOptional": true, "engines": { "node": ">=6" } @@ -17505,7 +17525,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -17525,7 +17544,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -17676,7 +17694,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, "dependencies": { "pend": "~1.2.0" } @@ -18401,8 +18418,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-exists-sync": { "version": "0.1.0", @@ -18509,7 +18525,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "devOptional": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -19295,7 +19310,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "devOptional": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -19930,7 +19944,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "devOptional": true, "engines": { "node": ">=8" } @@ -28299,6 +28312,11 @@ "optional": true, "peer": true }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==" + }, "node_modules/mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -28361,14 +28379,12 @@ "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "devOptional": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/msrcrypto": { "version": "1.5.8", @@ -29206,7 +29222,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "devOptional": true, "dependencies": { "wrappy": "1" } @@ -29668,8 +29683,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/performance-now": { "version": "2.1.0", @@ -31179,7 +31193,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "devOptional": true, "engines": { "node": ">=0.4.0" } @@ -31274,8 +31287,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/ps-tree": { "version": "1.2.0", @@ -31302,7 +31314,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "devOptional": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -31341,6 +31352,60 @@ "node": ">=10.18.1" } }, + "node_modules/puppeteer-core": { + "version": "19.11.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.11.1.tgz", + "integrity": "sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA==", + "dependencies": { + "@puppeteer/browsers": "0.5.0", + "chromium-bidi": "0.4.7", + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1107588", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.13.0" + }, + "engines": { + "node": ">=14.14.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1107588", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz", + "integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==" + }, + "node_modules/puppeteer-core/node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/puppeteer/node_modules/ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", @@ -33277,7 +33342,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "devOptional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -33552,7 +33616,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -35451,7 +35514,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "devOptional": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -35479,7 +35541,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "devOptional": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -35492,8 +35553,7 @@ "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/string.prototype.matchall": { "version": "4.0.8", @@ -35560,7 +35620,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -35978,7 +36037,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -35990,7 +36048,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -36237,8 +36294,7 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "devOptional": true + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/through2": { "version": "2.0.5", @@ -36980,7 +37036,6 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -37262,8 +37317,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "devOptional": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/util.promisify": { "version": "1.0.1", @@ -38305,7 +38359,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -38322,7 +38375,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "devOptional": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -38337,7 +38389,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "devOptional": true, "dependencies": { "color-name": "~1.1.4" }, @@ -38348,14 +38399,12 @@ "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "devOptional": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "devOptional": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -38473,7 +38522,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "devOptional": true, "engines": { "node": ">=10" } @@ -38493,10 +38541,9 @@ } }, "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "devOptional": true, + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -38514,7 +38561,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "devOptional": true, "engines": { "node": ">=12" } @@ -38523,7 +38569,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/webapp/package.json b/webapp/package.json index 665520b9..f975c549 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -40,6 +40,7 @@ "leaflet": "^1.9.3", "lodash": "^4.17.21", "node-sessionstorage": "^1.0.0", + "puppeteer-core": "^19.11.1", "react": "^17.0.2", "react-async": "^10.0.1", "react-dom": "^17.0.2", diff --git a/webapp/public/fotosCarrusel/logo.jpeg b/webapp/public/fotosCarrusel/logo.jpeg deleted file mode 100644 index 5c5de9318365f60f30a72f4127182427ee634acf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5625 zcmbW4cT`jDlgC4oCRLggK><;^AP9kw7nI&!dM7F(9i)d6B194CpokIy>C#1-bWxfj z1PCNZ?@b zeFFNO-oBdOaF(9iaL~X({RwzUA=XIQ`3z8f&Zmz3egN)T4{MTos6Q2 z=DXYv1BRJ+#BR@v@BKmhhwOg`7W4li`xn@MaZLa&(oj*7N5cUC15Q}uZ&b&F?=S@` zXSh?j7qqLP3zAmST$1djk)HX9>9AY6sh-oRGp}vjibzrz*`lWqPoW^Hhn{2TFuz3nrR?p*@g_|PpOqleZ+eXo6CCt`8aI007#^5>)>Ry{u9h#dD z#Y+uqbBod4Pz&%!lYr(?Ip-N`9c)noWPpbQ8Q_UCdtq@&-?hY-qkd*4Jm)0=uD*&j z2wFCGEO!aFbhUT zZ!I0YPHmVeoWcNlN-F2==3gnQ^7K2)=a-01^zdr*{0j7D3J;>e#`hf_ZrR){i`u+> zJ44%Guds5(FfbG}wWYrQJm zJ(hIsXkeb@8l$w2D9x6lUW@a3iZi?!7ICjICeTUH#&=z*?;=5ubuCio-Xk`0AqQJV1pMkQ8310b z=SBgOeNP30C4Uw+A?q8|m?3d&Vcrc!}kt9;{7gkiz7U<=+K_c z0Z$*tB|17JN1Y^32_wg`lJ%i_nCjaCecPLE(CbEX)vAkm^f4NBW7;wjgiQW2!#7p! zFatQmK&o!^aMF~2998adi$Te@=X6V1BM}^L+t#K_22|_?UqU38uDP1$)?$NH%+c1_ ze{0%O9z~7Mw@Z@wUjGnFF8RBU5k4@nlj1VF+dgWXCV%}% z>xdO6sJjh?yD8b&?uF!)ZS!qH_biF|a zrL~c}9(!I!9(f!S#IhOiOgF)LOV@vg48W~v@{)qjc7CC!yJa-QiDW>hI+_f?I<#}_ zCaosaU!~=Xp8;n@WS-W@l@jLW;P^gxY$WeT=quX@ktA=ChrW+9^w<{>?+J5faQokT zehHP*L9;|1(w);v1r1r*%-CjM5*ZLmN|wB89BHLY`n5h{W>VyoxgeLI?&MK2&c;gg zBiKKJY*f9T-$pi}2!XlP==hfW4W3+%y0toxuNi9%=N6?H%1=bEtO}i;g&(7;n@}M4 zAAF)Qs;H5yYFVF zv8TRlxbNQ0N*RUsZBjI^n~FR$fwFmY%Y~IJT{2B}aI+Mn@T0yRCy9i*Ntk($9Oru4 zaY&=g^7LdisRcEAPCeb;@pMV;equ5n4du0s#hmykkO3dLRZB(uSuW zaw-jNU|{&$)Qzb4j&y70y(Ff#2$hd(w7w(N;QmN*=6rD+Px8#im>awQ5_EKWXWzUN zJ0u3I$5aEi5&Df0l_drGiPz2oOqU&#Lab%Zkh?8r?=CU5fZ^pOG4g8a== zGb>xA?ZOKyFeO#Pgm-eX*S};W^ebkDfDEtbe_U7DLf6ZBt8Sz&}L_wN05Z`=Ioia3WvzQM(`lv?-NfG%##p?&l!*K z%!t^-Md4VWAU4j?q2J42Oi^dpSl~5uoZae$uLs5ky^c+DoHP`p2z=z8iU_vAm^-(- zO@4qO8QmSScYY+x?Z*{*g$y{add5+)jL!((lSyk`#dl?eWS!<_maYU@zMAa!QcoQa z&{b%%(WRC5eJesB12pi$C996cwg=wmPfenQukTj$D39Ze z$4~@8f&}RRJFp(0!!VZ|cvx9F`Xt=5xxiB?`_43IIMjaFmjwRU?+Rm#g$^=+1cs_V zf@(+ymY6nPU5t#zwe=eJtf_pVha%SfX1>+EQ!Z1K##rqvZ2OO&u^Wsd7J7mhO8x~( zsm2dj8Fb?I{4 zIjs=vGw|@runDVg-_LAS%Zz;eMd+ikAQ_r2HCtp{RR5D{Md?RRXHH|`JFgtwHk{v8 z5YyCs=7oZ?mHgW9To1h7oXuBs#r4MK&-40mB0`>| zx|^R&i=O`ZecDmRe{39@K^ikm^f#(JIrZDW-W490-c)Si+j^ z{_@ybG*9{7ZR2aB+41I5x{RzVwc7-0GFfqD)SgX@aJ1Wx=u! zPlBiJ{I|Zj89qPOG0(FnLAq|H^~udQtB?KFRhdTL8UJtiRiOxM{C?O*&ROj?Sa{UR zs$}y~#m{O(+VYy&s$murcCT<>lF*K>ZQ4QKHpw zC!NC(VwQB8``2zU!f&pHA=0Xf_vLHfPw26Renr+qSkoFTY?Gy>{xh-3O=h6g-pn9MFEY4IdgQ+T{C;lbyLfeS-iRQ*)5 zlZ~c<69WrdY71X8@3mMI8Hr678x877@G&i_ze24hw?+2b4g0BsOATFMj4@Eu-9FJ8 z`Y#$|m3{%rC5`Z*wMx$?WPlq6WY;mLd?3?mdMTi?u>ZOmXOUi&>50FS+tYwg#4JZw zofKe{v?bHh3o@XpCbRQWddcqmfe2w^%jubGJ=^m@9oFNzE&WFzlkp`Zwt?sVcx)u_ z_ebM0_W+IIGW*;9zADtN$EoLGB;3tN6VT8DJTfKNCEemUq{Lib;I3#7&MK|pb6O0; zT)dQk!`h>Z^V{H)jLLwT`O?=gbZI>L)IXUiEba~{m-P4w#TS5jnw`9*X;UZ04(7u+H_EoiO zEnx`@rku{i67%$<6XQXsE%te0h}9JY{$z|Rd%;F*l>2L8(*y9ymEaG zF@(s1Wh_xj%Eo%6j+aAuDUFpu2{$1!bS`7+Bb(1s+~ldK{$!51jz-XJmjFoH2AbPG zpMboZ=Bn{T>7Tnv%yrOdf1GTutu#CWQI9ScdLz`>=1iB}7ybAR7s{W-Fr0T6 zIz+y~cs!*}y#Gn)tR;w`06pyvwO`(=IaTv$_DS2nk3QPk|9ZYFL=+4X0->ZfEL3mE zxtXr~!VOqB_vB1RbP%bRR#gd$2>I2d09|4jZ0VIc?;pKc{uJ3Cr3TMS1T9161#ANGGcF^Uq~la9!U^{&I5 z66kB?!QcDl&NZH^E6yW@nb&U-kzFq{{Ib3q`*o;p{sO6zQd9@oZZ1GLXQAa5=||`P z=xkeuBFPVDUV26Pf%;zK6Sr)k2LsNgu9E}ERMOv=%&uPRbl7~mPQ3)d0o;^g8r4Md zT#awN=~nJhxd36Q+PF@)y$Lw3L^c87Z1f^Qy@F3vWMN^I9gM`!gm3ogQxokjes63A z)Wn?U$bh&arq&ZnG9dOk_gP7c-8A@X@44L|EN~`%n`ATZAmd=9A-+4Y{rN#Vu3LA& zdwP(57vFcZm`u;Ov5qAJs%=eJk*c_npzLNkV~fTu+1#&LsII zFV!|H*sB$c{Pu~G_L#)>*X=pg!R32+*6B++_E9CKs?CjAlrHRh&HeGq27Q5GYavZS zQEf|B4^Ao}jQ{fD{U2g(7fUEJc<#D$V!zj(m+4HqQ%QnM!Evm7qbCSNBxz&=54+@c zqTE8>7EQo&NtXuX!(DPRhKRgcDfXCWnGjjzxd*8nA%!s@4#km6#Ickw2vn-Q|caij8 zjy$lJL)D;&2@aWEz~z-Z`H9D`Bs-@6mM}>hA%9GrK2)d{;-RQpxt@Iw)1ml*4Di+XfUlIGzk}ip zv`-C&hq0JEOc_ZTiC@9_Bb_hpS*c=7_smLvsyU{JC1nHC?8ikk>9-r1?8@PX z9O@izS8zpQwx*)bX4tMw`F}k)nb<8!kW-f^6(1{iW$Txgc%24gsLBeoJ_?-N2d<48 zM*xvgIx4-I=#OLoKg1V5LoELm629_wMtpZpg20M$ zXBhY*8}CZiWlP*gUEZ=jtc5mbG<{M?m|pz3AJ`G<{jebjLgQ&)C+v;%%`B$+GV9El zkaDDJebg&l1VMK5!=L*+`n>zqCGgr7(k9zqlr^BHdY27*Jl2yd*Cydg%+h+5(s9R? zn5~K_m_QOC9Gi~l`l#EBen9ph|#u2hWUvqxq9PH@#y1MmG zqC3liER1_CdwCYN-~EPv3-zjyon?0qnLy+ohc{^4JI0Gc{fcjv8104>47At63Ujxe zCyu{sbgRL<(zxmy>-`pNfS}f*!m+`Yb9OJrj!|f>o@98~;9hQ*OT5{flpbX`g_hs@ z8@~E_lMML4-DhT)Bm9H-qOOFL`*LlDcl0(JEhM3jWau9?e$CLqP+9xcc&3Ud#mg#K zPH-)xF&&i$eLTUNx}yk@duxe5z9epuliTO-C~~s!rh4*+tYt;}foY||t>qYfe*WG# xB{_D}RnI%=PGGYyr1DMPr(mjy+O_ - - -